Skip to content

Commit 7338e00

Browse files
committed
[Macros] Suppress lookups into macro expansions in direct lookup in types/extensions
Eliminate a source of cyclic dependencies by not expanding macros when we are resolving macro arguments within a type or extension context. This extends the scheme introduced for module-scope lookup to also apply to lookup within types.
1 parent 3b7bc6e commit 7338e00

File tree

4 files changed

+48
-12
lines changed

4 files changed

+48
-12
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3835,6 +3835,8 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
38353835
/// Whether to include @_implements members.
38363836
/// Used by conformance-checking to find special @_implements members.
38373837
IncludeAttrImplements = 1 << 0,
3838+
/// Whether to exclude members of macro expansions.
3839+
ExcludeMacroExpansions = 1 << 1,
38383840
};
38393841

38403842
/// Find all of the declarations with the given name within this nominal type

lib/AST/NameLookup.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,13 +1713,24 @@ void NominalTypeDecl::prepareLookupTable() {
17131713
}
17141714

17151715
static TinyPtrVector<ValueDecl *>
1716-
maybeFilterOutAttrImplements(TinyPtrVector<ValueDecl *> decls,
1717-
DeclName name,
1718-
bool includeAttrImplements) {
1719-
if (includeAttrImplements)
1716+
maybeFilterOutUnwantedDecls(TinyPtrVector<ValueDecl *> decls,
1717+
DeclName name,
1718+
bool includeAttrImplements,
1719+
bool excludeMacroExpansions) {
1720+
if (includeAttrImplements && !excludeMacroExpansions)
17201721
return decls;
17211722
TinyPtrVector<ValueDecl*> result;
17221723
for (auto V : decls) {
1724+
// If we're supposed to exclude anything that comes from a macro expansion,
1725+
// check whether the source location of the declaration is in a macro
1726+
// expansion, and skip this declaration if it does.
1727+
if (excludeMacroExpansions) {
1728+
auto sourceFile =
1729+
V->getModuleContext()->getSourceFileContainingLocation(V->getLoc());
1730+
if (sourceFile && sourceFile->Kind == SourceFileKind::MacroExpansion)
1731+
continue;
1732+
}
1733+
17231734
// Filter-out any decl that doesn't have the name we're looking for
17241735
// (asserting as a consistency-check that such entries all have
17251736
// @_implements attrs for the name!)
@@ -1755,12 +1766,16 @@ DirectLookupRequest::evaluate(Evaluator &evaluator,
17551766
decl->hasLazyMembers());
17561767
const bool includeAttrImplements =
17571768
flags.contains(NominalTypeDecl::LookupDirectFlags::IncludeAttrImplements);
1769+
const bool excludeMacroExpansions =
1770+
flags.contains(NominalTypeDecl::LookupDirectFlags::ExcludeMacroExpansions);
17581771

17591772
LLVM_DEBUG(llvm::dbgs() << decl->getNameStr() << ".lookupDirect("
17601773
<< name << ")"
17611774
<< ", hasLazyMembers()=" << decl->hasLazyMembers()
17621775
<< ", useNamedLazyMemberLoading="
17631776
<< useNamedLazyMemberLoading
1777+
<< ", excludeMacroExpansions="
1778+
<< excludeMacroExpansions
17641779
<< "\n");
17651780

17661781
decl->prepareLookupTable();
@@ -1797,8 +1812,9 @@ DirectLookupRequest::evaluate(Evaluator &evaluator,
17971812
if (!allFound.empty()) {
17981813
auto known = Table.find(name);
17991814
if (known != Table.end()) {
1800-
auto swiftLookupResult = maybeFilterOutAttrImplements(
1801-
known->second, name, includeAttrImplements);
1815+
auto swiftLookupResult = maybeFilterOutUnwantedDecls(
1816+
known->second, name, includeAttrImplements,
1817+
excludeMacroExpansions);
18021818
for (auto foundSwiftDecl : swiftLookupResult) {
18031819
allFound.push_back(foundSwiftDecl);
18041820
}
@@ -1828,7 +1844,8 @@ DirectLookupRequest::evaluate(Evaluator &evaluator,
18281844
}
18291845

18301846
DeclName macroExpansionKey = adjustLazyMacroExpansionNameKey(ctx, name);
1831-
if (!Table.isLazilyCompleteForMacroExpansion(macroExpansionKey)) {
1847+
if (!excludeMacroExpansions &&
1848+
!Table.isLazilyCompleteForMacroExpansion(macroExpansionKey)) {
18321849
populateLookupTableEntryFromMacroExpansions(
18331850
ctx, Table, macroExpansionKey, decl);
18341851
for (auto ext : decl->getExtensions()) {
@@ -1845,8 +1862,9 @@ DirectLookupRequest::evaluate(Evaluator &evaluator,
18451862
}
18461863

18471864
// We found something; return it.
1848-
return maybeFilterOutAttrImplements(known->second, name,
1849-
includeAttrImplements);
1865+
return maybeFilterOutUnwantedDecls(known->second, name,
1866+
includeAttrImplements,
1867+
excludeMacroExpansions);
18501868
}
18511869

18521870
bool NominalTypeDecl::createObjCMethodLookup() {
@@ -2201,6 +2219,8 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
22012219
auto flags = OptionSet<NominalTypeDecl::LookupDirectFlags>();
22022220
if (options & NL_IncludeAttributeImplements)
22032221
flags |= NominalTypeDecl::LookupDirectFlags::IncludeAttrImplements;
2222+
if (options & NL_ExcludeMacroExpansions)
2223+
flags |= NominalTypeDecl::LookupDirectFlags::ExcludeMacroExpansions;
22042224
for (auto decl : current->lookupDirect(member.getFullName(), flags)) {
22052225
// If we're performing a type lookup, don't even attempt to validate
22062226
// the decl if its not a type.

lib/AST/NameLookupRequests.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -555,8 +555,17 @@ static UnqualifiedLookupDescriptor excludeMacrosIfNeeded(
555555
/// Exclude macros in the direct lookup descriptor if we need to.
556556
static DirectLookupDescriptor excludeMacrosIfNeeded(
557557
DirectLookupDescriptor descriptor) {
558-
// FIXME: Direct lookups don't currently have an "exclude macro expansions"
559-
// flag.
558+
if (descriptor.Options.contains(
559+
NominalTypeDecl::LookupDirectFlags::ExcludeMacroExpansions))
560+
return descriptor;
561+
562+
auto &evaluator = descriptor.DC->getASTContext().evaluator;
563+
if (!evaluator.hasActiveResolveMacroRequest())
564+
return descriptor;
565+
566+
descriptor.Options |=
567+
NominalTypeDecl::LookupDirectFlags::ExcludeMacroExpansions;
568+
560569
return descriptor;
561570
}
562571

test/Macros/macro_expand.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,10 @@ _ = StructWithUnqualifiedLookup().foo()
282282
func testFreestandingMacroExpansion() {
283283
// Explicit structs to force macros to be parsed as decl.
284284
struct Foo {
285+
static let singleton = Foo()
286+
287+
static let s2 = Foo.singleton
288+
285289
#bitwidthNumberedStructs("MyIntOne")
286290
}
287291

@@ -341,9 +345,10 @@ func testFreestandingMacroExpansion() {
341345
testFreestandingMacroExpansion()
342346

343347
// Explicit structs to force macros to be parsed as decl.
348+
var globalBool = true
344349
struct ContainerOfNumberedStructs {
345350
#bitwidthNumberedStructs("MyIntOne")
346-
#bitwidthNumberedStructs("MyIntTwo")
351+
#bitwidthNumberedStructs("MyIntTwo", blah: globalBool)
347352
}
348353

349354
// Avoid re-type-checking declaration macro arguments.

0 commit comments

Comments
 (0)