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, ""); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits