]> granicus.if.org Git - clang/commitdiff
Support `#pragma comment(lib, "name")` in the frontend for ELF
authorSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 7 Feb 2018 01:46:46 +0000 (01:46 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 7 Feb 2018 01:46:46 +0000 (01:46 +0000)
This adds the frontend support required to support the use of the
comment pragma to enable auto linking on ELFish targets. This is a
generic ELF extension supported by LLVM. We need to change the handling
for the "dependentlib" in order to accommodate the previously discussed
encoding for the dependent library descriptor. Without the custom
handling of the PCK_Lib directive, the -l prefixed option would be
encoded into the resulting object (which is treated as a frontend
error).

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

docs/LanguageExtensions.rst
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
lib/Parse/ParsePragma.cpp
test/CodeGen/elf-linker-options.c [new file with mode: 0644]
test/CodeGen/pragma-comment.c
test/Preprocessor/pragma-comment-linux.c [new file with mode: 0644]
test/Preprocessor/pragma_microsoft.c

index 41f161302f2b0d452c09998285a3b80bfefd472b..6d9bbcbd3a555df5362e14b25ebdfd02b06ce918 100644 (file)
@@ -2725,3 +2725,11 @@ The ``#pragma clang section`` directive obeys the following rules:
 * The decision about which section-kind applies to each global is taken in the back-end.
   Once the section-kind is known, appropriate section name, as specified by the user using
   ``#pragma clang section`` directive, is applied to that global.
+
+Specifying Linker Options on ELF Targets
+========================================
+
+The ``#pragma comment(lib, ...)`` directive is supported on all ELF targets.
+The second parameter is the library name (without the traditional Unix prefix of
+``lib``).  This allows you to provide an implicit link of dependent libraries.
+
index 760327deb173d95da2ad7838a1c68a8a354aa1c6..b39e0f445c7977245bf81872058cb55d7b636c33 100644 (file)
@@ -1411,6 +1411,12 @@ void CodeGenModule::AddDetectMismatch(StringRef Name, StringRef Value) {
   LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts));
 }
 
+void CodeGenModule::AddELFLibDirective(StringRef Lib) {
+  auto &C = getLLVMContext();
+  LinkerOptionsMetadata.push_back(llvm::MDNode::get(
+      C, {llvm::MDString::get(C, "lib"), llvm::MDString::get(C, Lib)}));
+}
+
 void CodeGenModule::AddDependentLib(StringRef Lib) {
   llvm::SmallString<24> Opt;
   getTargetCodeGenInfo().getDependentLibraryOption(Lib, Opt);
@@ -4329,7 +4335,11 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
       AppendLinkerOptions(PCD->getArg());
       break;
     case PCK_Lib:
-      AddDependentLib(PCD->getArg());
+      if (getTarget().getTriple().isOSBinFormatELF() &&
+          !getTarget().getTriple().isPS4())
+        AddELFLibDirective(PCD->getArg());
+      else
+        AddDependentLib(PCD->getArg());
       break;
     case PCK_Compiler:
     case PCK_ExeStr:
index 42e9e1be31669bf401c02ce9794c579f89f173ec..61b97e61248ec005444a9bc3977d20a5f1921e9b 100644 (file)
@@ -1094,6 +1094,8 @@ public:
   /// value.
   void AddDependentLib(StringRef Lib);
 
+  void AddELFLibDirective(StringRef Lib);
+
   llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD);
 
   void setFunctionLinkage(GlobalDecl GD, llvm::Function *F) {
index 8152176484df250c2586d5eac41df893d5392dc3..3517264d4e945fb42482a9db91297eb90ee981cd 100644 (file)
@@ -295,7 +295,8 @@ void Parser::initializePragmaHandlers() {
     OpenMPHandler.reset(new PragmaNoOpenMPHandler());
   PP.AddPragmaHandler(OpenMPHandler.get());
 
-  if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
+  if (getLangOpts().MicrosoftExt ||
+      getTargetInfo().getTriple().isOSBinFormatELF()) {
     MSCommentHandler.reset(new PragmaCommentHandler(Actions));
     PP.AddPragmaHandler(MSCommentHandler.get());
   }
@@ -377,7 +378,8 @@ void Parser::resetPragmaHandlers() {
   PP.RemovePragmaHandler(OpenMPHandler.get());
   OpenMPHandler.reset();
 
-  if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
+  if (getLangOpts().MicrosoftExt ||
+      getTargetInfo().getTriple().isOSBinFormatELF()) {
     PP.RemovePragmaHandler(MSCommentHandler.get());
     MSCommentHandler.reset();
   }
@@ -2449,6 +2451,12 @@ void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
     return;
   }
 
+  if (PP.getTargetInfo().getTriple().isOSBinFormatELF() && Kind != PCK_Lib) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
+        << II->getName();
+    return;
+  }
+
   // On PS4, issue a warning about any pragma comments other than
   // #pragma comment lib.
   if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) {
diff --git a/test/CodeGen/elf-linker-options.c b/test/CodeGen/elf-linker-options.c
new file mode 100644 (file)
index 0000000..cf2d1b9
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple i686---elf -emit-llvm %s -o - | FileCheck %s
+
+#pragma comment(lib, "alpha")
+
+// CHECK: !llvm.linker.options = !{[[NODE:![0-9]+]]}
+// CHECK: [[NODE]] = !{!"lib", !"alpha"}
+
index fae9b8fb9ed8860ba0ba8fac1acccdf5732884d1..1896e5c0fb983bfb21a04b12425f38384cfa7cb0 100644 (file)
 // CHECK: ![[bar]] = !{!" /bar=2"}
 // CHECK: ![[foo]] = !{!" /foo=\22foo bar\22"}
 
-// LINUX: !{!"-lmsvcrt.lib"}
-// LINUX: !{!"-lkernel32"}
-// LINUX: !{!"-lUSER32.LIB"}
-// LINUX: !{!" /bar=2"}
+// LINUX: !{!"lib", !"msvcrt.lib"}
+// LINUX: !{!"lib", !"kernel32"}
+// LINUX: !{!"lib", !"USER32.LIB"}
 
 // PS4: !{!"\01msvcrt.lib"}
 // PS4: !{!"\01kernel32"}
diff --git a/test/Preprocessor/pragma-comment-linux.c b/test/Preprocessor/pragma-comment-linux.c
new file mode 100644 (file)
index 0000000..fcac049
--- /dev/null
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -fsyntax-only -verify %s -Wunknown-pragmas
+
+#pragma comment(linker, "")
+// expected-warning@-1 {{'#pragma comment linker' ignored}}
+
index b256b2bee6cf3a66481785dda0034301afa880eb..5d089432732594091fd8f18880a8b4040a83b92b 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions -Wunknown-pragmas
-// RUN: not %clang_cc1 %s -fms-extensions -E | FileCheck %s
+// RUN: %clang_cc1 -triple i686-unknown-windows-msvc %s -fsyntax-only -verify -fms-extensions -Wunknown-pragmas
+// RUN: not %clang_cc1 -triple i686-unknown-windows-msvc %s -fms-extensions -E | FileCheck %s
 // REQUIRES: non-ps4-sdk
 
 // rdar://6495941