@@ -39,103 +39,11 @@ bool Argument::isInOut() const {
39
39
return ArgExpr->isSemanticallyInOutExpr ();
40
40
}
41
41
42
- // / Attempt to extract the underlying array expr from an implicit variadic
43
- // / expansion expr.
44
- static ArrayExpr *getVariadicArrayFrom (const Expr *E) {
45
- auto *vargExpr = dyn_cast<VarargExpansionExpr>(E);
46
- if (!vargExpr || !vargExpr->isImplicit ())
47
- return nullptr ;
48
- auto *vargArray = dyn_cast<ArrayExpr>(vargExpr->getSubExpr ());
49
- if (!vargArray || !vargArray->isImplicit ())
50
- return nullptr ;
51
- return vargArray;
52
- }
53
-
54
- namespace {
55
- struct TrailingClosureInfo {
56
- Optional<unsigned > ArgIndex;
57
- bool HasMultiple;
58
-
59
- TrailingClosureInfo () : HasMultiple(false ) {}
60
- TrailingClosureInfo (Optional<unsigned > argIndex, bool hasMultiple)
61
- : ArgIndex(argIndex), HasMultiple(hasMultiple) {}
62
- };
63
- } // end anonymous namespace
64
-
65
- static bool argExprHasValidSourceRange (const Expr *expr) {
66
- // Default arguments may have source info, but it's not a valid argument
67
- // source range.
68
- return !isa<DefaultArgumentExpr>(expr) && expr->getSourceRange ().isValid ();
69
- }
70
-
71
- // / Whether a given argument expression in a non-implicit arg list is either a
72
- // / trailing closure, or is a variadic expansion containing a trailing closure.
73
- static bool isTrailingArgOfNonImplicitArgList (const Expr *argExpr,
74
- SourceLoc rparenLoc) {
75
- // If the argument has no valid source info, we can't count it as a trailing
76
- // closure.
77
- if (!argExprHasValidSourceRange (argExpr))
78
- return false ;
79
-
80
- // If the right paren loc is invalid, this is something like 'fn {}'.
81
- if (rparenLoc.isInvalid ())
82
- return true ;
83
-
84
- // Otherwise the argument must come after the r-paren. Note we check the end
85
- // loc of the argument to match against variadic args that contain both
86
- // non-trailing and trailing closures.
87
- return rparenLoc.getOpaquePointerValue () <
88
- argExpr->getEndLoc ().getOpaquePointerValue ();
89
- }
90
-
91
- static TrailingClosureInfo
92
- computeTrailingClosureInfo (ArrayRef<Argument> args, SourceLoc rparenLoc,
93
- bool isImplicit) {
94
- // Implicit argument lists never have trailing closures.
95
- if (isImplicit)
96
- return {};
97
-
98
- auto iter = llvm::find_if (args, [&](const auto &arg) {
99
- return isTrailingArgOfNonImplicitArgList (arg.getExpr (), rparenLoc);
100
- });
101
- if (iter == args.end ()) {
102
- assert (rparenLoc.isValid () &&
103
- " Explicit argument list with no parens and no trailing closures?" );
104
- return {};
105
- }
106
- auto argIdx = iter - args.begin ();
107
-
108
- // For the variadic case we need to dig into the variadic array to figure out
109
- // if we have multiple trailing closures.
110
- if (auto *array = getVariadicArrayFrom (args[argIdx].getExpr ())) {
111
- auto numTrailing = llvm::count_if (array->getElements (), [&](auto *expr) {
112
- return isTrailingArgOfNonImplicitArgList (expr, rparenLoc);
113
- });
114
- assert (numTrailing > 0 && " Variadic args didn't have trailing closure?" );
115
- if (numTrailing > 1 )
116
- return TrailingClosureInfo (argIdx, /* HasMultiple*/ true );
117
- }
118
-
119
- // Otherwise, look for the next trailing closure if any.
120
- auto restOfArgs = args.drop_front (argIdx + 1 );
121
- auto nextIter = llvm::find_if (restOfArgs, [&](const auto &arg) {
122
- return isTrailingArgOfNonImplicitArgList (arg.getExpr (), rparenLoc);
123
- });
124
- return TrailingClosureInfo (argIdx, /* HasMultiple*/ nextIter != args.end ());
125
- }
126
-
127
42
ArgumentList *ArgumentList::create (ASTContext &ctx, SourceLoc lParenLoc,
128
43
ArrayRef<Argument> args, SourceLoc rParenLoc,
129
44
Optional<unsigned > firstTrailingClosureIndex,
130
- bool hasMultipleTrailingClosures,
131
- bool isImplicit, AllocationArena arena) {
132
- #ifndef NDEBUG
133
- auto trailingInfo = computeTrailingClosureInfo (args, rParenLoc, isImplicit);
134
- assert (trailingInfo.ArgIndex == firstTrailingClosureIndex);
135
- assert (trailingInfo.HasMultiple == hasMultipleTrailingClosures);
136
- #endif
137
-
138
- assert (lParenLoc.isValid () == rParenLoc.isValid ());
45
+ bool isImplicit, ArgumentList *originalArgs,
46
+ AllocationArena arena) {
139
47
SmallVector<Expr *, 4 > exprs;
140
48
SmallVector<Identifier, 4 > labels;
141
49
SmallVector<SourceLoc, 4 > labelLocs;
@@ -156,12 +64,13 @@ ArgumentList *ArgumentList::create(ASTContext &ctx, SourceLoc lParenLoc,
156
64
if (!hasLabelLocs)
157
65
labelLocs.clear ();
158
66
159
- auto numBytes = totalSizeToAlloc<Expr *, Identifier, SourceLoc>(
160
- exprs.size (), labels.size (), labelLocs.size ());
67
+ auto numBytes =
68
+ totalSizeToAlloc<Expr *, Identifier, SourceLoc, ArgumentList *>(
69
+ exprs.size (), labels.size (), labelLocs.size (), originalArgs ? 1 : 0 );
161
70
auto *mem = ctx.Allocate (numBytes, alignof (ArgumentList), arena);
162
- auto *argList = new (mem) ArgumentList (
163
- lParenLoc, rParenLoc, args.size (), firstTrailingClosureIndex,
164
- hasMultipleTrailingClosures , isImplicit, hasLabels, hasLabelLocs);
71
+ auto *argList = new (mem)
72
+ ArgumentList ( lParenLoc, rParenLoc, args.size (), firstTrailingClosureIndex,
73
+ originalArgs , isImplicit, hasLabels, hasLabelLocs);
165
74
166
75
std::uninitialized_copy (exprs.begin (), exprs.end (),
167
76
argList->getExprsBuffer ().begin ());
@@ -173,24 +82,35 @@ ArgumentList *ArgumentList::create(ASTContext &ctx, SourceLoc lParenLoc,
173
82
std::uninitialized_copy (labelLocs.begin (), labelLocs.end (),
174
83
argList->getLabelLocsBuffer ().begin ());
175
84
}
85
+ if (originalArgs) {
86
+ *argList->getTrailingObjects <ArgumentList *>() = originalArgs;
87
+ }
176
88
return argList;
177
89
}
178
90
179
- ArgumentList *ArgumentList::create (ASTContext &ctx, SourceLoc lParenLoc,
180
- ArrayRef<Argument> args, SourceLoc rParenLoc,
181
- bool isImplicit, AllocationArena arena) {
182
- auto trailingClosureInfo =
183
- computeTrailingClosureInfo (args, rParenLoc, isImplicit);
184
- return ArgumentList::create (
185
- ctx, lParenLoc, args, rParenLoc, trailingClosureInfo.ArgIndex ,
186
- trailingClosureInfo.HasMultiple , isImplicit, arena);
91
+ ArgumentList *
92
+ ArgumentList::createParsed (ASTContext &ctx, SourceLoc lParenLoc,
93
+ ArrayRef<Argument> args, SourceLoc rParenLoc,
94
+ Optional<unsigned > firstTrailingClosureIndex) {
95
+ return create (ctx, lParenLoc, args, rParenLoc, firstTrailingClosureIndex,
96
+ /* implicit*/ false );
97
+ }
98
+
99
+ ArgumentList *ArgumentList::createTypeChecked (ASTContext &ctx,
100
+ ArgumentList *originalArgs,
101
+ ArrayRef<Argument> newArgs) {
102
+ return create (ctx, originalArgs->getLParenLoc (), newArgs,
103
+ originalArgs->getRParenLoc (), /* trailingClosureIdx*/ None,
104
+ originalArgs->isImplicit (), originalArgs);
187
105
}
188
106
189
107
ArgumentList *ArgumentList::createImplicit (ASTContext &ctx, SourceLoc lParenLoc,
190
108
ArrayRef<Argument> args,
191
109
SourceLoc rParenLoc,
192
110
AllocationArena arena) {
193
- return create (ctx, lParenLoc, args, rParenLoc, /* implicit*/ true , arena);
111
+ return create (ctx, lParenLoc, args, rParenLoc,
112
+ /* firstTrailingClosureIdx*/ None, /* implicit*/ true ,
113
+ /* originalArgs*/ nullptr , arena);
194
114
}
195
115
196
116
ArgumentList *ArgumentList::createImplicit (ASTContext &ctx,
@@ -258,24 +178,13 @@ SourceRange ArgumentList::getSourceRange() const {
258
178
}
259
179
}
260
180
auto end = RParenLoc;
261
- if (hasAnyTrailingClosures ()) {
262
- // If we have trailing closures, the end loc is the end loc of the last
263
- // trailing closure.
264
- for (auto arg : llvm::reverse (*this )) {
265
- if (isTrailingArgOfNonImplicitArgList (arg.getExpr (), RParenLoc)) {
266
- end = arg.getEndLoc ();
267
- break ;
268
- }
269
- }
270
- } else if (RParenLoc.isInvalid ()) {
271
- // If we don't have trailing closures and the r-paren loc is invalid, this
272
- // is an implicit argument list. Take the last valid argument loc.
273
- assert (isImplicit ());
274
- for (auto arg : llvm::reverse (*this )) {
275
- if (argExprHasValidSourceRange (arg.getExpr ())) {
276
- end = arg.getEndLoc ();
181
+ if (hasAnyTrailingClosures () || RParenLoc.isInvalid ()) {
182
+ // Scan backward for the first valid source loc. We use getOriginalArgs to
183
+ // filter out default arguments and get accurate trailing closure info.
184
+ for (auto arg : llvm::reverse (*getOriginalArgs ())) {
185
+ end = arg.getEndLoc ();
186
+ if (end.isValid ())
277
187
break ;
278
- }
279
188
}
280
189
}
281
190
if (start.isInvalid () || end.isInvalid ())
@@ -393,59 +302,3 @@ bool ArgumentList::matches(ArrayRef<AnyFunctionType::Param> params,
393
302
}
394
303
return true ;
395
304
}
396
-
397
- OriginalArguments ArgumentList::getOriginalArguments () const {
398
- // We need to sort out the trailing closures separately to handle cases like:
399
- //
400
- // func foo(fn: () -> Void, x: Int = 0) {}
401
- // foo(x: 0) {}
402
- //
403
- // where we currently allow the re-ordering of a trailing closure argument
404
- // such that it appears as the first argument in the type-checked AST. To
405
- // remedy this, separate out the trailing closures and make sure to append
406
- // them after the regular arguments.
407
- OriginalArguments::Storage newArgs;
408
- SmallVector<Argument, 1 > trailingClosures;
409
-
410
- auto addArg = [&](Argument arg) {
411
- if (hasAnyTrailingClosures () &&
412
- isTrailingArgOfNonImplicitArgList (arg.getExpr (), getRParenLoc ())) {
413
- trailingClosures.push_back (arg);
414
- return ;
415
- }
416
- newArgs.push_back (arg);
417
- };
418
- for (auto arg : *this ) {
419
- auto *expr = arg.getExpr ();
420
- if (isa<DefaultArgumentExpr>(expr))
421
- continue ;
422
-
423
- if (auto *vargArray = getVariadicArrayFrom (expr)) {
424
- auto elts = vargArray->getElements ();
425
- for (auto idx : indices (elts)) {
426
- // The first element in a variadic expansion takes the argument label,
427
- // the rest are unlabeled.
428
- if (idx == 0 ) {
429
- addArg (Argument (arg.getLabelLoc (), arg.getLabel (), elts[idx]));
430
- } else {
431
- addArg (Argument::unlabeled (elts[idx]));
432
- }
433
- }
434
- continue ;
435
- }
436
- addArg (arg);
437
- }
438
- Optional<unsigned > trailingClosureIdx;
439
- if (!trailingClosures.empty ())
440
- trailingClosureIdx = newArgs.size ();
441
-
442
- newArgs.append (trailingClosures.begin (), trailingClosures.end ());
443
- auto origArgs = OriginalArguments (std::move (newArgs), trailingClosureIdx);
444
- #ifndef NDEBUG
445
- auto trailingInfo = computeTrailingClosureInfo (origArgs.getArray (),
446
- getRParenLoc (), isImplicit ());
447
- assert (trailingInfo.ArgIndex == trailingClosureIdx);
448
- assert (trailingInfo.HasMultiple == origArgs.hasMultipleTrailingClosures ());
449
- #endif
450
- return origArgs;
451
- }
0 commit comments