From: Daniel Dunbar Date: Tue, 29 Jul 2008 23:18:29 +0000 (+0000) Subject: Rework codegen emission of globals X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bd012ff1fa088181646a784f385b28867372d434;p=clang Rework codegen emission of globals - No (intended) functionality change. - Primary purpose is to clearly separate (lazy) construction of globals that are a forward declaration or tentative definition from those that are the final definition. - Lazy construction is now encapsulated in GetAddrOf{Function,GlobalVar} while final definitions are constructed in EmitGlobal{Function,Var}Definition. - External interface for dealing with globals is now limited to EmitGlobal and GetAddrOf{Function,GlobalVar}. - Also updated helper functions dealing with statics, annotations, and ctors to be private. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54179 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 3b5eba84dc..b219b7a67d 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -373,7 +373,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { if (VD && (VD->isBlockVarDecl() || isa(VD) || isa(VD))) { if (VD->getStorageClass() == VarDecl::Extern) - return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false), + return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD), E->getType().getCVRQualifiers()); else { llvm::Value *V = LocalDeclMap[VD]; @@ -381,10 +381,10 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { return LValue::MakeAddr(V, E->getType().getCVRQualifiers()); } } else if (VD && VD->isFileVarDecl()) { - return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false), + return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD), E->getType().getCVRQualifiers()); } else if (const FunctionDecl *FD = dyn_cast(E->getDecl())) { - return LValue::MakeAddr(CGM.GetAddrOfFunctionDecl(FD, false), + return LValue::MakeAddr(CGM.GetAddrOfFunction(FD), E->getType().getCVRQualifiers()); } else if (const ImplicitParamDecl *IPD = diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 9efe801852..681993a5d4 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -735,10 +735,10 @@ public: case Expr::DeclRefExprClass: { ValueDecl *Decl = cast(E)->getDecl(); if (const FunctionDecl *FD = dyn_cast(Decl)) - return CGM.GetAddrOfFunctionDecl(FD, false); + return CGM.GetAddrOfFunction(FD); if (const VarDecl* VD = dyn_cast(Decl)) { if (VD->isFileVarDecl()) - return CGM.GetAddrOfGlobalVar(VD, false); + return CGM.GetAddrOfGlobalVar(VD); else if (VD->isBlockVarDecl()) { assert(CGF && "Can't access static local vars without CGF"); return CGF->GetAddrOfStaticLocalVar(VD); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 679a0f7404..e153ad9fd8 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -102,10 +102,11 @@ void CodeGenFunction::GenerateFunction(const Stmt *Body) { assert(!verifyFunction(*CurFn) && "Generated function is not well formed."); } -void CodeGenFunction::GenerateCode(const FunctionDecl *FD) { +void CodeGenFunction::GenerateCode(const FunctionDecl *FD, + llvm::Function *Fn) { CurFuncDecl = FD; FnRetTy = FD->getResultType(); - CurFn = cast(CGM.GetAddrOfFunctionDecl(FD, true)); + CurFn = Fn; assert(CurFn->isDeclaration() && "Function already has body?"); llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 5bf6bc1fea..38e10e90ce 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1,4 +1,4 @@ -//===--- CodeGenFunction.h - Per-Function state for LLVM CodeGen ----------===// +//===-- CodeGenFunction.h - Per-Function state for LLVM CodeGen -*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -277,7 +277,8 @@ public: ASTContext &getContext() const; void GenerateObjCMethod(const ObjCMethodDecl *OMD); - void GenerateCode(const FunctionDecl *FD); + void GenerateCode(const FunctionDecl *FD, + llvm::Function *Fn); void GenerateFunction(const Stmt *Body); const llvm::Type *ConvertType(QualType T); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 565286c43d..1e91ac2f25 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -153,8 +153,6 @@ void CodeGenModule::EmitGlobalCtors() { CtorValues)); } - - void CodeGenModule::EmitAnnotations() { if (Annotations.empty()) return; @@ -171,16 +169,6 @@ void CodeGenModule::EmitAnnotations() { gv->setSection("llvm.metadata"); } -/// ReplaceMapValuesWith - This is a really slow and bad function that -/// searches for any entries in GlobalDeclMap that point to OldVal, changing -/// them to point to NewVal. This is badbadbad, FIXME! -void CodeGenModule::ReplaceMapValuesWith(llvm::Constant *OldVal, - llvm::Constant *NewVal) { - for (llvm::DenseMap::iterator - I = GlobalDeclMap.begin(), E = GlobalDeclMap.end(); I != E; ++I) - if (I->second == OldVal) I->second = NewVal; -} - bool hasAggregateLLVMType(QualType T) { return !T->isRealType() && !T->isPointerLikeType() && !T->isVoidType() && !T->isVectorType() && !T->isFunctionType(); @@ -251,110 +239,6 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, SetGlobalValueAttributes(FD, F); } - - -llvm::Constant *CodeGenModule::GetAddrOfFunctionDecl(const FunctionDecl *D, - bool isDefinition) { - // See if it is already in the map. If so, just return it. - llvm::Constant *&Entry = GlobalDeclMap[D]; - if (!isDefinition && Entry) return Entry; - - const llvm::Type *Ty = getTypes().ConvertType(D->getType()); - - // Check to see if the function already exists. - llvm::Function *F = getModule().getFunction(D->getName()); - const llvm::FunctionType *FTy = cast(Ty); - - // If it doesn't already exist, just create and return an entry. - if (F == 0) { - // FIXME: param attributes for sext/zext etc. - if (D->getBody() || !D->getAttr()) - F = llvm::Function::Create(FTy, llvm::Function::ExternalLinkage, - D->getName(), &getModule()); - else { - const std::string& aliaseeName = D->getAttr()->getAliasee(); - llvm::Function *aliasee = getModule().getFunction(aliaseeName); - llvm::GlobalValue *alias = new llvm::GlobalAlias(aliasee->getType(), - llvm::Function::ExternalLinkage, - D->getName(), - aliasee, - &getModule()); - SetGlobalValueAttributes(D, alias); - return Entry = alias; - } - - SetFunctionAttributes(D, F, FTy); - return Entry = F; - } - - // If the pointer type matches, just return it. - llvm::Type *PFTy = llvm::PointerType::getUnqual(Ty); - if (PFTy == F->getType()) return Entry = F; - - // If this isn't a definition, just return it casted to the right type. - if (!isDefinition) - return Entry = llvm::ConstantExpr::getBitCast(F, PFTy); - - // Otherwise, we have a definition after a prototype with the wrong type. - // F is the Function* for the one with the wrong type, we must make a new - // Function* and update everything that used F (a declaration) with the new - // Function* (which will be a definition). - // - // This happens if there is a prototype for a function (e.g. "int f()") and - // then a definition of a different type (e.g. "int f(int x)"). Start by - // making a new function of the correct type, RAUW, then steal the name. - llvm::Function *NewFn = llvm::Function::Create(FTy, - llvm::Function::ExternalLinkage, - "", &getModule()); - NewFn->takeName(F); - - // Replace uses of F with the Function we will endow with a body. - llvm::Constant *NewPtrForOldDecl = - llvm::ConstantExpr::getBitCast(NewFn, F->getType()); - F->replaceAllUsesWith(NewPtrForOldDecl); - - // FIXME: Update the globaldeclmap for the previous decl of this name. We - // really want a way to walk all of these, but we don't have it yet. This - // is incredibly slow! - ReplaceMapValuesWith(F, NewPtrForOldDecl); - - // Ok, delete the old function now, which is dead. - assert(F->isDeclaration() && "Shouldn't replace non-declaration"); - F->eraseFromParent(); - - SetFunctionAttributes(D, NewFn, FTy); - // Return the new function which has the right type. - return Entry = NewFn; -} - -llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, - bool isDefinition) { - assert(D->hasGlobalStorage() && "Not a global variable"); - assert(!isDefinition && "This shouldn't be called for definitions!"); - - // See if it is already in the map. - llvm::Constant *&Entry = GlobalDeclMap[D]; - if (Entry) return Entry; - - QualType ASTTy = D->getType(); - const llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy); - - // Check to see if the global already exists. - llvm::GlobalVariable *GV = getModule().getGlobalVariable(D->getName(), true); - - // If it doesn't already exist, just create and return an entry. - if (GV == 0) { - return Entry = new llvm::GlobalVariable(Ty, false, - llvm::GlobalValue::ExternalLinkage, - 0, D->getName(), &getModule(), 0, - ASTTy.getAddressSpace()); - } - - // Otherwise, it already exists; return the existing version - llvm::PointerType *PTy = llvm::PointerType::get(Ty, ASTTy.getAddressSpace()); - return Entry = llvm::ConstantExpr::getBitCast(GV, PTy); -} - void CodeGenModule::EmitObjCMethod(const ObjCMethodDecl *OMD) { // If this is not a prototype, emit the body. if (OMD->getBody()) @@ -509,25 +393,6 @@ void CodeGenModule::EmitObjCClassImplementation( ClassMethodSels, ClassMethodTypes, Protocols); } - -void CodeGenModule::EmitFunction(const FunctionDecl *FD) { - // If this is not a prototype, emit the body. - if (!FD->isThisDeclarationADefinition()) { - if (FD->getAttr()) - GetAddrOfFunctionDecl(FD, true); - return; - } - - // If the function is a static, defer code generation until later so we can - // easily omit unused statics. - if (FD->getStorageClass() != FunctionDecl::Static) { - CodeGenFunction(*this).GenerateCode(FD); - return; - } - - StaticDecls.push_back(FD); -} - void CodeGenModule::EmitStatics() { // Emit code for each used static decl encountered. Since a previously unused // static decl may become used during the generation of code for a static @@ -536,7 +401,7 @@ void CodeGenModule::EmitStatics() { do { Changed = false; for (unsigned i = 0, e = StaticDecls.size(); i != e; ++i) { - const Decl *D = StaticDecls[i]; + const ValueDecl *D = StaticDecls[i]; // Check if we have used a decl with the same name // FIXME: The AST should have some sort of aggregate decls or @@ -549,17 +414,9 @@ void CodeGenModule::EmitStatics() { continue; } - // If this is a function decl, generate code for the static function if it - // has a body. Otherwise, we must have a var decl for a static global - // variable. - if (const FunctionDecl *FD = dyn_cast(D)) { - if (FD->getBody()) - CodeGenFunction(*this).GenerateCode(FD); - else if (FD->getAttr()) - GetAddrOfFunctionDecl(FD, true); - } else { - EmitGlobalVarInit(cast(D)); - } + // Emit the definition. + EmitGlobalDefinition(D); + // Erase the used decl from the list. StaticDecls[i] = StaticDecls.back(); StaticDecls.pop_back(); @@ -572,10 +429,6 @@ void CodeGenModule::EmitStatics() { } while (Changed); } -llvm::Constant *CodeGenModule::EmitGlobalInit(const Expr *Expr) { - return EmitConstantExpr(Expr); -} - /// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the /// annotation information for a given GlobalValue. The annotation struct is /// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the @@ -620,25 +473,85 @@ llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV, return llvm::ConstantStruct::get(Fields, 4, false); } -void CodeGenModule::EmitGlobalVar(const VarDecl *D) { - // If the VarDecl is a static, defer code generation until later so we can - // easily omit unused statics. - if (D->getStorageClass() == VarDecl::Static) { - StaticDecls.push_back(D); +/// ReplaceMapValuesWith - This is a really slow and bad function that +/// searches for any entries in GlobalDeclMap that point to OldVal, changing +/// them to point to NewVal. This is badbadbad, FIXME! +void CodeGenModule::ReplaceMapValuesWith(llvm::Constant *OldVal, + llvm::Constant *NewVal) { + for (llvm::DenseMap::iterator + I = GlobalDeclMap.begin(), E = GlobalDeclMap.end(); I != E; ++I) + if (I->second == OldVal) I->second = NewVal; +} + +void CodeGenModule::EmitGlobal(const ValueDecl *Global) { + bool isDef, isStatic; + + if (const FunctionDecl *FD = dyn_cast(Global)) { + isDef = (FD->isThisDeclarationADefinition() || + FD->getAttr()); + isStatic = FD->getStorageClass() == FunctionDecl::Static; + } else if (const VarDecl *VD = cast(Global)) { + assert(VD->isFileVarDecl() && "Cannot emit local var decl as global."); + + isDef = !(VD->getStorageClass() == VarDecl::Extern && VD->getInit() == 0); + isStatic = VD->getStorageClass() == VarDecl::Static; + } else { + assert(0 && "Invalid argument to EmitGlobal"); return; } - // If this is just a forward declaration of the variable, don't emit it now, - // allow it to be emitted lazily on its first use. - if (D->getStorageClass() == VarDecl::Extern && D->getInit() == 0) + // Forward declarations are emitted lazily on first use. + if (!isDef) return; - - EmitGlobalVarInit(D); + + // If the global is a static, defer code generation until later so + // we can easily omit unused statics. + if (isStatic) { + StaticDecls.push_back(Global); + return; + } + + // Otherwise emit the definition. + EmitGlobalDefinition(Global); +} + +void CodeGenModule::EmitGlobalDefinition(const ValueDecl *D) { + if (const FunctionDecl *FD = dyn_cast(D)) { + EmitGlobalFunctionDefinition(FD); + } else if (const VarDecl *VD = dyn_cast(D)) { + EmitGlobalVarDefinition(VD); + } else { + assert(0 && "Invalid argument to EmitGlobalDefinition()"); + } } -void CodeGenModule::EmitGlobalVarInit(const VarDecl *D) { +llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D) { assert(D->hasGlobalStorage() && "Not a global variable"); + // See if it is already in the map. + llvm::Constant *&Entry = GlobalDeclMap[D]; + if (Entry) return Entry; + + QualType ASTTy = D->getType(); + const llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy); + + // Check to see if the global already exists. + llvm::GlobalVariable *GV = getModule().getGlobalVariable(D->getName(), true); + + // If it doesn't already exist, just create and return an entry. + if (GV == 0) { + return Entry = new llvm::GlobalVariable(Ty, false, + llvm::GlobalValue::ExternalLinkage, + 0, D->getName(), &getModule(), 0, + ASTTy.getAddressSpace()); + } + + // Otherwise, it already exists; return the existing version + llvm::PointerType *PTy = llvm::PointerType::get(Ty, ASTTy.getAddressSpace()); + return Entry = llvm::ConstantExpr::getBitCast(GV, PTy); +} + +void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { llvm::Constant *Init = 0; QualType ASTTy = D->getType(); const llvm::Type *VarTy = getTypes().ConvertTypeForMem(ASTTy); @@ -659,7 +572,7 @@ void CodeGenModule::EmitGlobalVarInit(const VarDecl *D) { } Init = llvm::Constant::getNullValue(InitTy); } else { - Init = EmitGlobalInit(D->getInit()); + Init = EmitConstantExpr(D->getInit()); } const llvm::Type* InitType = Init->getType(); @@ -772,6 +685,111 @@ void CodeGenModule::EmitGlobalVarInit(const VarDecl *D) { } } +llvm::GlobalValue * +CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D) { + // FIXME: param attributes for sext/zext etc. + if (const AliasAttr *AA = D->getAttr()) { + assert(!D->getBody() && "Unexpected alias attr on function with body."); + + const std::string& aliaseeName = AA->getAliasee(); + llvm::Function *aliasee = getModule().getFunction(aliaseeName); + llvm::GlobalValue *alias = new llvm::GlobalAlias(aliasee->getType(), + llvm::Function::ExternalLinkage, + D->getName(), + aliasee, + &getModule()); + SetGlobalValueAttributes(D, alias); + return alias; + } else { + const llvm::Type *Ty = getTypes().ConvertType(D->getType()); + const llvm::FunctionType *FTy = cast(Ty); + llvm::Function *F = llvm::Function::Create(FTy, + llvm::Function::ExternalLinkage, + D->getName(), &getModule()); + + SetFunctionAttributes(D, F, FTy); + return F; + } +} + +llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D) { + // See if it is already in the map. If so, just return it. + llvm::Constant *&Entry = GlobalDeclMap[D]; + if (Entry) return Entry; + + // Check to see if the function already exists; this occurs when + // this decl shadows a previous one. If it exists we bitcast it to + // the proper type for this decl and return. + llvm::Function *F = getModule().getFunction(D->getName()); + if (F) { + const llvm::Type *Ty = getTypes().ConvertType(D->getType()); + llvm::Type *PFTy = llvm::PointerType::getUnqual(Ty); + return Entry = llvm::ConstantExpr::getBitCast(F, PFTy); + } + + // It doesn't exist; create and return an entry. + return Entry = EmitForwardFunctionDefinition(D); +} + +void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { + llvm::Constant *&Entry = GlobalDeclMap[D]; + + const llvm::Type *Ty = getTypes().ConvertType(D->getType()); + const llvm::FunctionType *FTy = cast(Ty); + + // Check to see if the function already exists. + llvm::Function *F = getModule().getFunction(D->getName()); + + // If it doesn't already exist, just create and return an entry. + if (F == 0) { + Entry = EmitForwardFunctionDefinition(D); + } else { + // If the pointer type matches, just return it. + llvm::Type *PFTy = llvm::PointerType::getUnqual(Ty); + if (PFTy == F->getType()) { + Entry = F; + } else { + // Otherwise, we have a definition after a prototype with the wrong type. + // F is the Function* for the one with the wrong type, we must make a new + // Function* and update everything that used F (a declaration) with the new + // Function* (which will be a definition). + // + // This happens if there is a prototype for a function (e.g. "int f()") and + // then a definition of a different type (e.g. "int f(int x)"). Start by + // making a new function of the correct type, RAUW, then steal the name. + llvm::Function *NewFn = llvm::Function::Create(FTy, + llvm::Function::ExternalLinkage, + "", &getModule()); + NewFn->takeName(F); + + // Replace uses of F with the Function we will endow with a body. + llvm::Constant *NewPtrForOldDecl = + llvm::ConstantExpr::getBitCast(NewFn, F->getType()); + F->replaceAllUsesWith(NewPtrForOldDecl); + + // FIXME: Update the globaldeclmap for the previous decl of this name. We + // really want a way to walk all of these, but we don't have it yet. This + // is incredibly slow! + ReplaceMapValuesWith(F, NewPtrForOldDecl); + + // Ok, delete the old function now, which is dead. + assert(F->isDeclaration() && "Shouldn't replace non-declaration"); + F->eraseFromParent(); + + SetFunctionAttributes(D, NewFn, FTy); + // Return the new function which has the right type. + Entry = NewFn; + } + } + + if (D->getAttr()) { + ; + } else { + llvm::Function *Fn = cast(Entry); + CodeGenFunction(*this).GenerateCode(D, Fn); + } +} + void CodeGenModule::UpdateCompletedType(const TagDecl *TD) { // Make sure that this type is translated. Types.UpdateCompletedType(TD); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 8609497242..57363cddee 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -1,4 +1,4 @@ -//===--- CodeGenModule.h - Per-Module state for LLVM CodeGen --------------===// +//===--- CodeGenModule.h - Per-Module state for LLVM CodeGen ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -40,6 +40,7 @@ namespace clang { class Expr; class Stmt; class NamedDecl; + class ValueDecl; class VarDecl; struct LangOptions; class Diagnostic; @@ -66,7 +67,13 @@ class CodeGenModule { llvm::Function *MemMoveFn; llvm::Function *MemSetFn; llvm::DenseMap GlobalDeclMap; - std::vector StaticDecls; + + /// List of static global for which code generation is delayed. When + /// the translation unit has been fully processed we will lazily + /// emit definitions for only the decls that were actually used. + /// This should contain only Function and Var decls, and only those + /// which actually define something. + std::vector StaticDecls; std::vector GlobalCtors; std::vector Annotations; @@ -90,11 +97,14 @@ public: CodeGenTypes &getTypes() { return Types; } Diagnostic &getDiags() const { return Diags; } const llvm::TargetData &getTargetData() const { return TheTargetData; } - - llvm::Constant *GetAddrOfFunctionDecl(const FunctionDecl *D, - bool isDefinition); - llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D, bool isDefinition); - + + /// GetAddrOfGlobalVar - Return the llvm::Constant for the address + /// of the given global variable. + llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D); + + /// GetAddrOfFunction - Return the llvm::Constant for the address + /// of the given function. + llvm::Constant *GetAddrOfFunction(const FunctionDecl *D); /// getBuiltinLibFunction - Given a builtin id for a function like /// "__builtin_fabsf", return a Function* for "fabsf". @@ -111,21 +121,18 @@ public: llvm::Function *getIntrinsic(unsigned IID, const llvm::Type **Tys = 0, unsigned NumTys = 0); - void AddGlobalCtor(llvm::Function * Ctor); - void EmitGlobalCtors(void); - void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); } - void EmitAnnotations(void); - void EmitStatics(void); - void EmitObjCMethod(const ObjCMethodDecl *OMD); void EmitObjCCategoryImpl(const ObjCCategoryImplDecl *OCD); void EmitObjCClassImplementation(const ObjCImplementationDecl *OID); void EmitObjCProtocolImplementation(const ObjCProtocolDecl *PD); - void EmitFunction(const FunctionDecl *FD); - void EmitGlobalVar(const VarDecl *D); - void EmitGlobalVarInit(const VarDecl *D); + + /// EmitGlobal - Emit code for a singal global function or var + /// decl. Forward declarations are emitted lazily. + void EmitGlobal(const ValueDecl *D); + + void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); } + void UpdateCompletedType(const TagDecl *D); - llvm::Constant *EmitGlobalInit(const Expr *E); llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0); llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV, const AnnotateAttr *AA, unsigned LineNo); @@ -157,6 +164,16 @@ private: void SetGlobalValueAttributes(const FunctionDecl *FD, llvm::GlobalValue *GV); + void EmitGlobalDefinition(const ValueDecl *D); + llvm::GlobalValue *EmitForwardFunctionDefinition(const FunctionDecl *D); + void EmitGlobalFunctionDefinition(const FunctionDecl *D); + void EmitGlobalVarDefinition(const VarDecl *D); + + void AddGlobalCtor(llvm::Function * Ctor); + void EmitGlobalCtors(void); + void EmitAnnotations(void); + void EmitStatics(void); + }; } // end namespace CodeGen } // end namespace clang diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp index 3fa086fc6a..201092f4d8 100644 --- a/lib/CodeGen/ModuleBuilder.cpp +++ b/lib/CodeGen/ModuleBuilder.cpp @@ -66,7 +66,9 @@ namespace { return; if (FunctionDecl *FD = dyn_cast(D)) { - Builder->EmitFunction(FD); + Builder->EmitGlobal(FD); + } else if (VarDecl *VD = dyn_cast(D)) { + Builder->EmitGlobal(VD); } else if (isa(D)){ //Forward declaration. Only used for type checking. } else if (ObjCProtocolDecl *PD = dyn_cast(D)){ @@ -85,8 +87,6 @@ namespace { // Ignore - generated when the implementation decl is CodeGen'd } else if (ObjCMethodDecl *OMD = dyn_cast(D)){ Builder->EmitObjCMethod(OMD); - } else if (VarDecl *VD = dyn_cast(D)) { - Builder->EmitGlobalVar(VD); } else if (isa(D) || isa(D)) { // Forward declaration. Only used for type checking. } else if (ObjCMethodDecl *OMD = dyn_cast(D)){