[cfe-commits] r131060 - in /cfe/trunk: lib/CodeGen/CodeGenModule.cpp test/CodeGenCXX/global-llvm-constant.cpp

Douglas Gregor dgregor at apple.com
Sat May 7 15:06:46 PDT 2011


Author: dgregor
Date: Sat May  7 17:06:45 2011
New Revision: 131060

URL: http://llvm.org/viewvc/llvm-project?rev=131060&view=rev
Log:
In C++, allow us to emit a global as 'constant' even if it has class
type, so long as it is known to have a constant initializer and the
class type is a POD class. Fixes <rdar://problem/9306265>.

Modified:
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/test/CodeGenCXX/global-llvm-constant.cpp

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=131060&r1=131059&r2=131060&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sat May  7 17:06:45 2011
@@ -938,14 +938,17 @@
   return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false);
 }
 
-static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D) {
+static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D,
+                                 bool ConstantInit) {
   if (!D->getType().isConstant(Context) && !D->getType()->isReferenceType())
     return false;
-  if (Context.getLangOptions().CPlusPlus &&
-      Context.getBaseElementType(D->getType())->getAs<RecordType>()) {
-    // FIXME: We should do something fancier here!
-    return false;
+  
+  if (Context.getLangOptions().CPlusPlus) {
+    if (const RecordType *Record 
+          = Context.getBaseElementType(D->getType())->getAs<RecordType>())
+      return ConstantInit && cast<CXXRecordDecl>(Record->getDecl())->isPOD();
   }
+  
   return true;
 }
 
@@ -1002,7 +1005,7 @@
   if (D) {
     // FIXME: This code is overly simple and should be merged with other global
     // handling.
-    GV->setConstant(DeclIsConstantGlobal(Context, D));
+    GV->setConstant(DeclIsConstantGlobal(Context, D, false));
 
     // Set linkage and visibility in case we never see a definition.
     NamedDecl::LinkageInfo LV = D->getLinkageAndVisibility();
@@ -1284,7 +1287,7 @@
 
   // If it is safe to mark the global 'constant', do so now.
   GV->setConstant(false);
-  if (!NonConstInit && DeclIsConstantGlobal(Context, D))
+  if (!NonConstInit && DeclIsConstantGlobal(Context, D, true))
     GV->setConstant(true);
 
   GV->setAlignment(getContext().getDeclAlign(D).getQuantity());

Modified: cfe/trunk/test/CodeGenCXX/global-llvm-constant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/global-llvm-constant.cpp?rev=131060&r1=131059&r2=131060&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/global-llvm-constant.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/global-llvm-constant.cpp Sat May  7 17:06:45 2011
@@ -8,3 +8,13 @@
 const A x;
 
 // CHECK: @_ZL1x = internal global
+
+struct X {
+  int (*fp)(int, int);
+};
+
+int add(int x, int y) { return x + y; }
+
+// CHECK: @x2 = constant
+extern const X x2;
+const X x2 = { &add };





More information about the cfe-commits mailing list