Example #1
0
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.");
}
Example #2
0
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.");
}