static std::string getMaterializeForSetCallbackName(ProtocolConformance *conformance, FuncDecl *requirement) { DeclContext *dc = requirement; ClosureExpr closure(/*patterns*/ nullptr, /*throws*/ SourceLoc(), /*arrow*/ SourceLoc(), /*in*/ SourceLoc(), /*result*/ TypeLoc(), /*discriminator*/ 0, /*context*/ requirement); closure.setType(TupleType::getEmpty(dc->getASTContext())); closure.getCaptureInfo().setGenericParamCaptures(true); Mangle::ASTMangler Mangler; std::string New; if (conformance) { // Concrete witness thunk for a conformance: // // Mangle this as if it were a conformance thunk for a closure // within the requirement. return Mangler.mangleClosureWitnessThunk(conformance, &closure); } // Default witness thunk or concrete implementation: // // Mangle this as if it were a closure within the requirement. return Mangler.mangleClosureEntity(&closure, Mangle::ASTMangler::SymbolKind::Default); }
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."); }
bool ConformanceLookupTable::addProtocol(NominalTypeDecl *nominal, ProtocolDecl *protocol, SourceLoc loc, ConformanceSource source) { DeclContext *dc = source.getDeclContext(); ASTContext &ctx = dc->getASTContext(); // Determine the kind of conformance. ConformanceEntryKind kind = source.getKind(); // If this entry is synthesized or implied, scan to determine // whether there are any explicit better conformances that make this // conformance trivially superseded (and, therefore, not worth // recording). auto &conformanceEntries = Conformances[protocol]; if (kind == ConformanceEntryKind::Implied || kind == ConformanceEntryKind::Synthesized) { for (const auto *existingEntry : conformanceEntries) { switch (existingEntry->getKind()) { case ConformanceEntryKind::Explicit: case ConformanceEntryKind::Inherited: return false; case ConformanceEntryKind::Implied: // An implied conformance is better than a synthesized one. // Ignore implied circular protocol inheritance if (kind == ConformanceEntryKind::Synthesized || existingEntry->getProtocol() == protocol) return false; break; case ConformanceEntryKind::Synthesized: break; } } } /// Build the conformance entry (if it hasn't been built before). ConformanceEntry *entry = new (ctx) ConformanceEntry(loc, protocol, source); conformanceEntries.push_back(entry); // Record this as a conformance within the given declaration // context. AllConformances[dc].push_back(entry); return true; }