summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp33
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h9
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp18
-rw-r--r--clang/test/CodeGen/dependent-lib.c6
-rw-r--r--clang/test/CodeGen/elf-linker-options.c7
-rw-r--r--clang/test/CodeGen/pragma-comment.c21
-rw-r--r--clang/test/Modules/autolink.m4
7 files changed, 41 insertions, 57 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 3a84bdf94c8..e592442e6bd 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -446,6 +446,19 @@ void CodeGenModule::Release() {
EmitModuleLinkOptions();
}
+ // On ELF we pass the dependent library specifiers directly to the linker
+ // without manipulating them. This is in contrast to other platforms where
+ // they are mapped to a specific linker option by the compiler. This
+ // difference is a result of the greater variety of ELF linkers and the fact
+ // that ELF linkers tend to handle libraries in a more complicated fashion
+ // than on other platforms. This forces us to defer handling the dependent
+ // libs to the linker.
+ if (!ELFDependentLibraries.empty()) {
+ auto *NMD = getModule().getOrInsertNamedMetadata("llvm.dependent-libraries");
+ for (auto *MD : ELFDependentLibraries)
+ NMD->addOperand(MD);
+ }
+
// Record mregparm value now so it is visible through rest of codegen.
if (Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
getModule().addModuleFlag(llvm::Module::Error, "NumRegisterParameters",
@@ -1903,17 +1916,18 @@ void CodeGenModule::AddDetectMismatch(StringRef Name, StringRef Value) {
LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts));
}
-void CodeGenModule::AddELFLibDirective(StringRef Lib) {
+void CodeGenModule::AddDependentLib(StringRef Lib) {
auto &C = getLLVMContext();
- LinkerOptionsMetadata.push_back(llvm::MDNode::get(
- C, {llvm::MDString::get(C, "lib"), llvm::MDString::get(C, Lib)}));
-}
+ if (getTarget().getTriple().isOSBinFormatELF()) {
+ ELFDependentLibraries.push_back(
+ llvm::MDNode::get(C, llvm::MDString::get(C, Lib)));
+ return;
+ }
-void CodeGenModule::AddDependentLib(StringRef Lib) {
llvm::SmallString<24> Opt;
getTargetCodeGenInfo().getDependentLibraryOption(Lib, Opt);
auto *MDOpts = llvm::MDString::get(getLLVMContext(), Opt);
- LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts));
+ LinkerOptionsMetadata.push_back(llvm::MDNode::get(C, MDOpts));
}
/// Add link options implied by the given module, including modules
@@ -1936,7 +1950,6 @@ static void addLinkOptionsPostorder(CodeGenModule &CGM, Module *Mod,
// described by this module.
llvm::LLVMContext &Context = CGM.getLLVMContext();
bool IsELF = CGM.getTarget().getTriple().isOSBinFormatELF();
- bool IsPS4 = CGM.getTarget().getTriple().isPS4();
// For modules that use export_as for linking, use that module
// name instead.
@@ -1956,7 +1969,7 @@ static void addLinkOptionsPostorder(CodeGenModule &CGM, Module *Mod,
}
// Link against a library.
- if (IsELF && !IsPS4) {
+ if (IsELF) {
llvm::Metadata *Args[2] = {
llvm::MDString::get(Context, "lib"),
llvm::MDString::get(Context, Mod->LinkLibraries[I - 1].Library),
@@ -5197,10 +5210,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
AppendLinkerOptions(PCD->getArg());
break;
case PCK_Lib:
- if (getTarget().getTriple().isOSBinFormatELF() &&
- !getTarget().getTriple().isPS4())
- AddELFLibDirective(PCD->getArg());
- else
AddDependentLib(PCD->getArg());
break;
case PCK_Compiler:
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 61ce3ab2275..332177f6642 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -465,9 +465,12 @@ private:
/// have been emitted.
llvm::SmallPtrSet<clang::Module *, 16> EmittedModuleInitializers;
- /// A vector of metadata strings.
+ /// A vector of metadata strings for linker options.
SmallVector<llvm::MDNode *, 16> LinkerOptionsMetadata;
+ /// A vector of metadata strings for dependent libraries for ELF.
+ SmallVector<llvm::MDNode *, 16> ELFDependentLibraries;
+
/// @name Cache for Objective-C runtime types
/// @{
@@ -1152,11 +1155,9 @@ public:
/// Appends a detect mismatch command to the linker options.
void AddDetectMismatch(StringRef Name, StringRef Value);
- /// Appends a dependent lib to the "llvm.linker.options" metadata
- /// value.
+ /// Appends a dependent lib to the appropriate metadata value.
void AddDependentLib(StringRef Lib);
- void AddELFLibDirective(StringRef Lib);
llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD);
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 432e55da411..abd630411d2 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -2348,22 +2348,6 @@ public:
}
};
-class PS4TargetCodeGenInfo : public X86_64TargetCodeGenInfo {
-public:
- PS4TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, X86AVXABILevel AVXLevel)
- : X86_64TargetCodeGenInfo(CGT, AVXLevel) {}
-
- void getDependentLibraryOption(llvm::StringRef Lib,
- llvm::SmallString<24> &Opt) const override {
- Opt = "\01";
- // If the argument contains a space, enclose it in quotes.
- if (Lib.find(" ") != StringRef::npos)
- Opt += "\"" + Lib.str() + "\"";
- else
- Opt += Lib;
- }
-};
-
static std::string qualifyWindowsLibrary(llvm::StringRef Lib) {
// If the argument does not end in .lib, automatically add the suffix.
// If the argument contains a space, enclose it in quotes.
@@ -9493,8 +9477,6 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
switch (Triple.getOS()) {
case llvm::Triple::Win32:
return SetCGInfo(new WinX86_64TargetCodeGenInfo(Types, AVXLevel));
- case llvm::Triple::PS4:
- return SetCGInfo(new PS4TargetCodeGenInfo(Types, AVXLevel));
default:
return SetCGInfo(new X86_64TargetCodeGenInfo(Types, AVXLevel));
}
diff --git a/clang/test/CodeGen/dependent-lib.c b/clang/test/CodeGen/dependent-lib.c
index 7178a29692a..fdd2ff3957b 100644
--- a/clang/test/CodeGen/dependent-lib.c
+++ b/clang/test/CodeGen/dependent-lib.c
@@ -1,12 +1,12 @@
// RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple thumbv7-windows -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-win32 -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple x86_64-pc-win32 -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-linux -emit-llvm -o - | FileCheck -check-prefix LINUX %s
+// RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-linux -emit-llvm -o - | FileCheck -check-prefix LINUX %s --implicit-check-not llvm.linker.options
// CHECK: !llvm.linker.options = !{![[msvcrt:[0-9]+]]}
// CHECK: ![[msvcrt]] = !{!"/DEFAULTLIB:msvcrt.lib"}
-// LINUX: !llvm.linker.options = !{![[msvcrt:[0-9]+]]}
-// LINUX: ![[msvcrt]] = !{!"-lmsvcrt"}
+// LINUX: !llvm.dependent-libraries = !{![[msvcrt:[0-9]+]]}
+// LINUX: ![[msvcrt]] = !{!"msvcrt"}
int f();
diff --git a/clang/test/CodeGen/elf-linker-options.c b/clang/test/CodeGen/elf-linker-options.c
deleted file mode 100644
index cf2d1b92b99..00000000000
--- a/clang/test/CodeGen/elf-linker-options.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// 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"}
-
diff --git a/clang/test/CodeGen/pragma-comment.c b/clang/test/CodeGen/pragma-comment.c
index 1896e5c0fb9..25675d94c5a 100644
--- a/clang/test/CodeGen/pragma-comment.c
+++ b/clang/test/CodeGen/pragma-comment.c
@@ -1,9 +1,9 @@
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s -triple thumbv7-windows -fms-extensions -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 %s -triple thumbv7-linux-gnueabihf -fms-extensions -emit-llvm -o - | FileCheck -check-prefix LINUX %s
-// RUN: %clang_cc1 %s -triple i686-pc-linux -fms-extensions -emit-llvm -o - | FileCheck -check-prefix LINUX %s
-// RUN: %clang_cc1 %s -triple x86_64-scei-ps4 -fms-extensions -emit-llvm -o - | FileCheck -check-prefix PS4 %s
+// RUN: %clang_cc1 %s -triple thumbv7-linux-gnueabihf -fms-extensions -emit-llvm -o - | FileCheck -check-prefix ELF %s --implicit-check-not llvm.linker.options
+// RUN: %clang_cc1 %s -triple i686-pc-linux -fms-extensions -emit-llvm -o - | FileCheck -check-prefix ELF %s --implicit-check-not llvm.linker.options
+// RUN: %clang_cc1 %s -triple x86_64-scei-ps4 -fms-extensions -emit-llvm -o - | FileCheck -check-prefix ELF %s --implicit-check-not llvm.linker.options
// RUN: %clang_cc1 %s -triple aarch64-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
#pragma comment(lib, "msvcrt.lib")
@@ -23,11 +23,10 @@
// CHECK: ![[bar]] = !{!" /bar=2"}
// CHECK: ![[foo]] = !{!" /foo=\22foo bar\22"}
-// LINUX: !{!"lib", !"msvcrt.lib"}
-// LINUX: !{!"lib", !"kernel32"}
-// LINUX: !{!"lib", !"USER32.LIB"}
-
-// PS4: !{!"\01msvcrt.lib"}
-// PS4: !{!"\01kernel32"}
-// PS4: !{!"\01USER32.LIB"}
-// PS4: !{!"\01\22with space\22"}
+// ELF: !llvm.dependent-libraries = !{![[msvcrt:[0-9]+]], ![[kernel32:[0-9]+]], ![[USER32:[0-9]+]], ![[space:[0-9]+]]
+// ELF: ![[msvcrt]] = !{!"msvcrt.lib"}
+// ELF: ![[kernel32]] = !{!"kernel32"}
+// ELF: ![[USER32]] = !{!"USER32.LIB"}
+// ELF: ![[space]] = !{!"with space"}
+// ELF-NOT: bar
+// ELF-NOT: foo
diff --git a/clang/test/Modules/autolink.m b/clang/test/Modules/autolink.m
index f15472692dd..f180f6910b5 100644
--- a/clang/test/Modules/autolink.m
+++ b/clang/test/Modules/autolink.m
@@ -37,9 +37,9 @@ int use_autolink_sub3() {
// NOTE: "autolink_sub" is intentionally not linked.
// CHECK: !llvm.linker.options = !{![[AUTOLINK_PCH:[0-9]+]], ![[AUTOLINK_FRAMEWORK:[0-9]+]], ![[AUTOLINK:[0-9]+]], ![[DEPENDSONMODULE:[0-9]+]], ![[MODULE:[0-9]+]], ![[NOUMBRELLA:[0-9]+]]}
-// CHECK: ![[AUTOLINK_PCH]] = !{!"{{(\\01|-l|/DEFAULTLIB:|lib", !")}}autolink_from_pch{{(\.lib)?}}"}
+// CHECK: ![[AUTOLINK_PCH]] = !{!"{{(-l|/DEFAULTLIB:|lib", !")}}autolink_from_pch{{(\.lib)?}}"}
// CHECK: ![[AUTOLINK_FRAMEWORK]] = !{!"-framework", !"autolink_framework"}
-// CHECK: ![[AUTOLINK]] = !{!"{{(\\01|-l|/DEFAULTLIB:|lib", !")}}autolink{{(\.lib)?}}"}
+// CHECK: ![[AUTOLINK]] = !{!"{{(-l|/DEFAULTLIB:|lib", !")}}autolink{{(\.lib)?}}"}
// CHECK: ![[DEPENDSONMODULE]] = !{!"-framework", !"DependsOnModule"}
// CHECK: ![[MODULE]] = !{!"-framework", !"Module"}
// CHECK: ![[NOUMBRELLA]] = !{!"-framework", !"NoUmbrella"}
OpenPOWER on IntegriCloud