summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2011-11-22 22:48:32 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2011-11-22 22:48:32 +0000
commit2d988f0f05db22d0771d31e5839ed6df01e8ac19 (patch)
treef95ac3e798e7e8ba2529865cc8ba6ceb83b98fb7
parent1959df2c9c2ee2a0b82d08fb6fe0bdfb32d70598 (diff)
downloadbcm5719-llvm-2d988f0f05db22d0771d31e5839ed6df01e8ac19.tar.gz
bcm5719-llvm-2d988f0f05db22d0771d31e5839ed6df01e8ac19.zip
Use static storage duration for file-scope compound literals, even when they
appear in non-constant initializers in C++. llvm-svn: 145087
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp5
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp6
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h4
-rw-r--r--clang/test/CodeGenCXX/compound-literals.cpp5
4 files changed, 20 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index a35bb5f7118..e4f81b7a3f4 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1947,6 +1947,11 @@ CodeGenFunction::EmitLValueForFieldInitialization(llvm::Value *BaseValue,
}
LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
+ if (E->isFileScope()) {
+ llvm::Value *GlobalPtr = CGM.GetAddrOfConstantCompoundLiteral(E);
+ return MakeAddrLValue(GlobalPtr, E->getType());
+ }
+
llvm::Value *DeclPtr = CreateMemTemp(E->getType(), ".compoundliteral");
const Expr *InitExpr = E->getInitializer();
LValue Result = MakeAddrLValue(DeclPtr, E->getType());
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 7485c71d7db..5d436619d75 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -1087,6 +1087,12 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
return C;
}
+llvm::Constant *
+CodeGenModule::GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E) {
+ assert(E->isFileScope() && "not a file-scope compound literal expr");
+ return ConstExprEmitter(*this, 0).EmitLValue(E);
+}
+
static uint64_t getFieldOffset(ASTContext &C, const FieldDecl *field) {
const ASTRecordLayout &layout = C.getASTRecordLayout(field->getParent());
return layout.getFieldOffset(field->getFieldIndex());
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 7b82819af3d..4c31737b296 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -599,6 +599,10 @@ public:
llvm::Constant *GetAddrOfConstantCString(const std::string &str,
const char *GlobalName=0,
unsigned Alignment=1);
+
+ /// GetAddrOfConstantCompoundLiteral - Returns a pointer to a constant global
+ /// variable for the given file-scope compound literal expression.
+ llvm::Constant *GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E);
/// \brief Retrieve the record type that describes the state of an
/// Objective-C fast enumeration loop (for..in).
diff --git a/clang/test/CodeGenCXX/compound-literals.cpp b/clang/test/CodeGenCXX/compound-literals.cpp
index f520ff99516..aa9ae3cacfd 100644
--- a/clang/test/CodeGenCXX/compound-literals.cpp
+++ b/clang/test/CodeGenCXX/compound-literals.cpp
@@ -37,3 +37,8 @@ int g() {
// CHECK-NEXT: ret i32 [[A0]]
return v[0];
}
+
+struct Z { int i[3]; };
+int *p = (Z){ {1, 2, 3} }.i;
+// CHECK: define {{.*}}__cxx_global_var_init()
+// CHECK: store i32* getelementptr inbounds (%struct.Z* @.compoundliteral, i32 0, i32 0, i32 0), i32** @p, align 8
OpenPOWER on IntegriCloud