[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