void TypeChecker::markInvalidGenericSignature(ValueDecl *VD) { GenericParamList *genericParams; if (auto *AFD = dyn_cast<AbstractFunctionDecl>(VD)) genericParams = AFD->getGenericParams(); else genericParams = cast<GenericTypeDecl>(VD)->getGenericParams(); // If there aren't any generic parameters at this level, we're done. if (genericParams == nullptr) return; DeclContext *DC = VD->getDeclContext(); ArchetypeBuilder builder = createArchetypeBuilder(DC->getParentModule()); if (auto sig = DC->getGenericSignatureOfContext()) builder.addGenericSignature(sig, true); // Visit each of the generic parameters. for (auto param : *genericParams) builder.addGenericParameter(param); // Wire up the archetypes. for (auto GP : *genericParams) GP->setArchetype(builder.getArchetype(GP)); genericParams->setAllArchetypes( Context.AllocateCopy(builder.getAllArchetypes())); }
GenericEnvironment * TypeChecker::markInvalidGenericSignature(DeclContext *DC) { GenericParamList *genericParams = DC->getGenericParamsOfContext(); GenericSignature *genericSig = DC->getGenericSignatureOfContext(); // Build new archetypes without any generic requirements. DeclContext *parentDC = DC->getParent(); auto builder = createArchetypeBuilder(parentDC->getParentModule()); auto parentSig = parentDC->getGenericSignatureOfContext(); auto parentEnv = parentDC->getGenericEnvironmentOfContext(); assert(parentSig != nullptr || DC->isInnermostContextGeneric()); if (parentSig != nullptr) builder.addGenericSignature(parentSig, parentEnv); if (DC->isInnermostContextGeneric()) { // Visit each of the generic parameters. for (auto param : *genericParams) builder.addGenericParameter(param); } // Wire up the archetypes. auto genericEnv = builder.getGenericEnvironment( genericSig->getGenericParams()); return genericEnv; }
/// Check the generic parameters in the given generic parameter list (and its /// parent generic parameter lists) according to the given resolver. void TypeChecker::checkGenericParamList(GenericSignatureBuilder *builder, GenericParamList *genericParams, GenericSignature *parentSig, GenericTypeResolver *resolver) { // If there is a parent context, add the generic parameters and requirements // from that context. if (builder) builder->addGenericSignature(parentSig); // If there aren't any generic parameters at this level, we're done. if (!genericParams) return; assert(genericParams->size() > 0 && "Parsed an empty generic parameter list?"); // Determine where and how to perform name lookup for the generic // parameter lists and where clause. TypeResolutionOptions options; DeclContext *lookupDC = genericParams->begin()[0]->getDeclContext(); if (!lookupDC->isModuleScopeContext()) { assert((isa<GenericTypeDecl>(lookupDC) || isa<ExtensionDecl>(lookupDC) || isa<AbstractFunctionDecl>(lookupDC) || isa<SubscriptDecl>(lookupDC)) && "not a proper generic parameter context?"); options = TR_GenericSignature; } // First, add the generic parameters to the generic signature builder. // Do this before checking the inheritance clause, since it may // itself be dependent on one of these parameters. if (builder) { for (auto param : *genericParams) builder->addGenericParameter(param); } // Now, check the inheritance clauses of each parameter. for (auto param : *genericParams) { checkInheritanceClause(param, resolver); if (builder) builder->addGenericParameterRequirements(param); } // Visit each of the requirements, adding them to the builder. // Add the requirements clause to the builder, validating the types in // the requirements clause along the way. for (auto &req : genericParams->getRequirements()) { if (validateRequirement(genericParams->getWhereLoc(), req, lookupDC, options, resolver)) continue; if (builder && isErrorResult(builder->addRequirement(&req, lookupDC->getParentModule()))) req.setInvalid(); } }
SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const { // Anonymous functions have shared linkage. // FIXME: This should really be the linkage of the parent function. if (getAbstractClosureExpr()) return SILLinkage::Shared; // Native function-local declarations have shared linkage. // FIXME: @objc declarations should be too, but we currently have no way // of marking them "used" other than making them external. ValueDecl *d = getDecl(); DeclContext *moduleContext = d->getDeclContext(); while (!moduleContext->isModuleScopeContext()) { if (!isForeign && moduleContext->isLocalContext()) return SILLinkage::Shared; moduleContext = moduleContext->getParent(); } // Currying and calling convention thunks have shared linkage. if (isThunk()) // If a function declares a @_cdecl name, its native-to-foreign thunk // is exported with the visibility of the function. if (!isNativeToForeignThunk() || !d->getAttrs().hasAttribute<CDeclAttr>()) return SILLinkage::Shared; // Enum constructors are essentially the same as thunks, they are // emitted by need and have shared linkage. if (kind == Kind::EnumElement) return SILLinkage::Shared; // Declarations imported from Clang modules have shared linkage. const SILLinkage ClangLinkage = SILLinkage::Shared; if (isClangImported()) return ClangLinkage; // Declarations that were derived on behalf of types in Clang modules get // shared linkage. if (auto *FD = dyn_cast<FuncDecl>(d)) { if (auto derivedFor = FD->getDerivedForTypeDecl()) if (isa<ClangModuleUnit>(derivedFor->getModuleScopeContext())) return ClangLinkage; } // If the module is being built with -sil-serialize-all, everything has // to have public linkage. if (moduleContext->getParentModule()->getResilienceStrategy() == ResilienceStrategy::Fragile) { return (forDefinition ? SILLinkage::Public : SILLinkage::PublicExternal); } // Otherwise, linkage is determined by accessibility at the AST level. switch (d->getEffectiveAccess()) { case Accessibility::Private: return (forDefinition ? SILLinkage::Private : SILLinkage::PrivateExternal); case Accessibility::Internal: return (forDefinition ? SILLinkage::Hidden : SILLinkage::HiddenExternal); default: return (forDefinition ? SILLinkage::Public : SILLinkage::PublicExternal); } }
std::pair<SynthesizedExtensionInfo, ExtensionMergeInfo> isApplicable(ExtensionDecl *Ext, bool IsSynthesized, ExtensionDecl *EnablingExt, NormalProtocolConformance *Conf) { SynthesizedExtensionInfo Result(IsSynthesized, EnablingExt); ExtensionMergeInfo MergeInfo; MergeInfo.HasDocComment = !Ext->getRawComment().isEmpty(); MergeInfo.InheritsCount = countInherits(Ext); // There's (up to) two extensions here: the extension with the items that we // might be merging, plus the "enabling extension", which is the route // through which \c Ext itself applies, e.g. extension SomeProtocol {} // extension SomeType: SomeProtocol where T: SomeProtocol {}. The former is // Ext and the latter is EnablingExt/Conf. Either of these can be // conditional in ways that need to be considered when merging. auto conformanceIsConditional = Conf && !Conf->getConditionalRequirements().empty(); if (!Ext->isConstrainedExtension() && !conformanceIsConditional) { if (IncludeUnconditional) Result.Ext = Ext; return {Result, MergeInfo}; } auto handleRequirements = [&](SubstitutionMap subMap, GenericSignature *GenericSig, ArrayRef<Requirement> Reqs) { for (auto Req : Reqs) { auto Kind = Req.getKind(); // FIXME: Could do something here if (Kind == RequirementKind::Layout) continue; auto First = Req.getFirstType(); auto Second = Req.getSecondType(); if (!BaseType->isExistentialType()) { First = First.subst(subMap); Second = Second.subst(subMap); if (!First || !Second) { // Substitution with interface type bases can only fail // if a concrete type fails to conform to a protocol. // In this case, just give up on the extension altogether. return true; } } switch (Kind) { case RequirementKind::Conformance: case RequirementKind::Superclass: // FIXME: This could be more accurate; check // conformance instead of subtyping if (!canPossiblyConvertTo(First, Second, *DC)) return true; else if (!isConvertibleTo(First, Second, *DC)) MergeInfo.addRequirement(GenericSig, First, Second, Kind); break; case RequirementKind::SameType: if (!canPossiblyEqual(First, Second, *DC)) { return true; } else if (!First->isEqual(Second)) { MergeInfo.addRequirement(GenericSig, First, Second, Kind); } break; case RequirementKind::Layout: llvm_unreachable("Handled above"); } } return false; }; auto *M = DC->getParentModule(); if (Ext->isConstrainedExtension()) { // Get the substitutions from the generic signature of // the extension to the interface types of the base type's // declaration. SubstitutionMap subMap; if (!BaseType->isExistentialType()) subMap = BaseType->getContextSubstitutionMap(M, Ext); assert(Ext->getGenericSignature() && "No generic signature."); auto GenericSig = Ext->getGenericSignature(); if (handleRequirements(subMap, GenericSig, GenericSig->getRequirements())) return {Result, MergeInfo}; } if (Conf && handleRequirements(Conf->getSubstitutions(M), Conf->getGenericSignature(), Conf->getConditionalRequirements())) return {Result, MergeInfo}; Result.Ext = Ext; return {Result, MergeInfo}; }
std::pair<SynthesizedExtensionInfo, ExtensionMergeInfo> isApplicable(ExtensionDecl *Ext, bool IsSynthesized) { SynthesizedExtensionInfo Result(IsSynthesized); ExtensionMergeInfo MergeInfo; MergeInfo.HasDocComment = !Ext->getRawComment().isEmpty(); MergeInfo.InheritsCount = countInherits(Ext); if (!Ext->isConstrainedExtension()) { if (IncludeUnconditional) Result.Ext = Ext; return {Result, MergeInfo}; } // Get the substitutions from the generic signature of // the extension to the interface types of the base type's // declaration. auto *M = DC->getParentModule(); SubstitutionMap subMap; if (!BaseType->isExistentialType()) subMap = BaseType->getContextSubstitutionMap(M, Ext); assert(Ext->getGenericSignature() && "No generic signature."); for (auto Req : Ext->getGenericSignature()->getRequirements()) { auto Kind = Req.getKind(); // FIXME: Could do something here if (Kind == RequirementKind::Layout) continue; auto First = Req.getFirstType(); auto Second = Req.getSecondType(); if (!BaseType->isExistentialType()) { First = First.subst(subMap); Second = Second.subst(subMap); if (!First || !Second) { // Substitution with interface type bases can only fail // if a concrete type fails to conform to a protocol. // In this case, just give up on the extension altogether. return {Result, MergeInfo}; } } switch (Kind) { case RequirementKind::Conformance: case RequirementKind::Superclass: // FIXME: This could be more accurate; check // conformance instead of subtyping if (!canPossiblyConvertTo(First, Second, *DC)) return {Result, MergeInfo}; else if (!isConvertibleTo(First, Second, *DC)) MergeInfo.addRequirement(First, Second, Kind); break; case RequirementKind::SameType: if (!canPossiblyEqual(First, Second, *DC)) { return {Result, MergeInfo}; } else if (!First->isEqual(Second)) { MergeInfo.addRequirement(First, Second, Kind); } break; case RequirementKind::Layout: llvm_unreachable("Handled above"); } } Result.Ext = Ext; return {Result, MergeInfo}; }