[lld] r218321 - Make -core/-flavor options have higher priority than linker name

Rui Ueyama ruiu at google.com
Tue Sep 23 11:09:39 PDT 2014


Author: ruiu
Date: Tue Sep 23 13:09:38 2014
New Revision: 218321

URL: http://llvm.org/viewvc/llvm-project?rev=218321&view=rev
Log:
Make -core/-flavor options have higher priority than linker name

Also allows -core/flavor to appear at any position in the command line.
Patch from Oleg Ranevskyy!

http://reviews.llvm.org/D5384

Added:
    lld/trunk/test/Driver/flavor-option.test
Modified:
    lld/trunk/lib/Driver/UniversalDriver.cpp

Modified: lld/trunk/lib/Driver/UniversalDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/UniversalDriver.cpp?rev=218321&r1=218320&r2=218321&view=diff
==============================================================================
--- lld/trunk/lib/Driver/UniversalDriver.cpp (original)
+++ lld/trunk/lib/Driver/UniversalDriver.cpp Tue Sep 23 13:09:38 2014
@@ -69,10 +69,10 @@ public:
 
 enum class Flavor {
   invalid,
-  gnu_ld,       // -flavor gnu
-  win_link,     // -flavor link
-  darwin_ld,    // -flavor darwin
-  core          // -flavor core OR -core
+  gnu_ld,    // -flavor gnu
+  win_link,  // -flavor link
+  darwin_ld, // -flavor darwin
+  core       // -flavor core OR -core
 };
 
 struct ProgramNameParts {
@@ -107,7 +107,7 @@ static ProgramNameParts parseProgramName
 
   // Find the flavor component.
   auto flIter = std::find_if(components.begin(), components.end(),
-                             [](StringRef str)->bool {
+                             [](StringRef str) -> bool {
     return strToFlavor(str) != Flavor::invalid;
   });
 
@@ -123,8 +123,27 @@ static ProgramNameParts parseProgramName
   return ret;
 }
 
+// Removes the argument from argv along with its value, if exists, and updates
+// argc.
+static void removeArg(llvm::opt::Arg *arg, int &argc, const char **&argv) {
+  unsigned int numToRemove = arg->getNumValues() + 1;
+  unsigned int argIndex = arg->getIndex() + 1;
+
+  std::rotate(&argv[argIndex], &argv[argIndex + numToRemove], argv + argc);
+  argc -= numToRemove;
+}
+
 static Flavor getFlavor(int &argc, const char **&argv,
                         std::unique_ptr<llvm::opt::InputArgList> &parsedArgs) {
+  if (llvm::opt::Arg *argCore = parsedArgs->getLastArg(OPT_core)) {
+    removeArg(argCore, argc, argv);
+    return Flavor::core;
+  }
+  if (llvm::opt::Arg *argFlavor = parsedArgs->getLastArg(OPT_flavor)) {
+    removeArg(argFlavor, argc, argv);
+    return strToFlavor(argFlavor->getValue());
+  }
+
 #if LLVM_ON_UNIX
   if (llvm::sys::path::filename(argv[0]).equals("ld")) {
 #if __APPLE__
@@ -135,16 +154,7 @@ static Flavor getFlavor(int &argc, const
     return Flavor::gnu_ld;
   }
 #endif
-  if (parsedArgs->getLastArg(OPT_core)) {
-    argc--;
-    argv++;
-    return Flavor::core;
-  }
-  if (llvm::opt::Arg *argFlavor = parsedArgs->getLastArg(OPT_flavor)) {
-    argc -= 2;
-    argv += 2;
-    return strToFlavor(argFlavor->getValue());
-  }
+
   StringRef name = llvm::sys::path::stem(argv[0]);
   return strToFlavor(parseProgramName(name)._flavor);
 }
@@ -174,7 +184,7 @@ bool UniversalDriver::link(int argc, con
 
   // Handle --help
   if (parsedArgs->getLastArg(OPT_help)) {
-    table.PrintHelp(llvm::outs(), argv[0], "LLVM Linker", false);
+    table.PrintHelp(llvm::outs(), programName.data(), "LLVM Linker", false);
     return true;
   }
 

Added: lld/trunk/test/Driver/flavor-option.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/Driver/flavor-option.test?rev=218321&view=auto
==============================================================================
--- lld/trunk/test/Driver/flavor-option.test (added)
+++ lld/trunk/test/Driver/flavor-option.test Tue Sep 23 13:09:38 2014
@@ -0,0 +1,8 @@
+# a) the -flavor option is position independent and does not need to be the 1st
+#    argument in the command line (bug 20975);
+# b) UniversalDriver correctly removes -flavor along with its value and the
+#    underlying linker does not get a corrupted command line (bug 20977).
+RUN: lld --help -flavor gnu | FileCheck %s
+
+CHECK: --noinhibit-exec
+CHECK: --output-filetype





More information about the llvm-commits mailing list