@@ -708,9 +708,10 @@ namespace {
708
708
709
709
class OverrideFilteringConsumer : public VisibleDeclConsumer {
710
710
public:
711
- std::set<ValueDecl *> AllFoundDecls;
712
- std::map<DeclBaseName, std::set<ValueDecl *>> FoundDecls;
713
- llvm::SetVector<FoundDeclTy> DeclsToReport;
711
+ llvm::SetVector<FoundDeclTy> Results;
712
+ llvm::SmallVector<ValueDecl *, 8 > Decls;
713
+ llvm::SetVector<FoundDeclTy> FilteredResults;
714
+ llvm::DenseMap<DeclBaseName, llvm::SmallVector<ValueDecl *, 2 >> DeclsByName;
714
715
Type BaseTy;
715
716
const DeclContext *DC;
716
717
@@ -723,133 +724,128 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
723
724
724
725
void foundDecl (ValueDecl *VD, DeclVisibilityKind Reason,
725
726
DynamicLookupInfo dynamicLookupInfo) override {
726
- if (!AllFoundDecls .insert (VD). second )
727
+ if (!Results .insert ({VD, Reason, dynamicLookupInfo}) )
727
728
return ;
728
729
729
- // If this kind of declaration doesn't participate in overriding, there's
730
- // no filtering to do here.
731
- if (!isa<AbstractFunctionDecl>(VD) &&
732
- !isa<AbstractStorageDecl>(VD) &&
733
- !isa<AssociatedTypeDecl>(VD)) {
734
- DeclsToReport.insert (FoundDeclTy (VD, Reason, dynamicLookupInfo));
735
- return ;
736
- }
730
+ DeclsByName[VD->getBaseName ()] = {};
731
+ Decls.push_back (VD);
732
+ }
737
733
738
- if (!VD-> getInterfaceType () ) {
739
- return ;
740
- }
734
+ void filterDecls (VisibleDeclConsumer &Consumer ) {
735
+ removeOverriddenDecls (Decls) ;
736
+ removeShadowedDecls (Decls, DC);
741
737
742
- if (VD-> isInvalid ()) {
743
- FoundDecls[VD-> getBaseName ()]. insert (VD);
744
- DeclsToReport. insert ( FoundDeclTy (VD, Reason, dynamicLookupInfo));
745
- return ;
746
- }
747
- auto &PossiblyConflicting = FoundDecls[VD-> getBaseName ()] ;
738
+ size_t index = 0 ;
739
+ for ( auto DeclAndReason : Results) {
740
+ if (index >= Decls. size ())
741
+ break ;
742
+ if (DeclAndReason. D != Decls[index])
743
+ continue ;
748
744
749
- // Check all overridden decls.
750
- {
751
- auto *CurrentVD = VD->getOverriddenDecl ();
752
- while (CurrentVD) {
753
- if (!AllFoundDecls.insert (CurrentVD).second )
754
- break ;
755
- if (PossiblyConflicting.count (CurrentVD)) {
756
- PossiblyConflicting.erase (CurrentVD);
757
- PossiblyConflicting.insert (VD);
745
+ index++;
758
746
759
- bool Erased = DeclsToReport.remove (
760
- FoundDeclTy (CurrentVD, DeclVisibilityKind::LocalVariable, {}));
761
- assert (Erased);
762
- (void )Erased;
747
+ auto *VD = DeclAndReason.D ;
748
+ auto Reason = DeclAndReason.Reason ;
749
+ auto dynamicLookupInfo = DeclAndReason.dynamicLookupInfo ;
763
750
764
- DeclsToReport.insert (FoundDeclTy (VD, Reason, dynamicLookupInfo));
765
- return ;
766
- }
767
- CurrentVD = CurrentVD->getOverriddenDecl ();
751
+ // If this kind of declaration doesn't participate in overriding, there's
752
+ // no filtering to do here.
753
+ if (!isa<AbstractFunctionDecl>(VD) &&
754
+ !isa<AbstractStorageDecl>(VD) &&
755
+ !isa<AssociatedTypeDecl>(VD)) {
756
+ FilteredResults.insert (FoundDeclTy (VD, Reason, dynamicLookupInfo));
757
+ continue ;
768
758
}
769
- }
770
759
771
- // Does it make sense to substitute types?
772
-
773
- // If the base type is AnyObject, we might be doing a dynamic
774
- // lookup, so the base type won't match the type of the member's
775
- // context type.
776
- //
777
- // If the base type is not a nominal type, we can't substitute
778
- // the member type.
779
- //
780
- // If the member is a free function and not a member of a type,
781
- // don't substitute either.
782
- bool shouldSubst = (Reason != DeclVisibilityKind::DynamicLookup &&
783
- !BaseTy->isAnyObject () && !BaseTy->hasTypeVariable () &&
784
- !BaseTy->hasUnboundGenericType () &&
785
- (BaseTy->getNominalOrBoundGenericNominal () ||
786
- BaseTy->is <ArchetypeType>()) &&
787
- VD->getDeclContext ()->isTypeContext ());
788
- ModuleDecl *M = DC->getParentModule ();
789
-
790
- // Hack; we shouldn't be filtering at this level anyway.
791
- if (!VD->hasInterfaceType ()) {
792
- FoundDecls[VD->getBaseName ()].insert (VD);
793
- DeclsToReport.insert (FoundDeclTy (VD, Reason, dynamicLookupInfo));
794
- return ;
795
- }
760
+ if (!VD->getInterfaceType ()) {
761
+ continue ;
762
+ }
796
763
797
- auto FoundSignature = VD->getOverloadSignature ();
798
- auto FoundSignatureType = VD->getOverloadSignatureType ();
799
- if (FoundSignatureType && shouldSubst) {
800
- auto subs = BaseTy->getMemberSubstitutionMap (M, VD);
801
- auto CT = FoundSignatureType.subst (subs);
802
- if (!CT->hasError ())
803
- FoundSignatureType = CT->getCanonicalType ();
804
- }
764
+ auto &PossiblyConflicting = DeclsByName[VD->getBaseName ()];
805
765
806
- for (auto I = PossiblyConflicting.begin (), E = PossiblyConflicting.end ();
807
- I != E; ++I) {
808
- auto *OtherVD = *I;
809
- if (OtherVD->isInvalid () || !OtherVD->hasInterfaceType ()) {
810
- // For some invalid decls it might be impossible to compute the
811
- // signature, for example, if the types could not be resolved.
766
+ if (VD->isInvalid ()) {
767
+ FilteredResults.insert (FoundDeclTy (VD, Reason, dynamicLookupInfo));
768
+ PossiblyConflicting.push_back (VD);
812
769
continue ;
813
770
}
814
771
815
- auto OtherSignature = OtherVD->getOverloadSignature ();
816
- auto OtherSignatureType = OtherVD->getOverloadSignatureType ();
817
- if (OtherSignatureType && shouldSubst) {
818
- auto ActualBaseTy = getBaseTypeForMember (M, OtherVD, BaseTy);
819
- auto subs = ActualBaseTy->getMemberSubstitutionMap (M, OtherVD);
820
- auto CT = OtherSignatureType.subst (subs);
772
+ // Does it make sense to substitute types?
773
+
774
+ // If the base type is AnyObject, we might be doing a dynamic
775
+ // lookup, so the base type won't match the type of the member's
776
+ // context type.
777
+ //
778
+ // If the base type is not a nominal type, we can't substitute
779
+ // the member type.
780
+ //
781
+ // If the member is a free function and not a member of a type,
782
+ // don't substitute either.
783
+ bool shouldSubst = (Reason != DeclVisibilityKind::DynamicLookup &&
784
+ !BaseTy->isAnyObject () && !BaseTy->hasTypeVariable () &&
785
+ !BaseTy->hasUnboundGenericType () &&
786
+ (BaseTy->getNominalOrBoundGenericNominal () ||
787
+ BaseTy->is <ArchetypeType>()) &&
788
+ VD->getDeclContext ()->isTypeContext ());
789
+ ModuleDecl *M = DC->getParentModule ();
790
+
791
+ auto FoundSignature = VD->getOverloadSignature ();
792
+ auto FoundSignatureType = VD->getOverloadSignatureType ();
793
+ if (FoundSignatureType && shouldSubst) {
794
+ auto subs = BaseTy->getMemberSubstitutionMap (M, VD);
795
+ auto CT = FoundSignatureType.subst (subs);
821
796
if (!CT->hasError ())
822
- OtherSignatureType = CT->getCanonicalType ();
797
+ FoundSignatureType = CT->getCanonicalType ();
823
798
}
824
799
825
- if (conflicting (M->getASTContext (), FoundSignature, FoundSignatureType,
826
- OtherSignature, OtherSignatureType,
827
- /* wouldConflictInSwift5*/ nullptr ,
828
- /* skipProtocolExtensionCheck*/ true )) {
829
- if (VD->getFormalAccess () > OtherVD->getFormalAccess () ||
830
- // Prefer available one.
831
- (!AvailableAttr::isUnavailable (VD) &&
832
- AvailableAttr::isUnavailable (OtherVD))) {
833
- PossiblyConflicting.erase (I);
834
- PossiblyConflicting.insert (VD);
835
-
836
- bool Erased = DeclsToReport.remove (
837
- FoundDeclTy (OtherVD, DeclVisibilityKind::LocalVariable, {}));
838
- assert (Erased);
839
- (void )Erased;
840
-
841
- DeclsToReport.insert (FoundDeclTy (VD, Reason, dynamicLookupInfo));
800
+ bool FoundConflicting = false ;
801
+ for (auto I = PossiblyConflicting.begin (), E = PossiblyConflicting.end ();
802
+ I != E; ++I) {
803
+ auto *OtherVD = *I;
804
+ if (OtherVD->isInvalid () || !OtherVD->getInterfaceType ()) {
805
+ // For some invalid decls it might be impossible to compute the
806
+ // signature, for example, if the types could not be resolved.
807
+ continue ;
842
808
}
843
- return ;
809
+
810
+ auto OtherSignature = OtherVD->getOverloadSignature ();
811
+ auto OtherSignatureType = OtherVD->getOverloadSignatureType ();
812
+ if (OtherSignatureType && shouldSubst) {
813
+ auto ActualBaseTy = getBaseTypeForMember (M, OtherVD, BaseTy);
814
+ auto subs = ActualBaseTy->getMemberSubstitutionMap (M, OtherVD);
815
+ auto CT = OtherSignatureType.subst (subs);
816
+ if (!CT->hasError ())
817
+ OtherSignatureType = CT->getCanonicalType ();
818
+ }
819
+
820
+ if (conflicting (M->getASTContext (), FoundSignature, FoundSignatureType,
821
+ OtherSignature, OtherSignatureType,
822
+ /* wouldConflictInSwift5*/ nullptr ,
823
+ /* skipProtocolExtensionCheck*/ true )) {
824
+ FoundConflicting = true ;
825
+ if (VD->getFormalAccess () > OtherVD->getFormalAccess () ||
826
+ // Prefer available one.
827
+ (!AvailableAttr::isUnavailable (VD) &&
828
+ AvailableAttr::isUnavailable (OtherVD))) {
829
+ FilteredResults.remove (
830
+ FoundDeclTy (OtherVD, DeclVisibilityKind::LocalVariable, {}));
831
+ FilteredResults.insert (FoundDeclTy (VD, Reason, dynamicLookupInfo));
832
+ *I = VD;
833
+ }
834
+ }
835
+ }
836
+
837
+ if (!FoundConflicting) {
838
+ FilteredResults.insert (FoundDeclTy (VD, Reason, dynamicLookupInfo));
839
+ PossiblyConflicting.push_back (VD);
844
840
}
845
841
}
846
842
847
- PossiblyConflicting. insert (VD);
848
- DeclsToReport. insert ( FoundDeclTy (VD, Reason, dynamicLookupInfo) );
843
+ for ( auto Result : FilteredResults)
844
+ Consumer. foundDecl (Result. D , Result. Reason , Result. dynamicLookupInfo );
849
845
}
850
846
851
847
bool seenBaseName (DeclBaseName name) {
852
- return FoundDecls .find (name) != FoundDecls .end ();
848
+ return DeclsByName .find (name) != DeclsByName .end ();
853
849
}
854
850
};
855
851
@@ -1003,9 +999,7 @@ static void lookupVisibleMemberDecls(
1003
999
GSB, Visited, seenDynamicLookup);
1004
1000
1005
1001
// Report the declarations we found to the real consumer.
1006
- for (const auto &DeclAndReason : overrideConsumer.DeclsToReport )
1007
- Consumer.foundDecl (DeclAndReason.D , DeclAndReason.Reason ,
1008
- DeclAndReason.dynamicLookupInfo );
1002
+ overrideConsumer.filterDecls (Consumer);
1009
1003
}
1010
1004
1011
1005
static void lookupVisibleDeclsImpl (VisibleDeclConsumer &Consumer,
0 commit comments