[llvm] r352626 - [llvm-objcopy] Support -X|--discard-locals.

Jordan Rupprecht via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 30 06:58:13 PST 2019


Author: rupprecht
Date: Wed Jan 30 06:58:13 2019
New Revision: 352626

URL: http://llvm.org/viewvc/llvm-project?rev=352626&view=rev
Log:
[llvm-objcopy] Support -X|--discard-locals.

Summary:
This adds support for the --discard-locals flag, which acts similarly to --discard-all, except it only applies to compiler-generated symbols (i.e. symbols starting with `.L` in ELF).

I am not sure about COFF local symbols: those appear to also use `.L` in most cases, but also use just `L` in other cases, so for now I am just leaving it unimplemented there.

Fixes PR36160

Reviewers: jhenderson, alexshap, jakehehrlich, mstorsjo, espindola

Reviewed By: jhenderson

Subscribers: llvm-commits, emaste, arichardson

Differential Revision: https://reviews.llvm.org/D57248

Added:
    llvm/trunk/test/tools/llvm-objcopy/ELF/discard-locals-rel.test
    llvm/trunk/test/tools/llvm-objcopy/ELF/discard-locals.test
    llvm/trunk/test/tools/llvm-objcopy/ELF/discard-mix-local-and-all.test
Modified:
    llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
    llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp
    llvm/trunk/tools/llvm-objcopy/CopyConfig.h
    llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
    llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td
    llvm/trunk/tools/llvm-objcopy/StripOpts.td

Added: llvm/trunk/test/tools/llvm-objcopy/ELF/discard-locals-rel.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/discard-locals-rel.test?rev=352626&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/discard-locals-rel.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/discard-locals-rel.test Wed Jan 30 06:58:13 2019
@@ -0,0 +1,27 @@
+# RUN: yaml2obj %s > %t
+# RUN: not llvm-objcopy --discard-locals %t %t2 2>&1 | FileCheck %s
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    Info:            .text
+    Relocations:
+      - Offset: 0x1000
+        Symbol: .L.rel
+        Type:   R_X86_64_PC32
+Symbols:
+  Local:
+    - Name:     .L.rel
+      Type:     STT_FUNC
+      Section:  .text
+
+# CHECK: not stripping symbol '.L.rel' because it is named in a relocation.

Added: llvm/trunk/test/tools/llvm-objcopy/ELF/discard-locals.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/discard-locals.test?rev=352626&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/discard-locals.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/discard-locals.test Wed Jan 30 06:58:13 2019
@@ -0,0 +1,121 @@
+# RUN: yaml2obj %s > %t
+# RUN: cp %t %t1
+# RUN: llvm-objcopy --discard-locals %t %t2
+# Verify that llvm-objcopy has not modified the input.
+# RUN: cmp %t %t1
+# RUN: llvm-readobj --symbols %t2 | FileCheck %s
+
+# RUN: llvm-objcopy -X %t %t3
+# Verify that llvm-objcopy has not modified the input.
+# RUN: cmp %t %t1
+# RUN: cmp %t2 %t3
+
+# Verify that llvm-strip modifies the symbol table the same way.
+
+# RUN: cp %t %t4
+# RUN: llvm-strip --discard-locals %t4
+# RUN: cmp %t2 %t4
+
+# RUN: cp %t %t5
+# RUN: llvm-strip -X %t5
+# RUN: cmp %t2 %t5
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+  - Name:            .LLVM.Custom.Section
+    Type:            SHT_PROGBITS
+Symbols:
+  Local:
+    - Name:     Local
+      Type:     STT_FUNC
+      Section:  .text
+    - Name:     .L.LocalSection
+      Type:     STT_SECTION
+      Section:  .text
+    - Type:     STT_SECTION
+      Section:  .LLVM.Custom.Section
+    - Name:     .L.LocalFile
+      Type:     STT_FILE
+    - Name:     .L.str
+      Type:     STT_OBJECT
+      Section:  .text
+    - Name:     .L.undefined
+    - Name:     .L.abs
+      Index:    SHN_ABS
+  Global:
+    - Name:     .L.Global
+      Type:     STT_FUNC
+      Section:  .text
+
+# CHECK:      Symbols [
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name:
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: None
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Undefined
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: Local
+# CHECK-NEXT:     Value:
+# CHECK-NEXT:     Size:
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: Function
+# CHECK-NEXT:     Other:
+# CHECK-NEXT:     Section: .text
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: .L.LocalSection
+# CHECK-NEXT:     Value:
+# CHECK-NEXT:     Size:
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: Section
+# CHECK-NEXT:     Other:
+# CHECK-NEXT:     Section: .text
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name:
+# CHECK-NEXT:     Value:
+# CHECK-NEXT:     Size:
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: Section
+# CHECK-NEXT:     Other:
+# CHECK-NEXT:     Section: .LLVM.Custom.Section
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: .L.LocalFile
+# CHECK-NEXT:     Value:
+# CHECK-NEXT:     Size:
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: File
+# CHECK-NEXT:     Other:
+# CHECK-NEXT:     Section: Undefined
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: .L.undefined
+# CHECK-NEXT:     Value:
+# CHECK-NEXT:     Size:
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: None
+# CHECK-NEXT:     Other:
+# CHECK-NEXT:     Section: Undefined
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: .L.Global
+# CHECK-NEXT:     Value:
+# CHECK-NEXT:     Size:
+# CHECK-NEXT:     Binding: Global
+# CHECK-NEXT:     Type: Function
+# CHECK-NEXT:     Other:
+# CHECK-NEXT:     Section: .text
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]

