[clang] cb5f205 - [clang][Interp] Implement nested struct initialization
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 14 01:22:23 PDT 2022
Author: Timm Bäder
Date: 2022-10-14T10:21:53+02:00
New Revision: cb5f205828e696fb23cfe3de57af83d151ffad38
URL: https://github.com/llvm/llvm-project/commit/cb5f205828e696fb23cfe3de57af83d151ffad38
DIFF: https://github.com/llvm/llvm-project/commit/cb5f205828e696fb23cfe3de57af83d151ffad38.diff
LOG: [clang][Interp] Implement nested struct initialization
Recurse into visitInitializer() if necessary.
Differential Revision: https://reviews.llvm.org/D134175
Added:
Modified:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeStmtGen.cpp
clang/test/AST/Interp/records.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index d743e3a22342..66e373e427c8 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -613,9 +613,11 @@ bool ByteCodeExprGen<Emitter>::visitArrayInitializer(const Expr *Initializer) {
return false;
} else if (Optional<PrimType> T = classify(InitType)) {
// Visit the primitive element like normal.
+ if (!this->emitDupPtr(Init))
+ return false;
if (!this->visit(Init))
return false;
- if (!this->emitInitElem(*T, ElementIndex, Init))
+ if (!this->emitInitElemPop(*T, ElementIndex, Init))
return false;
} else {
assert(false && "Unhandled type in array initializer initlist");
@@ -623,12 +625,13 @@ bool ByteCodeExprGen<Emitter>::visitArrayInitializer(const Expr *Initializer) {
++ElementIndex;
}
-
- } else {
- assert(false && "Unknown expression for array initialization");
+ return true;
+ } else if (const auto *DIE = dyn_cast<CXXDefaultInitExpr>(Initializer)) {
+ return this->visitInitializer(DIE->getExpr());
}
- return true;
+ assert(false && "Unknown expression for array initialization");
+ return false;
}
template <class Emitter>
@@ -683,7 +686,10 @@ bool ByteCodeExprGen<Emitter>::visitRecordInitializer(const Expr *Initializer) {
return this->visit(CE);
}
+ } else if (const auto *DIE = dyn_cast<CXXDefaultInitExpr>(Initializer)) {
+ return this->visitInitializer(DIE->getExpr());
}
+
return false;
}
diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index 54a0f50d198b..b4a61ebed0e7 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -102,10 +102,9 @@ bool ByteCodeStmtGen<Emitter>::visitFunc(const FunctionDecl *F) {
for (const auto *Init : Ctor->inits()) {
const FieldDecl *Member = Init->getMember();
const Expr *InitExpr = Init->getInit();
+ const Record::Field *F = R->getField(Member);
if (Optional<PrimType> T = this->classify(InitExpr->getType())) {
- const Record::Field *F = R->getField(Member);
-
if (!this->emitDupPtr(InitExpr))
return false;
@@ -115,7 +114,19 @@ bool ByteCodeStmtGen<Emitter>::visitFunc(const FunctionDecl *F) {
if (!this->emitInitField(*T, F->Offset, InitExpr))
return false;
} else {
- assert(false && "Handle initializer for non-primitive values");
+ // Non-primitive case. Get a pointer to the field-to-initialize
+ // on the stack and call visitInitialzer() for it.
+ if (!this->emitDupPtr(InitExpr))
+ return false;
+
+ if (!this->emitGetPtrField(F->Offset, InitExpr))
+ return false;
+
+ if (!this->visitInitializer(InitExpr))
+ return false;
+
+ if (!this->emitPopPtr(InitExpr))
+ return false;
}
}
}
diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp
index ab363ffc8770..8d62b53d622a 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -12,7 +12,8 @@ struct Ints {
int a = 20;
int b = 30;
bool c = true;
- // BoolPair bp = {true, false}; FIXME
+ BoolPair bp = {true, false};
+ int numbers[3] = {1,2,3};
static const int five = 5;
static constexpr int getFive() {
@@ -32,6 +33,13 @@ static_assert(ints.b == 30, "");
static_assert(ints.c, "");
static_assert(ints.getTen() == 10, "");
+constexpr const BoolPair &BP = ints.bp;
+static_assert(BP.first, "");
+static_assert(!BP.second, "");
+static_assert(ints.bp.first, "");
+static_assert(!ints.bp.second, "");
+
+
constexpr Ints ints2{-20, -30, false};
static_assert(ints2.a == -20, "");
static_assert(ints2.b == -30, "");
More information about the cfe-commits
mailing list