diff options
Diffstat (limited to 'lib/CodeGen/CGDecl.cpp')
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 970f0b2389..8c154f0708 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -273,11 +273,23 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, llvm::Value *&DMEntry = LocalDeclMap[&D]; assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); - llvm::GlobalVariable *GV = CreateStaticVarDecl(D, ".", Linkage); + // Check to see if we already have a global variable for this + // declaration. This can happen when double-emitting function + // bodies, e.g. with complete and base constructors. + llvm::Constant *addr = + CGM.getStaticLocalDeclAddress(&D); + + llvm::GlobalVariable *var; + if (addr) { + var = cast<llvm::GlobalVariable>(addr->stripPointerCasts()); + } else { + addr = var = CreateStaticVarDecl(D, ".", Linkage); + } // Store into LocalDeclMap before generating initializer to handle // circular references. - DMEntry = GV; + DMEntry = addr; + CGM.setStaticLocalDeclAddress(&D, addr); // We can't have a VLA here, but we can have a pointer to a VLA, // even though that doesn't really make any sense. @@ -285,42 +297,38 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, if (D.getType()->isVariablyModifiedType()) EmitVariablyModifiedType(D.getType()); - // Local static block variables must be treated as globals as they may be - // referenced in their RHS initializer block-literal expresion. - CGM.setStaticLocalDeclAddress(&D, GV); + // Save the type in case adding the initializer forces a type change. + llvm::Type *expectedType = addr->getType(); // If this value has an initializer, emit it. if (D.getInit()) - GV = AddInitializerToStaticVarDecl(D, GV); + var = AddInitializerToStaticVarDecl(D, var); - GV->setAlignment(getContext().getDeclAlign(&D).getQuantity()); + var->setAlignment(getContext().getDeclAlign(&D).getQuantity()); if (D.hasAttr<AnnotateAttr>()) - CGM.AddGlobalAnnotations(&D, GV); + CGM.AddGlobalAnnotations(&D, var); if (const SectionAttr *SA = D.getAttr<SectionAttr>()) - GV->setSection(SA->getName()); + var->setSection(SA->getName()); if (D.hasAttr<UsedAttr>()) - CGM.AddUsedGlobal(GV); + CGM.AddUsedGlobal(var); // We may have to cast the constant because of the initializer // mismatch above. // // FIXME: It is really dangerous to store this in the map; if anyone // RAUW's the GV uses of this constant will be invalid. - llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType()); - llvm::Type *LPtrTy = - LTy->getPointerTo(CGM.getContext().getTargetAddressSpace(D.getType())); - llvm::Constant *CastedVal = llvm::ConstantExpr::getBitCast(GV, LPtrTy); - DMEntry = CastedVal; - CGM.setStaticLocalDeclAddress(&D, CastedVal); + llvm::Constant *castedAddr = llvm::ConstantExpr::getBitCast(var, expectedType); + DMEntry = castedAddr; + CGM.setStaticLocalDeclAddress(&D, castedAddr); // Emit global variable debug descriptor for static vars. CGDebugInfo *DI = getDebugInfo(); if (DI) { DI->setLocation(D.getLocation()); - DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(GV), &D); + DI->EmitGlobalVariable(var, &D); } } |