@@ -1679,34 +1679,65 @@ class PlaceholderExpansionScanner {
1679
1679
public:
1680
1680
const SourceManager &SM;
1681
1681
SourceLoc TargetLoc;
1682
- std::pair<Expr * , ArgumentList *> EnclosingCallAndArg;
1682
+ std::pair<ASTNode , ArgumentList *> EnclosingCallAndArg;
1683
1683
Expr *OuterExpr;
1684
1684
Stmt *OuterStmt;
1685
- explicit CallExprFinder (const SourceManager &SM)
1686
- :SM(SM) { }
1687
-
1688
- bool checkCallExpr (Expr *E) {
1689
- ArgumentList *Args = nullptr ;
1690
- if (auto *CE = dyn_cast<CallExpr>(E)) {
1691
- // Call expression can have argument.
1692
- Args = CE->getArgs ();
1685
+ Decl *OuterDecl;
1686
+
1687
+ explicit CallExprFinder (const SourceManager &SM) : SM(SM) {}
1688
+
1689
+ void checkArgumentList (ArgumentList *Args) {
1690
+ ASTNode Enclosing;
1691
+ if (auto *E = Parent.getAsExpr ()) {
1692
+ // Must have a function call or macro parent.
1693
+ if (!isa<CallExpr, MacroExpansionExpr>(E) ||
1694
+ E->getArgs () != Args) {
1695
+ return ;
1696
+ }
1697
+ // If the outer expression is the call itself, disregard it.
1698
+ if (OuterExpr == E)
1699
+ OuterExpr = nullptr ;
1700
+
1701
+ Enclosing = E;
1693
1702
}
1694
- if (!Args)
1695
- return false ;
1696
- if (EnclosingCallAndArg.first )
1697
- OuterExpr = EnclosingCallAndArg.first ;
1698
- EnclosingCallAndArg = {E, Args};
1699
- return true ;
1703
+ if (auto *D = Parent.getAsDecl ()) {
1704
+ // Must have a macro decl parent.
1705
+ auto *MED = dyn_cast<MacroExpansionDecl>(D);
1706
+ if (!MED || MED->getArgs () != Args)
1707
+ return ;
1708
+ Enclosing = D;
1709
+ }
1710
+ if (!Enclosing)
1711
+ return ;
1712
+
1713
+ // If we have an outer enclosing call, update the outer nodes if needed.
1714
+ if (auto EnclosingCall = EnclosingCallAndArg.first ) {
1715
+ if (!OuterExpr)
1716
+ OuterExpr = EnclosingCall.dyn_cast <Expr *>();
1717
+ if (!OuterDecl)
1718
+ OuterDecl = EnclosingCall.dyn_cast <Decl *>();
1719
+ }
1720
+
1721
+ EnclosingCallAndArg = {Enclosing, Args};
1700
1722
}
1701
1723
1702
1724
MacroWalking getMacroWalkingBehavior () const override {
1703
1725
return MacroWalking::Arguments;
1704
1726
}
1705
1727
1728
+ PreWalkResult<ArgumentList *>
1729
+ walkToArgumentListPre (ArgumentList *ArgList) override {
1730
+ auto SR = ArgList->getSourceRange ();
1731
+ if (SR.isValid () && SM.rangeContainsTokenLoc (SR, TargetLoc))
1732
+ checkArgumentList (ArgList);
1733
+
1734
+ return Action::Continue (ArgList);
1735
+ }
1736
+
1706
1737
PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
1707
1738
auto SR = E->getSourceRange ();
1708
1739
if (SR.isValid () && SM.rangeContainsTokenLoc (SR, TargetLoc) &&
1709
- !checkCallExpr (E) && !EnclosingCallAndArg.first ) {
1740
+ !OuterExpr && !EnclosingCallAndArg.first ) {
1710
1741
if (!isa<TryExpr>(E) && !isa<AwaitExpr>(E) && !isa<UnsafeExpr>(E) &&
1711
1742
!isa<PrefixUnaryExpr>(E)) {
1712
1743
// We don't want to expand to trailing closures if the call is
@@ -1782,6 +1813,7 @@ class PlaceholderExpansionScanner {
1782
1813
EnclosingCallAndArg = {nullptr , nullptr };
1783
1814
OuterExpr = nullptr ;
1784
1815
OuterStmt = nullptr ;
1816
+ OuterDecl = nullptr ;
1785
1817
TargetLoc = SL;
1786
1818
SF.walk (*this );
1787
1819
return EnclosingCallAndArg.second ;
@@ -1791,14 +1823,9 @@ class PlaceholderExpansionScanner {
1791
1823
CallExprFinder CEFinder (SM);
1792
1824
auto *Args = CEFinder.findEnclosingCallArg (SF, SL);
1793
1825
1794
- if (!Args)
1795
- return std::make_pair (Args, false );
1796
- if (CEFinder.OuterExpr )
1797
- return std::make_pair (Args, false );
1798
- if (CEFinder.OuterStmt )
1799
- return std::make_pair (Args, false );
1800
-
1801
- return std::make_pair (Args, true );
1826
+ auto HasOuterNode =
1827
+ CEFinder.OuterExpr || CEFinder.OuterStmt || CEFinder.OuterDecl ;
1828
+ return std::make_pair (Args, /* useTrailingClosure*/ Args && !HasOuterNode);
1802
1829
}
1803
1830
1804
1831
struct ParamClosureInfo {
0 commit comments