]> granicus.if.org Git - clang/commitdiff
Switch autolinking metadata format over to actual linker options, e.g.,
authorDouglas Gregor <dgregor@apple.com>
Mon, 14 Jan 2013 18:28:43 +0000 (18:28 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 14 Jan 2013 18:28:43 +0000 (18:28 +0000)
  !0 = metadata !{metadata !"-lautolink"}
  !1 = metadata !{metadata !"-framework", metadata !"autolink_framework"}

referenced from llvm.module.linkoptions, e.g.,

  !llvm.module.linkoptions = !{!0, !1, !2, !3}

This conceptually moves the logic for figuring out the syntax the
linker will accept from LLVM into Clang. Moreover, it makes it easier
to support MSVC's

  #pragma comment(linker, "some option")

in the future, should anyone care to do so.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172441 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
test/Modules/autolink.m

index da37e4982d4b805425c92973c3f9c70b8528ac06..c43528866b024b78382177b74c0178e61318f970 100644 (file)
@@ -173,8 +173,7 @@ void CodeGenModule::Release() {
   EmitCtorList(GlobalDtors, "llvm.global_dtors");
   EmitGlobalAnnotations();
   EmitLLVMUsed();
-  EmitLinkLibraries();
-  
+
   SimplifyPersonality();
 
   if (getCodeGenOpts().EmitDeclMetadata)
@@ -716,24 +715,6 @@ void CodeGenModule::EmitLLVMUsed() {
   GV->setSection("llvm.metadata");
 }
 
-void CodeGenModule::EmitLinkLibraries() {
-  // If there are no libraries to link against, do nothing.
-  if (LinkLibraries.empty())
-    return;
-
-  // Create metadata for each library we're linking against.
-  llvm::NamedMDNode *Metadata
-    = getModule().getOrInsertNamedMetadata("llvm.link.libraries");
-  for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
-    llvm::Value *Args[2] = {
-      llvm::MDString::get(getLLVMContext(), LinkLibraries[I].Library),
-      llvm::ConstantInt::get(llvm::Type::getInt1Ty(getLLVMContext()),
-                             LinkLibraries[I].IsFramework)
-    };
-    Metadata->addOperand(llvm::MDNode::get(getLLVMContext(), Args));
-  }
-}
-
 void CodeGenModule::EmitDeferred() {
   // Emit code for any potentially referenced deferred decls.  Since a
   // previously unused static decl may become used during the generation of code
@@ -2802,16 +2783,44 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
       Stack.push_back(Mod);
     }
 
+    if (Stack.empty())
+      break;
+
+    // Get/create metadata for the link options.
+    llvm::NamedMDNode *Metadata
+      = getModule().getOrInsertNamedMetadata("llvm.module.linkoptions");
+
     // Find all of the non-explicit submodules of the modules we've imported and
     // import them.
     while (!Stack.empty()) {
       clang::Module *Mod = Stack.back();
       Stack.pop_back();
 
-      // Add the link libraries for this module.
-      LinkLibraries.insert(LinkLibraries.end(),
-                           Mod->LinkLibraries.begin(),
-                           Mod->LinkLibraries.end());
+      // Add linker options to link against the libraries/frameworks
+      // described by this module.
+      for (unsigned I = 0, N = Mod->LinkLibraries.size(); I != N; ++I) {
+        // FIXME: -lfoo is Unix-centric and -framework Foo is Darwin-centric.
+        // We need to know more about the linker to know how to encode these
+        // options propertly.
+
+        // Link against a framework.
+        if (Mod->LinkLibraries[I].IsFramework) {
+          llvm::Value *Args[2] = {
+            llvm::MDString::get(getLLVMContext(), "-framework"),
+            llvm::MDString::get(getLLVMContext(),
+                                Mod->LinkLibraries[I].Library)
+          };
+          
+          Metadata->addOperand(llvm::MDNode::get(getLLVMContext(), Args));
+          continue;
+        }
+
+        // Link against a library.
+        llvm::Value *OptString
+          = llvm::MDString::get(getLLVMContext(),
+                                "-l" + Mod->LinkLibraries[I].Library);
+        Metadata->addOperand(llvm::MDNode::get(getLLVMContext(), OptString));
+      }
 
       // We've imported this module; now import any of its children that haven't
       // already been imported.
index 0d644a748e053a2192d77b38302ca267aac231de..4088caca50839a5e5a725efe526e18759b795c09 100644 (file)
@@ -319,9 +319,6 @@ class CodeGenModule : public CodeGenTypeCache {
   /// \brief The complete set of modules that has been imported.
   llvm::SetVector<clang::Module *> ImportedModules;
 
-  /// \brief The set of libraries to link against.
-  std::vector<clang::Module::LinkLibrary> LinkLibraries;
-
   /// @name Cache for Objective-C runtime types
   /// @{
 
@@ -998,9 +995,6 @@ private:
   /// references to global which may otherwise be optimized out.
   void EmitLLVMUsed();
 
-  /// \brief Emit the set of libraries to link against.
-  void EmitLinkLibraries();
-
   void EmitDeclMetadata();
 
   /// EmitCoverageFile - Emit the llvm.gcov metadata used to tell LLVM where
index 3c6998f7bf3c6314d19f5293f42a407d3ef594eb..836d910914a2c572b93183006d5975e90415b721 100644 (file)
@@ -23,8 +23,8 @@ int use_no_umbrella() {
   return no_umbrella_A;
 }
 
-// CHECK: !llvm.link.libraries = !{![[AUTOLINK:[0-9]+]], ![[AUTOLINK_FRAMEWORK:[0-9]+]], ![[MODULE:[0-9]+]], ![[NOUMBRELLA:[0-9]+]]}
-// CHECK: ![[AUTOLINK]] = metadata !{metadata !"autolink", i1 false}
-// CHECK: ![[AUTOLINK_FRAMEWORK]] = metadata !{metadata !"autolink_framework", i1 true}
-// CHECK: ![[MODULE]] = metadata !{metadata !"Module", i1 true}
-// CHECK: ![[NOUMBRELLA]] = metadata !{metadata !"NoUmbrella", i1 true}
+// CHECK: !llvm.module.linkoptions = !{![[AUTOLINK:[0-9]+]], ![[AUTOLINK_FRAMEWORK:[0-9]+]], ![[MODULE:[0-9]+]], ![[NOUMBRELLA:[0-9]+]]}
+// CHECK: ![[AUTOLINK]] = metadata !{metadata !"-lautolink"}
+// CHECK: ![[AUTOLINK_FRAMEWORK]] = metadata !{metadata !"-framework", metadata !"autolink_framework"}
+// CHECK: ![[MODULE]] = metadata !{metadata !"-framework", metadata !"Module"}
+// CHECK: ![[NOUMBRELLA]] = metadata !{metadata !"-framework", metadata !"NoUmbrella"}