19
19
#include " swift/AST/Types.h"
20
20
#include " llvm/ADT/PointerUnion.h"
21
21
#include " llvm/ADT/SmallVector.h"
22
+ #include " llvm/ADT/TinyPtrVector.h"
23
+ #include < algorithm>
22
24
23
25
namespace llvm {
24
26
class raw_ostream ;
@@ -36,38 +38,46 @@ class Atom final {
36
38
GenericTypeParamType *,
37
39
LayoutConstraint>;
38
40
39
- const ProtocolDecl *Proto ;
41
+ llvm::TinyPtrVector< const ProtocolDecl *> Protos ;
40
42
Storage Value;
41
43
42
- explicit Atom (const ProtocolDecl *proto, Storage value)
43
- : Proto(proto), Value(value) {
44
+ explicit Atom (llvm::TinyPtrVector<const ProtocolDecl *> protos,
45
+ Storage value)
46
+ : Protos(protos), Value(value) {
44
47
// Triggers assertion if the atom is not valid.
45
48
(void ) getKind ();
46
49
}
47
50
48
51
public:
49
52
static Atom forName (Identifier name) {
50
- return Atom (nullptr , name);
53
+ return Atom ({} , name);
51
54
}
52
55
53
56
static Atom forProtocol (const ProtocolDecl *proto) {
54
- return Atom (proto, Storage ());
57
+ return Atom ({ proto} , Storage ());
55
58
}
56
59
57
60
static Atom forAssociatedType (const ProtocolDecl *proto,
58
61
Identifier name) {
59
62
assert (proto != nullptr );
60
- return Atom (proto, name);
63
+ return Atom ({proto}, name);
64
+ }
65
+
66
+ static Atom forAssociatedType (
67
+ llvm::TinyPtrVector<const ProtocolDecl *>protos,
68
+ Identifier name) {
69
+ assert (!protos.empty ());
70
+ return Atom (protos, name);
61
71
}
62
72
63
73
static Atom forGenericParam (GenericTypeParamType *param) {
64
74
assert (param->isCanonical ());
65
- return Atom (nullptr , param);
75
+ return Atom ({} , param);
66
76
}
67
77
68
78
static Atom forLayout (LayoutConstraint layout) {
69
79
assert (layout->isKnownLayout ());
70
- return Atom (nullptr , layout);
80
+ return Atom ({} , layout);
71
81
}
72
82
73
83
enum class Kind : uint8_t {
@@ -80,23 +90,23 @@ class Atom final {
80
90
81
91
Kind getKind () const {
82
92
if (!Value) {
83
- assert (Proto != nullptr );
93
+ assert (Protos. size () == 1 );
84
94
return Kind::Protocol;
85
95
}
86
96
87
97
if (Value.is <Identifier>()) {
88
- if (Proto != nullptr )
98
+ if (!Protos. empty () )
89
99
return Kind::AssociatedType;
90
100
return Kind::Name;
91
101
}
92
102
93
103
if (Value.is <GenericTypeParamType *>()) {
94
- assert (Proto == nullptr );
104
+ assert (Protos. empty () );
95
105
return Kind::GenericParam;
96
106
}
97
107
98
108
if (Value.is <LayoutConstraint>()) {
99
- assert (Proto == nullptr );
109
+ assert (Protos. empty () );
100
110
return Kind::Layout;
101
111
}
102
112
@@ -110,9 +120,16 @@ class Atom final {
110
120
}
111
121
112
122
const ProtocolDecl *getProtocol () const {
123
+ assert (getKind () == Kind::Protocol);
124
+ assert (Protos.size () == 1 );
125
+ return Protos.front ();
126
+ }
127
+
128
+ llvm::TinyPtrVector<const ProtocolDecl *> getProtocols () const {
113
129
assert (getKind () == Kind::Protocol ||
114
130
getKind () == Kind::AssociatedType);
115
- return Proto;
131
+ assert (!Protos.empty ());
132
+ return Protos;
116
133
}
117
134
118
135
GenericTypeParamType *getGenericParam () const {
@@ -130,7 +147,9 @@ class Atom final {
130
147
void dump (llvm::raw_ostream &out) const ;
131
148
132
149
friend bool operator ==(Atom lhs, Atom rhs) {
133
- return (lhs.Proto == rhs.Proto &&
150
+ return (lhs.Protos .size () == rhs.Protos .size () &&
151
+ std::equal (lhs.Protos .begin (), lhs.Protos .end (),
152
+ rhs.Protos .begin ()) &&
134
153
lhs.Value == rhs.Value );
135
154
}
136
155
0 commit comments