@@ -39,103 +39,11 @@ bool Argument::isInOut() const {
3939 return ArgExpr->isSemanticallyInOutExpr ();
4040}
4141
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-
12742ArgumentList *ArgumentList::create (ASTContext &ctx, SourceLoc lParenLoc,
12843 ArrayRef<Argument> args, SourceLoc rParenLoc,
12944 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) {
13947 SmallVector<Expr *, 4 > exprs;
14048 SmallVector<Identifier, 4 > labels;
14149 SmallVector<SourceLoc, 4 > labelLocs;
@@ -156,12 +64,13 @@ ArgumentList *ArgumentList::create(ASTContext &ctx, SourceLoc lParenLoc,
15664 if (!hasLabelLocs)
15765 labelLocs.clear ();
15866
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 );
16170 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);
16574
16675 std::uninitialized_copy (exprs.begin (), exprs.end (),
16776 argList->getExprsBuffer ().begin ());
@@ -173,24 +82,35 @@ ArgumentList *ArgumentList::create(ASTContext &ctx, SourceLoc lParenLoc,
17382 std::uninitialized_copy (labelLocs.begin (), labelLocs.end (),
17483 argList->getLabelLocsBuffer ().begin ());
17584 }
85+ if (originalArgs) {
86+ *argList->getTrailingObjects <ArgumentList *>() = originalArgs;
87+ }
17688 return argList;
17789}
17890
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);
187105}
188106
189107ArgumentList *ArgumentList::createImplicit (ASTContext &ctx, SourceLoc lParenLoc,
190108 ArrayRef<Argument> args,
191109 SourceLoc rParenLoc,
192110 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);
194114}
195115
196116ArgumentList *ArgumentList::createImplicit (ASTContext &ctx,
@@ -258,24 +178,13 @@ SourceRange ArgumentList::getSourceRange() const {
258178 }
259179 }
260180 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 ())
277187 break ;
278- }
279188 }
280189 }
281190 if (start.isInvalid () || end.isInvalid ())
@@ -393,59 +302,3 @@ bool ArgumentList::matches(ArrayRef<AnyFunctionType::Param> params,
393302 }
394303 return true ;
395304}
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