@@ -67,6 +67,18 @@ namespace swift {
67
67
class KeyPathExpr ;
68
68
class CaptureListExpr ;
69
69
70
+ struct TrailingClosure {
71
+ Identifier Label;
72
+ SourceLoc LabelLoc;
73
+ Expr *ClosureExpr;
74
+
75
+ TrailingClosure (Expr *closure)
76
+ : TrailingClosure(Identifier(), SourceLoc(), closure) {}
77
+
78
+ TrailingClosure (Identifier label, SourceLoc labelLoc, Expr *closure)
79
+ : Label(label), LabelLoc(labelLoc), ClosureExpr(closure) {}
80
+ };
81
+
70
82
enum class ExprKind : uint8_t {
71
83
#define EXPR (Id, Parent ) Id,
72
84
#define LAST_EXPR (Id ) Last_Expr = Id,
@@ -200,10 +212,7 @@ class alignas(8) Expr {
200
212
FieldNo : 32
201
213
);
202
214
203
- SWIFT_INLINE_BITFIELD_FULL (TupleExpr, Expr, 1 +1 +1 +32 ,
204
- // / Whether this tuple has a trailing closure.
205
- HasTrailingClosure : 1 ,
206
-
215
+ SWIFT_INLINE_BITFIELD_FULL (TupleExpr, Expr, 1 +1 +32 ,
207
216
// / Whether this tuple has any labels.
208
217
HasElementNames : 1 ,
209
218
@@ -533,6 +542,11 @@ class alignas(8) Expr {
533
542
bool isSelfExprOf (const AbstractFunctionDecl *AFD,
534
543
bool sameBase = false ) const ;
535
544
545
+ // / Given that this is a packed argument expression of the sort that
546
+ // / would be produced from packSingleArgument, return the index of the
547
+ // / unlabeled trailing closure, if there is one.
548
+ Optional<unsigned > getUnlabeledTrailingClosureIndexOfPackedArgument () const ;
549
+
536
550
// / Produce a mapping from each subexpression to its parent
537
551
// / expression, with the provided expression serving as the root of
538
552
// / the parent map.
@@ -1197,7 +1211,7 @@ class ObjectLiteralExpr final
1197
1211
ArrayRef<Identifier> argLabels,
1198
1212
ArrayRef<SourceLoc> argLabelLocs,
1199
1213
SourceLoc rParenLoc,
1200
- Expr *trailingClosure ,
1214
+ ArrayRef<TrailingClosure> trailingClosures ,
1201
1215
bool implicit);
1202
1216
1203
1217
LiteralKind getLiteralKind () const {
@@ -1219,6 +1233,11 @@ class ObjectLiteralExpr final
1219
1233
return Bits.ObjectLiteralExpr .HasTrailingClosure ;
1220
1234
}
1221
1235
1236
+ // / Return the index of the unlabeled trailing closure argument.
1237
+ Optional<unsigned > getUnlabeledTrailingClosureIndex () const {
1238
+ return getArg ()->getUnlabeledTrailingClosureIndexOfPackedArgument ();
1239
+ }
1240
+
1222
1241
SourceLoc getSourceLoc () const { return PoundLoc; }
1223
1242
SourceRange getSourceRange () const {
1224
1243
return SourceRange (PoundLoc, Arg->getEndLoc ());
@@ -1783,6 +1802,11 @@ class DynamicSubscriptExpr final
1783
1802
return Bits.DynamicSubscriptExpr .HasTrailingClosure ;
1784
1803
}
1785
1804
1805
+ // / Return the index of the unlabeled trailing closure argument.
1806
+ Optional<unsigned > getUnlabeledTrailingClosureIndex () const {
1807
+ return Index->getUnlabeledTrailingClosureIndexOfPackedArgument ();
1808
+ }
1809
+
1786
1810
SourceLoc getLoc () const { return Index->getStartLoc (); }
1787
1811
1788
1812
SourceLoc getStartLoc () const { return getBase ()->getStartLoc (); }
@@ -1825,7 +1849,7 @@ class UnresolvedMemberExpr final
1825
1849
ArrayRef<Identifier> argLabels,
1826
1850
ArrayRef<SourceLoc> argLabelLocs,
1827
1851
SourceLoc rParenLoc,
1828
- Expr *trailingClosure ,
1852
+ ArrayRef<TrailingClosure> trailingClosures ,
1829
1853
bool implicit);
1830
1854
1831
1855
DeclNameRef getName () const { return Name; }
@@ -1852,6 +1876,11 @@ class UnresolvedMemberExpr final
1852
1876
return Bits.UnresolvedMemberExpr .HasTrailingClosure ;
1853
1877
}
1854
1878
1879
+ // / Return the index of the unlabeled trailing closure argument.
1880
+ Optional<unsigned > getUnlabeledTrailingClosureIndex () const {
1881
+ return getArgument ()->getUnlabeledTrailingClosureIndexOfPackedArgument ();
1882
+ }
1883
+
1855
1884
SourceLoc getLoc () const { return NameLoc.getBaseNameLoc (); }
1856
1885
1857
1886
SourceLoc getStartLoc () const { return DotLoc; }
@@ -2033,6 +2062,11 @@ class ParenExpr : public IdentityExpr {
2033
2062
// / Whether this expression has a trailing closure as its argument.
2034
2063
bool hasTrailingClosure () const { return Bits.ParenExpr .HasTrailingClosure ; }
2035
2064
2065
+ Optional<unsigned >
2066
+ getUnlabeledTrailingClosureIndexOfPackedArgument () const {
2067
+ return hasTrailingClosure () ? Optional<unsigned >(0 ) : None;
2068
+ }
2069
+
2036
2070
static bool classof (const Expr *E) { return E->getKind () == ExprKind::Paren; }
2037
2071
};
2038
2072
@@ -2046,6 +2080,8 @@ class TupleExpr final : public Expr,
2046
2080
SourceLoc LParenLoc;
2047
2081
SourceLoc RParenLoc;
2048
2082
2083
+ Optional<unsigned > FirstTrailingArgumentAt;
2084
+
2049
2085
size_t numTrailingObjects (OverloadToken<Expr *>) const {
2050
2086
return getNumElements ();
2051
2087
}
@@ -2072,11 +2108,11 @@ class TupleExpr final : public Expr,
2072
2108
return { getTrailingObjects<SourceLoc>(), getNumElements () };
2073
2109
}
2074
2110
2075
- TupleExpr (SourceLoc LParenLoc, ArrayRef<Expr *> SubExprs,
2076
- ArrayRef<Identifier> ElementNames,
2111
+ TupleExpr (SourceLoc LParenLoc, SourceLoc RParenLoc,
2112
+ ArrayRef<Expr *> SubExprs,
2113
+ ArrayRef<Identifier> ElementNames,
2077
2114
ArrayRef<SourceLoc> ElementNameLocs,
2078
- SourceLoc RParenLoc, bool HasTrailingClosure, bool Implicit,
2079
- Type Ty);
2115
+ Optional<unsigned > FirstTrailingArgumentAt, bool Implicit, Type Ty);
2080
2116
2081
2117
public:
2082
2118
// / Create a tuple.
@@ -2088,6 +2124,15 @@ class TupleExpr final : public Expr,
2088
2124
SourceLoc RParenLoc, bool HasTrailingClosure,
2089
2125
bool Implicit, Type Ty = Type());
2090
2126
2127
+ static TupleExpr *create (ASTContext &ctx,
2128
+ SourceLoc LParenLoc,
2129
+ SourceLoc RParenLoc,
2130
+ ArrayRef<Expr *> SubExprs,
2131
+ ArrayRef<Identifier> ElementNames,
2132
+ ArrayRef<SourceLoc> ElementNameLocs,
2133
+ Optional<unsigned > FirstTrailingArgumentAt,
2134
+ bool Implicit, Type Ty = Type());
2135
+
2091
2136
// / Create an empty tuple.
2092
2137
static TupleExpr *createEmpty (ASTContext &ctx, SourceLoc LParenLoc,
2093
2138
SourceLoc RParenLoc, bool Implicit);
@@ -2101,8 +2146,25 @@ class TupleExpr final : public Expr,
2101
2146
2102
2147
SourceRange getSourceRange () const ;
2103
2148
2149
+ bool hasAnyTrailingClosures () const {
2150
+ return (bool ) FirstTrailingArgumentAt;
2151
+ }
2152
+
2104
2153
// / Whether this expression has a trailing closure as its argument.
2105
- bool hasTrailingClosure () const { return Bits.TupleExpr .HasTrailingClosure ; }
2154
+ bool hasTrailingClosure () const {
2155
+ return FirstTrailingArgumentAt
2156
+ ? *FirstTrailingArgumentAt == getNumElements () - 1
2157
+ : false ;
2158
+ }
2159
+
2160
+ bool hasMultipleTrailingClosures () const {
2161
+ return FirstTrailingArgumentAt ? !hasTrailingClosure () : false ;
2162
+ }
2163
+
2164
+ Optional<unsigned >
2165
+ getUnlabeledTrailingClosureIndexOfPackedArgument () const {
2166
+ return FirstTrailingArgumentAt;
2167
+ }
2106
2168
2107
2169
// / Retrieve the elements of this tuple.
2108
2170
MutableArrayRef<Expr*> getElements () {
@@ -2113,8 +2175,22 @@ class TupleExpr final : public Expr,
2113
2175
ArrayRef<Expr*> getElements () const {
2114
2176
return { getTrailingObjects<Expr *>(), getNumElements () };
2115
2177
}
2178
+
2179
+ MutableArrayRef<Expr*> getTrailingElements () {
2180
+ return getElements ().take_back (getNumTrailingElements ());
2181
+ }
2182
+
2183
+ ArrayRef<Expr*> getTrailingElements () const {
2184
+ return getElements ().take_back (getNumTrailingElements ());
2185
+ }
2116
2186
2117
2187
unsigned getNumElements () const { return Bits.TupleExpr .NumElements ; }
2188
+
2189
+ unsigned getNumTrailingElements () const {
2190
+ return FirstTrailingArgumentAt
2191
+ ? getNumElements () - *FirstTrailingArgumentAt
2192
+ : 0 ;
2193
+ }
2118
2194
2119
2195
Expr *getElement (unsigned i) const {
2120
2196
return getElements ()[i];
@@ -2350,7 +2426,7 @@ class SubscriptExpr final : public LookupExpr,
2350
2426
ArrayRef<Identifier> indexArgLabels,
2351
2427
ArrayRef<SourceLoc> indexArgLabelLocs,
2352
2428
SourceLoc rSquareLoc,
2353
- Expr *trailingClosure ,
2429
+ ArrayRef<TrailingClosure> trailingClosures ,
2354
2430
ConcreteDeclRef decl = ConcreteDeclRef(),
2355
2431
bool implicit = false,
2356
2432
AccessSemantics semantics
@@ -2374,6 +2450,11 @@ class SubscriptExpr final : public LookupExpr,
2374
2450
return Bits.SubscriptExpr .HasTrailingClosure ;
2375
2451
}
2376
2452
2453
+ // / Return the index of the unlabeled trailing closure argument.
2454
+ Optional<unsigned > getUnlabeledTrailingClosureIndex () const {
2455
+ return getIndex ()->getUnlabeledTrailingClosureIndexOfPackedArgument ();
2456
+ }
2457
+
2377
2458
// / Determine whether this subscript reference should bypass the
2378
2459
// / ordinary accessors.
2379
2460
AccessSemantics getAccessSemantics () const {
@@ -4230,6 +4311,9 @@ class ApplyExpr : public Expr {
4230
4311
// / Whether this application was written using a trailing closure.
4231
4312
bool hasTrailingClosure () const ;
4232
4313
4314
+ // / Return the index of the unlabeled trailing closure argument.
4315
+ Optional<unsigned > getUnlabeledTrailingClosureIndex () const ;
4316
+
4233
4317
static bool classof (const Expr *E) {
4234
4318
return E->getKind () >= ExprKind::First_ApplyExpr &&
4235
4319
E->getKind () <= ExprKind::Last_ApplyExpr;
@@ -4267,13 +4351,14 @@ class CallExpr final : public ApplyExpr,
4267
4351
// / \param args The call arguments, not including a trailing closure (if any).
4268
4352
// / \param argLabels The argument labels, whose size must equal args.size(),
4269
4353
// / or which must be empty.
4270
- static CallExpr *
4271
- createImplicit (ASTContext &ctx, Expr *fn, ArrayRef<Expr *> args,
4272
- ArrayRef<Identifier> argLabels,
4273
- llvm::function_ref<Type(const Expr *)> getType =
4274
- [](const Expr *E) -> Type { return E->getType (); }) {
4275
- return create (ctx, fn, SourceLoc (), args, argLabels, { }, SourceLoc (),
4276
- /* trailingClosure=*/ nullptr , /* implicit=*/ true , getType);
4354
+ static CallExpr *createImplicit (
4355
+ ASTContext &ctx, Expr *fn, ArrayRef<Expr *> args,
4356
+ ArrayRef<Identifier> argLabels,
4357
+ llvm::function_ref<Type(const Expr *)> getType = [](const Expr *E) -> Type {
4358
+ return E->getType ();
4359
+ }) {
4360
+ return create (ctx, fn, SourceLoc (), args, argLabels, {}, SourceLoc (),
4361
+ /* trailingClosures=*/ {}, /* implicit=*/ true , getType);
4277
4362
}
4278
4363
4279
4364
// / Create a new call expression.
@@ -4284,13 +4369,15 @@ class CallExpr final : public ApplyExpr,
4284
4369
// / or which must be empty.
4285
4370
// / \param argLabelLocs The locations of the argument labels, whose size must
4286
4371
// / equal args.size() or which must be empty.
4287
- // / \param trailingClosure The trailing closure, if any.
4288
- static CallExpr *
4289
- create (ASTContext &ctx, Expr *fn, SourceLoc lParenLoc, ArrayRef<Expr *> args,
4290
- ArrayRef<Identifier> argLabels, ArrayRef<SourceLoc> argLabelLocs,
4291
- SourceLoc rParenLoc, Expr *trailingClosure, bool implicit,
4292
- llvm::function_ref<Type(const Expr *)> getType =
4293
- [](const Expr *E) -> Type { return E->getType (); });
4372
+ // / \param trailingClosures The list of trailing closures, if any.
4373
+ static CallExpr *create (
4374
+ ASTContext &ctx, Expr *fn, SourceLoc lParenLoc, ArrayRef<Expr *> args,
4375
+ ArrayRef<Identifier> argLabels, ArrayRef<SourceLoc> argLabelLocs,
4376
+ SourceLoc rParenLoc, ArrayRef<TrailingClosure> trailingClosures,
4377
+ bool implicit,
4378
+ llvm::function_ref<Type(const Expr *)> getType = [](const Expr *E) -> Type {
4379
+ return E->getType ();
4380
+ });
4294
4381
4295
4382
SourceLoc getStartLoc () const {
4296
4383
SourceLoc fnLoc = getFn ()->getStartLoc ();
@@ -4309,9 +4396,14 @@ class CallExpr final : public ApplyExpr,
4309
4396
unsigned getNumArguments () const { return Bits.CallExpr .NumArgLabels ; }
4310
4397
bool hasArgumentLabelLocs () const { return Bits.CallExpr .HasArgLabelLocs ; }
4311
4398
4312
- // / Whether this call with written with a trailing closure.
4399
+ // / Whether this call with written with a single trailing closure.
4313
4400
bool hasTrailingClosure () const { return Bits.CallExpr .HasTrailingClosure ; }
4314
4401
4402
+ // / Return the index of the unlabeled trailing closure argument.
4403
+ Optional<unsigned > getUnlabeledTrailingClosureIndex () const {
4404
+ return getArg ()->getUnlabeledTrailingClosureIndexOfPackedArgument ();
4405
+ }
4406
+
4315
4407
using TrailingCallArguments::getArgumentLabels;
4316
4408
4317
4409
// / Retrieve the expression that directly represents the callee.
@@ -5182,7 +5274,7 @@ class KeyPathExpr : public Expr {
5182
5274
ArrayRef<Identifier> indexArgLabels,
5183
5275
ArrayRef<SourceLoc> indexArgLabelLocs,
5184
5276
SourceLoc rSquareLoc,
5185
- Expr *trailingClosure );
5277
+ ArrayRef<TrailingClosure> trailingClosures );
5186
5278
5187
5279
// / Create an unresolved component for a subscript.
5188
5280
// /
@@ -5234,7 +5326,7 @@ class KeyPathExpr : public Expr {
5234
5326
ArrayRef<Identifier> indexArgLabels,
5235
5327
ArrayRef<SourceLoc> indexArgLabelLocs,
5236
5328
SourceLoc rSquareLoc,
5237
- Expr *trailingClosure ,
5329
+ ArrayRef<TrailingClosure> trailingClosures ,
5238
5330
Type elementType,
5239
5331
ArrayRef<ProtocolConformanceRef> indexHashables);
5240
5332
@@ -5619,18 +5711,16 @@ inline const SourceLoc *CollectionExpr::getTrailingSourceLocs() const {
5619
5711
// /
5620
5712
// / \param argLabelLocs The argument label locations, which might be updated by
5621
5713
// / this function.
5622
- Expr *packSingleArgument (ASTContext &ctx, SourceLoc lParenLoc,
5623
- ArrayRef<Expr *> args,
5624
- ArrayRef<Identifier> &argLabels,
5625
- ArrayRef<SourceLoc> &argLabelLocs,
5626
- SourceLoc rParenLoc,
5627
- Expr *trailingClosure, bool implicit,
5628
- SmallVectorImpl<Identifier> &argLabelsScratch,
5629
- SmallVectorImpl<SourceLoc> &argLabelLocsScratch,
5630
- llvm::function_ref<Type(const Expr *)> getType =
5631
- [](const Expr *E) -> Type {
5632
- return E->getType ();
5633
- });
5714
+ Expr *packSingleArgument (
5715
+ ASTContext &ctx, SourceLoc lParenLoc, ArrayRef<Expr *> args,
5716
+ ArrayRef<Identifier> &argLabels, ArrayRef<SourceLoc> &argLabelLocs,
5717
+ SourceLoc rParenLoc, ArrayRef<TrailingClosure> trailingClosures,
5718
+ bool implicit,
5719
+ SmallVectorImpl<Identifier> &argLabelsScratch,
5720
+ SmallVectorImpl<SourceLoc> &argLabelLocsScratch,
5721
+ llvm::function_ref<Type(const Expr *)> getType = [](const Expr *E) -> Type {
5722
+ return E->getType ();
5723
+ });
5634
5724
5635
5725
void simple_display (llvm::raw_ostream &out, const ClosureExpr *CE);
5636
5726
void simple_display (llvm::raw_ostream &out, const DefaultArgumentExpr *expr);
0 commit comments