Skip to content

Commit a0d5234

Browse files
authored
Merge pull request swiftlang#67513 from DougGregor/freestanding-macros-step-into-the-light
2 parents 106f434 + 7d9b304 commit a0d5234

File tree

9 files changed

+76
-44
lines changed

9 files changed

+76
-44
lines changed

include/swift/AST/LookupKinds.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ enum NLOptions : unsigned {
5656
/// Exclude names introduced by macro expansions in the top-level module.
5757
NL_ExcludeMacroExpansions = 1 << 7,
5858

59+
/// This lookup should only return macro declarations.
60+
NL_OnlyMacros = 1 << 8,
61+
5962
/// The default set of options used for qualified name lookup.
6063
///
6164
/// FIXME: Eventually, add NL_ProtocolMembers to this, once all of the

include/swift/AST/MacroDeclaration.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,6 @@ StringRef getMacroIntroducedDeclNameString(
116116

117117
class CustomAttr;
118118

119-
/// Perform lookup to determine whether the given custom attribute refers to
120-
/// a macro declaration, and populate the \c macros vector with the lookup
121-
/// results that are attached macros.
122-
void findMacroForCustomAttr(CustomAttr *attr, DeclContext *dc,
123-
llvm::TinyPtrVector<ValueDecl *> &macros);
124-
125119
class MacroIntroducedDeclName {
126120
public:
127121
using Kind = MacroIntroducedDeclNameKind;

include/swift/AST/ModuleNameLookup.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ enum class ResolutionKind {
3636
Overloadable,
3737

3838
/// Lookup should match a single decl that declares a type.
39-
TypesOnly
39+
TypesOnly,
40+
41+
/// Lookup should only match macros.
42+
MacrosOnly,
4043
};
4144

4245
void simple_display(llvm::raw_ostream &out, ResolutionKind kind);

include/swift/AST/NameLookup.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ enum class UnqualifiedLookupFlags {
242242
IncludeUsableFromInline = 1 << 5,
243243
/// This lookup should exclude any names introduced by macro expansions.
244244
ExcludeMacroExpansions = 1 << 6,
245+
/// This lookup should only return macros.
246+
MacroLookup = 1 << 7,
245247
};
246248

247249
using UnqualifiedLookupOptions = OptionSet<UnqualifiedLookupFlags>;

lib/AST/ModuleNameLookup.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ void ModuleNameLookup<LookupStrategy>::lookupInModule(
162162
[&](ValueDecl *VD) {
163163
if (resolutionKind == ResolutionKind::TypesOnly && !isa<TypeDecl>(VD))
164164
return true;
165+
if (resolutionKind == ResolutionKind::MacrosOnly && !isa<MacroDecl>(VD))
166+
return true;
165167
if (respectAccessControl &&
166168
!VD->isAccessibleFrom(moduleScopeContext, false,
167169
includeUsableFromInline))
@@ -311,6 +313,9 @@ void namelookup::simple_display(llvm::raw_ostream &out, ResolutionKind kind) {
311313
case ResolutionKind::TypesOnly:
312314
out << "TypesOnly";
313315
return;
316+
case ResolutionKind::MacrosOnly:
317+
out << "MacrosOnly";
318+
return;
314319
}
315320
llvm_unreachable("Unhandled case in switch");
316321
}

lib/AST/NameLookup.cpp

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ void swift::simple_display(llvm::raw_ostream &out,
112112
{UnqualifiedLookupFlags::IgnoreAccessControl, "IgnoreAccessControl"},
113113
{UnqualifiedLookupFlags::IncludeOuterResults, "IncludeOuterResults"},
114114
{UnqualifiedLookupFlags::TypeLookup, "TypeLookup"},
115+
{UnqualifiedLookupFlags::MacroLookup, "MacroLookup"},
115116
};
116117

117118
auto flagsToPrint = llvm::make_filter_range(
@@ -1618,6 +1619,11 @@ namelookup::lookupMacros(DeclContext *dc, DeclNameRef macroName,
16181619
auto moduleScopeDC = dc->getModuleScopeContext();
16191620
ASTContext &ctx = moduleScopeDC->getASTContext();
16201621

1622+
// When performing lookup for freestanding macro roles, only consider
1623+
// macro names, ignoring types.
1624+
bool onlyMacros = static_cast<bool>(roles & getFreestandingMacroRoles()) &&
1625+
!(roles - getFreestandingMacroRoles());
1626+
16211627
// Macro lookup should always exclude macro expansions; macro
16221628
// expansions cannot introduce new macro declarations. Note that
16231629
// the source location here doesn't matter.
@@ -1626,8 +1632,12 @@ namelookup::lookupMacros(DeclContext *dc, DeclNameRef macroName,
16261632
UnqualifiedLookupFlags::ExcludeMacroExpansions
16271633
};
16281634

1635+
if (onlyMacros)
1636+
descriptor.Options |= UnqualifiedLookupFlags::MacroLookup;
1637+
16291638
auto lookup = evaluateOrDefault(
16301639
ctx.evaluator, UnqualifiedLookupRequest{descriptor}, {});
1640+
16311641
for (const auto &found : lookup.allResults()) {
16321642
if (auto macro = dyn_cast<MacroDecl>(found.getValueDecl())) {
16331643
auto candidateRoles = macro->getMacroRoles();
@@ -1638,6 +1648,7 @@ namelookup::lookupMacros(DeclContext *dc, DeclNameRef macroName,
16381648
}
16391649
}
16401650
}
1651+
16411652
return choices;
16421653
}
16431654

@@ -2408,6 +2419,11 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
24082419
if ((options & NL_OnlyTypes) && !isa<TypeDecl>(decl))
24092420
continue;
24102421

2422+
// If we're performing a macro lookup, don't even attempt to validate
2423+
// the decl if its not a macro.
2424+
if ((options & NL_OnlyMacros) && !isa<MacroDecl>(decl))
2425+
continue;
2426+
24112427
if (isAcceptableLookupResult(DC, options, decl, onlyCompleteObjectInits))
24122428
decls.push_back(decl);
24132429
}
@@ -2491,8 +2507,8 @@ ModuleQualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
24912507
using namespace namelookup;
24922508
QualifiedLookupResult decls;
24932509

2494-
auto kind = (options & NL_OnlyTypes
2495-
? ResolutionKind::TypesOnly
2510+
auto kind = (options & NL_OnlyTypes ? ResolutionKind::TypesOnly
2511+
: options & NL_OnlyMacros ? ResolutionKind::MacrosOnly
24962512
: ResolutionKind::Overloadable);
24972513
auto topLevelScope = DC->getModuleScopeContext();
24982514
if (module == topLevelScope->getParentModule()) {
@@ -2534,8 +2550,8 @@ AnyObjectLookupRequest::evaluate(Evaluator &evaluator, const DeclContext *dc,
25342550
using namespace namelookup;
25352551
QualifiedLookupResult decls;
25362552

2537-
// Type-only lookup won't find anything on AnyObject.
2538-
if (options & NL_OnlyTypes)
2553+
// Type-only and macro lookup won't find anything on AnyObject.
2554+
if (options & (NL_OnlyTypes | NL_OnlyMacros))
25392555
return decls;
25402556

25412557
// Collect all of the visible declarations.
@@ -3458,40 +3474,19 @@ GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) c
34583474
parsedGenericParams->getRAngleLoc());
34593475
}
34603476

3461-
void swift::findMacroForCustomAttr(CustomAttr *attr, DeclContext *dc,
3462-
llvm::TinyPtrVector<ValueDecl *> &macros) {
3463-
auto *identTypeRepr = dyn_cast_or_null<IdentTypeRepr>(attr->getTypeRepr());
3464-
if (!identTypeRepr)
3465-
return;
3466-
3467-
// Look for macros at module scope. They can only occur at module scope, and
3468-
// we need to be sure not to trigger name lookup into type contexts along
3469-
// the way.
3470-
auto moduleScopeDC = dc->getModuleScopeContext();
3471-
ASTContext &ctx = moduleScopeDC->getASTContext();
3472-
UnqualifiedLookupDescriptor descriptor(
3473-
identTypeRepr->getNameRef(), moduleScopeDC
3474-
);
3475-
auto lookup = evaluateOrDefault(
3476-
ctx.evaluator, UnqualifiedLookupRequest{descriptor}, {});
3477-
for (const auto &result : lookup.allResults()) {
3478-
// Only keep attached macros, which can be spelled as custom attributes.
3479-
if (auto macro = dyn_cast<MacroDecl>(result.getValueDecl()))
3480-
if (isAttachedMacro(macro->getMacroRoles()))
3481-
macros.push_back(macro);
3482-
}
3483-
}
3484-
34853477
NominalTypeDecl *
34863478
CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
34873479
CustomAttr *attr, DeclContext *dc) const {
34883480
// Look for names at module scope, so we don't trigger name lookup for
34893481
// nested scopes. At this point, we're looking to see whether there are
34903482
// any suitable macros.
3491-
llvm::TinyPtrVector<ValueDecl *> macros;
3492-
findMacroForCustomAttr(attr, dc, macros);
3493-
if (!macros.empty())
3494-
return nullptr;
3483+
if (auto *identTypeRepr =
3484+
dyn_cast_or_null<IdentTypeRepr>(attr->getTypeRepr())) {
3485+
auto macros = namelookup::lookupMacros(
3486+
dc, identTypeRepr->getNameRef(), getAttachedMacroRoles());
3487+
if (!macros.empty())
3488+
return nullptr;
3489+
}
34953490

34963491
// Find the types referenced by the custom attribute.
34973492
auto &ctx = dc->getASTContext();
@@ -4027,6 +4022,7 @@ void swift::simple_display(llvm::raw_ostream &out, NLOptions options) {
40274022
FLAG(NL_RemoveOverridden)
40284023
FLAG(NL_IgnoreAccessControl)
40294024
FLAG(NL_OnlyTypes)
4025+
FLAG(NL_OnlyMacros)
40304026
FLAG(NL_IncludeAttributeImplements)
40314027
#undef FLAG
40324028
};

lib/AST/UnqualifiedLookup.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ namespace {
106106

107107
const Options options;
108108
const bool isOriginallyTypeLookup;
109+
const bool isOriginallyMacroLookup;
109110
const NLOptions baseNLOptions;
110111

111112
// Outputs
@@ -167,7 +168,8 @@ namespace {
167168
#pragma mark common helper declarations
168169
static NLOptions
169170
computeBaseNLOptions(const UnqualifiedLookupOptions options,
170-
const bool isOriginallyTypeLookup);
171+
const bool isOriginallyTypeLookup,
172+
const bool isOriginallyMacroLookup);
171173

172174
void findResultsAndSaveUnavailables(
173175
const DeclContext *lookupContextForThisContext,
@@ -260,7 +262,10 @@ UnqualifiedLookupFactory::UnqualifiedLookupFactory(
260262
DebugClient(M.getDebugClient()),
261263
options(options),
262264
isOriginallyTypeLookup(options.contains(Flags::TypeLookup)),
263-
baseNLOptions(computeBaseNLOptions(options, isOriginallyTypeLookup)),
265+
isOriginallyMacroLookup(options.contains(Flags::MacroLookup)),
266+
baseNLOptions(
267+
computeBaseNLOptions(
268+
options, isOriginallyTypeLookup, isOriginallyMacroLookup)),
264269
Results(Results),
265270
IndexOfFirstOuterResult(IndexOfFirstOuterResult)
266271
{}
@@ -525,7 +530,8 @@ void UnqualifiedLookupFactory::addImportedResults(const DeclContext *const dc) {
525530
using namespace namelookup;
526531
SmallVector<ValueDecl *, 8> CurModuleResults;
527532
auto resolutionKind = isOriginallyTypeLookup ? ResolutionKind::TypesOnly
528-
: ResolutionKind::Overloadable;
533+
: isOriginallyMacroLookup ? ResolutionKind::MacrosOnly
534+
: ResolutionKind::Overloadable;
529535
auto nlOptions = NL_UnqualifiedDefault;
530536
if (options.contains(Flags::IncludeUsableFromInline))
531537
nlOptions |= NL_IncludeUsableFromInline;
@@ -619,12 +625,15 @@ void UnqualifiedLookupFactory::findResultsAndSaveUnavailables(
619625

620626
NLOptions UnqualifiedLookupFactory::computeBaseNLOptions(
621627
const UnqualifiedLookupOptions options,
622-
const bool isOriginallyTypeLookup) {
628+
const bool isOriginallyTypeLookup,
629+
const bool isOriginallyMacroLookup) {
623630
NLOptions baseNLOptions = NL_UnqualifiedDefault;
624631
if (options.contains(Flags::AllowProtocolMembers))
625632
baseNLOptions |= NL_ProtocolMembers;
626633
if (isOriginallyTypeLookup)
627634
baseNLOptions |= NL_OnlyTypes;
635+
if (isOriginallyMacroLookup)
636+
baseNLOptions |= NL_OnlyMacros;
628637
if (options.contains(Flags::IgnoreAccessControl))
629638
baseNLOptions |= NL_IgnoreAccessControl;
630639
return baseNLOptions;

test/IDE/complete_macro_declaration.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ macro expect(file: Int = #^DEFAULT_ARG^#) = #externalMacro(module: "MyModule", t
77
// DEFAULT_ARG: Decl[GlobalVar]/CurrModule/TypeRelation[Convertible]: globalVar[#Int#]; name=globalVar
88

99
@freestanding(expression)
10-
macro externalMacro() = ##^EXTERNAL_MACRO^#
10+
macro otherExternalMacro() = ##^EXTERNAL_MACRO^#
1111
// EXTERNAL_MACRO: Decl[Macro]/OtherModule[Swift]/IsSystem: externalMacro({#module: String#}, {#type: String#})[#T#]; name=externalMacro(module:type:)
1212

1313
@freestanding(expression)

test/Macros/macro_shadowing.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// REQUIRES: swift_swift_parser, executable_test
2+
3+
// RUN: %empty-directory(%t)
4+
5+
// Build macro implementations
6+
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath -swift-version 5
7+
8+
// Build library that declares macros
9+
// RUN: %target-swift-frontend -swift-version 5 -emit-module -o %t/freestanding_macro_library.swiftmodule %S/Inputs/freestanding_macro_library.swift -module-name freestanding_macro_library -load-plugin-library %t/%target-library-name(MacroDefinition)
10+
11+
//
12+
// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -I %t
13+
14+
import freestanding_macro_library
15+
16+
struct stringify<T> { }
17+
18+
func testStringify(a: Int, b: Int) {
19+
_ = #stringify(a + b)
20+
}

0 commit comments

Comments
 (0)