@@ -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.
@@ -1198,7 +1212,7 @@ class ObjectLiteralExpr final
1198
1212
ArrayRef<Identifier> argLabels,
1199
1213
ArrayRef<SourceLoc> argLabelLocs,
1200
1214
SourceLoc rParenLoc,
1201
- Expr *trailingClosure ,
1215
+ ArrayRef<TrailingClosure> trailingClosures ,
1202
1216
bool implicit);
1203
1217
1204
1218
LiteralKind getLiteralKind () const {
@@ -1220,6 +1234,11 @@ class ObjectLiteralExpr final
1220
1234
return Bits.ObjectLiteralExpr .HasTrailingClosure ;
1221
1235
}
1222
1236
1237
+ // / Return the index of the unlabeled trailing closure argument.
1238
+ Optional<unsigned > getUnlabeledTrailingClosureIndex () const {
1239
+ return getArg ()->getUnlabeledTrailingClosureIndexOfPackedArgument ();
1240
+ }
1241
+
1223
1242
SourceLoc getSourceLoc () const { return PoundLoc; }
1224
1243
SourceRange getSourceRange () const {
1225
1244
return SourceRange (PoundLoc, Arg->getEndLoc ());
@@ -1806,6 +1825,11 @@ class DynamicSubscriptExpr final
1806
1825
return Bits.DynamicSubscriptExpr .HasTrailingClosure ;
1807
1826
}
1808
1827
1828
+ // / Return the index of the unlabeled trailing closure argument.
1829
+ Optional<unsigned > getUnlabeledTrailingClosureIndex () const {
1830
+ return Index->getUnlabeledTrailingClosureIndexOfPackedArgument ();
1831
+ }
1832
+
1809
1833
SourceLoc getLoc () const { return Index->getStartLoc (); }
1810
1834
1811
1835
SourceLoc getStartLoc () const { return getBase ()->getStartLoc (); }
@@ -1848,7 +1872,7 @@ class UnresolvedMemberExpr final
1848
1872
ArrayRef<Identifier> argLabels,
1849
1873
ArrayRef<SourceLoc> argLabelLocs,
1850
1874
SourceLoc rParenLoc,
1851
- Expr *trailingClosure ,
1875
+ ArrayRef<TrailingClosure> trailingClosures ,
1852
1876
bool implicit);
1853
1877
1854
1878
DeclNameRef getName () const { return Name; }
@@ -1875,6 +1899,11 @@ class UnresolvedMemberExpr final
1875
1899
return Bits.UnresolvedMemberExpr .HasTrailingClosure ;
1876
1900
}
1877
1901
1902
+ // / Return the index of the unlabeled trailing closure argument.
1903
+ Optional<unsigned > getUnlabeledTrailingClosureIndex () const {
1904
+ return getArgument ()->getUnlabeledTrailingClosureIndexOfPackedArgument ();
1905
+ }
1906
+
1878
1907
SourceLoc getLoc () const { return NameLoc.getBaseNameLoc (); }
1879
1908
1880
1909
SourceLoc getStartLoc () const { return DotLoc; }
@@ -2056,6 +2085,11 @@ class ParenExpr : public IdentityExpr {
2056
2085
// / Whether this expression has a trailing closure as its argument.
2057
2086
bool hasTrailingClosure () const { return Bits.ParenExpr .HasTrailingClosure ; }
2058
2087
2088
+ Optional<unsigned >
2089
+ getUnlabeledTrailingClosureIndexOfPackedArgument () const {
2090
+ return hasTrailingClosure () ? Optional<unsigned >(0 ) : None;
2091
+ }
2092
+
2059
2093
static bool classof (const Expr *E) { return E->getKind () == ExprKind::Paren; }
2060
2094
};
2061
2095
@@ -2069,6 +2103,8 @@ class TupleExpr final : public Expr,
2069
2103
SourceLoc LParenLoc;
2070
2104
SourceLoc RParenLoc;
2071
2105
2106
+ Optional<unsigned > FirstTrailingArgumentAt;
2107
+
2072
2108
size_t numTrailingObjects (OverloadToken<Expr *>) const {
2073
2109
return getNumElements ();
2074
2110
}
@@ -2095,11 +2131,11 @@ class TupleExpr final : public Expr,
2095
2131
return { getTrailingObjects<SourceLoc>(), getNumElements () };
2096
2132
}
2097
2133
2098
- TupleExpr (SourceLoc LParenLoc, ArrayRef<Expr *> SubExprs,
2099
- ArrayRef<Identifier> ElementNames,
2134
+ TupleExpr (SourceLoc LParenLoc, SourceLoc RParenLoc,
2135
+ ArrayRef<Expr *> SubExprs,
2136
+ ArrayRef<Identifier> ElementNames,
2100
2137
ArrayRef<SourceLoc> ElementNameLocs,
2101
- SourceLoc RParenLoc, bool HasTrailingClosure, bool Implicit,
2102
- Type Ty);
2138
+ Optional<unsigned > FirstTrailingArgumentAt, bool Implicit, Type Ty);
2103
2139
2104
2140
public:
2105
2141
// / Create a tuple.
@@ -2111,6 +2147,15 @@ class TupleExpr final : public Expr,
2111
2147
SourceLoc RParenLoc, bool HasTrailingClosure,
2112
2148
bool Implicit, Type Ty = Type());
2113
2149
2150
+ static TupleExpr *create (ASTContext &ctx,
2151
+ SourceLoc LParenLoc,
2152
+ SourceLoc RParenLoc,
2153
+ ArrayRef<Expr *> SubExprs,
2154
+ ArrayRef<Identifier> ElementNames,
2155
+ ArrayRef<SourceLoc> ElementNameLocs,
2156
+ Optional<unsigned > FirstTrailingArgumentAt,
2157
+ bool Implicit, Type Ty = Type());
2158
+
2114
2159
// / Create an empty tuple.
2115
2160
static TupleExpr *createEmpty (ASTContext &ctx, SourceLoc LParenLoc,
2116
2161
SourceLoc RParenLoc, bool Implicit);
@@ -2124,8 +2169,25 @@ class TupleExpr final : public Expr,
2124
2169
2125
2170
SourceRange getSourceRange () const ;
2126
2171
2172
+ bool hasAnyTrailingClosures () const {
2173
+ return (bool ) FirstTrailingArgumentAt;
2174
+ }
2175
+
2127
2176
// / Whether this expression has a trailing closure as its argument.
2128
- bool hasTrailingClosure () const { return Bits.TupleExpr .HasTrailingClosure ; }
2177
+ bool hasTrailingClosure () const {
2178
+ return FirstTrailingArgumentAt
2179
+ ? *FirstTrailingArgumentAt == getNumElements () - 1
2180
+ : false ;
2181
+ }
2182
+
2183
+ bool hasMultipleTrailingClosures () const {
2184
+ return FirstTrailingArgumentAt ? !hasTrailingClosure () : false ;
2185
+ }
2186
+
2187
+ Optional<unsigned >
2188
+ getUnlabeledTrailingClosureIndexOfPackedArgument () const {
2189
+ return FirstTrailingArgumentAt;
2190
+ }
2129
2191
2130
2192
// / Retrieve the elements of this tuple.
2131
2193
MutableArrayRef<Expr*> getElements () {
@@ -2136,8 +2198,22 @@ class TupleExpr final : public Expr,
2136
2198
ArrayRef<Expr*> getElements () const {
2137
2199
return { getTrailingObjects<Expr *>(), getNumElements () };
2138
2200
}
2201
+
2202
+ MutableArrayRef<Expr*> getTrailingElements () {
2203
+ return getElements ().take_back (getNumTrailingElements ());
2204
+ }
2205
+
2206
+ ArrayRef<Expr*> getTrailingElements () const {
2207
+ return getElements ().take_back (getNumTrailingElements ());
2208
+ }
2139
2209
2140
2210
unsigned getNumElements () const { return Bits.TupleExpr .NumElements ; }
2211
+
2212
+ unsigned getNumTrailingElements () const {
2213
+ return FirstTrailingArgumentAt
2214
+ ? getNumElements () - *FirstTrailingArgumentAt
2215
+ : 0 ;
2216
+ }
2141
2217
2142
2218
Expr *getElement (unsigned i) const {
2143
2219
return getElements ()[i];
@@ -2374,7 +2450,7 @@ class SubscriptExpr final : public LookupExpr,
2374
2450
ArrayRef<Identifier> indexArgLabels,
2375
2451
ArrayRef<SourceLoc> indexArgLabelLocs,
2376
2452
SourceLoc rSquareLoc,
2377
- Expr *trailingClosure ,
2453
+ ArrayRef<TrailingClosure> trailingClosures ,
2378
2454
ConcreteDeclRef decl = ConcreteDeclRef(),
2379
2455
bool implicit = false,
2380
2456
AccessSemantics semantics
@@ -2398,6 +2474,11 @@ class SubscriptExpr final : public LookupExpr,
2398
2474
return Bits.SubscriptExpr .HasTrailingClosure ;
2399
2475
}
2400
2476
2477
+ // / Return the index of the unlabeled trailing closure argument.
2478
+ Optional<unsigned > getUnlabeledTrailingClosureIndex () const {
2479
+ return getIndex ()->getUnlabeledTrailingClosureIndexOfPackedArgument ();
2480
+ }
2481
+
2401
2482
// / Determine whether this subscript reference should bypass the
2402
2483
// / ordinary accessors.
2403
2484
AccessSemantics getAccessSemantics () const {
@@ -4243,6 +4324,9 @@ class ApplyExpr : public Expr {
4243
4324
// / Whether this application was written using a trailing closure.
4244
4325
bool hasTrailingClosure () const ;
4245
4326
4327
+ // / Return the index of the unlabeled trailing closure argument.
4328
+ Optional<unsigned > getUnlabeledTrailingClosureIndex () const ;
4329
+
4246
4330
static bool classof (const Expr *E) {
4247
4331
return E->getKind () >= ExprKind::First_ApplyExpr &&
4248
4332
E->getKind () <= ExprKind::Last_ApplyExpr;
@@ -4287,8 +4371,8 @@ class CallExpr final : public ApplyExpr,
4287
4371
llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
4288
4372
return E->getType ();
4289
4373
}) {
4290
- return create (ctx, fn, SourceLoc (), args, argLabels, { }, SourceLoc (),
4291
- /* trailingClosure =*/ nullptr , /* implicit=*/ true , getType);
4374
+ return create (ctx, fn, SourceLoc (), args, argLabels, {}, SourceLoc (),
4375
+ /* trailingClosures =*/ {} , /* implicit=*/ true , getType);
4292
4376
}
4293
4377
4294
4378
// / Create a new call expression.
@@ -4299,11 +4383,12 @@ class CallExpr final : public ApplyExpr,
4299
4383
// / or which must be empty.
4300
4384
// / \param argLabelLocs The locations of the argument labels, whose size must
4301
4385
// / equal args.size() or which must be empty.
4302
- // / \param trailingClosure The trailing closure , if any.
4386
+ // / \param trailingClosures The list of trailing closures , if any.
4303
4387
static CallExpr *create (
4304
4388
ASTContext &ctx, Expr *fn, SourceLoc lParenLoc, ArrayRef<Expr *> args,
4305
4389
ArrayRef<Identifier> argLabels, ArrayRef<SourceLoc> argLabelLocs,
4306
- SourceLoc rParenLoc, Expr *trailingClosure, bool implicit,
4390
+ SourceLoc rParenLoc, ArrayRef<TrailingClosure> trailingClosures,
4391
+ bool implicit,
4307
4392
llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
4308
4393
return E->getType ();
4309
4394
});
@@ -4325,9 +4410,14 @@ class CallExpr final : public ApplyExpr,
4325
4410
unsigned getNumArguments () const { return Bits.CallExpr .NumArgLabels ; }
4326
4411
bool hasArgumentLabelLocs () const { return Bits.CallExpr .HasArgLabelLocs ; }
4327
4412
4328
- // / Whether this call with written with a trailing closure.
4413
+ // / Whether this call with written with a single trailing closure.
4329
4414
bool hasTrailingClosure () const { return Bits.CallExpr .HasTrailingClosure ; }
4330
4415
4416
+ // / Return the index of the unlabeled trailing closure argument.
4417
+ Optional<unsigned > getUnlabeledTrailingClosureIndex () const {
4418
+ return getArg ()->getUnlabeledTrailingClosureIndexOfPackedArgument ();
4419
+ }
4420
+
4331
4421
using TrailingCallArguments::getArgumentLabels;
4332
4422
4333
4423
// / Retrieve the expression that directly represents the callee.
@@ -5191,7 +5281,7 @@ class KeyPathExpr : public Expr {
5191
5281
ArrayRef<Identifier> indexArgLabels,
5192
5282
ArrayRef<SourceLoc> indexArgLabelLocs,
5193
5283
SourceLoc rSquareLoc,
5194
- Expr *trailingClosure );
5284
+ ArrayRef<TrailingClosure> trailingClosures );
5195
5285
5196
5286
// / Create an unresolved component for a subscript.
5197
5287
// /
@@ -5243,7 +5333,7 @@ class KeyPathExpr : public Expr {
5243
5333
ArrayRef<Identifier> indexArgLabels,
5244
5334
ArrayRef<SourceLoc> indexArgLabelLocs,
5245
5335
SourceLoc rSquareLoc,
5246
- Expr *trailingClosure ,
5336
+ ArrayRef<TrailingClosure> trailingClosures ,
5247
5337
Type elementType,
5248
5338
ArrayRef<ProtocolConformanceRef> indexHashables);
5249
5339
@@ -5631,7 +5721,8 @@ inline const SourceLoc *CollectionExpr::getTrailingSourceLocs() const {
5631
5721
Expr *packSingleArgument (
5632
5722
ASTContext &ctx, SourceLoc lParenLoc, ArrayRef<Expr *> args,
5633
5723
ArrayRef<Identifier> &argLabels, ArrayRef<SourceLoc> &argLabelLocs,
5634
- SourceLoc rParenLoc, Expr *trailingClosure, bool implicit,
5724
+ SourceLoc rParenLoc, ArrayRef<TrailingClosure> trailingClosures,
5725
+ bool implicit,
5635
5726
SmallVectorImpl<Identifier> &argLabelsScratch,
5636
5727
SmallVectorImpl<SourceLoc> &argLabelLocsScratch,
5637
5728
llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
0 commit comments