aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGDecl.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-02-25 19:24:29 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-02-25 19:24:29 +0000
commit0096acf421c4609ce7f43e8b05f8c5ca866d4611 (patch)
treeb138a6cda73d80318e14c45fc3902baac44fbdb1 /lib/CodeGen/CGDecl.cpp
parent01e4b5c3bf9f529c0c873162119d56a4f9341167 (diff)
Pull COdeGenFunction::CreateStaticBlockVarDecl (just for creating the
global variable) out of GenerateStaticBlockVarDecl. - No intended functionality change. - Prep for some mild cleanups and PR3662. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65466 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGDecl.cpp')
-rw-r--r--lib/CodeGen/CGDecl.cpp90
1 files changed, 59 insertions, 31 deletions
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 0ca2ad351c..c0f2054394 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -74,50 +74,78 @@ void CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) {
}
}
-llvm::GlobalValue *
+llvm::GlobalVariable *
+CodeGenFunction::CreateStaticBlockVarDecl(const VarDecl &D,
+ const char *Separator,
+ llvm::GlobalValue::LinkageTypes
+ Linkage) {
+ QualType Ty = D.getType();
+ assert(Ty->isConstantSizeType() && "VLAs can't be static");
+
+ std::string ContextName;
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl))
+ ContextName = CGM.getMangledName(FD);
+ else if (isa<ObjCMethodDecl>(CurFuncDecl))
+ ContextName = std::string(CurFn->getNameStart(),
+ CurFn->getNameStart() + CurFn->getNameLen());
+ else
+ assert(0 && "Unknown context for block var decl");
+
+ const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
+ return new llvm::GlobalVariable(LTy, Ty.isConstant(getContext()), Linkage,
+ llvm::Constant::getNullValue(LTy),
+ ContextName + Separator + D.getNameAsString(),
+ &CGM.getModule(), 0, Ty.getAddressSpace());
+}
+
+llvm::GlobalVariable *
CodeGenFunction::GenerateStaticBlockVarDecl(const VarDecl &D,
bool NoInit,
const char *Separator,
llvm::GlobalValue
::LinkageTypes Linkage) {
- QualType Ty = D.getType();
- assert(Ty->isConstantSizeType() && "VLAs can't be static");
-
- const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
- llvm::Constant *Init = 0;
- if ((D.getInit() == 0) || NoInit) {
- Init = llvm::Constant::getNullValue(LTy);
- } else {
- Init = CGM.EmitConstantExpr(D.getInit(), this);
+ llvm::GlobalVariable *GV = CreateStaticBlockVarDecl(D, Separator, Linkage);
+
+ if (D.getInit() && !NoInit) {
+ llvm::Constant *Init = CGM.EmitConstantExpr(D.getInit(), this);
// If constant emission failed, then this should be a C++ static
// initializer.
if (!Init) {
- if (!getContext().getLangOptions().CPlusPlus) {
+ if (!getContext().getLangOptions().CPlusPlus)
CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");
- Init = llvm::Constant::getNullValue(LTy);
- } else {
- return GenerateStaticCXXBlockVarDecl(D);
- }
- }
- }
+ else
+ GenerateStaticCXXBlockVarDeclInit(D, GV);
+ } else {
+ // The initializer may differ in type from the global. Rewrite
+ // the global to match the initializer!?
+ //
+ // FIXME: This matches what we have been doing historically, but
+ // it seems bad. Shouldn't the init expression have the right
+ // type?
+ if (GV->getType() != Init->getType()) {
+ llvm::GlobalVariable *OldGV = GV;
+
+ GV = new llvm::GlobalVariable(Init->getType(), OldGV->isConstant(),
+ OldGV->getLinkage(), Init, "",
+ &CGM.getModule(), 0,
+ D.getType().getAddressSpace());
- assert(Init && "Unable to create initialiser for static decl");
+ // Steal the name of the old global
+ GV->takeName(OldGV);
- std::string ContextName;
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl))
- ContextName = CGM.getMangledName(FD);
- else if (isa<ObjCMethodDecl>(CurFuncDecl))
- ContextName = std::string(CurFn->getNameStart(),
- CurFn->getNameStart() + CurFn->getNameLen());
- else
- assert(0 && "Unknown context for block var decl");
+ // Replace all uses of the old global with the new global
+ llvm::Constant *NewPtrForOldDecl =
+ llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
+ OldGV->replaceAllUsesWith(NewPtrForOldDecl);
+
+ // Erase the old global, since it is no longer used.
+ OldGV->eraseFromParent();
+ }
- llvm::GlobalValue *GV =
- new llvm::GlobalVariable(Init->getType(), Ty.isConstant(getContext()),
- Linkage,
- Init, ContextName + Separator +D.getNameAsString(),
- &CGM.getModule(), 0, Ty.getAddressSpace());
+ GV->setInitializer(Init);
+ }
+ }
return GV;
}