diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-02-13 21:18:01 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-02-13 21:18:01 +0000 |
commit | 73241dfeb5c498255b662984cca369fd28ec3147 (patch) | |
tree | ff7b7b38d435c9c964beb6d28f84d7d468925575 /lib | |
parent | 0269871c9cba493f76237175ab60313406f3bafa (diff) |
Pull MayDeferGeneration out of EmitGlobal.
- Fix emission of static functions with constructor attribute while I
was here.
<rdar://problem/6140899> [codegen] "static" and attribute-constructor interact poorly
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64488 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 50 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 5 |
2 files changed, 39 insertions, 16 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 69af3d265c..ecfd8c98c3 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -429,7 +429,7 @@ void CodeGenModule::EmitDeferred() { // FIXME: The AST should have some sort of aggregate decls or // global symbol map. // FIXME: This is missing some important cases. For example, we - // need to check for uses in an alias and in a constructor. + // need to check for uses in an alias. if (!GlobalDeclMap.count(getMangledName(D))) { i++; continue; @@ -491,10 +491,31 @@ llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV, return llvm::ConstantStruct::get(Fields, 4, false); } -void CodeGenModule::EmitGlobal(const ValueDecl *Global) { - bool isDef, isStatic; +bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { + // Never defer when EmitAllDecls is specified. + if (Features.EmitAllDecls) + return false; if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) { + // Constructors and destructors should never be deferred. + if (FD->getAttr<ConstructorAttr>() || FD->getAttr<DestructorAttr>()) + return false; + + if (FD->getStorageClass() != FunctionDecl::Static) + return false; + } else { + const VarDecl *VD = cast<VarDecl>(Global); + assert(VD->isFileVarDecl() && "Invalid decl."); + + if (VD->getStorageClass() != VarDecl::Static) + return false; + } + + return true; +} + +void CodeGenModule::EmitGlobal(const ValueDecl *Global) { + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) { // Aliases are deferred until code for everything else has been // emitted. if (FD->getAttr<AliasAttr>()) { @@ -504,25 +525,22 @@ void CodeGenModule::EmitGlobal(const ValueDecl *Global) { return; } - isDef = FD->isThisDeclarationADefinition(); - isStatic = FD->getStorageClass() == FunctionDecl::Static; + // Forward declarations are emitted lazily on first use. + if (!FD->isThisDeclarationADefinition()) + return; } else { const VarDecl *VD = cast<VarDecl>(Global); assert(VD->isFileVarDecl() && "Cannot emit local var decl as global."); - isDef = !((VD->getStorageClass() == VarDecl::Extern || - VD->getStorageClass() == VarDecl::PrivateExtern) && - VD->getInit() == 0); - isStatic = VD->getStorageClass() == VarDecl::Static; + // Forward declarations are emitted lazily on first use. + if ((VD->getStorageClass() == VarDecl::Extern || + VD->getStorageClass() == VarDecl::PrivateExtern) && + VD->getInit() == 0) + return; } - // Forward declarations are emitted lazily on first use. - if (!isDef) - return; - - // If the global is a static, defer code generation until later so - // we can easily omit unused statics. - if (isStatic && !Features.EmitAllDecls) { + // Defer code generation when possible. + if (MayDeferGeneration(Global)) { DeferredDecls.push_back(Global); return; } diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 1d10f9d1e3..967889a92d 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -324,6 +324,11 @@ private: void EmitLLVMUsed(void); void BindRuntimeFunctions(); + + /// MayDeferGeneration - Determine if the given decl can be emitted + /// lazily; this is only relevant for definitions. The given decl + /// must be either a function or var decl. + bool MayDeferGeneration(const ValueDecl *D); }; } // end namespace CodeGen } // end namespace clang |