Skip to content

Commit f0f74e6

Browse files
committed
[Macros] Don't allow types to shadow freestanding macros.
When performing name lookup for freestanding macros (e.g., after the `#`), don't allow types to shadow macros from imported libraries. Fixes rdar://110429368.
1 parent 1d88dca commit f0f74e6

File tree

7 files changed

+68
-9
lines changed

7 files changed

+68
-9
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/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: 21 additions & 4 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.
@@ -4027,6 +4043,7 @@ void swift::simple_display(llvm::raw_ostream &out, NLOptions options) {
40274043
FLAG(NL_RemoveOverridden)
40284044
FLAG(NL_IgnoreAccessControl)
40294045
FLAG(NL_OnlyTypes)
4046+
FLAG(NL_OnlyMacros)
40304047
FLAG(NL_IncludeAttributeImplements)
40314048
#undef FLAG
40324049
};

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/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)