Implement pragma(lib) using module metadata.

Since LLVM 3.3 pragma(lib) can be implemented like DMD does.
This commit is contained in:
kai
2013-07-15 07:47:54 +02:00
parent d46d4ce4b1
commit 4f7bc678fb
3 changed files with 44 additions and 7 deletions

View File

@@ -22,6 +22,7 @@
#include "ir/ir.h"
#include "ir/irtype.h"
#include "ir/irvar.h"
#include "llvm/ADT/SmallString.h"
/* ================================================================== */
@@ -333,13 +334,38 @@ void PragmaDeclaration::codegen(Ir* p)
}
}
size_t const n = nameLen + 3;
char *arg = static_cast<char *>(mem.malloc(n));
arg[0] = '-';
arg[1] = 'l';
memcpy(arg + 2, se->string, nameLen);
arg[n-1] = 0;
global.params.linkswitches->push(arg);
#if LDC_LLVM_VER >= 303
// With LLVM 3.3 or later we can place the library name in the object
// file. This seems to be supported only on Windows.
if (global.params.targetTriple.getOS() == llvm::Triple::Win32)
{
llvm::SmallString<24> LibName(llvm::StringRef(static_cast<const char *>(se->string), nameLen));
// Win32: /DEFAULTLIB:"curl"
if (LibName.endswith(".a"))
LibName = LibName.substr(0, LibName.size()-2);
if (LibName.endswith(".lib"))
LibName = LibName.substr(0, LibName.size()-4);
llvm::SmallString<24> tmp("/DEFAULTLIB:\"");
tmp.append(LibName);
tmp.append("\"");
LibName = tmp;
// Embedd library name as linker option in object file
llvm::Value *Value = llvm::MDString::get(gIR->context(), LibName);
gIR->LinkerMetadataArgs.push_back(llvm::MDNode::get(gIR->context(), Value));
}
else
#endif
{
size_t const n = nameLen + 3;
char *arg = static_cast<char *>(mem.malloc(n));
arg[0] = '-';
arg[1] = 'l';
memcpy(arg + 2, se->string, nameLen);
arg[n-1] = 0;
global.params.linkswitches->push(arg);
}
}
AttribDeclaration::codegen(p);
}

View File

@@ -203,6 +203,11 @@ struct IRState
/// Whether to emit array bounds checking in the current function.
bool emitArrayBoundsChecks();
#if LDC_LLVM_VER >= 303
/// Vector of options passed to the linker as metadata in object file.
llvm::SmallVector<llvm::Value *, 5> LinkerMetadataArgs;
#endif
};
template <typename T>

View File

@@ -422,6 +422,12 @@ llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context, Ir* sir)
// generate ModuleInfo
genmoduleinfo();
#if LDC_LLVM_VER >= 303
// Add the linker options metadata flag.
ir.module->addModuleFlag(llvm::Module::AppendUnique, "Linker Options",
llvm::MDNode::get(ir.context(), ir.LinkerMetadataArgs));
#endif
// verify the llvm
verifyModule(*ir.module);