Serialization/Deserialization of expansion statements.

Should fix #165.
This commit is contained in:
Dan Katz
2025-06-30 14:18:21 -04:00
parent 97a102f706
commit a2bd2164c0
9 changed files with 290 additions and 32 deletions

View File

@@ -5923,12 +5923,17 @@ class CXXExpansionInitListExpr : public Expr {
unsigned NumSubExprs, SourceLocation LBraceLoc,
SourceLocation RBraceLoc);
CXXExpansionInitListExpr(EmptyShell Empty);
public:
static CXXExpansionInitListExpr *Create(const ASTContext &C,
Expr **SubExprs, unsigned NumSubExprs,
SourceLocation LBraceLoc,
SourceLocation RBraceLoc);
static CXXExpansionInitListExpr *Create(const ASTContext &C,
EmptyShell Empty);
ArrayRef<Expr *> getSubExprs() const { return {SubExprs, NumSubExprs}; }
bool containsPack() const { return ContainsPack; }
@@ -5954,6 +5959,8 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXExpansionInitListExprClass;
}
friend class ASTStmtReader;
};
class CXXIterableExpansionSelectExpr : public Expr {
@@ -5962,10 +5969,15 @@ class CXXIterableExpansionSelectExpr : public Expr {
CXXIterableExpansionSelectExpr(QualType ResultTy, VarDecl *DD, Expr *Impl);
CXXIterableExpansionSelectExpr(EmptyShell Empty);
public:
static CXXIterableExpansionSelectExpr *Create(const ASTContext &C,
VarDecl *RangeVar, Expr *Impl);
static CXXIterableExpansionSelectExpr *Create(const ASTContext &C,
EmptyShell Empty);
Expr *getImplExpr() const { return ImplExpr; }
VarDecl *getRangeVar() const { return RangeVar; }
@@ -5990,6 +6002,8 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXIterableExpansionSelectExprClass;
}
friend class ASTStmtReader;
};
class CXXDestructurableExpansionSelectExpr : public Expr {
@@ -6000,12 +6014,17 @@ class CXXDestructurableExpansionSelectExpr : public Expr {
CXXDestructurableExpansionSelectExpr(QualType ResultTy, DecompositionDecl *DD,
Expr *Idx, VarDecl *ExpansionVar);
CXXDestructurableExpansionSelectExpr(EmptyShell Empty);
public:
static CXXDestructurableExpansionSelectExpr *Create(const ASTContext &C,
DecompositionDecl *DD,
Expr *Idx,
VarDecl *ExpansionVar);
static CXXDestructurableExpansionSelectExpr *Create(const ASTContext &C,
EmptyShell Empty);
Expr *getIdxExpr() const { return IdxExpr; }
DecompositionDecl *getDecompositionDecl() const { return DD; }
VarDecl *getExpansionVar() const { return ExpansionVar; }
@@ -6027,6 +6046,8 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDestructurableExpansionSelectExprClass;
}
friend class ASTStmtReader;
};
class CXXIndeterminateExpansionSelectExpr : public Expr {
@@ -6042,11 +6063,16 @@ class CXXIndeterminateExpansionSelectExpr : public Expr {
unsigned NumLifetimeExtendTemps,
MaterializeTemporaryExpr **LifetimeExtendTemps);
CXXIndeterminateExpansionSelectExpr(EmptyShell Empty);
public:
static CXXIndeterminateExpansionSelectExpr *Create(
const ASTContext &C, Expr *Range, Expr *Idx, VarDecl *ExpansionVar,
ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps);
static CXXIndeterminateExpansionSelectExpr *Create(const ASTContext &C,
EmptyShell Empty);
Expr *getRangeExpr() const { return SubExprs[0]; }
Expr *getIdxExpr() const { return SubExprs[1]; }
VarDecl *getExpansionVar() const { return ExpansionVar; }
@@ -6069,6 +6095,8 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXIndeterminateExpansionSelectExprClass;
}
friend class ASTStmtReader;
};
class CXXExpansionInitListSelectExpr : public Expr {
@@ -6076,10 +6104,15 @@ class CXXExpansionInitListSelectExpr : public Expr {
CXXExpansionInitListSelectExpr(QualType ResultTy, Expr *Range, Expr *Idx);
CXXExpansionInitListSelectExpr(EmptyShell Empty);
public:
static CXXExpansionInitListSelectExpr *Create(const ASTContext &C,
Expr *Range, Expr *Idx);
static CXXExpansionInitListSelectExpr *Create(const ASTContext &C,
EmptyShell Empty);
Expr *getRangeExpr() const { return SubExprs[0]; }
Expr *getIdxExpr() const { return SubExprs[1]; }
@@ -6100,6 +6133,8 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXExpansionInitListSelectExprClass;
}
friend class ASTStmtReader;
};
} // namespace clang

