From: Anders Carlsson Date: Sat, 29 Jan 2011 18:20:20 +0000 (+0000) Subject: Add a new function, to be used by CGRTTI, CGVTables and CGVTT (which each has their... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3bd6202ea2d5b5f7c8229cd280a846ae3dcf2355;p=clang Add a new function, to be used by CGRTTI, CGVTables and CGVTT (which each has their own copy of this code). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124537 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 80d0f10c06..c261ccae2e 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -985,6 +985,45 @@ CodeGenModule::GetOrCreateLLVMGlobal(llvm::StringRef MangledName, } +llvm::GlobalVariable * +CodeGenModule::CreateOrReplaceCXXRuntimeVariable(llvm::StringRef Name, + const llvm::Type *Ty, + llvm::GlobalValue::LinkageTypes Linkage) { + llvm::GlobalVariable *GV = getModule().getNamedGlobal(Name); + llvm::GlobalVariable *OldGV = 0; + + + if (GV) { + // Check if the variable has the right type. + if (GV->getType()->getElementType() == Ty) + return GV; + + // Because C++ name mangling, the only way we can end up with an already + // existing global with the same name is if it has been declared extern "C". + assert(GV->isDeclaration() && "Declaration has wrong type!"); + OldGV = GV; + } + + // Create a new variable. + GV = new llvm::GlobalVariable(getModule(), Ty, /*isConstant=*/true, + Linkage, 0, Name); + + if (OldGV) { + // Replace occurrences of the old variable if needed. + GV->takeName(OldGV); + + if (!OldGV->use_empty()) { + llvm::Constant *NewPtrForOldDecl = + llvm::ConstantExpr::getBitCast(GV, OldGV->getType()); + OldGV->replaceAllUsesWith(NewPtrForOldDecl); + } + + OldGV->eraseFromParent(); + } + + return GV; +} + /// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the /// given global variable. If Ty is non-null and if the global doesn't exist, /// then it will be greated with the specified type instead of whatever the diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index bb32fff826..9ac692b263 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -280,6 +280,14 @@ public: return GetAddrOfGlobalVar(cast(GD.getDecl())); } + /// CreateOrReplaceCXXRuntimeVariable - Will return a global variable of the given + /// type. If a variable with a different type already exists then a new + /// variable with the right type will be created and all uses of the old + /// variable will be replaced with a bitcast to the new variable. + llvm::GlobalVariable * + CreateOrReplaceCXXRuntimeVariable(llvm::StringRef Name, const llvm::Type *Ty, + llvm::GlobalValue::LinkageTypes Linkage); + /// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the /// given global variable. If Ty is non-null and if the global doesn't exist, /// then it will be greated with the specified type instead of whatever the