@@ -4360,6 +4360,10 @@ class OpaqueValueExpr : public Expr {
43604360 Bits.OpaqueValueExpr .IsPlaceholder = isPlaceholder;
43614361 }
43624362
4363+ static OpaqueValueExpr *
4364+ createImplicit (ASTContext &ctx, Type Ty, bool isPlaceholder = false ,
4365+ AllocationArena arena = AllocationArena::Permanent);
4366+
43634367 // / Whether this opaque value expression represents a placeholder that
43644368 // / is injected before type checking to act as a placeholder for some
43654369 // / value to be specified later.
@@ -5975,6 +5979,63 @@ class KeyPathDotExpr : public Expr {
59755979 }
59765980};
59775981
5982+ // / An expression that may wrap a statement which produces a single value.
5983+ class SingleValueStmtExpr : public Expr {
5984+ public:
5985+ enum class Kind {
5986+ If, Switch
5987+ };
5988+
5989+ private:
5990+ Stmt *S;
5991+ DeclContext *DC;
5992+
5993+ SingleValueStmtExpr (Stmt *S, DeclContext *DC)
5994+ : Expr(ExprKind::SingleValueStmt, /* isImplicit*/ true ), S(S), DC(DC) {}
5995+
5996+ public:
5997+ // / Creates a new SingleValueStmtExpr wrapping a statement.
5998+ static SingleValueStmtExpr *create (ASTContext &ctx, Stmt *S, DeclContext *DC);
5999+
6000+ // / Creates a new SingleValueStmtExpr wrapping a statement, and recursively
6001+ // / attempts to wrap any branches of that statement that can become single
6002+ // / value statement expressions.
6003+ // /
6004+ // / If \p mustBeExpr is true, branches will be eagerly wrapped even if they
6005+ // / may not be valid SingleValueStmtExprs (which Sema will later diagnose).
6006+ static SingleValueStmtExpr *createWithWrappedBranches (ASTContext &ctx,
6007+ Stmt *S,
6008+ DeclContext *DC,
6009+ bool mustBeExpr);
6010+
6011+ // / Attempt to look through valid parent expressions to a child
6012+ // / SingleValueStmtExpr.
6013+ static SingleValueStmtExpr *tryDigOutSingleValueStmtExpr (Expr *E);
6014+
6015+ // / Retrieve the wrapped statement.
6016+ Stmt *getStmt () const { return S; }
6017+ void setStmt (Stmt *newS) { S = newS; }
6018+
6019+ // / Retrieve the kind of statement being wrapped.
6020+ Kind getStmtKind () const ;
6021+
6022+ // / Retrieve the complete set of branches for the underlying statement.
6023+ ArrayRef<Stmt *> getBranches (SmallVectorImpl<Stmt *> &scratch) const ;
6024+
6025+ // / Retrieve the single expression branches of the statement, excluding
6026+ // / branches that either have multiple expressions, or have statements.
6027+ ArrayRef<Expr *>
6028+ getSingleExprBranches (SmallVectorImpl<Expr *> &scratch) const ;
6029+
6030+ DeclContext *getDeclContext () const { return DC; }
6031+
6032+ SourceRange getSourceRange () const ;
6033+
6034+ static bool classof (const Expr *E) {
6035+ return E->getKind () == ExprKind::SingleValueStmt;
6036+ }
6037+ };
6038+
59786039// / Expression node that effects a "one-way" constraint in
59796040// / the constraint system, allowing type information to flow from the
59806041// / subexpression outward but not the other way.
@@ -6008,6 +6069,10 @@ class TypeJoinExpr final : public Expr,
60086069
60096070 DeclRefExpr *Var;
60106071
6072+ // / If this is joining the expression branches for a SingleValueStmtExpr,
6073+ // / this holds the expr node. Otherwise, it is \c nullptr.
6074+ SingleValueStmtExpr *SVE;
6075+
60116076 size_t numTrailingObjects () const {
60126077 return getNumElements ();
60136078 }
@@ -6016,11 +6081,34 @@ class TypeJoinExpr final : public Expr,
60166081 return { getTrailingObjects<Expr *>(), getNumElements () };
60176082 }
60186083
6019- TypeJoinExpr (DeclRefExpr *var, ArrayRef<Expr *> elements);
6084+ TypeJoinExpr (llvm::PointerUnion<DeclRefExpr *, TypeBase *> result,
6085+ ArrayRef<Expr *> elements, SingleValueStmtExpr *SVE);
6086+
6087+ static TypeJoinExpr *
6088+ createImpl (ASTContext &ctx,
6089+ llvm::PointerUnion<DeclRefExpr *, TypeBase *> varOrType,
6090+ ArrayRef<Expr *> elements,
6091+ AllocationArena arena = AllocationArena::Permanent,
6092+ SingleValueStmtExpr *SVE = nullptr );
60206093
60216094public:
6022- static TypeJoinExpr *create (ASTContext &ctx, DeclRefExpr *var,
6023- ArrayRef<Expr *> exprs);
6095+ static TypeJoinExpr *
6096+ create (ASTContext &ctx, DeclRefExpr *var, ArrayRef<Expr *> exprs,
6097+ AllocationArena arena = AllocationArena::Permanent) {
6098+ return createImpl (ctx, var, exprs, arena);
6099+ }
6100+
6101+ static TypeJoinExpr *
6102+ create (ASTContext &ctx, Type joinType, ArrayRef<Expr *> exprs,
6103+ AllocationArena arena = AllocationArena::Permanent) {
6104+ return createImpl (ctx, joinType.getPointer (), exprs, arena);
6105+ }
6106+
6107+ // / Create a join for the branch types of a SingleValueStmtExpr.
6108+ static TypeJoinExpr *
6109+ forBranchesOfSingleValueStmtExpr (ASTContext &ctx, Type joinType,
6110+ SingleValueStmtExpr *SVE,
6111+ AllocationArena arena);
60246112
60256113 SourceLoc getLoc () const { return SourceLoc (); }
60266114 SourceRange getSourceRange () const { return SourceRange (); }
@@ -6044,6 +6132,10 @@ class TypeJoinExpr final : public Expr,
60446132 getMutableElements ()[i] = E;
60456133 }
60466134
6135+ // / If this is joining the expression branches for a SingleValueStmtExpr,
6136+ // / this returns the expr node. Otherwise, returns \c nullptr.
6137+ SingleValueStmtExpr *getSingleValueStmtExpr () const { return SVE; }
6138+
60476139 unsigned getNumElements () const { return Bits.TypeJoinExpr .NumElements ; }
60486140
60496141 static bool classof (const Expr *E) {
0 commit comments