SubclassScope SILDeclRef::getSubclassScope() const { if (!hasDecl()) return SubclassScope::NotApplicable; // If this declaration is a function which goes into a vtable, then it's // symbol must be as visible as its class. Derived classes even have to put // all less visible methods of the base class into their vtables. auto *FD = dyn_cast<AbstractFunctionDecl>(getDecl()); if (!FD) return SubclassScope::NotApplicable; DeclContext *context = FD->getDeclContext(); // Methods from extensions don't go into vtables (yet). if (context->isExtensionContext()) return SubclassScope::NotApplicable; // Various forms of thunks don't either. if (isThunk() || isForeign) return SubclassScope::NotApplicable; // Default arg generators only need to be visible in Swift 3. if (isDefaultArgGenerator() && !context->getASTContext().isSwiftVersion3()) return SubclassScope::NotApplicable; auto *classType = context->getSelfClassDecl(); if (!classType || classType->isFinal()) return SubclassScope::NotApplicable; if (FD->isFinal()) return SubclassScope::NotApplicable; assert(FD->getEffectiveAccess() <= classType->getEffectiveAccess() && "class must be as visible as its members"); switch (classType->getEffectiveAccess()) { case AccessLevel::Private: case AccessLevel::FilePrivate: return SubclassScope::NotApplicable; case AccessLevel::Internal: case AccessLevel::Public: return SubclassScope::Internal; case AccessLevel::Open: return SubclassScope::External; } llvm_unreachable("Unhandled access level in switch."); }
static SILFunction::ClassVisibility_t getClassVisibility(SILDeclRef constant) { if (!constant.hasDecl()) return SILFunction::NotRelevant; // If this declaration is a function which goes into a vtable, then it's // symbol must be as visible as its class. Derived classes even have to put // all less visible methods of the base class into their vtables. auto *FD = dyn_cast<AbstractFunctionDecl>(constant.getDecl()); if (!FD) return SILFunction::NotRelevant; DeclContext *context = FD->getDeclContext(); // Methods from extensions don't go into vtables (yet). if (context->isExtensionContext()) return SILFunction::NotRelevant; auto *classType = context->getAsClassOrClassExtensionContext(); if (!classType || classType->isFinal()) return SILFunction::NotRelevant; if (FD->isFinal() && !FD->getOverriddenDecl()) return SILFunction::NotRelevant; assert(FD->getEffectiveAccess() <= classType->getEffectiveAccess() && "class must be as visible as its members"); switch (classType->getEffectiveAccess()) { case Accessibility::Private: case Accessibility::FilePrivate: return SILFunction::NotRelevant; case Accessibility::Internal: return SILFunction::InternalClass; case Accessibility::Public: case Accessibility::Open: return SILFunction::PublicClass; } llvm_unreachable("Unhandled Accessibility in switch."); }