void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) { llvm::Value *&DMEntry = LocalDeclMap[&D]; assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); llvm::GlobalVariable *GV = CreateStaticBlockVarDecl(D, ".", llvm::GlobalValue::InternalLinkage); // Store into LocalDeclMap before generating initializer to handle // circular references. DMEntry = GV; // Make sure to evaluate VLA bounds now so that we have them for later. // // FIXME: Can this happen? if (D.getType()->isVariablyModifiedType()) EmitVLASize(D.getType()); // If this value has an initializer, emit it. if (D.getInit()) GV = AddInitializerToGlobalBlockVarDecl(D, GV); // FIXME: Merge attribute handling. if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>()) { SourceManager &SM = CGM.getContext().getSourceManager(); llvm::Constant *Ann = CGM.EmitAnnotateAttr(GV, AA, SM.getInstantiationLineNumber(D.getLocation())); CGM.AddAnnotation(Ann); } if (const SectionAttr *SA = D.getAttr<SectionAttr>()) GV->setSection(SA->getName()); if (D.hasAttr<UsedAttr>()) CGM.AddUsedGlobal(GV); // 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. const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType()); const llvm::Type *LPtrTy = llvm::PointerType::get(LTy, D.getType().getAddressSpace()); DMEntry = llvm::ConstantExpr::getBitCast(GV, LPtrTy); // 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); } }
void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) { llvm::Value *&DMEntry = LocalDeclMap[&D]; assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); llvm::GlobalVariable *GV = CreateStaticBlockVarDecl(D, ".", llvm::GlobalValue::InternalLinkage); // Store into LocalDeclMap before generating initializer to handle // circular references. DMEntry = GV; // Make sure to evaluate VLA bounds now so that we have them for later. // // FIXME: Can this happen? if (D.getType()->isVariablyModifiedType()) EmitVLASize(D.getType()); if (D.getInit()) { llvm::Constant *Init = CGM.EmitConstantExpr(D.getInit(), D.getType(), this); // If constant emission failed, then this should be a C++ static // initializer. if (!Init) { if (!getContext().getLangOptions().CPlusPlus) CGM.ErrorUnsupported(D.getInit(), "constant l-value expression"); else EmitStaticCXXBlockVarDeclInit(D, GV); } else { // The initializer may differ in type from the global. Rewrite // the global to match the initializer. (We have to do this // because some types, like unions, can't be completely represented // in the LLVM type system.) if (GV->getType() != Init->getType()) { llvm::GlobalVariable *OldGV = GV; GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), OldGV->isConstant(), OldGV->getLinkage(), Init, "", 0, D.isThreadSpecified(), D.getType().getAddressSpace()); // Steal the name of the old global GV->takeName(OldGV); // 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(); } GV->setInitializer(Init); } } // FIXME: Merge attribute handling. if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>()) { SourceManager &SM = CGM.getContext().getSourceManager(); llvm::Constant *Ann = CGM.EmitAnnotateAttr(GV, AA, SM.getInstantiationLineNumber(D.getLocation())); CGM.AddAnnotation(Ann); } if (const SectionAttr *SA = D.getAttr<SectionAttr>()) GV->setSection(SA->getName()); if (D.hasAttr<UsedAttr>()) CGM.AddUsedGlobal(GV); // 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. const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType()); const llvm::Type *LPtrTy = llvm::PointerType::get(LTy, D.getType().getAddressSpace()); DMEntry = llvm::ConstantExpr::getBitCast(GV, LPtrTy); // 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); } }