diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h index 456fa92a53dad..8f4a28ab2da87 100644 --- a/include/swift/AST/Module.h +++ b/include/swift/AST/Module.h @@ -629,6 +629,11 @@ inline bool DeclContext::isModuleScopeContext() const { return isModuleContext(); } +/// Extract the source location from the given module declaration. +inline SourceLoc extractNearestSourceLoc(const ModuleDecl *mod) { + return extractNearestSourceLoc(static_cast(mod)); +} + } // end namespace swift namespace llvm { diff --git a/include/swift/AST/NameLookupRequests.h b/include/swift/AST/NameLookupRequests.h index d1ed1fd5a06cd..47f7a96a82d1f 100644 --- a/include/swift/AST/NameLookupRequests.h +++ b/include/swift/AST/NameLookupRequests.h @@ -405,6 +405,45 @@ class AnyObjectLookupRequest NLOptions options) const; }; +class ModuleQualifiedLookupRequest + : public SimpleRequest { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + // Evaluation. + llvm::Expected evaluate(Evaluator &evaluator, + const DeclContext *DC, + ModuleDecl *mod, DeclNameRef name, + NLOptions opts) const; +}; + +class QualifiedLookupRequest + : public SimpleRequest, + DeclNameRef, NLOptions), + CacheKind::Uncached> { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + // Evaluation. + llvm::Expected + evaluate(Evaluator &evaluator, const DeclContext *DC, + SmallVector decls, + DeclNameRef name, + NLOptions opts) const; +}; + #define SWIFT_TYPEID_ZONE NameLookup #define SWIFT_TYPEID_HEADER "swift/AST/NameLookupTypeIDZone.def" #include "swift/Basic/DefineTypeIDZone.h" diff --git a/include/swift/AST/NameLookupTypeIDZone.def b/include/swift/AST/NameLookupTypeIDZone.def index c0cf8900243c5..df16be2b66aa1 100644 --- a/include/swift/AST/NameLookupTypeIDZone.def +++ b/include/swift/AST/NameLookupTypeIDZone.def @@ -15,6 +15,9 @@ // //===----------------------------------------------------------------------===// +SWIFT_REQUEST(NameLookup, AnyObjectLookupRequest, + QualifiedLookupResult(const DeclContext *, DeclName, NLOptions), + Uncached, NoLocationInfo) SWIFT_REQUEST(NameLookup, CustomAttrNominalRequest, NominalTypeDecl *(CustomAttr *, DeclContext *), Cached, NoLocationInfo) @@ -34,6 +37,20 @@ SWIFT_REQUEST(NameLookup, InheritedDeclsReferencedRequest, DirectlyReferencedTypeDecls( llvm::PointerUnion, unsigned), Uncached, HasNearestLocation) +SWIFT_REQUEST(NameLookup, LookupInModuleRequest, + QualifiedLookupResult(const DeclContext *, DeclName, NLKind, + namelookup::ResolutionKind, + const DeclContext *), + Uncached, NoLocationInfo) +SWIFT_REQUEST(NameLookup, ModuleQualifiedLookupRequest, + QualifiedLookupResult( + const DeclContext *, ModuleDecl *, DeclNameRef, NLOptions), + Uncached, NoLocationInfo) +SWIFT_REQUEST(NameLookup, QualifiedLookupRequest, + QualifiedLookupResult( + const DeclContext *, SmallVector, + DeclNameRef, NLOptions), + Uncached, NoLocationInfo) SWIFT_REQUEST(NameLookup, SelfBoundsFromWhereClauseRequest, SelfBounds(llvm::PointerUnion), Uncached, NoLocationInfo) @@ -48,11 +65,3 @@ SWIFT_REQUEST(NameLookup, UnderlyingTypeDeclsReferencedRequest, SWIFT_REQUEST(NameLookup, UnqualifiedLookupRequest, LookupResult(UnqualifiedLookupDescriptor), Uncached, NoLocationInfo) -SWIFT_REQUEST(NameLookup, LookupInModuleRequest, - QualifiedLookupResult(const DeclContext *, DeclName, NLKind, - namelookup::ResolutionKind, - const DeclContext *), - Uncached, NoLocationInfo) -SWIFT_REQUEST(NameLookup, AnyObjectLookupRequest, - QualifiedLookupResult(const DeclContext *, DeclName, NLOptions), - Uncached, NoLocationInfo) diff --git a/include/swift/Basic/Statistics.def b/include/swift/Basic/Statistics.def index 725c082b8d877..657568f3ea3a0 100644 --- a/include/swift/Basic/Statistics.def +++ b/include/swift/Basic/Statistics.def @@ -138,12 +138,6 @@ FRONTEND_STATISTIC(AST, NumPrefixOperators) /// Number of precedence groups in the AST context. FRONTEND_STATISTIC(AST, NumPrecedenceGroups) -/// Number of qualified lookups into a nominal type. -FRONTEND_STATISTIC(AST, NumLookupQualifiedInNominal) - -/// Number of qualified lookups into a module. -FRONTEND_STATISTIC(AST, NumLookupQualifiedInModule) - /// Number of local lookups into a module. FRONTEND_STATISTIC(AST, NumModuleLookupValue) diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp index afdcc0b40b313..48c4fdd102be2 100644 --- a/lib/AST/NameLookup.cpp +++ b/lib/AST/NameLookup.cpp @@ -1587,17 +1587,24 @@ bool DeclContext::lookupQualified(ArrayRef typeDecls, DeclNameRef member, NLOptions options, SmallVectorImpl &decls) const { - using namespace namelookup; assert(decls.empty() && "additive lookup not supported"); + QualifiedLookupRequest req{this, {typeDecls.begin(), typeDecls.end()}, + member, options}; + decls = evaluateOrDefault(getASTContext().evaluator, req, {}); + return !decls.empty(); +} - auto *stats = getASTContext().Stats; - if (stats) - stats->getFrontendCounters().NumLookupQualifiedInNominal++; +llvm::Expected +QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC, + SmallVector typeDecls, + DeclNameRef member, NLOptions options) const { + using namespace namelookup; + QualifiedLookupResult decls; // Configure lookup and dig out the tracker. ReferencedNameTracker *tracker = nullptr; bool isLookupCascading; - configureLookup(this, options, tracker, isLookupCascading); + configureLookup(DC, options, tracker, isLookupCascading); // Tracking for the nominal types we'll visit. SmallVector stack; @@ -1645,8 +1652,7 @@ bool DeclContext::lookupQualified(ArrayRef typeDecls, if ((options & NL_OnlyTypes) && !isa(decl)) continue; - if (isAcceptableLookupResult(this, options, decl, - onlyCompleteObjectInits)) + if (isAcceptableLookupResult(DC, options, decl, onlyCompleteObjectInits)) decls.push_back(decl); } @@ -1706,34 +1712,40 @@ bool DeclContext::lookupQualified(ArrayRef typeDecls, } } - pruneLookupResultSet(this, options, decls); - if (auto *debugClient = this->getParentModule()->getDebugClient()) { - debugClient->finishLookupInNominals(this, typeDecls, member.getFullName(), + pruneLookupResultSet(DC, options, decls); + if (auto *debugClient = DC->getParentModule()->getDebugClient()) { + debugClient->finishLookupInNominals(DC, typeDecls, member.getFullName(), options, decls); } - // We're done. Report success/failure. - return !decls.empty(); + + return decls; } bool DeclContext::lookupQualified(ModuleDecl *module, DeclNameRef member, NLOptions options, SmallVectorImpl &decls) const { - using namespace namelookup; + assert(decls.empty() && "additive lookup not supported"); + ModuleQualifiedLookupRequest req{this, module, member, options}; + decls = evaluateOrDefault(getASTContext().evaluator, req, {}); + return !decls.empty(); +} - auto &ctx = getASTContext(); - auto *stats = ctx.Stats; - if (stats) - stats->getFrontendCounters().NumLookupQualifiedInModule++; +llvm::Expected +ModuleQualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC, + ModuleDecl *module, DeclNameRef member, + NLOptions options) const { + using namespace namelookup; + QualifiedLookupResult decls; // Configure lookup and dig out the tracker. ReferencedNameTracker *tracker = nullptr; bool isLookupCascading; - configureLookup(this, options, tracker, isLookupCascading); + configureLookup(DC, options, tracker, isLookupCascading); auto kind = (options & NL_OnlyTypes ? ResolutionKind::TypesOnly : ResolutionKind::Overloadable); - auto topLevelScope = getModuleScopeContext(); + auto topLevelScope = DC->getModuleScopeContext(); if (module == topLevelScope->getParentModule()) { if (tracker) { recordLookupOfTopLevelName(topLevelScope, member.getFullName(), @@ -1748,6 +1760,7 @@ bool DeclContext::lookupQualified(ModuleDecl *module, DeclNameRef member, // anything in this one. // Perform the lookup in all imports of this module. + auto &ctx = DC->getASTContext(); auto accessPaths = ctx.getImportCache().getAllVisibleAccessPaths( module, topLevelScope); if (llvm::any_of(accessPaths, @@ -1760,14 +1773,14 @@ bool DeclContext::lookupQualified(ModuleDecl *module, DeclNameRef member, } } - pruneLookupResultSet(this, options, decls); + pruneLookupResultSet(DC, options, decls); - if (auto *debugClient = this->getParentModule()->getDebugClient()) { - debugClient->finishLookupInModule(this, module, member.getFullName(), + if (auto *debugClient = DC->getParentModule()->getDebugClient()) { + debugClient->finishLookupInModule(DC, module, member.getFullName(), options, decls); } - // We're done. Report success/failure. - return !decls.empty(); + + return decls; } llvm::Expected @@ -1997,7 +2010,9 @@ directReferencesForQualifiedTypeLookup(Evaluator &evaluator, auto innerOptions = options; innerOptions &= ~NL_RemoveOverridden; innerOptions &= ~NL_RemoveNonVisible; - dc->lookupQualified(module, name, innerOptions, members); + SmallVector moduleMembers; + dc->lookupQualified(module, name, innerOptions, moduleMembers); + members.append(moduleMembers.begin(), moduleMembers.end()); } addResults(members); diff --git a/test/decl/circularity.swift b/test/decl/circularity.swift index 69731c3725c5c..fedb35a291b9a 100644 --- a/test/decl/circularity.swift +++ b/test/decl/circularity.swift @@ -96,7 +96,7 @@ class C4 { required init(x: Int) {} } -class D4 : C4, P1 { // expected-note {{through reference here}} +class D4 : C4, P1 { // expected-note 2 {{through reference here}} required init(x: X) { // expected-error {{circular reference}} // expected-note@-1 2{{through reference here}} super.init(x: x) diff --git a/test/decl/class/circular_inheritance.swift b/test/decl/class/circular_inheritance.swift index 0e0ceba0194b4..202e5a9ffe13f 100644 --- a/test/decl/class/circular_inheritance.swift +++ b/test/decl/class/circular_inheritance.swift @@ -8,12 +8,12 @@ // Check that we produced superclass type requests. // RUN: %{python} %utils/process-stats-dir.py --evaluate 'SuperclassTypeRequest == 18' %t/stats-dir -class Left // expected-error {{circular reference}} +class Left // expected-error {{circular reference}} expected-note {{through reference here}} : Right.Hand { // expected-note {{through reference here}} class Hand {} } -class Right // expected-note {{through reference here}} +class Right // expected-note 2 {{through reference here}} : Left.Hand { // expected-note {{through reference here}} class Hand {} } @@ -35,13 +35,13 @@ class Outer { class Inner : Outer {} } -class Outer2 // expected-error {{circular reference}} +class Outer2 // expected-error {{circular reference}} expected-note {{through reference here}} : Outer2.Inner { // expected-note {{through reference here}} class Inner {} } -class Outer3 // expected-error {{circular reference}} +class Outer3 // expected-error {{circular reference}} expected-note {{through reference here}} : Outer3.Inner { // expected-note {{through reference here}} class Inner {} } @@ -79,6 +79,7 @@ class WithDesignatedInit : WithDesignatedInit { // expected-error@-1 {{'WithDesignatedInit' inherits from itself}} // expected-error@-2 {{circular reference}} // expected-note@-3 {{through reference here}} + // expected-note@-4 2 {{through reference here}} init(x: Int) {} // expected-error {{circular reference}} }