aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CodeGenModule.cpp43
-rw-r--r--lib/CodeGen/CodeGenModule.h13
2 files changed, 56 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);
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 0a4a78d33c..6a201be376 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -73,6 +73,12 @@ class CodeGenModule {
llvm::Function *MemMoveFn;
llvm::Function *MemSetFn;
+ /// RuntimeFunctions - List of runtime functions whose names must be
+ /// protected from introducing conflicts. These functions should be
+ /// created unnamed, we will name them and patch up conflicts when
+ /// we release the module.
+ std::vector< std::pair<llvm::Function*, std::string> > RuntimeFunctions;
+
/// GlobalDeclMap - Mapping of decl names global variables we have
/// already emitted. Note that the entries in this map are the
/// actual globals and therefore may not be of the same type as the
@@ -195,6 +201,11 @@ public:
void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
+ /// CreateRuntimeFunction - Create a new runtime function whose name
+ /// must be protected from collisions.
+ llvm::Function *CreateRuntimeFunction(const llvm::FunctionType *Ty,
+ const std::string &Name);
+
void UpdateCompletedType(const TagDecl *D);
llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0);
llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
@@ -263,6 +274,8 @@ private:
void EmitAliases(void);
void EmitAnnotations(void);
void EmitStatics(void);
+
+ void BindRuntimeFunctions();
};
} // end namespace CodeGen
} // end namespace clang