View File

@@ -584,7 +584,9 @@ public:
}
Expr *getSizeExpr() { return cast<Expr>(SubStmts[SIZE]); }
Expr *getSizeExpr() {
return SubStmts[SIZE] ? cast<Expr>(SubStmts[SIZE]) : nullptr;
}
const Expr *getSizeExpr() const {
return const_cast<CXXExpansionStmt *>(this)->getSizeExpr();
}
@@ -670,6 +672,8 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXIndeterminateExpansionStmtClass;
}
friend class ASTStmtReader;
};
/// CXXIterableExpansionStmt - Expansion over a iterable expression.
@@ -712,6 +716,8 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXIterableExpansionStmtClass;
}
friend class ASTStmtReader;
};
/// CXXDestructurableExpansionStmt - Expansion over a destructurable expression.
@@ -750,6 +756,8 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDestructurableExpansionStmtClass;
}
friend class ASTStmtReader;
};
/// CXXInitListExpansionStmt - Expansion over an expansion-init-list.
@@ -786,6 +794,8 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXInitListExpansionStmtClass;
}
friend class ASTStmtReader;
};
} // end namespace clang

View File

@@ -2054,7 +2054,10 @@ enum StmtCode {
STMT_ITERABLE_EXPANSION,
STMT_DESTRUCTURABLE_EXPANSION,
STMT_INIT_LIST_EXPANSION,
EXPR_EXPANSION_SELECT,
EXPR_INDETERMINATE_EXPANSION_SELECT,
EXPR_ITERABLE_EXPANSION_SELECT,
EXPR_DESTRUCTURABLE_EXPANSION_SELECT,
EXPR_INIT_LIST_EXPANSION_SELECT,
EXPR_EXPANSION_INIT_LIST,
// FixedPointLiteral

View File

@@ -2132,6 +2132,10 @@ CXXExpansionInitListExpr::CXXExpansionInitListExpr(
setDependence(computeDependence(this));
}
CXXExpansionInitListExpr::CXXExpansionInitListExpr(EmptyShell Empty)
: Expr(CXXExpansionInitListExprClass, Empty) {
}
CXXExpansionInitListExpr *CXXExpansionInitListExpr::Create(
const ASTContext &C, Expr ** SubExprs, unsigned NumSubExprs,
SourceLocation LBraceLoc, SourceLocation RBraceLoc) {
@@ -2139,6 +2143,11 @@ CXXExpansionInitListExpr *CXXExpansionInitListExpr::Create(
LBraceLoc, RBraceLoc);
}
CXXExpansionInitListExpr *CXXExpansionInitListExpr::Create(
const ASTContext &C, EmptyShell Empty) {
return new (C) CXXExpansionInitListExpr(Empty);
}
CXXIndeterminateExpansionSelectExpr::CXXIndeterminateExpansionSelectExpr(
QualType ResultTy, Expr *Range, Expr *Idx, VarDecl *ExpansionVar,
unsigned NumLifetimeExtendTemps,
@@ -2151,6 +2160,11 @@ CXXIndeterminateExpansionSelectExpr::CXXIndeterminateExpansionSelectExpr(
setDependence(computeDependence(this));
}
CXXIndeterminateExpansionSelectExpr::CXXIndeterminateExpansionSelectExpr(
EmptyShell Empty)
: Expr(CXXIndeterminateExpansionSelectExprClass, Empty) {
}
CXXIndeterminateExpansionSelectExpr *
CXXIndeterminateExpansionSelectExpr::Create(
const ASTContext &C, Expr *Range, Expr *Idx, VarDecl *ExpansionVar,
@@ -2163,6 +2177,12 @@ CXXIndeterminateExpansionSelectExpr::Create(
temps);
}
CXXIndeterminateExpansionSelectExpr *
CXXIndeterminateExpansionSelectExpr::Create(const ASTContext &C,
EmptyShell Empty) {
return new (C) CXXIndeterminateExpansionSelectExpr(Empty);
}
ArrayRef<MaterializeTemporaryExpr *>
CXXIndeterminateExpansionSelectExpr::getLifetimeExtendTemps() const {
return ArrayRef<MaterializeTemporaryExpr *>(LifetimeExtendTemps,
@@ -2177,12 +2197,21 @@ CXXIterableExpansionSelectExpr::CXXIterableExpansionSelectExpr(
setDependence(computeDependence(this));
}
CXXIterableExpansionSelectExpr::CXXIterableExpansionSelectExpr(EmptyShell Empty)
: Expr(CXXIterableExpansionSelectExprClass, Empty) {
}
CXXIterableExpansionSelectExpr *
CXXIterableExpansionSelectExpr::Create(const ASTContext &C, VarDecl *RangeVar,
Expr *Impl) {
return new (C) CXXIterableExpansionSelectExpr(C.DependentTy, RangeVar, Impl);
}
CXXIterableExpansionSelectExpr *
CXXIterableExpansionSelectExpr::Create(const ASTContext &C, EmptyShell Empty) {
return new (C) CXXIterableExpansionSelectExpr(Empty);
}
CXXDestructurableExpansionSelectExpr::CXXDestructurableExpansionSelectExpr(
QualType ResultTy, DecompositionDecl *DD, Expr *Idx,
VarDecl *ExpansionVar)
@@ -2192,6 +2221,11 @@ CXXDestructurableExpansionSelectExpr::CXXDestructurableExpansionSelectExpr(
setDependence(computeDependence(this));
}
CXXDestructurableExpansionSelectExpr::CXXDestructurableExpansionSelectExpr(
EmptyShell Empty)
: Expr(CXXDestructurableExpansionSelectExprClass, Empty) {
}
CXXDestructurableExpansionSelectExpr *
CXXDestructurableExpansionSelectExpr::Create(const ASTContext &C,
DecompositionDecl *DD, Expr *Idx,
@@ -2200,6 +2234,12 @@ CXXDestructurableExpansionSelectExpr::Create(const ASTContext &C,
ExpansionVar);
}
CXXDestructurableExpansionSelectExpr *
CXXDestructurableExpansionSelectExpr::Create(const ASTContext &C,
EmptyShell Empty) {
return new (C) CXXDestructurableExpansionSelectExpr(Empty);
}
CXXExpansionInitListSelectExpr::CXXExpansionInitListSelectExpr(
QualType ResultTy, Expr *Range, Expr *Idx)
: Expr(CXXExpansionInitListSelectExprClass, ResultTy, VK_PRValue,
@@ -2208,12 +2248,21 @@ CXXExpansionInitListSelectExpr::CXXExpansionInitListSelectExpr(
setDependence(computeDependence(this));
}
CXXExpansionInitListSelectExpr::CXXExpansionInitListSelectExpr(EmptyShell Empty)
: Expr(CXXExpansionInitListSelectExprClass, Empty) {
}
CXXExpansionInitListSelectExpr *
CXXExpansionInitListSelectExpr::Create(const ASTContext &C, Expr *Range,
Expr *Idx) {
return new (C) CXXExpansionInitListSelectExpr(C.DependentTy, Range, Idx);
}
CXXExpansionInitListSelectExpr *
CXXExpansionInitListSelectExpr::Create(const ASTContext &C, EmptyShell Empty) {
return new (C) CXXExpansionInitListSelectExpr(Empty);
}
CUDAKernelCallExpr::CUDAKernelCallExpr(Expr *Fn, CallExpr *Config,
ArrayRef<Expr *> Args, QualType Ty,
ExprValueKind VK, SourceLocation RP,

View File

@@ -181,6 +181,11 @@ CXXIndeterminateExpansionStmt *CXXIndeterminateExpansionStmt::Create(
ColonLoc, RParenLoc, TParamRef);
}
CXXIndeterminateExpansionStmt *CXXIndeterminateExpansionStmt::Create(
const ASTContext &C, EmptyShell Empty) {
return new (C) CXXIndeterminateExpansionStmt(Empty);
}
CXXIterableExpansionStmt *CXXIterableExpansionStmt::Create(
const ASTContext &C, Stmt *Init, DeclStmt *ExpansionVar, Expr *SizeExpr,
unsigned NumInstantiations, SourceLocation TemplateKWLoc,
@@ -194,7 +199,7 @@ CXXIterableExpansionStmt *CXXIterableExpansionStmt::Create(
CXXIterableExpansionStmt *CXXIterableExpansionStmt::Create(const ASTContext &C,
EmptyShell Empty) {
return new CXXIterableExpansionStmt(Empty);
return new (C) CXXIterableExpansionStmt(Empty);
}
bool CXXIterableExpansionStmt::hasDependentSize() const {
@@ -218,7 +223,7 @@ CXXDestructurableExpansionStmt *CXXDestructurableExpansionStmt::Create(
CXXDestructurableExpansionStmt *CXXDestructurableExpansionStmt::Create(
const ASTContext &C, EmptyShell Empty) {
return new CXXDestructurableExpansionStmt(Empty);
return new (C) CXXDestructurableExpansionStmt(Empty);
}
bool CXXDestructurableExpansionStmt::hasDependentSize() const {

View File

@@ -551,46 +551,100 @@ void ASTStmtReader::VisitExplDependentCallExpr(ExplDependentCallExpr *E) {
llvm_unreachable("unimplemented");
}
void ASTStmtReader::VisitCXXExpansionStmt(CXXExpansionStmt *S) {
VisitStmt(S);
S->TemplateKWLoc = Record.readSourceLocation();
S->ForLoc = Record.readSourceLocation();
S->LParenLoc = Record.readSourceLocation();
S->ColonLoc = Record.readSourceLocation();
S->RParenLoc = Record.readSourceLocation();
S->SubStmts[CXXExpansionStmt::INIT] = Record.readStmt();
S->SubStmts[CXXExpansionStmt::TPARAM] = Record.readStmt();
S->SubStmts[CXXExpansionStmt::VAR] = Record.readStmt();
S->SubStmts[CXXExpansionStmt::SIZE] = Record.readStmt();
S->SubStmts[CXXExpansionStmt::BODY] = Record.readStmt();
if (unsigned NumExpansions = Record.readUInt32(); NumExpansions > 0) {
Stmt **Expansions = new (Record.getContext()) Stmt *[NumExpansions];
for (size_t k = 0; k < NumExpansions; ++k)
Expansions[k] = Record.readStmt();
S->Expansions = Expansions;
}
}
void ASTStmtReader::VisitCXXIndeterminateExpansionStmt(
CXXIndeterminateExpansionStmt *S) {
llvm_unreachable("unimplemented");
VisitCXXExpansionStmt(S);
}
void ASTStmtReader::VisitCXXIterableExpansionStmt(CXXIterableExpansionStmt *S) {
llvm_unreachable("unimplemented");
VisitCXXExpansionStmt(S);
S->NumInstantiations = Record.readUInt32();
}
void ASTStmtReader::VisitCXXDestructurableExpansionStmt(
CXXDestructurableExpansionStmt *S) {
llvm_unreachable("unimplemented");
VisitCXXExpansionStmt(S);
}
void ASTStmtReader::VisitCXXInitListExpansionStmt(CXXInitListExpansionStmt *S) {
llvm_unreachable("unimplemented");
VisitCXXExpansionStmt(S);
}
void ASTStmtReader::VisitCXXIndeterminateExpansionSelectExpr(
CXXIndeterminateExpansionSelectExpr *E) {
llvm_unreachable("unimplemented");
VisitExpr(E);
E->SubExprs[0] = Record.readExpr();
E->SubExprs[1] = Record.readExpr();
E->ExpansionVar = readDeclAs<VarDecl>();
E->NumLifetimeExtendTemps = Record.readUInt32();
Expr **Temps = new (Record.getContext()) Expr *[E->NumLifetimeExtendTemps];
for (size_t k = 0; k < E->NumLifetimeExtendTemps; ++k)
Temps[k] = Record.readExpr();
E->LifetimeExtendTemps = reinterpret_cast<MaterializeTemporaryExpr **>(Temps);
}
void ASTStmtReader::VisitCXXIterableExpansionSelectExpr(
CXXIterableExpansionSelectExpr *E) {
llvm_unreachable("unimplemented");
VisitExpr(E);
E->ImplExpr = Record.readExpr();
E->RangeVar = readDeclAs<VarDecl>();
}
void ASTStmtReader::VisitCXXDestructurableExpansionSelectExpr(
CXXDestructurableExpansionSelectExpr *E) {
llvm_unreachable("unimplemented");
VisitExpr(E);
E->IdxExpr = Record.readExpr();
E->DD = Record.readDeclAs<DecompositionDecl>();
E->ExpansionVar = Record.readDeclAs<VarDecl>();
}
void ASTStmtReader::VisitCXXExpansionInitListSelectExpr(
CXXExpansionInitListSelectExpr *E) {
llvm_unreachable("unimplemented");
VisitExpr(E);
E->SubExprs[0] = Record.readExpr();
E->SubExprs[1] = Record.readExpr();
}
void ASTStmtReader::VisitCXXExpansionInitListExpr(CXXExpansionInitListExpr *E) {
llvm_unreachable("unimplemented");
VisitExpr(E);
E->LBraceLoc = readSourceLocation();
E->RBraceLoc = readSourceLocation();
E->NumSubExprs = Record.readUInt32();
Expr **SubExprs = new (Record.getContext()) Expr *[E->NumSubExprs];
for (size_t k = 0; k < E->NumSubExprs; ++k)
SubExprs[k] = Record.readExpr();
E->SubExprs = SubExprs;
}
void ASTStmtReader::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) {
@@ -4613,6 +4667,42 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
S = CXXDependentMemberSpliceExpr::CreateEmpty(Context);
break;
}
case STMT_INDETERMINATE_EXPANSION: {
S = CXXIndeterminateExpansionStmt::Create(Context, Empty);
break;
}
case STMT_ITERABLE_EXPANSION: {
S = CXXIterableExpansionStmt::Create(Context, Empty);
break;
}
case STMT_DESTRUCTURABLE_EXPANSION: {
S = CXXDestructurableExpansionStmt::Create(Context, Empty);
break;
}
case STMT_INIT_LIST_EXPANSION: {
S = CXXInitListExpansionStmt::Create(Context, Empty);
break;
}
case EXPR_INDETERMINATE_EXPANSION_SELECT: {
S = CXXIndeterminateExpansionSelectExpr::Create(Context, Empty);
break;
}
case EXPR_ITERABLE_EXPANSION_SELECT: {
S = CXXIterableExpansionSelectExpr::Create(Context, Empty);
break;
}
case EXPR_DESTRUCTURABLE_EXPANSION_SELECT: {
S = CXXDestructurableExpansionSelectExpr::Create(Context, Empty);
break;
}
case EXPR_INIT_LIST_EXPANSION_SELECT: {
S = CXXExpansionInitListSelectExpr::Create(Context, Empty);
break;
}
case EXPR_EXPANSION_INIT_LIST: {
S = CXXExpansionInitListExpr::Create(Context, Empty);
break;
}
}
// We hit a STMT_STOP, so we're done with this expression.

View File

@@ -535,63 +535,111 @@ void ASTStmtWriter::VisitExplDependentCallExpr(ExplDependentCallExpr *E) {
Code = serialization::EXPR_EXPL_DEPENDENT_CALL;
}
void ASTStmtWriter::VisitCXXExpansionStmt(CXXExpansionStmt *S) {
VisitStmt(S);
Record.AddSourceLocation(S->getTemplateKWLoc());
Record.AddSourceLocation(S->getForLoc());
Record.AddSourceLocation(S->getLParenLoc());
Record.AddSourceLocation(S->getColonLoc());
Record.AddSourceLocation(S->getRParenLoc());
Record.AddStmt(S->getInit());
Record.AddStmt(S->getTParamRef());
Record.AddStmt(S->getExpansionVarStmt());
Record.AddStmt(S->getSizeExpr());
Record.AddStmt(S->getBody());
Record.writeUInt32(S->getNumInstantiations());
for (size_t k = 0; k < S->getNumInstantiations(); ++k)
Record.AddStmt(S->getInstantiation(k));
}
void ASTStmtWriter::VisitCXXIndeterminateExpansionStmt(
CXXIndeterminateExpansionStmt *S) {
VisitStmt(S);
// TODO(P2996): Implement this.
VisitCXXExpansionStmt(S);
Code = serialization::STMT_INDETERMINATE_EXPANSION;
}
void ASTStmtWriter::VisitCXXIterableExpansionStmt(CXXIterableExpansionStmt *S) {
VisitStmt(S);
// TODO(P2996): Implement this.
VisitCXXExpansionStmt(S);
Record.writeUInt32(S->getNumInstantiations());
Code = serialization::STMT_ITERABLE_EXPANSION;
}
void ASTStmtWriter::VisitCXXDestructurableExpansionStmt(
CXXDestructurableExpansionStmt *S) {
VisitStmt(S);
// TODO(P2996): Implement this.
VisitCXXExpansionStmt(S);
Code = serialization::STMT_DESTRUCTURABLE_EXPANSION;
}
void ASTStmtWriter::VisitCXXInitListExpansionStmt(CXXInitListExpansionStmt *S) {
VisitStmt(S);
// TODO(P2996): Implement this.
VisitCXXExpansionStmt(S);
Code = serialization::STMT_INIT_LIST_EXPANSION;
}
void ASTStmtWriter::VisitCXXIndeterminateExpansionSelectExpr(
CXXIndeterminateExpansionSelectExpr *E) {
VisitExpr(E);
// TODO(P2996): Implement this.
Code = serialization::EXPR_EXPANSION_SELECT;
Record.AddStmt(E->getRangeExpr());
Record.AddStmt(E->getIdxExpr());
Record.AddDeclRef(E->getExpansionVar());
auto Temps = E->getLifetimeExtendTemps();
Record.writeUInt32(Temps.size());
for (auto Temp : Temps)
Record.AddStmt(Temp);
Code = serialization::EXPR_INDETERMINATE_EXPANSION_SELECT;
}
void ASTStmtWriter::VisitCXXIterableExpansionSelectExpr(
CXXIterableExpansionSelectExpr *E) {
VisitExpr(E);
// TODO(P2996): Implement this.
Code = serialization::EXPR_EXPANSION_SELECT;
Record.AddStmt(E->getImplExpr());
Record.AddDeclRef(E->getRangeVar());
Code = serialization::EXPR_ITERABLE_EXPANSION_SELECT;
}
void ASTStmtWriter::VisitCXXDestructurableExpansionSelectExpr(
CXXDestructurableExpansionSelectExpr *E) {
VisitExpr(E);
// TODO(P2996): Implement this.
Code = serialization::EXPR_EXPANSION_SELECT;
Record.AddStmt(E->getIdxExpr());
Record.AddDeclRef(E->getDecompositionDecl());
Record.AddDeclRef(E->getExpansionVar());
Code = serialization::EXPR_DESTRUCTURABLE_EXPANSION_SELECT;
}
void ASTStmtWriter::VisitCXXExpansionInitListSelectExpr(
CXXExpansionInitListSelectExpr *E) {
VisitExpr(E);
// TODO(P2996): Implement this.
Code = serialization::EXPR_EXPANSION_SELECT;
Record.AddStmt(E->getRangeExpr());
Record.AddStmt(E->getIdxExpr());
Code = serialization::EXPR_INIT_LIST_EXPANSION_SELECT;
}
void ASTStmtWriter::VisitCXXExpansionInitListExpr(CXXExpansionInitListExpr *E) {
VisitExpr(E);
// TODO(P2996): Implement this.
Record.AddSourceLocation(E->getLBraceLoc());
Record.AddSourceLocation(E->getRBraceLoc());
auto Exprs = E->getSubExprs();
Record.writeUInt32(Exprs.size());
for (Expr *E : Exprs)
Record.AddStmt(E);
Code = serialization::EXPR_EXPANSION_INIT_LIST;
}

View File

@@ -1,5 +1,6 @@
module;
#include <meta>
#include <tuple>
export module Example;
namespace Example {
@@ -73,4 +74,21 @@ export constexpr auto rBase2 = bases_of(^^Child, ctx)[1];
export constexpr auto rTDMS = data_member_spec(^^int, {.name="test"});
// ====================
// Expansion statements
// ====================
void test() {
// Iterating expansion statement.
constexpr static auto sequence = std::array{0, 1, 2, 3, 4};
template for (constexpr auto i : sequence) { (void) i; }
// Destructurable expansion statement.
constexpr auto tup = std::make_tuple(1, true, 'c');
template for (constexpr auto i : tup) { (void) i; }
// Enumerating expansion statement.
template for (auto i : {1, 2, 3}) { (void) i; }
}
} // namespace Example

View File

@@ -2,10 +2,10 @@
//
// RUN: mkdir %t
// RUN: %{cxx} %{compile_flags} -std=c++26 \
// RUN: -freflection -fparameter-reflection \
// RUN: -freflection-latest \
// RUN: --precompile example-module.cppm -o %t/example-module.pcm
// RUN: %{cxx} %{compile_flags} %{link_flags} -std=c++26 \
// RUN: -freflection -fparameter-reflection \
// RUN: -freflection-latest \
// RUN: -fmodule-file=Example=%t/example-module.pcm %t/example-module.pcm \
// RUN: module-imports.sh.cpp -o %t/module-imports.sh.cpp.tsk
// RUN: %t/module-imports.sh.cpp.tsk > %t/stdout.txt