Skip to content

[AST] Add the skeleton for PackExpansionExpr. #61523

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions include/swift/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -3527,6 +3527,51 @@ class VarargExpansionExpr : public Expr {
}
};

/// A pack expansion expression is a pattern expression followed by
/// the expansion operator '...'. The pattern expression contains
/// references to parameter packs of length N, and the expansion
/// operator will repeat the pattern N times.
///
/// Pack expansion expressions are permitted in expression contexts
/// that naturally accept a comma-separated list of values, including
/// call argument lists, the elements of a tuple value, and the source
/// of a for-in loop.
class PackExpansionExpr: public Expr {
Expr *PatternExpr;
SourceLoc DotsLoc;

PackExpansionExpr(Expr *patternExpr,
SourceLoc dotsLoc,
bool implicit, Type type)
: Expr(ExprKind::PackExpansion, implicit, type),
PatternExpr(patternExpr), DotsLoc(dotsLoc) {}

public:
static PackExpansionExpr *create(ASTContext &ctx,
Expr *patternExpr,
SourceLoc dotsLoc,
bool implicit = false,
Type type = Type());

Expr *getPatternExpr() const { return PatternExpr; }

void setPatternExpr(Expr *patternExpr) {
PatternExpr = patternExpr;
}

SourceLoc getStartLoc() const {
return PatternExpr->getStartLoc();
}

SourceLoc getEndLoc() const {
return DotsLoc;
}

static bool classof(const Expr *E) {
return E->getKind() == ExprKind::PackExpansion;
}
};

/// SequenceExpr - A list of binary operations which has not yet been
/// folded into a tree. The operands all have even indices, while the
/// subexpressions with odd indices are all (potentially overloaded)
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/ExprNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ ABSTRACT_EXPR(AbstractClosure, Expr)
EXPR_RANGE(AbstractClosure, Closure, AutoClosure)
EXPR(InOut, Expr)
EXPR(VarargExpansion, Expr)
EXPR(PackExpansion, Expr)
EXPR(DynamicType, Expr)
EXPR(RebindSelfInConstructor, Expr)
EXPR(OpaqueValue, Expr)
Expand Down
6 changes: 6 additions & 0 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2432,6 +2432,12 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void visitPackExpansionExpr(PackExpansionExpr *E) {
printCommon(E, "pack_expansion_expr") << "\n";
printRec(E->getPatternExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void visitForceTryExpr(ForceTryExpr *E) {
printCommon(E, "force_try_expr");
OS << '\n';
Expand Down
4 changes: 4 additions & 0 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4750,6 +4750,10 @@ void PrintAST::visitVarargExpansionExpr(VarargExpansionExpr *expr) {
visit(expr->getSubExpr());
}

void PrintAST::visitPackExpansionExpr(PackExpansionExpr *expr) {
visit(expr->getPatternExpr());
}

void PrintAST::visitArchetypeToSuperExpr(ArchetypeToSuperExpr *expr) {
}

Expand Down
8 changes: 8 additions & 0 deletions lib/AST/ASTWalker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,14 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
return nullptr;
}

Expr *visitPackExpansionExpr(PackExpansionExpr *E) {
if (Expr *pattern = doIt(E->getPatternExpr())) {
E->setPatternExpr(pattern);
return E;
}
return nullptr;
}

Expr *visitSequenceExpr(SequenceExpr *E) {
for (unsigned i = 0, e = E->getNumElements(); i != e; ++i)
if (Expr *Elt = doIt(E->getElement(i)))
Expand Down
11 changes: 11 additions & 0 deletions lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
PASS_THROUGH_REFERENCE(InOut, getSubExpr);

NO_REFERENCE(VarargExpansion);
NO_REFERENCE(PackExpansion);
NO_REFERENCE(DynamicType);

PASS_THROUGH_REFERENCE(RebindSelfInConstructor, getSubExpr);
Expand Down Expand Up @@ -745,6 +746,7 @@ bool Expr::canAppendPostfixExpression(bool appendingPostfixOperator) const {
case ExprKind::OpenExistential:
case ExprKind::MakeTemporarilyEscapable:
case ExprKind::VarargExpansion:
case ExprKind::PackExpansion:
return false;

case ExprKind::Call:
Expand Down Expand Up @@ -918,6 +920,7 @@ bool Expr::isValidParentOfTypeExpr(Expr *typeExpr) const {
case ExprKind::AutoClosure:
case ExprKind::InOut:
case ExprKind::VarargExpansion:
case ExprKind::PackExpansion:
case ExprKind::DynamicType:
case ExprKind::RebindSelfInConstructor:
case ExprKind::OpaqueValue:
Expand Down Expand Up @@ -1235,6 +1238,14 @@ VarargExpansionExpr *VarargExpansionExpr::createArrayExpansion(ASTContext &ctx,
return new (ctx) VarargExpansionExpr(AE, /*implicit*/ true, AE->getType());
}

PackExpansionExpr *
PackExpansionExpr::create(ASTContext &ctx, Expr *patternExpr,
SourceLoc dotsLoc, bool implicit,
Type type) {
return new (ctx) PackExpansionExpr(patternExpr, dotsLoc,
implicit, type);
}

SequenceExpr *SequenceExpr::create(ASTContext &ctx, ArrayRef<Expr*> elements) {
assert(elements.size() & 1 && "even number of elements in sequence");
size_t bytes = totalSizeToAlloc<Expr *>(elements.size());
Expand Down
7 changes: 7 additions & 0 deletions lib/SILGen/SILGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ namespace {
SGFContext C);
RValue visitBridgeToObjCExpr(BridgeToObjCExpr *E, SGFContext C);
RValue visitReifyPackExpr(ReifyPackExpr *E, SGFContext C);
RValue visitPackExpansionExpr(PackExpansionExpr *E, SGFContext C);
RValue visitBridgeFromObjCExpr(BridgeFromObjCExpr *E, SGFContext C);
RValue visitConditionalBridgeFromObjCExpr(ConditionalBridgeFromObjCExpr *E,
SGFContext C);
Expand Down Expand Up @@ -1517,6 +1518,12 @@ RValueEmitter::visitReifyPackExpr(ReifyPackExpr *E, SGFContext C) {
llvm_unreachable("Unimplemented!");
}

RValue
RValueEmitter::visitPackExpansionExpr(PackExpansionExpr *E,
SGFContext C) {
llvm_unreachable("not implemented for PackExpansionExpr");
}

RValue RValueEmitter::visitArchetypeToSuperExpr(ArchetypeToSuperExpr *E,
SGFContext C) {
ManagedValue archetype = SGF.emitRValueAsSingleValue(E->getSubExpr());
Expand Down
4 changes: 4 additions & 0 deletions lib/Sema/CSApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3692,6 +3692,10 @@ namespace {
return expr;
}

Expr *visitPackExpansionExpr(PackExpansionExpr *expr) {
llvm_unreachable("not implemented for PackExpansionExpr");
}

Expr *visitDynamicTypeExpr(DynamicTypeExpr *expr) {
Expr *base = expr->getBase();
base = cs.coerceToRValue(base);
Expand Down
4 changes: 4 additions & 0 deletions lib/Sema/CSGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2885,6 +2885,10 @@ namespace {
return variadicSeq;
}

Type visitPackExpansionExpr(PackExpansionExpr *expr) {
llvm_unreachable("not implemented for PackExpansionExpr");
}

Type visitDynamicTypeExpr(DynamicTypeExpr *expr) {
auto tv = CS.createTypeVariable(CS.getConstraintLocator(expr),
TVO_CanBindToNoEscape);
Expand Down