aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2008-10-01 00:49:24 +0000
committerDaniel Dunbar <daniel@zuster.org>2008-10-01 00:49:24 +0000
commitf1968f28869f4e0675450ae39c478a37c5b9abd6 (patch)
tree897c9408e26e67fe467db0719932983976914af9 /lib/CodeGen/CodeGenModule.cpp
parent60a6e0ce72a24d6247602625c631fc3dc7bfd8d4 (diff)
Add simple interface for protecting runtime functions from name
collisions. - Provide CodeGenModule::CreateRuntimeFunction which guarantees that the function it creates will have the provided name in the final module. This allows the runtime to have its functions protected from declarations of the same name in the source code. - One could argue that this is a reason to abuse the llvm::Module namespace for dealing with function redeclarations. However, that approach seems conceptually flawed to me. This one also happens to be somewhat more efficient. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56899 91177308-0d34-0410-b5e6-96231b3b80d8
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);