16
16
#include " swift/Basic/Mangler.h"
17
17
#include " swift/AST/Types.h"
18
18
#include " swift/AST/Decl.h"
19
+ #include " swift/Basic/TaggedUnion.h"
19
20
20
21
namespace clang {
21
22
class NamedDecl ;
@@ -79,8 +80,50 @@ class ASTMangler : public Mangler {
79
80
bool RespectOriginallyDefinedIn = true ;
80
81
81
82
public:
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
+ };
84
127
protected:
85
128
86
129
// / If set, the mangler calls this function to determine whether to symbolic
@@ -90,8 +133,8 @@ class ASTMangler : public Mangler {
90
133
91
134
bool canSymbolicReference (SymbolicReferent referent) {
92
135
// 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 () )) {
95
138
if (proto->isMarkerProtocol ())
96
139
return false ;
97
140
}
@@ -521,6 +564,10 @@ class ASTMangler : public Mangler {
521
564
GenericSignature sig);
522
565
void appendOpParamForLayoutConstraint (LayoutConstraint Layout);
523
566
567
+ void appendSymbolicExtendedExistentialType (SymbolicReferent shapeReferent,
568
+ Type type,
569
+ GenericSignature sig,
570
+ const ValueDecl *forDecl);
524
571
void appendSymbolicReference (SymbolicReferent referent);
525
572
526
573
void appendOpaqueDeclName (const OpaqueTypeDecl *opaqueDecl);
0 commit comments