[cfe-commits] r136294 - in /cfe/trunk: include/clang/Driver/Driver.h lib/Driver/Driver.cpp

Chad Rosier mcrosier at apple.com
Wed Jul 27 16:36:45 PDT 2011


Author: mcrosier
Date: Wed Jul 27 18:36:45 2011
New Revision: 136294

URL: http://llvm.org/viewvc/llvm-project?rev=136294&view=rev
Log:
The -fapple-kext flag was designed to "do the right thing" for building code for
use in KEXTs. However, users/Xcode still need to tweak the linker flags to do 
the right thing, and end up using -Xlinker, for example.  Instead, have the 
driver "do the right thing" when linking when -fapple-kext is present on the 
command line, and we should have Xcode use -fapple-kext instead of setting other
flags like -Xlinker -kext or -nodefaultlibs.
rdar://7809940

Modified:
    cfe/trunk/include/clang/Driver/Driver.h
    cfe/trunk/lib/Driver/Driver.cpp

Modified: cfe/trunk/include/clang/Driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=136294&r1=136293&r2=136294&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Driver.h (original)
+++ cfe/trunk/include/clang/Driver/Driver.h Wed Jul 27 18:36:45 2011
@@ -29,6 +29,7 @@
 namespace clang {
 namespace driver {
   class Action;
+  class Arg;
   class ArgList;
   class Compilation;
   class DerivedArgList;
@@ -171,6 +172,11 @@
   /// arguments, after applying the standard argument translations.
   DerivedArgList *TranslateInputArgs(const InputArgList &Args) const;
 
+  // getFinalPhase - Determine which compilation mode we are in and record 
+  // which option we used to determine the final phase.
+  phases::ID getFinalPhase(const DerivedArgList &DAL, Arg **FinalPhaseArg = 0)
+    const;
+
 public:
   Driver(StringRef _ClangExecutable,
          StringRef _DefaultHostTriple,

Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=136294&r1=136293&r2=136294&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Wed Jul 27 18:36:45 2011
@@ -120,6 +120,43 @@
   return Args;
 }
 
+// Determine which compilation mode we are in. We look for options which
+// affect the phase, starting with the earliest phases, and record which
+// option we used to determine the final phase.
+phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, Arg **FinalPhaseArg)
+const {
+  Arg *PhaseArg = 0;
+  phases::ID FinalPhase;
+  
+  // -{E,M,MM} only run the preprocessor.
+  if (CCCIsCPP ||
+      (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
+      (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM))) {
+    FinalPhase = phases::Preprocess;
+    
+    // -{fsyntax-only,-analyze,emit-ast,S} only run up to the compiler.
+  } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
+             (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
+             (PhaseArg = DAL.getLastArg(options::OPT__analyze,
+                                              options::OPT__analyze_auto)) ||
+             (PhaseArg = DAL.getLastArg(options::OPT_emit_ast)) ||
+             (PhaseArg = DAL.getLastArg(options::OPT_S))) {
+    FinalPhase = phases::Compile;
+
+    // -c only runs up to the assembler.
+  } else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
+    FinalPhase = phases::Assemble;
+
+    // Otherwise do everything.
+  } else
+    FinalPhase = phases::Link;
+
+  if (FinalPhaseArg)
+    *FinalPhaseArg = PhaseArg;
+
+  return FinalPhase;
+}
+
 DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
   DerivedArgList *DAL = new DerivedArgList(Args);
 
@@ -198,6 +235,23 @@
   }
 #endif
 
+  // If -fapple-kext has been specified, add -kext to linker command if not 
+  // already done so.  Also check to make sure we're actually linking.
+  if (Args.hasArg(options::OPT_fapple_kext) && getFinalPhase(*DAL) ==
+      phases::Link) {
+    bool add_kext = true;
+    std::vector<std::string> LinkerArgs =
+      Args.getAllArgValues(options::OPT_Xlinker);
+    for (std::vector<std::string>::iterator it = LinkerArgs.begin(), 
+           ie = LinkerArgs.end(); it != ie; it++)
+      if (*it == "-kext") {
+        add_kext = false;
+        break;
+      }
+    if (add_kext)
+      DAL->AddSeparateArg(0, Opts->getOption(options::OPT_Xlinker), "-kext");
+  }
+
   return DAL;
 }
 
@@ -818,34 +872,8 @@
     return;
   }
 
-  // Determine which compilation mode we are in. We look for options which
-  // affect the phase, starting with the earliest phases, and record which
-  // option we used to determine the final phase.
-  Arg *FinalPhaseArg = 0;
-  phases::ID FinalPhase;
-
-  // -{E,M,MM} only run the preprocessor.
-  if (CCCIsCPP ||
-      (FinalPhaseArg = Args.getLastArg(options::OPT_E)) ||
-      (FinalPhaseArg = Args.getLastArg(options::OPT_M, options::OPT_MM))) {
-    FinalPhase = phases::Preprocess;
-
-    // -{fsyntax-only,-analyze,emit-ast,S} only run up to the compiler.
-  } else if ((FinalPhaseArg = Args.getLastArg(options::OPT_fsyntax_only)) ||
-             (FinalPhaseArg = Args.getLastArg(options::OPT_rewrite_objc)) ||
-             (FinalPhaseArg = Args.getLastArg(options::OPT__analyze,
-                                              options::OPT__analyze_auto)) ||
-             (FinalPhaseArg = Args.getLastArg(options::OPT_emit_ast)) ||
-             (FinalPhaseArg = Args.getLastArg(options::OPT_S))) {
-    FinalPhase = phases::Compile;
-
-    // -c only runs up to the assembler.
-  } else if ((FinalPhaseArg = Args.getLastArg(options::OPT_c))) {
-    FinalPhase = phases::Assemble;
-
-    // Otherwise do everything.
-  } else
-    FinalPhase = phases::Link;
+  Arg *FinalPhaseArg;
+  phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
 
   // Reject -Z* at the top level, these options should never have been exposed
   // by gcc.





More information about the cfe-commits mailing list