@@ -5463,8 +5463,8 @@ bool VarDecl::isSettable(const DeclContext *UseDC,
54635463 // If this is a convenience initializer (i.e. one that calls
54645464 // self.init), then let properties are never mutable in it. They are
54655465 // only mutable in designated initializers.
5466- if ( CD->getDelegatingOrChainedInitKind (nullptr ) ==
5467- ConstructorDecl:: BodyInitKind::Delegating)
5466+ auto initKindAndExpr = CD->getDelegatingOrChainedInitKind ();
5467+ if (initKindAndExpr. initKind == BodyInitKind::Delegating)
54685468 return false ;
54695469
54705470 return true ;
@@ -7522,7 +7522,6 @@ ConstructorDecl::ConstructorDecl(DeclName Name, SourceLoc ConstructorLoc,
75227522 if (BodyParams)
75237523 setParameters (BodyParams);
75247524
7525- Bits.ConstructorDecl .ComputedBodyInitKind = 0 ;
75267525 Bits.ConstructorDecl .HasStubImplementation = 0 ;
75277526 Bits.ConstructorDecl .Failable = Failable;
75287527
@@ -7750,169 +7749,17 @@ CtorInitializerKind ConstructorDecl::getInitKind() const {
77507749 CtorInitializerKind::Designated);
77517750}
77527751
7753- ConstructorDecl::BodyInitKind
7754- ConstructorDecl::getDelegatingOrChainedInitKind (DiagnosticEngine *diags,
7755- ApplyExpr **init) const {
7752+ BodyInitKindAndExpr
7753+ ConstructorDecl::getDelegatingOrChainedInitKind () const {
7754+ return evaluateOrDefault (getASTContext ().evaluator ,
7755+ BodyInitKindRequest{const_cast <ConstructorDecl *>(this )},
7756+ BodyInitKindAndExpr ());
77567757 assert (hasBody () && " Constructor does not have a definition" );
7758+ }
77577759
7758- if (init)
7759- *init = nullptr ;
7760-
7761- // If we already computed the result, return it.
7762- if (Bits.ConstructorDecl .ComputedBodyInitKind ) {
7763- auto Kind = static_cast <BodyInitKind>(
7764- Bits.ConstructorDecl .ComputedBodyInitKind - 1 );
7765- assert ((Kind == BodyInitKind::None || !init) &&
7766- " can't return cached result with the init expr" );
7767- return Kind;
7768- }
7769-
7770-
7771- struct FindReferenceToInitializer : ASTWalker {
7772- const ConstructorDecl *Decl;
7773- BodyInitKind Kind = BodyInitKind::None;
7774- ApplyExpr *InitExpr = nullptr ;
7775- DiagnosticEngine *Diags;
7776-
7777- FindReferenceToInitializer (const ConstructorDecl *decl,
7778- DiagnosticEngine *diags)
7779- : Decl(decl), Diags(diags) { }
7780-
7781- bool walkToDeclPre (class Decl *D) override {
7782- // Don't walk into further nominal decls.
7783- return !isa<NominalTypeDecl>(D);
7784- }
7785-
7786- std::pair<bool , Expr*> walkToExprPre (Expr *E) override {
7787- // Don't walk into closures.
7788- if (isa<ClosureExpr>(E))
7789- return { false , E };
7790-
7791- // Look for calls of a constructor on self or super.
7792- auto apply = dyn_cast<ApplyExpr>(E);
7793- if (!apply)
7794- return { true , E };
7795-
7796- auto Callee = apply->getSemanticFn ();
7797-
7798- Expr *arg;
7799-
7800- if (isa<OtherConstructorDeclRefExpr>(Callee)) {
7801- arg = apply->getArg ();
7802- } else if (auto *CRE = dyn_cast<ConstructorRefCallExpr>(Callee)) {
7803- arg = CRE->getArg ();
7804- } else if (auto *dotExpr = dyn_cast<UnresolvedDotExpr>(Callee)) {
7805- if (dotExpr->getName ().getBaseName () != DeclBaseName::createConstructor ())
7806- return { true , E };
7807-
7808- arg = dotExpr->getBase ();
7809- } else {
7810- // Not a constructor call.
7811- return { true , E };
7812- }
7813-
7814- // Look for a base of 'self' or 'super'.
7815- BodyInitKind myKind;
7816- if (arg->isSuperExpr ())
7817- myKind = BodyInitKind::Chained;
7818- else if (arg->isSelfExprOf (Decl, /* sameBase*/ true ))
7819- myKind = BodyInitKind::Delegating;
7820- else {
7821- // We're constructing something else.
7822- return { true , E };
7823- }
7824-
7825- if (Kind == BodyInitKind::None) {
7826- Kind = myKind;
7827-
7828- // If we're not emitting diagnostics, we're done.
7829- if (!Diags)
7830- return { false , nullptr };
7831-
7832- InitExpr = apply;
7833- return { true , E };
7834- }
7835-
7836- assert (Diags && " Failed to abort traversal early" );
7837-
7838- // If the kind changed, complain.
7839- if (Kind != myKind) {
7840- // The kind changed. Complain.
7841- Diags->diagnose (E->getLoc (), diag::init_delegates_and_chains);
7842- Diags->diagnose (InitExpr->getLoc (), diag::init_delegation_or_chain,
7843- Kind == BodyInitKind::Chained);
7844- }
7845-
7846- return { true , E };
7847- }
7848- };
7849-
7850- FindReferenceToInitializer finder (this , diags);
7851- getBody ()->walk (finder);
7852-
7853- // get the kind out of the finder.
7854- auto Kind = finder.Kind ;
7855-
7856- auto *NTD = getDeclContext ()->getSelfNominalTypeDecl ();
7857-
7858- // Protocol extension and enum initializers are always delegating.
7859- if (Kind == BodyInitKind::None) {
7860- if (isa<ProtocolDecl>(NTD) || isa<EnumDecl>(NTD)) {
7861- Kind = BodyInitKind::Delegating;
7862- }
7863- }
7864-
7865- // Struct initializers that cannot see the layout of the struct type are
7866- // always delegating. This occurs if the struct type is not fixed layout,
7867- // and the constructor is either inlinable or defined in another module.
7868- if (Kind == BodyInitKind::None && isa<StructDecl>(NTD)) {
7869- // Note: This is specifically not using isFormallyResilient. We relax this
7870- // rule for structs in non-resilient modules so that they can have inlinable
7871- // constructors, as long as those constructors don't reference private
7872- // declarations.
7873- if (NTD->isResilient () &&
7874- getResilienceExpansion () == ResilienceExpansion::Minimal) {
7875- Kind = BodyInitKind::Delegating;
7876-
7877- } else if (isa<ExtensionDecl>(getDeclContext ())) {
7878- const ModuleDecl *containingModule = getParentModule ();
7879- // Prior to Swift 5, cross-module initializers were permitted to be
7880- // non-delegating. However, if the struct isn't fixed-layout, we have to
7881- // be delegating because, well, we don't know the layout.
7882- // A dynamic replacement is permitted to be non-delegating.
7883- if (NTD->isResilient () ||
7884- (containingModule->getASTContext ().isSwiftVersionAtLeast (5 ) &&
7885- !getAttrs ().getAttribute <DynamicReplacementAttr>())) {
7886- if (containingModule != NTD->getParentModule ())
7887- Kind = BodyInitKind::Delegating;
7888- }
7889- }
7890- }
7891-
7892- // If we didn't find any delegating or chained initializers, check whether
7893- // the initializer was explicitly marked 'convenience'.
7894- if (Kind == BodyInitKind::None && getAttrs ().hasAttribute <ConvenienceAttr>())
7895- Kind = BodyInitKind::Delegating;
7896-
7897- // If we still don't know, check whether we have a class with a superclass: it
7898- // gets an implicit chained initializer.
7899- if (Kind == BodyInitKind::None) {
7900- if (auto classDecl = getDeclContext ()->getSelfClassDecl ()) {
7901- if (classDecl->hasSuperclass ())
7902- Kind = BodyInitKind::ImplicitChained;
7903- }
7904- }
7905-
7906- // Cache the result if it is trustworthy.
7907- if (diags) {
7908- auto *mutableThis = const_cast <ConstructorDecl *>(this );
7909- mutableThis->Bits .ConstructorDecl .ComputedBodyInitKind =
7910- static_cast <unsigned >(Kind) + 1 ;
7911- if (init)
7912- *init = finder.InitExpr ;
7913- }
7914-
7915- return Kind;
7760+ void ConstructorDecl::clearCachedDelegatingOrChainedInitKind () {
7761+ getASTContext ().evaluator .clearCachedOutput (
7762+ BodyInitKindRequest{const_cast <ConstructorDecl *>(this )});
79167763}
79177764
79187765SourceRange DestructorDecl::getSourceRange () const {
0 commit comments