void ClassHierarchyAnalysis::init() { // Process all types implementing protocols. SmallVector<Decl *, 32> Decls; // TODO: It would be better if we could get all declarations // from a given module, not only the top-level ones. M->getSwiftModule()->getTopLevelDecls(Decls); NominalTypeWalker Walker(ProtocolImplementationsCache); for (auto *D: Decls) { D->walk(Walker); } // For each class declaration in our V-table list: for (auto &VT : M->getVTableList()) { ClassDecl *C = VT.getClass(); // Ignore classes that are at the top of the class hierarchy: if (!C->hasSuperclass()) continue; // Add the superclass to the list of inherited classes. ClassDecl *Super = C->getSuperclass()->getClassOrBoundGenericClass(); auto &K = DirectSubclassesCache[Super]; assert(std::find(K.begin(), K.end(), C) == K.end() && "Class vector must be unique"); K.push_back(C); } }
static void lookupVisibleMemberDeclsImpl( Type BaseTy, VisibleDeclConsumer &Consumer, const DeclContext *CurrDC, LookupState LS, DeclVisibilityKind Reason, LazyResolver *TypeResolver, VisitedSet &Visited) { // Just look through l-valueness. It doesn't affect name lookup. assert(BaseTy && "lookup into null type"); BaseTy = BaseTy->getRValueType(); // Handle metatype references, as in "some_type.some_member". These are // special and can't have extensions. if (auto MTT = BaseTy->getAs<AnyMetatypeType>()) { // The metatype represents an arbitrary named type: dig through to the // declared type to see what we're dealing with. Type Ty = MTT->getInstanceType(); // Just perform normal dot lookup on the type see if we find extensions or // anything else. For example, type SomeTy.SomeMember can look up static // functions, and can even look up non-static functions as well (thus // getting the address of the member). lookupVisibleMemberDeclsImpl(Ty, Consumer, CurrDC, LookupState::makeQualified().withOnMetatype(), Reason, TypeResolver, Visited); return; } // Lookup module references, as on some_module.some_member. These are // special and can't have extensions. if (ModuleType *MT = BaseTy->getAs<ModuleType>()) { AccessFilteringDeclConsumer FilteringConsumer(CurrDC, Consumer, TypeResolver); MT->getModule()->lookupVisibleDecls(Module::AccessPathTy(), FilteringConsumer, NLKind::QualifiedLookup); return; } // If the base is a protocol, enumerate its members. if (ProtocolType *PT = BaseTy->getAs<ProtocolType>()) { lookupVisibleProtocolMemberDecls(BaseTy, PT, Consumer, CurrDC, LS, Reason, TypeResolver, Visited); return; } // If the base is a protocol composition, enumerate members of the protocols. if (auto PC = BaseTy->getAs<ProtocolCompositionType>()) { for (auto Proto : PC->getProtocols()) lookupVisibleMemberDeclsImpl(Proto, Consumer, CurrDC, LS, Reason, TypeResolver, Visited); return; } // Enumerate members of archetype's requirements. if (ArchetypeType *Archetype = BaseTy->getAs<ArchetypeType>()) { for (auto Proto : Archetype->getConformsTo()) lookupVisibleProtocolMemberDecls( BaseTy, Proto->getDeclaredType(), Consumer, CurrDC, LS, getReasonForSuper(Reason), TypeResolver, Visited); if (auto superclass = Archetype->getSuperclass()) lookupVisibleMemberDeclsImpl(superclass, Consumer, CurrDC, LS, getReasonForSuper(Reason), TypeResolver, Visited); return; } do { NominalTypeDecl *CurNominal = BaseTy->getAnyNominal(); if (!CurNominal) break; // Look in for members of a nominal type. lookupTypeMembers(BaseTy, BaseTy, Consumer, CurrDC, LS, Reason, TypeResolver); lookupDeclsFromProtocolsBeingConformedTo(BaseTy, Consumer, LS, CurrDC, Reason, TypeResolver, Visited); // If we have a class type, look into its superclass. ClassDecl *CurClass = dyn_cast<ClassDecl>(CurNominal); if (CurClass && CurClass->hasSuperclass()) { assert(BaseTy.getPointer() != CurClass->getSuperclass().getPointer() && "type is its own superclass"); BaseTy = CurClass->getSuperclass(); Reason = getReasonForSuper(Reason); bool InheritsSuperclassInitializers = CurClass->inheritsSuperclassInitializers(TypeResolver); if (LS.isOnSuperclass() && !InheritsSuperclassInitializers) LS = LS.withoutInheritsSuperclassInitializers(); else if (!LS.isOnSuperclass()) { LS = LS.withOnSuperclass(); if (InheritsSuperclassInitializers) LS = LS.withInheritsSuperclassInitializers(); } } else { break; } } while (1); }