[cfe-commits] r64488 - in /cfe/trunk: lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h test/CodeGen/constructor-attribute.c
Daniel Dunbar
daniel at zuster.org
Fri Feb 13 13:18:02 PST 2009
Author: ddunbar
Date: Fri Feb 13 15:18:01 2009
New Revision: 64488
URL: http://llvm.org/viewvc/llvm-project?rev=64488&view=rev
Log:
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
Modified:
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/test/CodeGen/constructor-attribute.c
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=64488&r1=64487&r2=64488&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Feb 13 15:18:01 2009
@@ -429,7 +429,7 @@
// 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 @@
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 @@
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;
}
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=64488&r1=64487&r2=64488&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Feb 13 15:18:01 2009
@@ -324,6 +324,11 @@
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
Modified: cfe/trunk/test/CodeGen/constructor-attribute.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/constructor-attribute.c?rev=64488&r1=64487&r2=64488&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/constructor-attribute.c (original)
+++ cfe/trunk/test/CodeGen/constructor-attribute.c Fri Feb 13 15:18:01 2009
@@ -1,6 +1,8 @@
// RUN: clang -emit-llvm -o %t %s &&
// RUN: grep -e "global_ctors.*@A" %t &&
-// RUN: grep -e "global_dtors.*@B" %t
+// RUN: grep -e "global_dtors.*@B" %t &&
+// RUN: grep -e "global_ctors.*@C" %t &&
+// RUN: grep -e "global_dtors.*@D" %t
#include <stdio.h>
@@ -15,6 +17,22 @@
printf("B\n");
}
+static void C() __attribute__((constructor));
+
+static void D() __attribute__((destructor));
+
+static int foo() {
+ return 10;
+}
+
+static void C() {
+ printf("A: %d\n", foo());
+}
+
+static void D() {
+ printf("B\n");
+}
+
int main() {
return 0;
}
More information about the cfe-commits
mailing list