@@ -4350,6 +4350,10 @@ class OpaqueValueExpr : public Expr {
43504350 Bits.OpaqueValueExpr .IsPlaceholder = isPlaceholder;
43514351 }
43524352
4353+ static OpaqueValueExpr *
4354+ createImplicit (ASTContext &ctx, Type Ty, bool isPlaceholder = false ,
4355+ AllocationArena arena = AllocationArena::Permanent);
4356+
43534357 // / Whether this opaque value expression represents a placeholder that
43544358 // / is injected before type checking to act as a placeholder for some
43554359 // / value to be specified later.
@@ -5965,6 +5969,63 @@ class KeyPathDotExpr : public Expr {
59655969 }
59665970};
59675971
5972+ // / An expression that may wrap a statement which produces a single value.
5973+ class SingleValueStmtExpr : public Expr {
5974+ public:
5975+ enum class Kind {
5976+ If, Switch
5977+ };
5978+
5979+ private:
5980+ Stmt *S;
5981+ DeclContext *DC;
5982+
5983+ SingleValueStmtExpr (Stmt *S, DeclContext *DC)
5984+ : Expr(ExprKind::SingleValueStmt, /* isImplicit*/ true ), S(S), DC(DC) {}
5985+
5986+ public:
5987+ // / Creates a new SingleValueStmtExpr wrapping a statement.
5988+ static SingleValueStmtExpr *create (ASTContext &ctx, Stmt *S, DeclContext *DC);
5989+
5990+ // / Creates a new SingleValueStmtExpr wrapping a statement, and recursively
5991+ // / attempts to wrap any branches of that statement that can become single
5992+ // / value statement expressions.
5993+ // /
5994+ // / If \p mustBeExpr is true, branches will be eagerly wrapped even if they
5995+ // / may not be valid SingleValueStmtExprs (which Sema will later diagnose).
5996+ static SingleValueStmtExpr *createWithWrappedBranches (ASTContext &ctx,
5997+ Stmt *S,
5998+ DeclContext *DC,
5999+ bool mustBeExpr);
6000+
6001+ // / Attempt to look through valid parent expressions to a child
6002+ // / SingleValueStmtExpr.
6003+ static SingleValueStmtExpr *tryDigOutSingleValueStmtExpr (Expr *E);
6004+
6005+ // / Retrieve the wrapped statement.
6006+ Stmt *getStmt () const { return S; }
6007+ void setStmt (Stmt *newS) { S = newS; }
6008+
6009+ // / Retrieve the kind of statement being wrapped.
6010+ Kind getStmtKind () const ;
6011+
6012+ // / Retrieve the complete set of branches for the underlying statement.
6013+ ArrayRef<Stmt *> getBranches (SmallVectorImpl<Stmt *> &scratch) const ;
6014+
6015+ // / Retrieve the single expression branches of the statement, excluding
6016+ // / branches that either have multiple expressions, or have statements.
6017+ ArrayRef<Expr *>
6018+ getSingleExprBranches (SmallVectorImpl<Expr *> &scratch) const ;
6019+
6020+ DeclContext *getDeclContext () const { return DC; }
6021+
6022+ SourceRange getSourceRange () const ;
6023+
6024+ static bool classof (const Expr *E) {
6025+ return E->getKind () == ExprKind::SingleValueStmt;
6026+ }
6027+ };
6028+
59686029// / Expression node that effects a "one-way" constraint in
59696030// / the constraint system, allowing type information to flow from the
59706031// / subexpression outward but not the other way.
@@ -5998,6 +6059,10 @@ class TypeJoinExpr final : public Expr,
59986059
59996060 DeclRefExpr *Var;
60006061
6062+ // / If this is joining the expression branches for a SingleValueStmtExpr,
6063+ // / this holds the expr node. Otherwise, it is \c nullptr.
6064+ SingleValueStmtExpr *SVE;
6065+
60016066 size_t numTrailingObjects () const {
60026067 return getNumElements ();
60036068 }
@@ -6006,11 +6071,34 @@ class TypeJoinExpr final : public Expr,
60066071 return { getTrailingObjects<Expr *>(), getNumElements () };
60076072 }
60086073
6009- TypeJoinExpr (DeclRefExpr *var, ArrayRef<Expr *> elements);
6074+ TypeJoinExpr (llvm::PointerUnion<DeclRefExpr *, TypeBase *> result,
6075+ ArrayRef<Expr *> elements, SingleValueStmtExpr *SVE);
6076+
6077+ static TypeJoinExpr *
6078+ createImpl (ASTContext &ctx,
6079+ llvm::PointerUnion<DeclRefExpr *, TypeBase *> varOrType,
6080+ ArrayRef<Expr *> elements,
6081+ AllocationArena arena = AllocationArena::Permanent,
6082+ SingleValueStmtExpr *SVE = nullptr );
60106083
60116084public:
6012- static TypeJoinExpr *create (ASTContext &ctx, DeclRefExpr *var,
6013- ArrayRef<Expr *> exprs);
6085+ static TypeJoinExpr *
6086+ create (ASTContext &ctx, DeclRefExpr *var, ArrayRef<Expr *> exprs,
6087+ AllocationArena arena = AllocationArena::Permanent) {
6088+ return createImpl (ctx, var, exprs, arena);
6089+ }
6090+
6091+ static TypeJoinExpr *
6092+ create (ASTContext &ctx, Type joinType, ArrayRef<Expr *> exprs,
6093+ AllocationArena arena = AllocationArena::Permanent) {
6094+ return createImpl (ctx, joinType.getPointer (), exprs, arena);
6095+ }
6096+
6097+ // / Create a join for the branch types of a SingleValueStmtExpr.
6098+ static TypeJoinExpr *
6099+ forBranchesOfSingleValueStmtExpr (ASTContext &ctx, Type joinType,
6100+ SingleValueStmtExpr *SVE,
6101+ AllocationArena arena);
60146102
60156103 SourceLoc getLoc () const { return SourceLoc (); }
60166104 SourceRange getSourceRange () const { return SourceRange (); }
@@ -6034,6 +6122,10 @@ class TypeJoinExpr final : public Expr,
60346122 getMutableElements ()[i] = E;
60356123 }
60366124
6125+ // / If this is joining the expression branches for a SingleValueStmtExpr,
6126+ // / this returns the expr node. Otherwise, returns \c nullptr.
6127+ SingleValueStmtExpr *getSingleValueStmtExpr () const { return SVE; }
6128+
60376129 unsigned getNumElements () const { return Bits.TypeJoinExpr .NumElements ; }
60386130
60396131 static bool classof (const Expr *E) {
0 commit comments