Added: llvm/trunk/test/tools/llvm-objcopy/ELF/discard-mix-local-and-all.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/discard-mix-local-and-all.test?rev=352626&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/discard-mix-local-and-all.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/discard-mix-local-and-all.test Wed Jan 30 06:58:13 2019
@@ -0,0 +1,107 @@
+# RUN: yaml2obj %s > %t
+# Establish baseline objects for further checks. --discard-locals only discards
+# compiler-generated local symbols (starting with .L), --discard-all discards
+# all regular local symbols.
+# RUN: llvm-objcopy %t %t-discard-none
+# RUN: llvm-readobj --symbols %t-discard-none | FileCheck %s --check-prefixes=CHECK,LOCAL,COMPILER-LOCAL
+# RUN: llvm-objcopy --discard-all %t %t-discard-all
+# RUN: llvm-readobj --symbols %t-discard-all | FileCheck %s
+# RUN: llvm-objcopy --discard-locals %t %t-discard-locals
+# RUN: llvm-readobj --symbols %t-discard-locals | FileCheck %s --check-prefixes=CHECK,LOCAL
+
+# When mixing --discard-all and --discard-locals, the last one wins.
+# RUN: llvm-objcopy --discard-all --discard-locals %t %t.1.o
+# RUN: cmp %t.1.o %t-discard-locals
+# RUN: llvm-objcopy --discard-locals --discard-all %t %t.2.o
+# RUN: cmp %t.2.o %t-discard-all
+# RUN: llvm-objcopy -x -X %t %t.3.o
+# RUN: cmp %t.3.o %t-discard-locals
+# RUN: llvm-objcopy -X -x %t %t.4.o
+# RUN: cmp %t.4.o %t-discard-all
+# RUN: llvm-objcopy -x -X -x -X %t %t.5.o
+# RUN: cmp %t.5.o %t-discard-locals
+# RUN: llvm-objcopy -X -x -X -x %t %t.6.o
+# RUN: cmp %t.6.o %t-discard-all
+# RUN: llvm-objcopy -X -x -X -x --discard-locals %t %t.7.o
+# RUN: cmp %t.7.o %t-discard-locals
+# RUN: llvm-objcopy -X -x -X -x --discard-all %t %t.8.o
+# RUN: cmp %t.8.o %t-discard-all
+
+# llvm-strip works in the same way.
+# RUN: llvm-strip --discard-all --discard-locals %t -o %t.9.o
+# RUN: cmp %t.9.o %t-discard-locals
+# RUN: llvm-strip --discard-locals --discard-all %t -o %t.10.o
+# RUN: cmp %t.10.o %t-discard-all
+# RUN: llvm-strip -x -X %t -o %t.11.o
+# RUN: cmp %t.11.o %t-discard-locals
+# RUN: llvm-strip -X -x %t -o %t.12.o
+# RUN: cmp %t.12.o %t-discard-all
+# RUN: llvm-strip -x -X -x -X %t -o %t.13.o
+# RUN: cmp %t.13.o %t-discard-locals
+# RUN: llvm-strip -X -x -X -x %t -o %t.14.o
+# RUN: cmp %t.14.o %t-discard-all
+# RUN: llvm-strip -X -x -X -x --discard-locals %t -o %t.15.o
+# RUN: cmp %t.15.o %t-discard-locals
+# RUN: llvm-strip -X -x -X -x --discard-all %t -o %t.16.o
+# RUN: cmp %t.16.o %t-discard-all
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+Symbols:
+  Local:
+    - Name:     Local
+      Type:     STT_FUNC
+      Section:  .text
+    - Name:     .L.str
+      Type:     STT_OBJECT
+      Section:  .text
+  Global:
+    - Name:     Global
+      Type:     STT_FUNC
+      Section:  .text
+
+# CHECK:               Symbols [
+# CHECK-NEXT:            Symbol {
+# CHECK-NEXT:              Name:
+# CHECK-NEXT:              Value: 0x0
+# CHECK-NEXT:              Size: 0
+# CHECK-NEXT:              Binding: Local
+# CHECK-NEXT:              Type: None
+# CHECK-NEXT:              Other: 0
+# CHECK-NEXT:              Section: Undefined
+# CHECK-NEXT:            }
+# LOCAL-NEXT:            Symbol {
+# LOCAL-NEXT:              Name: Local
+# LOCAL-NEXT:              Value:
+# LOCAL-NEXT:              Size:
+# LOCAL-NEXT:              Binding: Local
+# LOCAL-NEXT:              Type: Function
+# LOCAL-NEXT:              Other:
+# LOCAL-NEXT:              Section: .text
+# LOCAL-NEXT:            }
+# COMPILER-LOCAL-NEXT:   Symbol {
+# COMPILER-LOCAL-NEXT:     Name: .L.str
+# COMPILER-LOCAL-NEXT:     Value:
+# COMPILER-LOCAL-NEXT:     Size:
+# COMPILER-LOCAL-NEXT:     Binding: Local
+# COMPILER-LOCAL-NEXT:     Type: Object
+# COMPILER-LOCAL-NEXT:     Other:
+# COMPILER-LOCAL-NEXT:     Section: .text
+# COMPILER-LOCAL-NEXT:   }
+# CHECK-NEXT:            Symbol {
+# CHECK-NEXT:              Name: Global
+# CHECK-NEXT:              Value:
+# CHECK-NEXT:              Size:
+# CHECK-NEXT:              Binding: Global
+# CHECK-NEXT:              Type: Function
+# CHECK-NEXT:              Other:
+# CHECK-NEXT:              Section: .text
+# CHECK-NEXT:            }
+# CHECK-NEXT:          ]

