aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--lib/CodeGen/CodeGenModule.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 6c9999df24..a74f0578a5 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -63,6 +63,7 @@ void CodeGenModule::Release() {
EmitCtorList(GlobalCtors, "llvm.global_ctors");
EmitCtorList(GlobalDtors, "llvm.global_dtors");
EmitAnnotations();
+ BindRuntimeFunctions();
// Run the verifier to check that the generated code is consistent.
if (verifyModule(TheModule, llvm::PrintMessageAction)) {
TheModule.dump();
@@ -70,6 +71,38 @@ void CodeGenModule::Release() {
}
}
+void CodeGenModule::BindRuntimeFunctions() {
+ // Deal with protecting runtime function names.
+ for (unsigned i = 0, e = RuntimeFunctions.size(); i < e; ++i) {
+ llvm::Function *Fn = RuntimeFunctions[i].first;
+ const std::string &Name = RuntimeFunctions[i].second;
+
+ // See if there is a conflict against a function.
+ llvm::Function *Conflict = TheModule.getFunction(Name);
+ if (Conflict) {
+ // Decide which version to take. If the conflict is a definition
+ // we are forced to take that, otherwise assume the runtime
+ // knows best.
+ if (!Conflict->isDeclaration()) {
+ llvm::Value *Casted =
+ llvm::ConstantExpr::getBitCast(Conflict, Fn->getType());
+ Fn->replaceAllUsesWith(Casted);
+ Fn->eraseFromParent();
+ } else {
+ Fn->takeName(Conflict);
+ llvm::Value *Casted =
+ llvm::ConstantExpr::getBitCast(Fn, Conflict->getType());
+ Conflict->replaceAllUsesWith(Casted);
+ Conflict->eraseFromParent();
+ }
+ } else {
+ // FIXME: There still may be conflicts with aliases and
+ // variables.
+ Fn->setName(Name);
+ }
+ }
+}
+
/// ErrorUnsupported - Print out an error that codegen doesn't support the
/// specified stmt yet.
void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type,
@@ -655,6 +688,16 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) {
}
}
+llvm::Function *
+CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy,
+ const std::string &Name) {
+ llvm::Function *Fn = llvm::Function::Create(FTy,
+ llvm::Function::ExternalLinkage,
+ "", &TheModule);
+ RuntimeFunctions.push_back(std::make_pair(Fn, Name));
+ return Fn;
+}
+
void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
// Make sure that this type is translated.
Types.UpdateCompletedType(TD);