Skip to content

Commit 9dc87ba

Browse files
committed
Switch back to parsing top-level MacroExpansionExpr.
Use a "substitute decl" in `MacroExpansionExpr` to represent top-level or local macro expansions that can be interpreted as a declaration macro or code item macro expansion.
1 parent 8ab31c4 commit 9dc87ba

21 files changed

+110
-149
lines changed

include/swift/AST/Decl.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8462,7 +8462,6 @@ class MacroExpansionDecl : public Decl {
84628462
ArrayRef<ASTNode> getRewritten() const;
84638463
ConcreteDeclRef getMacroRef() const { return macroRef; }
84648464
void setMacroRef(ConcreteDeclRef ref) { macroRef = ref; }
8465-
MacroExpansionExpr *createExpr() const;
84668465

84678466
/// Returns a discriminator which determines this macro expansion's index
84688467
/// in the sequence of macro expansions within the current function.

include/swift/AST/Expr.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6156,6 +6156,7 @@ class MacroExpansionExpr final : public Expr {
61566156
ArgumentList *ArgList;
61576157
Expr *Rewritten;
61586158
MacroRoles Roles;
6159+
MacroExpansionDecl *SubstituteDecl;
61596160

61606161
/// The referenced macro.
61616162
ConcreteDeclRef macroRef;
@@ -6178,7 +6179,7 @@ class MacroExpansionExpr final : public Expr {
61786179
MacroName(macroName), MacroNameLoc(macroNameLoc),
61796180
LeftAngleLoc(leftAngleLoc), RightAngleLoc(rightAngleLoc),
61806181
GenericArgs(genericArgs),
6181-
Rewritten(nullptr), Roles(roles) {
6182+
Rewritten(nullptr), Roles(roles), SubstituteDecl(nullptr) {
61826183
Bits.MacroExpansionExpr.Discriminator = InvalidDiscriminator;
61836184

61846185
// Macro expansions always have an argument list. If one is not provided, create
@@ -6235,6 +6236,10 @@ class MacroExpansionExpr final : public Expr {
62356236

62366237
SourceRange getSourceRange() const;
62376238

6239+
MacroExpansionDecl *createSubstituteDecl() const;
6240+
MacroExpansionDecl *getSubstituteDecl() const;
6241+
void setSubstituteDecl(MacroExpansionDecl *decl);
6242+
62386243
static bool classof(const Expr *E) {
62396244
return E->getKind() == ExprKind::MacroExpansion;
62406245
}

lib/AST/Decl.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,28 @@ void Decl::visitAuxiliaryDecls(AuxiliaryDeclCallback callback) const {
394394
}
395395
}
396396

397+
if (auto *med = dyn_cast<MacroExpansionDecl>(this)) {
398+
for (auto node : med->getRewritten())
399+
if (auto *decl = node.dyn_cast<Decl *>())
400+
callback(decl);
401+
}
402+
403+
// Top-level macro expansion expressions are treated as top-level decls.
404+
else if (auto *tlcd = dyn_cast<TopLevelCodeDecl>(this)) {
405+
for (auto node : tlcd->getBody()->getElements()) {
406+
if (auto *expr = node.dyn_cast<Expr *>()) {
407+
if (auto *mee = dyn_cast<MacroExpansionExpr>(expr)) {
408+
auto *med = mee->getSubstituteDecl();
409+
if (!med) {
410+
med = mee->createSubstituteDecl();
411+
mee->setSubstituteDecl(med);
412+
}
413+
callback(med);
414+
}
415+
}
416+
}
417+
}
418+
397419
// FIXME: fold VarDecl::visitAuxiliaryDecls into this.
398420
}
399421

@@ -9950,13 +9972,6 @@ SourceRange MacroExpansionDecl::getSourceRange() const {
99509972
return SourceRange(PoundLoc, endLoc);
99519973
}
99529974

9953-
MacroExpansionExpr *MacroExpansionDecl::createExpr() const {
9954-
return new (getASTContext()) MacroExpansionExpr(
9955-
getDeclContext(), PoundLoc, MacroName, MacroNameLoc, LeftAngleLoc,
9956-
GenericArgs, RightAngleLoc, ArgList,
9957-
MacroRoles(MacroRole::Expression) | MacroRole::Declaration);
9958-
}
9959-
99609975
unsigned MacroExpansionDecl::getDiscriminator() const {
99619976
if (getRawDiscriminator() != InvalidDiscriminator)
99629977
return getRawDiscriminator();

lib/AST/Expr.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2709,6 +2709,23 @@ unsigned MacroExpansionExpr::getDiscriminator() const {
27092709
return getRawDiscriminator();
27102710
}
27112711

2712+
MacroExpansionDecl *MacroExpansionExpr::createSubstituteDecl() const {
2713+
auto dc = getDeclContext();
2714+
if (auto *tlcd = dyn_cast_or_null<TopLevelCodeDecl>(dc->getAsDecl()))
2715+
dc = tlcd->getDeclContext();
2716+
return new (DC->getASTContext()) MacroExpansionDecl(
2717+
getDeclContext(), SigilLoc, MacroName, MacroNameLoc, LeftAngleLoc,
2718+
GenericArgs, RightAngleLoc, ArgList);
2719+
}
2720+
2721+
MacroExpansionDecl *MacroExpansionExpr::getSubstituteDecl() const {
2722+
return SubstituteDecl;
2723+
}
2724+
2725+
void MacroExpansionExpr::setSubstituteDecl(MacroExpansionDecl *decl) {
2726+
SubstituteDecl = decl;
2727+
}
2728+
27122729
void swift::simple_display(llvm::raw_ostream &out, const ClosureExpr *CE) {
27132730
if (!CE) {
27142731
out << "(null)";

lib/AST/Module.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ void SourceLookupCache::addToUnqualifiedLookupCache(Range decls,
263263

264264
else if (auto *MED = dyn_cast<MacroExpansionDecl>(D))
265265
DelayedMacroExpansions.push_back(MED);
266+
267+
else if (isa<TopLevelCodeDecl>(D)) {
268+
D->visitAuxiliaryDecls([&](Decl *auxDecl) {
269+
addToUnqualifiedLookupCache(ArrayRef<Decl *>{auxDecl}, false);
270+
});
271+
}
266272
}
267273
}
268274

@@ -339,13 +345,12 @@ SourceLookupCache::SourceLookupCache(const ModuleDecl &M) {
339345
}
340346

341347
void SourceLookupCache::addDelayedMacroExpansions() {
342-
for (unsigned i = 0; i != DelayedMacroExpansions.size(); ++i) {
343-
auto *MED = DelayedMacroExpansions[i];
348+
while (!DelayedMacroExpansions.empty()) {
349+
auto *MED = DelayedMacroExpansions.pop_back_val();
344350
for (auto node : MED->getRewritten())
345351
if (auto *decl = node.dyn_cast<Decl *>())
346352
addToUnqualifiedLookupCache(TinyPtrVector<Decl *>{decl}, false);
347353
}
348-
DelayedMacroExpansions.clear();
349354
}
350355

351356
void SourceLookupCache::lookupValue(DeclName Name, NLKind LookupKind,

lib/AST/NameLookup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1336,7 +1336,6 @@ MemberLookupTable::MemberLookupTable(ASTContext &ctx) {
13361336
}
13371337

13381338
void MemberLookupTable::addMember(Decl *member) {
1339-
13401339
// Only value declarations matter.
13411340
auto vd = dyn_cast<ValueDecl>(member);
13421341
if (!vd)
@@ -1514,6 +1513,7 @@ populateLookupTableEntryFromMacroExpansions(ASTContext &ctx,
15141513
MemberLookupTable &table,
15151514
DeclName name,
15161515
NominalTypeDecl *dc) {
1516+
// FIXME: Recurse
15171517
auto expandAndPopulate = [&](MacroExpansionDecl *med) {
15181518
for (auto node : med->getRewritten())
15191519
if (auto *decl = node.dyn_cast<Decl *>())

lib/AST/TypeCheckRequests.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,10 +1743,7 @@ ArgumentList *UnresolvedMacroReference::getArgs() const {
17431743
}
17441744

17451745
MacroRoles UnresolvedMacroReference::getMacroRoles() const {
1746-
if (pointer.is<MacroExpansionExpr *>())
1747-
return MacroRole::Expression;
1748-
1749-
if (pointer.is<MacroExpansionDecl *>())
1746+
if (pointer.is<MacroExpansionExpr *>() || pointer.is<MacroExpansionDecl *>())
17501747
return getFreestandingMacroRoles();
17511748

17521749
if (pointer.is<CustomAttr *>())

lib/Parse/ParseDecl.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4682,7 +4682,6 @@ bool swift::isKeywordPossibleDeclStart(const Token &Tok) {
46824682
case tok::kw_subscript:
46834683
case tok::kw_typealias:
46844684
case tok::kw_var:
4685-
case tok::pound:
46864685
case tok::pound_if:
46874686
case tok::pound_warning:
46884687
case tok::pound_error:
@@ -4794,10 +4793,6 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
47944793
return isStartOfSwiftDecl(allowPoundIfAttributes);
47954794
}
47964795

4797-
// Macro expansion starts with a pound and a custom identifier.
4798-
if (Tok.is(tok::pound) && peekToken().is(tok::identifier))
4799-
return true;
4800-
48014796
// Skip a #if that contains only attributes in all branches. These will be
48024797
// parsed as attributes of a declaration, not as separate declarations.
48034798
if (Tok.is(tok::pound_if) && allowPoundIfAttributes) {
@@ -9591,9 +9586,6 @@ Parser::parseDeclMacroExpansion(ParseDeclOptions flags,
95919586
}
95929587
}
95939588

9594-
if (!argList)
9595-
argList = ArgumentList::createImplicit(Context, {});
9596-
95979589
return makeParserResult(
95989590
status,
95999591
new (Context) MacroExpansionDecl(

lib/Parse/ParseExpr.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3387,7 +3387,9 @@ ParserResult<Expr> Parser::parseExprMacroExpansion(bool isExprBasic) {
33873387
new (Context) MacroExpansionExpr(
33883388
CurDeclContext, poundLoc, macroNameRef, macroNameLoc, leftAngleLoc,
33893389
Context.AllocateCopy(genericArgs), rightAngleLoc, argList,
3390-
MacroRole::Expression));
3390+
CurDeclContext->isTypeContext()
3391+
? MacroRole::Declaration
3392+
: getFreestandingMacroRoles()));
33913393
}
33923394

33933395
/// parseExprCollection - Parse a collection literal expression.

lib/Parse/ParseRequests.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,13 @@ SourceFileParsingResult ParseSourceFileRequest::evaluate(Evaluator &evaluator,
173173

174174
switch (generatedInfo->kind) {
175175
case GeneratedSourceInfo::FreestandingDeclMacroExpansion:
176+
if (parser.CurDeclContext->isTypeContext()) {
177+
parser.parseExpandedMemberList(items);
178+
} else {
179+
parser.parseTopLevelItems(items);
180+
}
181+
break;
182+
176183
case GeneratedSourceInfo::ExpressionMacroExpansion:
177184
case GeneratedSourceInfo::ReplacedFunctionBody:
178185
case GeneratedSourceInfo::PrettyPrinted: {

lib/SILGen/SILGen.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,8 +1792,7 @@ void SILGenModule::visitMacroDecl(MacroDecl *d) {
17921792
}
17931793

17941794
void SILGenModule::visitMacroExpansionDecl(MacroExpansionDecl *d) {
1795-
// Expanded declaration macros were already added to the parent decl context
1796-
// for name lookup to work. Nothing to be done here.
1795+
// Expanded declaration macros were already visited
17971796
}
17981797

17991798
bool

lib/Sema/CSApply.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5365,16 +5365,23 @@ namespace {
53655365
ConcreteDeclRef macroRef = resolveConcreteDeclRef(macro, locator);
53665366
E->setMacroRef(macroRef);
53675367

5368-
// For now, only expand macro expansion expressions that fulfill
5369-
// `MacroRole::Expression` exactly. Freestanding code item macros
5370-
// have a `getMacroRoles()` value equal to `getFreestandingMacroRoles()`,
5371-
// which includes expression macros, and they are expanded in a separate
5372-
// request.
5373-
if (E->getMacroRoles() == MacroRole::Expression &&
5374-
!cs.Options.contains(ConstraintSystemFlags::DisableMacroExpansions)) {
5375-
if (auto newExpr = expandMacroExpr(dc, E, macroRef, expandedType)) {
5376-
E->setRewritten(newExpr);
5368+
if (!cs.Options.contains(ConstraintSystemFlags::DisableMacroExpansions)) {
5369+
if (macro->getMacroRoles().contains(MacroRole::Expression)) {
5370+
if (auto newExpr = expandMacroExpr(dc, E, macroRef, expandedType)) {
5371+
E->setRewritten(newExpr);
5372+
}
5373+
}
5374+
// For a non-expression macro, expand it as a declaration.
5375+
else if (macro->getMacroRoles().contains(MacroRole::Declaration)) {
5376+
if (!E->getSubstituteDecl()) {
5377+
auto *med = E->createSubstituteDecl();
5378+
E->setSubstituteDecl(med);
5379+
TypeChecker::typeCheckDecl(med);
5380+
}
5381+
cs.setType(E, cs.getASTContext().getVoidType());
53775382
}
5383+
// Other macro roles may also be encountered here, as they use
5384+
// `MacroExpansionExpr` for resolution. In those cases, do not expand.
53785385
}
53795386

53805387
cs.cacheExprTypes(E);

lib/Sema/MiscDiagnostics.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include "TypeCheckAvailability.h"
1919
#include "TypeCheckConcurrency.h"
2020
#include "TypeChecker.h"
21-
#include "swift/AST/ASTScope.h"
2221
#include "swift/AST/ASTWalker.h"
2322
#include "swift/AST/DiagnosticsSema.h"
2423
#include "swift/AST/ExistentialLayout.h"
@@ -3708,8 +3707,8 @@ ASTWalker::PreWalkResult<Expr *> VarDeclUsageChecker::walkToExprPre(Expr *E) {
37083707
return Action::SkipChildren(E);
37093708
}
37103709

3711-
// FIXME: `MacroExpansionDecl` may expand to a `MacroExpansionExpr` with the
3712-
// same argument expressions.
3710+
// TODO: `MacroExpansionExpr` may have a substitute `MacroExpansionDecl` with
3711+
// the same argument expressions. How should we assert here?
37133712
// assert(AllExprsSeen.insert(E).second && "duplicate traversal");
37143713

37153714
// If this is a DeclRefExpr found in a random place, it is a load of the

lib/Sema/TypeCheckDecl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1617,7 +1617,9 @@ TypeChecker::lookupMacros(DeclContext *dc, DeclNameRef macroName,
16171617
for (const auto &found : lookup.allResults()) {
16181618
if (auto macro = dyn_cast<MacroDecl>(found.getValueDecl())) {
16191619
auto candidateRoles = macro->getMacroRoles();
1620-
if (candidateRoles && roles.contains(candidateRoles)) {
1620+
if ((candidateRoles && roles.contains(candidateRoles)) ||
1621+
// FIXME: `externalMacro` should have all roles.
1622+
macro->getBaseIdentifier().str() == "externalMacro") {
16211623
foundRoles |= candidateRoles;
16221624
results.push_back(macro);
16231625
}

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 6 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,23 +2054,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
20542054
}
20552055

20562056
void visitMacroExpansionDecl(MacroExpansionDecl *MED) {
2057+
// Expansion already visited as auxiliary decls.
20572058
// Assign a discriminator.
20582059
(void)MED->getDiscriminator();
2059-
2060-
auto *args = MED->getArgs();
2061-
for (auto argIndex : range(args->size())) {
2062-
auto expr = args->getExpr(argIndex);
2063-
TypeChecker::typeCheckExpression(expr, MED->getDeclContext());
2064-
args->setExpr(argIndex, expr);
2065-
}
2066-
2067-
for (auto node : MED->getRewritten()) {
2068-
if (auto *decl = node.dyn_cast<Decl *>()) {
2069-
if (auto *tlcd = dyn_cast<TopLevelCodeDecl>(decl))
2070-
continue; // Already handled.
2071-
visit(decl);
2072-
}
2073-
}
20742060
}
20752061

20762062
void visitBoundVariable(VarDecl *VD) {
@@ -3779,14 +3765,6 @@ ExpandMacroExpansionDeclRequest::evaluate(Evaluator &evaluator,
37793765
MacroExpansionDecl *MED) const {
37803766
auto &ctx = MED->getASTContext();
37813767
auto *dc = MED->getDeclContext();
3782-
MacroRoles viableRoles(MacroRole::Declaration);
3783-
3784-
// In a code block context, a macro expansion decl can also expand to an
3785-
// arbitrary code item.
3786-
if (dc->isLocalContext() ||
3787-
dc->getContextKind() == DeclContextKind::FileUnit) {
3788-
viableRoles |= MacroRole::Expression;
3789-
}
37903768

37913769
// Resolve macro candidates.
37923770
auto macro = evaluateOrDefault(
@@ -3796,31 +3774,11 @@ ExpandMacroExpansionDeclRequest::evaluate(Evaluator &evaluator,
37963774
MED->setMacroRef(macro);
37973775

37983776
auto roles = macro->getMacroRoles();
3799-
3800-
// If the resolved macro is an expression-only macro, expand to a macro
3801-
// expansion expr.
3802-
if (roles.containsOnly(MacroRole::Expression)) {
3803-
// Make an equivalent `MacroExpansionExpr` as the expansion.
3804-
Expr *mee = MED->createExpr();
3805-
ASTNode expansionNode;
3806-
3807-
// If top-level, wrap it in a `TopLevelCodeDecl(BraceStmt(...))`.
3808-
if (dc->getContextKind() == DeclContextKind::FileUnit) {
3809-
auto *tlcd = new (ctx) TopLevelCodeDecl(
3810-
dc, BraceStmt::createImplicit(ctx, {mee}));
3811-
tlcd->setDeclContext(dc);
3812-
TypeChecker::typeCheckTopLevelCodeDecl(tlcd);
3813-
TypeChecker::contextualizeTopLevelCode(tlcd);
3814-
expansionNode = tlcd;
3815-
}
3816-
else {
3817-
TypeChecker::typeCheckExpression(
3818-
mee, dc, {}, TypeCheckExprFlags::IsDiscarded);
3819-
TypeChecker::postTypeCheckMacroExpansion(mee, dc);
3820-
expansionNode = mee;
3821-
}
3822-
return ctx.AllocateCopy(ArrayRef<ASTNode>{expansionNode});
3823-
}
3777+
// If it's not a declaration macro or a code item macro, it must have been
3778+
// parsed as an expression macro, and this decl is just its substitute decl.
3779+
// So there's no thing to be done here.
3780+
if (!roles.contains(MacroRole::Declaration))
3781+
return {};
38243782

38253783
// Otherwise, we treat it as a declaration macro.
38263784
assert(roles.contains(MacroRole::Declaration));

lib/Sema/TypeCheckEffects.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,10 +1566,6 @@ class Context {
15661566
return Context(closureTypeThrows, closureTypeIsAsync, AnyFunctionRef(E));
15671567
}
15681568

1569-
static Context forMacroExpansion(MacroExpansionExpr *E) {
1570-
return Context(/*handlesErrors*/ true, /*handlesAsync*/ true, None);
1571-
}
1572-
15731569
static Context forCatchPattern(CaseStmt *S) {
15741570
return Context(Kind::CatchPattern);
15751571
}
@@ -3019,19 +3015,6 @@ void TypeChecker::checkPropertyWrapperEffects(
30193015
expr->walk(LocalFunctionEffectsChecker());
30203016
}
30213017

3022-
void TypeChecker::checkMacroExpansionEffects(DeclContext *DC,
3023-
MacroExpansionExpr *E) {
3024-
auto &ctx = DC->getASTContext();
3025-
CheckEffectsCoverage checker(ctx, Context::forMacroExpansion(E));
3026-
if (auto *rewritten = E->getRewritten()) {
3027-
rewritten->walk(checker);
3028-
rewritten->walk(LocalFunctionEffectsChecker());
3029-
}
3030-
// In some language modes, we allow top-level code to omit 'try' marking.
3031-
if (ctx.LangOpts.EnableThrowWithoutTry && isa<TopLevelCodeDecl>(DC))
3032-
checker.setTopLevelThrowWithoutTry();
3033-
}
3034-
30353018
bool TypeChecker::canThrow(Expr *expr) {
30363019
ApplyClassifier classifier;
30373020
auto effect = classifier.classifyExpr(expr, EffectKind::Throws);

0 commit comments

Comments
 (0)