aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-02-13 21:18:01 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-02-13 21:18:01 +0000
commit73241dfeb5c498255b662984cca369fd28ec3147 (patch)
treeff7b7b38d435c9c964beb6d28f84d7d468925575 /lib
parent0269871c9cba493f76237175ab60313406f3bafa (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.cpp50
-rw-r--r--lib/CodeGen/CodeGenModule.h5
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