diff options
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 43 |
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); |