Skip to content

Commit 446bf5c

Browse files
committed
[Macros] Support module-qualified macro lookup
Allow both attached and freestanding macro expansion syntax to have a module qualifier, i.e. `#Foo.Bar` and `@Foo.Bar`. rdar://108621205
1 parent 4d8dab0 commit 446bf5c

19 files changed

+258
-64
lines changed

include/swift/AST/Decl.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8591,6 +8591,8 @@ class MacroDecl : public GenericContext, public ValueDecl {
85918591
/// declaration/expression nodes.
85928592
struct MacroExpansionInfo : ASTAllocated<MacroExpansionInfo> {
85938593
SourceLoc SigilLoc;
8594+
DeclNameRef ModuleName;
8595+
DeclNameLoc ModuleNameLoc;
85948596
DeclNameRef MacroName;
85958597
DeclNameLoc MacroNameLoc;
85968598
SourceLoc LeftAngleLoc, RightAngleLoc;
@@ -8601,12 +8603,15 @@ struct MacroExpansionInfo : ASTAllocated<MacroExpansionInfo> {
86018603
ConcreteDeclRef macroRef;
86028604

86038605
MacroExpansionInfo(SourceLoc sigilLoc,
8606+
DeclNameRef moduleName,
8607+
DeclNameLoc moduleNameLoc,
86048608
DeclNameRef macroName,
86058609
DeclNameLoc macroNameLoc,
86068610
SourceLoc leftAngleLoc, SourceLoc rightAngleLoc,
86078611
ArrayRef<TypeRepr *> genericArgs,
86088612
ArgumentList *argList)
8609-
: SigilLoc(sigilLoc), MacroName(macroName), MacroNameLoc(macroNameLoc),
8613+
: SigilLoc(sigilLoc), ModuleName(moduleName), ModuleNameLoc(moduleNameLoc),
8614+
MacroName(macroName), MacroNameLoc(macroNameLoc),
86108615
LeftAngleLoc(leftAngleLoc), RightAngleLoc(rightAngleLoc),
86118616
GenericArgs(genericArgs), ArgList(argList) { }
86128617
};
@@ -8619,8 +8624,9 @@ class MacroExpansionDecl : public Decl {
86198624

86208625
MacroExpansionDecl(DeclContext *dc, MacroExpansionInfo *info);
86218626

8622-
MacroExpansionDecl(DeclContext *dc, SourceLoc poundLoc, DeclNameRef macro,
8623-
DeclNameLoc macroLoc,
8627+
MacroExpansionDecl(DeclContext *dc, SourceLoc poundLoc,
8628+
DeclNameRef moduleName, DeclNameLoc moduleNameLoc,
8629+
DeclNameRef macroName, DeclNameLoc macroNameLoc,
86248630
SourceLoc leftAngleLoc,
86258631
ArrayRef<TypeRepr *> genericArgs,
86268632
SourceLoc rightAngleLoc,
@@ -8637,6 +8643,8 @@ class MacroExpansionDecl : public Decl {
86378643
SourceRange getSourceRange() const;
86388644
SourceLoc getLocFromSource() const { return info->SigilLoc; }
86398645
SourceLoc getPoundLoc() const { return info->SigilLoc; }
8646+
DeclNameLoc getModuleNameLoc() const { return info->ModuleNameLoc; }
8647+
DeclNameRef getModuleMacroName() const { return info->ModuleName; }
86408648
DeclNameLoc getMacroNameLoc() const { return info->MacroNameLoc; }
86418649
DeclNameRef getMacroName() const { return info->MacroName; }
86428650
ArgumentList *getArgs() const { return info->ArgList; }

include/swift/AST/Expr.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6208,7 +6208,10 @@ class MacroExpansionExpr final : public Expr {
62086208
}
62096209

62106210
explicit MacroExpansionExpr(DeclContext *dc,
6211-
SourceLoc sigilLoc, DeclNameRef macroName,
6211+
SourceLoc sigilLoc,
6212+
DeclNameRef moduleName,
6213+
DeclNameLoc moduleNameLoc,
6214+
DeclNameRef macroName,
62126215
DeclNameLoc macroNameLoc,
62136216
SourceLoc leftAngleLoc,
62146217
ArrayRef<TypeRepr *> genericArgs,
@@ -6218,6 +6221,8 @@ class MacroExpansionExpr final : public Expr {
62186221
bool isImplicit = false,
62196222
Type ty = Type());
62206223

6224+
DeclNameRef getModuleName() const { return info->ModuleName; }
6225+
DeclNameLoc getModuleNameLoc() const { return info->ModuleNameLoc; }
62216226
DeclNameRef getMacroName() const { return info->MacroName; }
62226227
DeclNameLoc getMacroNameLoc() const { return info->MacroNameLoc; }
62236228

include/swift/AST/TypeCheckRequests.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3226,6 +3226,8 @@ class UnresolvedMacroReference {
32263226
}
32273227

32283228
SourceLoc getSigilLoc() const;
3229+
DeclNameRef getModuleName() const;
3230+
DeclNameLoc getModuleNameLoc() const;
32293231
DeclNameRef getMacroName() const;
32303232
DeclNameLoc getMacroNameLoc() const;
32313233
SourceRange getGenericArgsRange() const;

lib/AST/Decl.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10559,14 +10559,15 @@ MacroExpansionDecl::MacroExpansionDecl(
1055910559
}
1056010560

1056110561
MacroExpansionDecl::MacroExpansionDecl(
10562-
DeclContext *dc, SourceLoc poundLoc, DeclNameRef macro,
10563-
DeclNameLoc macroLoc, SourceLoc leftAngleLoc,
10562+
DeclContext *dc, SourceLoc poundLoc, DeclNameRef moduleName,
10563+
DeclNameLoc moduleNameLoc, DeclNameRef macroName,
10564+
DeclNameLoc macroNameLoc, SourceLoc leftAngleLoc,
1056410565
ArrayRef<TypeRepr *> genericArgs, SourceLoc rightAngleLoc,
1056510566
ArgumentList *args
1056610567
) : Decl(DeclKind::MacroExpansion, dc) {
1056710568
ASTContext &ctx = dc->getASTContext();
1056810569
info = new (ctx) MacroExpansionInfo{
10569-
poundLoc, macro, macroLoc,
10570+
poundLoc, moduleName, moduleNameLoc, macroName, macroNameLoc,
1057010571
leftAngleLoc, rightAngleLoc, genericArgs,
1057110572
args ? args : ArgumentList::createImplicit(ctx, {})
1057210573
};

lib/AST/Expr.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2713,7 +2713,8 @@ TypeJoinExpr::forBranchesOfSingleValueStmtExpr(ASTContext &ctx, Type joinType,
27132713
}
27142714

27152715
MacroExpansionExpr::MacroExpansionExpr(
2716-
DeclContext *dc, SourceLoc sigilLoc, DeclNameRef macroName,
2716+
DeclContext *dc, SourceLoc sigilLoc, DeclNameRef moduleName,
2717+
DeclNameLoc moduleNameLoc, DeclNameRef macroName,
27172718
DeclNameLoc macroNameLoc, SourceLoc leftAngleLoc,
27182719
ArrayRef<TypeRepr *> genericArgs, SourceLoc rightAngleLoc,
27192720
ArgumentList *argList, MacroRoles roles, bool isImplicit,
@@ -2722,7 +2723,7 @@ MacroExpansionExpr::MacroExpansionExpr(
27222723
Rewritten(nullptr), Roles(roles), SubstituteDecl(nullptr) {
27232724
ASTContext &ctx = dc->getASTContext();
27242725
info = new (ctx) MacroExpansionInfo{
2725-
sigilLoc, macroName, macroNameLoc,
2726+
sigilLoc, moduleName, moduleNameLoc, macroName, macroNameLoc,
27262727
leftAngleLoc, rightAngleLoc, genericArgs,
27272728
argList ? argList : ArgumentList::createImplicit(ctx, {})
27282729
};

lib/AST/NameLookup.cpp

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3269,15 +3269,51 @@ GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) c
32693269

32703270
void swift::findMacroForCustomAttr(CustomAttr *attr, DeclContext *dc,
32713271
llvm::TinyPtrVector<ValueDecl *> &macros) {
3272-
auto *identTypeRepr = dyn_cast_or_null<IdentTypeRepr>(attr->getTypeRepr());
3273-
if (!identTypeRepr)
3274-
return;
3275-
32763272
// Look for macros at module scope. They can only occur at module scope, and
32773273
// we need to be sure not to trigger name lookup into type contexts along
32783274
// the way.
32793275
auto moduleScopeDC = dc->getModuleScopeContext();
32803276
ASTContext &ctx = moduleScopeDC->getASTContext();
3277+
3278+
// Handle a module-qualified name.
3279+
if (auto *memTypeRepr = dyn_cast_or_null<MemberTypeRepr>(attr->getTypeRepr())) {
3280+
auto baseTypeRepr = memTypeRepr->getBaseComponent();
3281+
auto *moduleNameRepr = dyn_cast<IdentTypeRepr>(baseTypeRepr);
3282+
auto memberReprs = memTypeRepr->getMemberComponents();
3283+
if (!moduleNameRepr || memberReprs.size() != 1)
3284+
return;
3285+
auto moduleName = moduleNameRepr->getNameRef();
3286+
auto *macroNameRepr = dyn_cast<IdentTypeRepr>(memberReprs.front());
3287+
if (!macroNameRepr)
3288+
return;
3289+
auto macroName = macroNameRepr->getNameRef();
3290+
3291+
UnqualifiedLookupDescriptor moduleLookupDesc(
3292+
moduleName, moduleScopeDC, SourceLoc(),
3293+
UnqualifiedLookupFlags::TypeLookup);
3294+
auto moduleLookup = evaluateOrDefault(
3295+
ctx.evaluator, UnqualifiedLookupRequest{moduleLookupDesc}, {});
3296+
auto foundTypeDecl = moduleLookup.getSingleTypeResult();
3297+
auto *moduleDecl = dyn_cast_or_null<ModuleDecl>(foundTypeDecl);
3298+
if (!moduleDecl)
3299+
return;
3300+
3301+
ModuleQualifiedLookupRequest req{
3302+
moduleScopeDC, moduleDecl, macroName, NL_ExcludeMacroExpansions};
3303+
auto lookup = evaluateOrDefault(ctx.evaluator, req, {});
3304+
for (auto *found : lookup)
3305+
// Only keep attached macros, which can be spelled as custom attributes.
3306+
if (auto macro = dyn_cast<MacroDecl>(found))
3307+
if (isAttachedMacro(macro->getMacroRoles()))
3308+
macros.push_back(macro);
3309+
return;
3310+
}
3311+
3312+
// Handle an unqualified name.
3313+
auto *identTypeRepr = dyn_cast_or_null<IdentTypeRepr>(attr->getTypeRepr());
3314+
if (!identTypeRepr)
3315+
return;
3316+
32813317
UnqualifiedLookupDescriptor descriptor(
32823318
identTypeRepr->getNameRef(), moduleScopeDC
32833319
);

lib/AST/TypeCheckRequests.cpp

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,27 +1680,76 @@ void swift::simple_display(
16801680
// ResolveMacroRequest computation.
16811681
//----------------------------------------------------------------------------//
16821682

1683-
DeclNameRef UnresolvedMacroReference::getMacroName() const {
1683+
SourceLoc UnresolvedMacroReference::getSigilLoc() const {
1684+
if (auto *med = pointer.dyn_cast<MacroExpansionDecl *>())
1685+
return med->getPoundLoc();
1686+
if (auto *mee = pointer.dyn_cast<MacroExpansionExpr *>())
1687+
return mee->getLoc();
1688+
if (auto *attr = pointer.dyn_cast<CustomAttr *>())
1689+
return attr->getRangeWithAt().Start;
1690+
llvm_unreachable("Unhandled case");
1691+
}
1692+
1693+
/// Destructure a type repr for a macro reference.
1694+
///
1695+
/// For a 1-level member type repr whose base and member are both identifier
1696+
/// types, e.g. `Foo.Bar`, return a pair of the base and the member.
1697+
///
1698+
/// For an identifier type repr, return a pair of `nullptr` and the identifier.
1699+
static std::pair<IdentTypeRepr *, IdentTypeRepr *>
1700+
destructureMacroRefTypeRepr(TypeRepr *typeRepr) {
1701+
if (!typeRepr)
1702+
return {nullptr, nullptr};
1703+
if (auto *identType = dyn_cast<IdentTypeRepr>(typeRepr))
1704+
return {nullptr, identType};
1705+
if (auto *memType = dyn_cast<MemberTypeRepr>(typeRepr))
1706+
if (auto *base = dyn_cast<IdentTypeRepr>(memType->getBaseComponent()))
1707+
if (memType->getMemberComponents().size() == 1)
1708+
if (auto first = dyn_cast<IdentTypeRepr>(
1709+
memType->getMemberComponents().front()))
1710+
return {base, first};
1711+
return {nullptr, nullptr};
1712+
}
1713+
1714+
DeclNameRef UnresolvedMacroReference::getModuleName() const {
16841715
if (auto *med = pointer.dyn_cast<MacroExpansionDecl *>())
16851716
return med->getMacroName();
16861717
if (auto *mee = pointer.dyn_cast<MacroExpansionExpr *>())
16871718
return mee->getMacroName();
16881719
if (auto *attr = pointer.dyn_cast<CustomAttr *>()) {
1689-
auto *identTypeRepr = dyn_cast_or_null<IdentTypeRepr>(attr->getTypeRepr());
1690-
if (!identTypeRepr)
1720+
auto [base, _] = destructureMacroRefTypeRepr(attr->getTypeRepr());
1721+
if (!base)
16911722
return DeclNameRef();
1692-
return identTypeRepr->getNameRef();
1723+
return base->getNameRef();
16931724
}
16941725
llvm_unreachable("Unhandled case");
16951726
}
16961727

1697-
SourceLoc UnresolvedMacroReference::getSigilLoc() const {
1728+
DeclNameLoc UnresolvedMacroReference::getModuleNameLoc() const {
16981729
if (auto *med = pointer.dyn_cast<MacroExpansionDecl *>())
1699-
return med->getPoundLoc();
1730+
return med->getModuleNameLoc();
17001731
if (auto *mee = pointer.dyn_cast<MacroExpansionExpr *>())
1701-
return mee->getLoc();
1702-
if (auto *attr = pointer.dyn_cast<CustomAttr *>())
1703-
return attr->getRangeWithAt().Start;
1732+
return mee->getModuleNameLoc();
1733+
if (auto *attr = pointer.dyn_cast<CustomAttr *>()) {
1734+
auto [base, _] = destructureMacroRefTypeRepr(attr->getTypeRepr());
1735+
if (!base)
1736+
return DeclNameLoc();
1737+
return base->getNameLoc();
1738+
}
1739+
llvm_unreachable("Unhandled case");
1740+
}
1741+
1742+
DeclNameRef UnresolvedMacroReference::getMacroName() const {
1743+
if (auto *med = pointer.dyn_cast<MacroExpansionDecl *>())
1744+
return med->getMacroName();
1745+
if (auto *mee = pointer.dyn_cast<MacroExpansionExpr *>())
1746+
return mee->getMacroName();
1747+
if (auto *attr = pointer.dyn_cast<CustomAttr *>()) {
1748+
auto [_, member] = destructureMacroRefTypeRepr(attr->getTypeRepr());
1749+
if (!member)
1750+
return DeclNameRef();
1751+
return member->getNameRef();
1752+
}
17041753
llvm_unreachable("Unhandled case");
17051754
}
17061755

@@ -1710,10 +1759,10 @@ DeclNameLoc UnresolvedMacroReference::getMacroNameLoc() const {
17101759
if (auto *mee = pointer.dyn_cast<MacroExpansionExpr *>())
17111760
return mee->getMacroNameLoc();
17121761
if (auto *attr = pointer.dyn_cast<CustomAttr *>()) {
1713-
auto *identTypeRepr = dyn_cast_or_null<IdentTypeRepr>(attr->getTypeRepr());
1714-
if (!identTypeRepr)
1762+
auto [_, member] = destructureMacroRefTypeRepr(attr->getTypeRepr());
1763+
if (!member)
17151764
return DeclNameLoc();
1716-
return identTypeRepr->getNameLoc();
1765+
return member->getNameLoc();
17171766
}
17181767
llvm_unreachable("Unhandled case");
17191768
}

lib/Parse/ParseDecl.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9762,13 +9762,29 @@ ParserResult<MacroExpansionDecl>
97629762
Parser::parseDeclMacroExpansion(ParseDeclOptions flags,
97639763
DeclAttributes &attributes) {
97649764
SourceLoc poundLoc = consumeToken(tok::pound);
9765-
DeclNameLoc macroNameLoc;
9766-
DeclNameRef macroNameRef = parseDeclNameRef(
9767-
macroNameLoc, diag::macro_expansion_decl_expected_macro_identifier,
9765+
DeclNameLoc moduleNameLoc, macroNameLoc;
9766+
DeclNameRef moduleNameRef, macroNameRef;
9767+
9768+
DeclNameLoc firstNameLoc;
9769+
DeclNameRef firstNameRef = parseDeclNameRef(
9770+
firstNameLoc, diag::macro_expansion_decl_expected_macro_identifier,
97689771
DeclNameOptions());
9769-
if (!macroNameRef)
9772+
if (!firstNameRef)
97709773
return makeParserError();
97719774

9775+
if (consumeIf(tok::period)) {
9776+
moduleNameLoc = firstNameLoc;
9777+
moduleNameRef = firstNameRef;
9778+
macroNameRef = parseDeclNameRef(
9779+
macroNameLoc, diag::macro_expansion_decl_expected_macro_identifier,
9780+
DeclNameOptions());
9781+
if (!macroNameRef)
9782+
return makeParserError();
9783+
} else {
9784+
macroNameRef = firstNameRef;
9785+
macroNameLoc = firstNameLoc;
9786+
}
9787+
97729788
ParserStatus status;
97739789
SourceLoc leftAngleLoc, rightAngleLoc;
97749790
SmallVector<TypeRepr *, 8> genericArgs;
@@ -9806,7 +9822,7 @@ Parser::parseDeclMacroExpansion(ParseDeclOptions flags,
98069822
return makeParserResult(
98079823
status,
98089824
new (Context) MacroExpansionDecl(
9809-
CurDeclContext, poundLoc, macroNameRef, macroNameLoc,
9810-
leftAngleLoc, Context.AllocateCopy(genericArgs), rightAngleLoc,
9811-
argList));
9825+
CurDeclContext, poundLoc, moduleNameRef, moduleNameLoc, macroNameRef,
9826+
macroNameLoc, leftAngleLoc, Context.AllocateCopy(genericArgs),
9827+
rightAngleLoc, argList));
98129828
}

lib/Parse/ParseExpr.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3371,13 +3371,28 @@ Parser::parseExprCallSuffix(ParserResult<Expr> fn, bool isExprBasic) {
33713371

33723372
ParserResult<Expr> Parser::parseExprMacroExpansion(bool isExprBasic) {
33733373
SourceLoc poundLoc = consumeToken(tok::pound);
3374-
DeclNameLoc macroNameLoc;
3375-
DeclNameRef macroNameRef = parseDeclNameRef(
3376-
macroNameLoc, diag::macro_expansion_expr_expected_macro_identifier,
3374+
DeclNameRef moduleNameRef, macroNameRef;
3375+
DeclNameLoc moduleNameLoc, macroNameLoc;
3376+
DeclNameLoc firstNameLoc;
3377+
DeclNameRef firstNameRef = parseDeclNameRef(
3378+
firstNameLoc, diag::macro_expansion_expr_expected_macro_identifier,
33773379
DeclNameOptions());
3378-
if (!macroNameRef)
3380+
if (!firstNameRef)
33793381
return makeParserError();
33803382

3383+
if (consumeIf(tok::period)) {
3384+
moduleNameRef = firstNameRef;
3385+
moduleNameLoc = firstNameLoc;
3386+
macroNameRef = parseDeclNameRef(
3387+
macroNameLoc, diag::macro_expansion_expr_expected_macro_identifier,
3388+
DeclNameOptions());
3389+
if (!macroNameRef)
3390+
return makeParserError();
3391+
} else {
3392+
macroNameRef = firstNameRef;
3393+
macroNameLoc = firstNameLoc;
3394+
}
3395+
33813396
ParserStatus status;
33823397
SourceLoc leftAngleLoc, rightAngleLoc;
33833398
SmallVector<TypeRepr *, 8> genericArgs;
@@ -3413,8 +3428,9 @@ ParserResult<Expr> Parser::parseExprMacroExpansion(bool isExprBasic) {
34133428
return makeParserResult(
34143429
status,
34153430
new (Context) MacroExpansionExpr(
3416-
CurDeclContext, poundLoc, macroNameRef, macroNameLoc, leftAngleLoc,
3417-
Context.AllocateCopy(genericArgs), rightAngleLoc, argList,
3431+
CurDeclContext, poundLoc, moduleNameRef, moduleNameLoc, macroNameRef,
3432+
macroNameLoc, leftAngleLoc, Context.AllocateCopy(genericArgs),
3433+
rightAngleLoc, argList,
34183434
CurDeclContext->isTypeContext()
34193435
? MacroRole::Declaration
34203436
: getFreestandingMacroRoles()));

lib/Sema/CSApply.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2938,9 +2938,10 @@ namespace {
29382938
auto macro = cast<MacroDecl>(overload.choice.getDecl());
29392939
ConcreteDeclRef macroRef = resolveConcreteDeclRef(macro, locator);
29402940
auto expansion = new (ctx) MacroExpansionExpr(
2941-
dc, expr->getStartLoc(), DeclNameRef(macro->getName()),
2942-
DeclNameLoc(expr->getLoc()), SourceLoc(), {}, SourceLoc(), nullptr,
2943-
MacroRole::Expression, /*isImplicit=*/true, expandedType);
2941+
dc, expr->getStartLoc(), DeclNameRef(), DeclNameLoc(),
2942+
DeclNameRef(macro->getName()), DeclNameLoc(expr->getLoc()),
2943+
SourceLoc(), {}, SourceLoc(), nullptr, MacroRole::Expression,
2944+
/*isImplicit=*/true, expandedType);
29442945
expansion->setMacroRef(macroRef);
29452946
(void)evaluateOrDefault(
29462947
ctx.evaluator, ExpandMacroExpansionExprRequest{expansion}, None);

0 commit comments

Comments
 (0)