1616#include " swift/Basic/Mangler.h"
1717#include " swift/AST/Types.h"
1818#include " swift/AST/Decl.h"
19+ #include " swift/Basic/TaggedUnion.h"
1920
2021namespace clang {
2122class NamedDecl ;
@@ -79,8 +80,50 @@ class ASTMangler : public Mangler {
7980 bool RespectOriginallyDefinedIn = true ;
8081
8182public:
82- using SymbolicReferent = llvm::PointerUnion<const NominalTypeDecl *,
83- const OpaqueTypeDecl *>;
83+ class SymbolicReferent {
84+ public:
85+ enum Kind {
86+ NominalType,
87+ OpaqueType,
88+ ExtendedExistentialTypeShape,
89+ };
90+ private:
91+ // TODO: make a TaggedUnion variant that works with an explicit
92+ // kind instead of requiring this redundant kind storage.
93+ TaggedUnion<const NominalTypeDecl *,
94+ const OpaqueTypeDecl *,
95+ Type>
96+ storage;
97+ Kind kind;
98+
99+ SymbolicReferent (Kind kind, Type type) : storage(type), kind(kind) {}
100+ public:
101+ SymbolicReferent (const NominalTypeDecl *decl)
102+ : storage(decl), kind(NominalType) {}
103+ SymbolicReferent (const OpaqueTypeDecl *decl)
104+ : storage(decl), kind(OpaqueType) {}
105+ static SymbolicReferent forExtendedExistentialTypeShape (Type type) {
106+ return SymbolicReferent (ExtendedExistentialTypeShape, type);
107+ }
108+
109+ Kind getKind () const { return kind; }
110+
111+ bool isNominalType () const { return kind == NominalType; }
112+ const NominalTypeDecl *getNominalType () const {
113+ assert (kind == NominalType);
114+ return storage.get <const NominalTypeDecl *>();
115+ }
116+
117+ const OpaqueTypeDecl *getOpaqueType () const {
118+ assert (kind == OpaqueType);
119+ return storage.get <const OpaqueTypeDecl *>();
120+ }
121+
122+ Type getType () const {
123+ assert (kind == ExtendedExistentialTypeShape);
124+ return storage.get <Type>();
125+ }
126+ };
84127protected:
85128
86129 // / If set, the mangler calls this function to determine whether to symbolic
@@ -90,8 +133,8 @@ class ASTMangler : public Mangler {
90133
91134 bool canSymbolicReference (SymbolicReferent referent) {
92135 // Marker protocols cannot ever be symbolically referenced.
93- if (auto nominal = referent.dyn_cast < const NominalTypeDecl *> ()) {
94- if (auto proto = dyn_cast<ProtocolDecl>(nominal )) {
136+ if (referent.isNominalType ()) {
137+ if (auto proto = dyn_cast<ProtocolDecl>(referent. getNominalType () )) {
95138 if (proto->isMarkerProtocol ())
96139 return false ;
97140 }
@@ -521,6 +564,10 @@ class ASTMangler : public Mangler {
521564 GenericSignature sig);
522565 void appendOpParamForLayoutConstraint (LayoutConstraint Layout);
523566
567+ void appendSymbolicExtendedExistentialType (SymbolicReferent shapeReferent,
568+ Type type,
569+ GenericSignature sig,
570+ const ValueDecl *forDecl);
524571 void appendSymbolicReference (SymbolicReferent referent);
525572
526573 void appendOpaqueDeclName (const OpaqueTypeDecl *opaqueDecl);
0 commit comments