@@ -1725,14 +1725,16 @@ class StorageRestrictionsAttr final
17251725// / The @_implements attribute, which treats a decl as the implementation for
17261726// / some named protocol requirement (but otherwise not-visible by that name).
17271727class ImplementsAttr : public DeclAttribute {
1728- TypeRepr *TyR;
1728+ // / If constructed by the \c create() variant with a TypeRepr, the TypeRepr;
1729+ // / if constructed by the \c create() variant with a DeclContext and
1730+ // / ProtocolDecl, the DeclContext.
1731+ llvm::PointerUnion<TypeRepr *, DeclContext *> TyROrDC;
17291732 DeclName MemberName;
17301733 DeclNameLoc MemberNameLoc;
17311734
17321735 ImplementsAttr (SourceLoc atLoc, SourceRange Range,
1733- TypeRepr *TyR,
1734- DeclName MemberName,
1735- DeclNameLoc MemberNameLoc);
1736+ llvm::PointerUnion<TypeRepr *, DeclContext *> TyROrDC,
1737+ DeclName MemberName, DeclNameLoc MemberNameLoc);
17361738
17371739public:
17381740 static ImplementsAttr *create (ASTContext &Ctx, SourceLoc atLoc,
@@ -1752,7 +1754,9 @@ class ImplementsAttr : public DeclAttribute {
17521754 // / otherwise `nullopt`. This should only be used for dumping.
17531755 std::optional<ProtocolDecl *> getCachedProtocol (DeclContext *dc) const ;
17541756
1755- TypeRepr *getProtocolTypeRepr () const { return TyR; }
1757+ TypeRepr *getProtocolTypeRepr () const {
1758+ return TyROrDC.dyn_cast <TypeRepr *>();
1759+ }
17561760
17571761 DeclName getMemberName () const { return MemberName; }
17581762 DeclNameLoc getMemberNameLoc () const { return MemberNameLoc; }
@@ -1763,8 +1767,12 @@ class ImplementsAttr : public DeclAttribute {
17631767
17641768 // / Create a copy of this attribute.
17651769 ImplementsAttr *clone (ASTContext &ctx) const {
1766- return new (ctx) ImplementsAttr (
1767- AtLoc, Range, TyR, getMemberName (), getMemberNameLoc ());
1770+ if (auto tyR = getProtocolTypeRepr ()) {
1771+ return create (ctx, AtLoc, Range, tyR, getMemberName (),
1772+ getMemberNameLoc ());
1773+ }
1774+ auto dc = TyROrDC.dyn_cast <DeclContext *>();
1775+ return create (dc, getProtocol (dc), getMemberName ());
17681776 }
17691777};
17701778
0 commit comments