summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp22
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h14
2 files changed, 32 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 62a9c8fa907..3db15c646f4 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -1023,16 +1023,17 @@ public:
switch (E->getStmtClass()) {
default: break;
case Expr::CompoundLiteralExprClass: {
- // Note that due to the nature of compound literals, this is guaranteed
- // to be the only use of the variable, so we just generate it here.
CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
+ CharUnits Align = CGM.getContext().getTypeAlignInChars(E->getType());
+ if (llvm::GlobalVariable *Addr =
+ CGM.getAddrOfConstantCompoundLiteralIfEmitted(CLE))
+ return ConstantAddress(Addr, Align);
+
llvm::Constant* C = CGM.EmitConstantExpr(CLE->getInitializer(),
CLE->getType(), CGF);
// FIXME: "Leaked" on failure.
if (!C) return ConstantAddress::invalid();
- CharUnits Align = CGM.getContext().getTypeAlignInChars(E->getType());
-
auto GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(),
E->getType().isConstant(CGM.getContext()),
llvm::GlobalValue::InternalLinkage,
@@ -1040,6 +1041,7 @@ public:
llvm::GlobalVariable::NotThreadLocal,
CGM.getContext().getTargetAddressSpace(E->getType()));
GV->setAlignment(Align.getQuantity());
+ CGM.setAddrOfConstantCompoundLiteral(CLE, GV);
return ConstantAddress(GV, Align);
}
case Expr::StringLiteralClass:
@@ -1492,6 +1494,18 @@ CodeGenModule::EmitConstantValueForMemory(const APValue &Value,
return C;
}
+llvm::GlobalVariable *CodeGenModule::getAddrOfConstantCompoundLiteralIfEmitted(
+ const CompoundLiteralExpr *E) {
+ return EmittedCompoundLiterals.lookup(E);
+}
+
+void CodeGenModule::setAddrOfConstantCompoundLiteral(
+ const CompoundLiteralExpr *CLE, llvm::GlobalVariable *GV) {
+ bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;
+ (void)Ok;
+ assert(Ok && "CLE has already been emitted!");
+}
+
ConstantAddress
CodeGenModule::GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E) {
assert(E->isFileScope() && "not a file-scope compound literal expr");
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 5f06ba90cf1..1d72b4edeb1 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -455,6 +455,10 @@ private:
bool isTriviallyRecursive(const FunctionDecl *F);
bool shouldEmitFunction(GlobalDecl GD);
+ /// Map used to be sure we don't emit the same CompoundLiteral twice.
+ llvm::DenseMap<const CompoundLiteralExpr *, llvm::GlobalVariable *>
+ EmittedCompoundLiterals;
+
/// Map of the global blocks we've emitted, so that we don't have to re-emit
/// them if the constexpr evaluator gets aggressive.
llvm::DenseMap<const BlockExpr *, llvm::Constant *> EmittedGlobalBlocks;
@@ -824,6 +828,16 @@ public:
/// compound literal expression.
ConstantAddress GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E);
+ /// If it's been emitted already, returns the GlobalVariable corresponding to
+ /// a compound literal. Otherwise, returns null.
+ llvm::GlobalVariable *
+ getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *E);
+
+ /// Notes that CLE's GlobalVariable is GV. Asserts that CLE isn't already
+ /// emitted.
+ void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *CLE,
+ llvm::GlobalVariable *GV);
+
/// \brief Returns a pointer to a global variable representing a temporary
/// with static or thread storage duration.
ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E,
OpenPOWER on IntegriCloud