summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-05-08 13:44:39 +0000
committerReid Kleckner <reid@kleckner.net>2013-05-08 13:44:39 +0000
commite43f0fea153bd67e39f085d92d9e12ada915bb99 (patch)
tree6e125ab241ac35e231eb1aca174c107b03fd2347 /clang/lib/CodeGen/CodeGenModule.cpp
parent7bbd7aa7fe63f9df9e4d30355180cfcf0785973c (diff)
downloadbcm5719-llvm-e43f0fea153bd67e39f085d92d9e12ada915bb99.tar.gz
bcm5719-llvm-e43f0fea153bd67e39f085d92d9e12ada915bb99.zip
Forward #pragma comment(lib/linker) through as flags metadata
Summary: Most of this change is wiring the pragma all the way through from the lexer, parser, and sema to codegen. I considered adding a Decl AST node for this, but it seemed too heavyweight. Mach-O already uses a metadata flag called "Linker Options" to do this kind of auto-linking. This change follows that pattern. LLVM knows how to forward the "Linker Options" metadata into the COFF .drectve section where these flags belong. ELF support is not implemented, but possible. This is related to auto-linking, which is http://llvm.org/PR13016. CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D723 llvm-svn: 181426
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp45
1 files changed, 30 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 0b03a3c4b67..1da4e87c0a5 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -186,7 +186,8 @@ void CodeGenModule::Release() {
EmitStaticExternCAliases();
EmitLLVMUsed();
- if (CodeGenOpts.Autolink && Context.getLangOpts().Modules) {
+ if (CodeGenOpts.Autolink &&
+ (Context.getLangOpts().Modules || !LinkerOptionsMetadata.empty())) {
EmitModuleLinkOptions();
}
@@ -762,31 +763,41 @@ void CodeGenModule::EmitLLVMUsed() {
GV->setSection("llvm.metadata");
}
+void CodeGenModule::AppendLinkerOptions(StringRef Opts) {
+ llvm::Value *MDOpts = llvm::MDString::get(getLLVMContext(), Opts);
+ LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts));
+}
+
+void CodeGenModule::AddDependentLib(StringRef Lib) {
+ llvm::SmallString<24> Opt;
+ getTargetCodeGenInfo().getDependentLibraryOption(Lib, Opt);
+ llvm::Value *MDOpts = llvm::MDString::get(getLLVMContext(), Opt);
+ LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts));
+}
+
/// \brief Add link options implied by the given module, including modules
/// it depends on, using a postorder walk.
-static void addLinkOptionsPostorder(llvm::LLVMContext &Context,
+static void addLinkOptionsPostorder(CodeGenModule &CGM,
Module *Mod,
SmallVectorImpl<llvm::Value *> &Metadata,
llvm::SmallPtrSet<Module *, 16> &Visited) {
// Import this module's parent.
if (Mod->Parent && Visited.insert(Mod->Parent)) {
- addLinkOptionsPostorder(Context, Mod->Parent, Metadata, Visited);
+ addLinkOptionsPostorder(CGM, Mod->Parent, Metadata, Visited);
}
// Import this module's dependencies.
for (unsigned I = Mod->Imports.size(); I > 0; --I) {
if (Visited.insert(Mod->Imports[I-1]))
- addLinkOptionsPostorder(Context, Mod->Imports[I-1], Metadata, Visited);
+ addLinkOptionsPostorder(CGM, Mod->Imports[I-1], Metadata, Visited);
}
// Add linker options to link against the libraries/frameworks
// described by this module.
+ llvm::LLVMContext &Context = CGM.getLLVMContext();
for (unsigned I = Mod->LinkLibraries.size(); I > 0; --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.
+ // Link against a framework. Frameworks are currently Darwin only, so we
+ // don't to ask TargetCodeGenInfo for the spelling of the linker option.
if (Mod->LinkLibraries[I-1].IsFramework) {
llvm::Value *Args[2] = {
llvm::MDString::get(Context, "-framework"),
@@ -798,9 +809,10 @@ static void addLinkOptionsPostorder(llvm::LLVMContext &Context,
}
// Link against a library.
- llvm::Value *OptString
- = llvm::MDString::get(Context,
- "-l" + Mod->LinkLibraries[I-1].Library);
+ llvm::SmallString<24> Opt;
+ CGM.getTargetCodeGenInfo().getDependentLibraryOption(
+ Mod->LinkLibraries[I-1].Library, Opt);
+ llvm::Value *OptString = llvm::MDString::get(Context, Opt);
Metadata.push_back(llvm::MDNode::get(Context, OptString));
}
}
@@ -852,20 +864,23 @@ void CodeGenModule::EmitModuleLinkOptions() {
}
// Add link options for all of the imported modules in reverse topological
- // order.
+ // order. We don't do anything to try to order import link flags with respect
+ // to linker options inserted by things like #pragma comment().
SmallVector<llvm::Value *, 16> MetadataArgs;
Visited.clear();
for (llvm::SetVector<clang::Module *>::iterator M = LinkModules.begin(),
MEnd = LinkModules.end();
M != MEnd; ++M) {
if (Visited.insert(*M))
- addLinkOptionsPostorder(getLLVMContext(), *M, MetadataArgs, Visited);
+ addLinkOptionsPostorder(*this, *M, MetadataArgs, Visited);
}
std::reverse(MetadataArgs.begin(), MetadataArgs.end());
+ LinkerOptionsMetadata.append(MetadataArgs.begin(), MetadataArgs.end());
// Add the linker options metadata flag.
getModule().addModuleFlag(llvm::Module::AppendUnique, "Linker Options",
- llvm::MDNode::get(getLLVMContext(), MetadataArgs));
+ llvm::MDNode::get(getLLVMContext(),
+ LinkerOptionsMetadata));
}
void CodeGenModule::EmitDeferred() {
OpenPOWER on IntegriCloud