Skip to content

Commit dd2d851

Browse files
committed
[Macros] Avoid type-checking a macro expansion declaration's arguments twice
Instead of trying to work around a double-type-check of macro expansion declaration arguments, avoid type checking them twice in the first place. We're caching the `ResolveMacroRequest` output in a somewhat dodgy manner to account for the `MacroExpansionDecl`/`MacroExpansionExpr` cloning.
1 parent 4a68116 commit dd2d851

File tree

2 files changed

+31
-16
lines changed

2 files changed

+31
-16
lines changed

lib/Sema/CSApply.cpp

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "swift/AST/ProtocolConformance.h"
3737
#include "swift/AST/SourceFile.h"
3838
#include "swift/AST/SubstitutionMap.h"
39+
#include "swift/AST/TypeCheckRequests.h"
3940
#include "swift/Basic/Defer.h"
4041
#include "swift/Basic/StringExtras.h"
4142
#include "swift/Sema/ConstraintSystem.h"
@@ -5394,27 +5395,20 @@ namespace {
53945395
}
53955396
// For a non-expression macro, expand it as a declaration.
53965397
else if (macro->getMacroRoles().contains(MacroRole::Declaration)) {
5398+
auto &ctx = cs.getASTContext();
53975399
if (!E->getSubstituteDecl()) {
53985400
auto *med = E->createSubstituteDecl();
5401+
5402+
// Cache the result of ResolveMacroRequest for this new declaration;
5403+
// we don't want to compute it again.
5404+
ctx.evaluator.cacheOutput(
5405+
ResolveMacroRequest{UnresolvedMacroReference{med},
5406+
med->getDeclContext()},
5407+
ConcreteDeclRef(macroRef));
5408+
53995409
E->setSubstituteDecl(med);
54005410
TypeChecker::typeCheckDecl(med);
54015411
}
5402-
// To prevent AST nodes from being visited twice, we've sunk the
5403-
// original argument list down to the substitute macro expansion decl,
5404-
// and we'll replace the expr's arguments with opaque values.
5405-
SmallVector<Argument, 4> newArguments;
5406-
for (auto arg : *E->getArgs()) {
5407-
arg.setExpr(new (cs.getASTContext()) OpaqueValueExpr(
5408-
arg.getSourceRange(), cs.getType(arg.getExpr())));
5409-
newArguments.push_back(arg);
5410-
}
5411-
auto newArgList = ArgumentList::create(
5412-
cs.getASTContext(), E->getArgs()->getLParenLoc(), newArguments,
5413-
E->getArgs()->getRParenLoc(),
5414-
E->getArgs()->getFirstTrailingClosureIndex(),
5415-
E->getArgs()->isImplicit());
5416-
E->setArgs(newArgList);
5417-
cs.setType(E, cs.getASTContext().getVoidType());
54185412
}
54195413
// Other macro roles may also be encountered here, as they use
54205414
// `MacroExpansionExpr` for resolution. In those cases, do not expand.

lib/Sema/TypeCheckMacros.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,6 +1482,16 @@ ConcreteDeclRef
14821482
ResolveMacroRequest::evaluate(Evaluator &evaluator,
14831483
UnresolvedMacroReference macroRef,
14841484
DeclContext *dc) const {
1485+
// Macro expressions and declarations have their own stored macro
1486+
// reference. Use it if it's there.
1487+
if (auto *expr = macroRef.getExpr()) {
1488+
if (auto ref = expr->getMacroRef())
1489+
return ref;
1490+
} else if (auto decl = macroRef.getDecl()) {
1491+
if (auto ref = decl->getMacroRef())
1492+
return ref;
1493+
}
1494+
14851495
auto &ctx = dc->getASTContext();
14861496
auto roles = macroRef.getMacroRoles();
14871497
auto foundMacros = TypeChecker::lookupMacros(
@@ -1511,5 +1521,16 @@ ResolveMacroRequest::evaluate(Evaluator &evaluator,
15111521
if (!macroExpansion->getMacroRef() && macroRef.getAttr())
15121522
macroRef.getAttr()->setInvalid();
15131523

1524+
// Macro expressions and declarations have their own stored macro
1525+
// reference. If we got a reference, store it there, too.
1526+
// FIXME: This duplication of state is really unfortunate.
1527+
if (auto ref = macroExpansion->getMacroRef()) {
1528+
if (auto *expr = macroRef.getExpr()) {
1529+
expr->setMacroRef(ref);
1530+
} else if (auto decl = macroRef.getDecl()) {
1531+
decl->setMacroRef(ref);
1532+
}
1533+
}
1534+
15141535
return macroExpansion->getMacroRef();
15151536
}

0 commit comments

Comments
 (0)