Modified: llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp?rev=352626&r1=352625&r2=352626&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp Wed Jan 30 06:58:13 2019
@@ -97,7 +97,7 @@ static Error handleArgs(const CopyConfig
       return true;
 
     if (Config.StripDebug || Config.StripAll || Config.StripAllGNU ||
-        Config.DiscardAll || Config.StripUnneeded) {
+        Config.DiscardMode == DiscardType::All || Config.StripUnneeded) {
       if (isDebugSection(Sec) &&
           (Sec.Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0)
         return true;
@@ -125,7 +125,7 @@ static Error handleArgs(const CopyConfig
       Sec.Relocs.clear();
 
   // If we need to do per-symbol removals, initialize the Referenced field.
-  if (Config.StripUnneeded || Config.DiscardAll ||
+  if (Config.StripUnneeded || Config.DiscardMode == DiscardType::All ||
       !Config.SymbolsToRemove.empty())
     if (Error E = Obj.markSymbols())
       return E;
@@ -159,7 +159,8 @@ static Error handleArgs(const CopyConfig
       // GNU objcopy keeps referenced local symbols and external symbols
       // if --discard-all is set, similar to what --strip-unneeded does,
       // but undefined local symbols are kept when --discard-all is set.
-      if (Config.DiscardAll && Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC &&
+      if (Config.DiscardMode == DiscardType::All &&
+          Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC &&
           Sym.Sym.SectionNumber != 0)
         return true;
     }
@@ -180,7 +181,8 @@ static Error handleArgs(const CopyConfig
       !Config.SetSectionFlags.empty() || !Config.SymbolsToRename.empty() ||
       Config.ExtractDWO || Config.KeepFileSymbols || Config.LocalizeHidden ||
       Config.PreserveDates || Config.StripDWO || Config.StripNonAlloc ||
-      Config.StripSections || Config.Weaken || Config.DecompressDebugSections) {
+      Config.StripSections || Config.Weaken || Config.DecompressDebugSections ||
+      Config.DiscardMode == DiscardType::Locals) {
     return createStringError(llvm::errc::invalid_argument,
                              "Option not supported by llvm-objcopy for COFF");
   }

Modified: llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp?rev=352626&r1=352625&r2=352626&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp Wed Jan 30 06:58:13 2019
@@ -387,7 +387,11 @@ DriverConfig parseObjcopyOptions(ArrayRe
   Config.ExtractDWO = InputArgs.hasArg(OBJCOPY_extract_dwo);
   Config.LocalizeHidden = InputArgs.hasArg(OBJCOPY_localize_hidden);
   Config.Weaken = InputArgs.hasArg(OBJCOPY_weaken);
-  Config.DiscardAll = InputArgs.hasArg(OBJCOPY_discard_all);
+  if (InputArgs.hasArg(OBJCOPY_discard_all, OBJCOPY_discard_locals))
+    Config.DiscardMode =
+        InputArgs.hasFlag(OBJCOPY_discard_all, OBJCOPY_discard_locals)
+            ? DiscardType::All
+            : DiscardType::Locals;
   Config.OnlyKeepDebug = InputArgs.hasArg(OBJCOPY_only_keep_debug);
   Config.KeepFileSymbols = InputArgs.hasArg(OBJCOPY_keep_file_symbols);
   Config.DecompressDebugSections =
@@ -467,13 +471,17 @@ DriverConfig parseStripOptions(ArrayRef<
   CopyConfig Config;
   Config.StripDebug = InputArgs.hasArg(STRIP_strip_debug);
 
-  Config.DiscardAll = InputArgs.hasArg(STRIP_discard_all);
+  if (InputArgs.hasArg(STRIP_discard_all, STRIP_discard_locals))
+    Config.DiscardMode =
+        InputArgs.hasFlag(STRIP_discard_all, STRIP_discard_locals)
+            ? DiscardType::All
+            : DiscardType::Locals;
   Config.StripUnneeded = InputArgs.hasArg(STRIP_strip_unneeded);
   Config.StripAll = InputArgs.hasArg(STRIP_strip_all);
   Config.StripAllGNU = InputArgs.hasArg(STRIP_strip_all_gnu);
 
-  if (!Config.StripDebug && !Config.StripUnneeded && !Config.DiscardAll &&
-      !Config.StripAllGNU)
+  if (!Config.StripDebug && !Config.StripUnneeded &&
+      Config.DiscardMode == DiscardType::None && !Config.StripAllGNU)
     Config.StripAll = true;
 
   for (auto Arg : InputArgs.filtered(STRIP_keep_section))

Modified: llvm/trunk/tools/llvm-objcopy/CopyConfig.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/CopyConfig.h?rev=352626&r1=352625&r2=352626&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/CopyConfig.h (original)
+++ llvm/trunk/tools/llvm-objcopy/CopyConfig.h Wed Jan 30 06:58:13 2019
@@ -42,6 +42,12 @@ struct SectionFlagsUpdate {
   uint64_t NewFlags;
 };
 
+enum class DiscardType {
+  None,   // Default
+  All,    // --discard-all (-x)
+  Locals, // --discard-locals (-X)
+};
+
 // Configuration for copying/stripping a single file.
 struct CopyConfig {
   // Main input/output options
@@ -62,6 +68,7 @@ struct CopyConfig {
   Optional<StringRef> BuildIdLinkOutput;
   StringRef SplitDWO;
   StringRef SymbolsPrefix;
+  DiscardType DiscardMode = DiscardType::None;
 
   // Repeated options
   std::vector<StringRef> AddSection;
@@ -83,7 +90,6 @@ struct CopyConfig {
 
   // Boolean options
   bool DeterministicArchives = true;
-  bool DiscardAll = false;
   bool ExtractDWO = false;
   bool KeepFileSymbols = false;
   bool LocalizeHidden = false;

Modified: llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp?rev=352626&r1=352625&r2=352626&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp Wed Jan 30 06:58:13 2019
@@ -337,9 +337,11 @@ static Error handleArgs(const CopyConfig
           (Config.KeepFileSymbols && Sym.Type == STT_FILE))
         return false;
 
-      if (Config.DiscardAll && Sym.Binding == STB_LOCAL &&
-          Sym.getShndx() != SHN_UNDEF && Sym.Type != STT_FILE &&
-          Sym.Type != STT_SECTION)
+      if ((Config.DiscardMode == DiscardType::All ||
+           (Config.DiscardMode == DiscardType::Locals &&
+            StringRef(Sym.Name).startswith(".L"))) &&
+          Sym.Binding == STB_LOCAL && Sym.getShndx() != SHN_UNDEF &&
+          Sym.Type != STT_FILE && Sym.Type != STT_SECTION)
         return true;
 
       if (Config.StripAll || Config.StripAllGNU)

Modified: llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td?rev=352626&r1=352625&r2=352626&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td (original)
+++ llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td Wed Jan 30 06:58:13 2019
@@ -149,6 +149,12 @@ defm weaken_symbol : Eq<"weaken-symbol",
 def W : JoinedOrSeparate<["-"], "W">, Alias<weaken_symbol>;
 def weaken : Flag<["-", "--"], "weaken">,
              HelpText<"Mark all global symbols as weak">;
+
+def discard_locals : Flag<["-", "--"], "discard-locals">,
+                     HelpText<"Remove compiler-generated local symbols, (e.g. "
+                              "symbols starting with .L)">;
+def X : Flag<["-"], "X">, Alias<discard_locals>;
+
 def discard_all
     : Flag<["-", "--"], "discard-all">,
       HelpText<"Remove all local symbols except file and section symbols">;

Modified: llvm/trunk/tools/llvm-objcopy/StripOpts.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/StripOpts.td?rev=352626&r1=352625&r2=352626&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/StripOpts.td (original)
+++ llvm/trunk/tools/llvm-objcopy/StripOpts.td Wed Jan 30 06:58:13 2019
@@ -57,6 +57,11 @@ defm keep_symbol : Eq<"keep-symbol", "Do
                    MetaVarName<"symbol">;
 def K : JoinedOrSeparate<["-"], "K">, Alias<keep_symbol>;
 
+def discard_locals : Flag<["-", "--"], "discard-locals">,
+                     HelpText<"Remove compiler-generated local symbols, (e.g. "
+                              "symbols starting with .L)">;
+def X : Flag<["-"], "X">, Alias<discard_locals>;
+
 def discard_all
     : Flag<["-", "--"], "discard-all">,
       HelpText<"Remove all local symbols except file and section symbols">;




More information about the llvm-commits mailing list