@@ -5979,6 +5979,63 @@ class KeyPathDotExpr : public Expr {
59795979 }
59805980};
59815981
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+
59826039// / Expression node that effects a "one-way" constraint in
59836040// / the constraint system, allowing type information to flow from the
59846041// / subexpression outward but not the other way.
@@ -6012,6 +6069,10 @@ class TypeJoinExpr final : public Expr,
60126069
60136070 DeclRefExpr *Var;
60146071
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+
60156076 size_t numTrailingObjects () const {
60166077 return getNumElements ();
60176078 }
@@ -6021,13 +6082,14 @@ class TypeJoinExpr final : public Expr,
60216082 }
60226083
60236084 TypeJoinExpr (llvm::PointerUnion<DeclRefExpr *, TypeBase *> result,
6024- ArrayRef<Expr *> elements);
6085+ ArrayRef<Expr *> elements, SingleValueStmtExpr *SVE );
60256086
60266087 static TypeJoinExpr *
60276088 createImpl (ASTContext &ctx,
60286089 llvm::PointerUnion<DeclRefExpr *, TypeBase *> varOrType,
60296090 ArrayRef<Expr *> elements,
6030- AllocationArena arena = AllocationArena::Permanent);
6091+ AllocationArena arena = AllocationArena::Permanent,
6092+ SingleValueStmtExpr *SVE = nullptr );
60316093
60326094public:
60336095 static TypeJoinExpr *
@@ -6042,6 +6104,12 @@ class TypeJoinExpr final : public Expr,
60426104 return createImpl (ctx, joinType.getPointer (), exprs, arena);
60436105 }
60446106
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);
6112+
60456113 SourceLoc getLoc () const { return SourceLoc (); }
60466114 SourceRange getSourceRange () const { return SourceRange (); }
60476115
@@ -6064,6 +6132,10 @@ class TypeJoinExpr final : public Expr,
60646132 getMutableElements ()[i] = E;
60656133 }
60666134
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+
60676139 unsigned getNumElements () const { return Bits.TypeJoinExpr .NumElements ; }
60686140
60696141 static bool classof (const Expr *E) {
0 commit comments