[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