aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGExprAgg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGExprAgg.cpp')
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp40
1 files changed, 32 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index b2a5cee..a8bb254 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -509,6 +509,16 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
uint64_t NumInitElements = Args.size();
uint64_t NumArrayElements = AType->getNumElements();
+ for (const auto *Init : Args) {
+ if (const auto *Embed = dyn_cast<EmbedExpr>(Init->IgnoreParenImpCasts())) {
+ NumInitElements += Embed->getDataElementCount() - 1;
+ if (NumInitElements > NumArrayElements) {
+ NumInitElements = NumArrayElements;
+ break;
+ }
+ }
+ }
+
assert(NumInitElements <= NumArrayElements);
QualType elementType =
@@ -577,23 +587,37 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1);
- // Emit the explicit initializers.
- for (uint64_t i = 0; i != NumInitElements; ++i) {
+ auto Emit = [&](Expr *Init, uint64_t ArrayIndex) {
llvm::Value *element = begin;
- if (i > 0) {
- element = Builder.CreateInBoundsGEP(llvmElementType, begin,
- llvm::ConstantInt::get(CGF.SizeTy, i),
- "arrayinit.element");
+ if (ArrayIndex > 0) {
+ element = Builder.CreateInBoundsGEP(
+ llvmElementType, begin,
+ llvm::ConstantInt::get(CGF.SizeTy, ArrayIndex), "arrayinit.element");
// Tell the cleanup that it needs to destroy up to this
// element. TODO: some of these stores can be trivially
// observed to be unnecessary.
- if (endOfInit.isValid()) Builder.CreateStore(element, endOfInit);
+ if (endOfInit.isValid())
+ Builder.CreateStore(element, endOfInit);
}
LValue elementLV = CGF.MakeAddrLValue(
Address(element, llvmElementType, elementAlign), elementType);
- EmitInitializationToLValue(Args[i], elementLV);
+ EmitInitializationToLValue(Init, elementLV);
+ return true;
+ };
+
+ unsigned ArrayIndex = 0;
+ // Emit the explicit initializers.
+ for (uint64_t i = 0; i != NumInitElements; ++i) {
+ if (ArrayIndex >= NumInitElements)
+ break;
+ if (auto *EmbedS = dyn_cast<EmbedExpr>(Args[i]->IgnoreParenImpCasts())) {
+ EmbedS->doForEachDataElement(Emit, ArrayIndex);
+ } else {
+ Emit(Args[i], ArrayIndex);
+ ArrayIndex++;
+ }
}
// Check whether there's a non-trivial array-fill expression.