aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--lib/CodeGen/CGCXX.cpp28
-rw-r--r--lib/CodeGen/CGDecl.cpp90
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp13
-rw-r--r--lib/CodeGen/CodeGenFunction.h26
4 files changed, 92 insertions, 65 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 489c67bc6b..f43130a12b 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -83,28 +83,24 @@ static std::string mangleGuardVariable(const VarDecl& D)
return S;
}
-llvm::GlobalValue *
-CodeGenFunction::GenerateStaticCXXBlockVarDecl(const VarDecl &D)
-{
+void
+CodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D,
+ llvm::GlobalVariable *GV) {
+ // FIXME: This should use __cxa_guard_{acquire,release}?
+
assert(!getContext().getLangOptions().ThreadsafeStatics &&
"thread safe statics are currently not supported!");
- const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
- // FIXME: If the function is inline, the linkage should be weak.
- llvm::GlobalValue::LinkageTypes linkage = llvm::GlobalValue::InternalLinkage;
-
// Create the guard variable.
llvm::GlobalValue *GuardV =
new llvm::GlobalVariable(llvm::Type::Int64Ty, false,
- linkage,
+ GV->getLinkage(),
llvm::Constant::getNullValue(llvm::Type::Int64Ty),
mangleGuardVariable(D),
&CGM.getModule());
- // FIXME: Address space.
- const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
-
// Load the first byte of the guard variable.
+ const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy),
"tmp");
@@ -120,13 +116,8 @@ CodeGenFunction::GenerateStaticCXXBlockVarDecl(const VarDecl &D)
EmitBlock(InitBlock);
- llvm::GlobalValue *GV =
- new llvm::GlobalVariable(LTy, false,
- llvm::GlobalValue::InternalLinkage,
- llvm::Constant::getNullValue(LTy),
- mangleVarDecl(D),
- &CGM.getModule(), 0,
- D.getType().getAddressSpace());
+ // Patch the name. FIXME: We shouldn't need to do this.
+ GV->setName(mangleVarDecl(D));
const Expr *Init = D.getInit();
if (!hasAggregateLLVMType(Init->getType())) {
@@ -142,6 +133,5 @@ CodeGenFunction::GenerateStaticCXXBlockVarDecl(const VarDecl &D)
Builder.CreateBitCast(GuardV, PtrTy));
EmitBlock(EndBlock);
- return GV;
}
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;
}
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index ccd961ac28..879b85891d 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -53,14 +53,15 @@ llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
return BB = createBasicBlock(S->getName());
}
-llvm::Constant *
-CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) {
- return cast<llvm::Constant>(LocalDeclMap[BVD]);
+llvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD) {
+ llvm::Value *Res = LocalDeclMap[VD];
+ assert(Res && "Invalid argument to GetAddrOfLocalVar(), no decl!");
+ return Res;
}
-llvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD)
-{
- return LocalDeclMap[VD];
+llvm::Constant *
+CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) {
+ return cast<llvm::Constant>(GetAddrOfLocalVar(BVD));
}
const llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) {
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index f13e79ae1d..02276b98b0 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -746,17 +746,25 @@ public:
/// LoadComplexFromAddr - Load a complex number from the specified address.
ComplexPairTy LoadComplexFromAddr(llvm::Value *SrcAddr, bool SrcIsVolatile);
+ /// CreateStaticBlockVarDecl - Create a zero-initialized LLVM global
+ /// for a static block var decl.
+ llvm::GlobalVariable * CreateStaticBlockVarDecl(const VarDecl &D,
+ const char *Separator,
+ llvm::GlobalValue::LinkageTypes
+ Linkage);
+
/// GenerateStaticBlockVarDecl - Return the the static declaration of local
/// variable.
- llvm::GlobalValue * GenerateStaticBlockVarDecl(const VarDecl &D,
- bool NoInit,
- const char *Separator,
- llvm::GlobalValue
- ::LinkageTypes Linkage);
-
- /// GenerateStaticCXXBlockVarDecl - Return the static declaration of a local
- /// variable. Performs initialization of the variable if necessary.
- llvm::GlobalValue *GenerateStaticCXXBlockVarDecl(const VarDecl &D);
+ llvm::GlobalVariable * GenerateStaticBlockVarDecl(const VarDecl &D,
+ bool NoInit,
+ const char *Separator,
+ llvm::GlobalValue
+ ::LinkageTypes Linkage);
+
+ /// GenerateStaticCXXBlockVarDecl - Create the initializer for a C++
+ /// runtime initialized static block var decl.
+ void GenerateStaticCXXBlockVarDeclInit(const VarDecl &D,
+ llvm::GlobalVariable *GV);
//===--------------------------------------------------------------------===//
// Internal Helpers