diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-11-22 22:48:32 +0000 | 
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-11-22 22:48:32 +0000 | 
| commit | 2d988f0f05db22d0771d31e5839ed6df01e8ac19 (patch) | |
| tree | f95ac3e798e7e8ba2529865cc8ba6ceb83b98fb7 | |
| parent | 1959df2c9c2ee2a0b82d08fb6fe0bdfb32d70598 (diff) | |
| download | bcm5719-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.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 4 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/compound-literals.cpp | 5 | 
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  | 

