@@ -149,15 +149,42 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
149
149
}
150
150
case MetadataKind::Existential: {
151
151
auto exis = static_cast <const ExistentialTypeMetadata *>(type);
152
- NodePointer proto_list = Dem.createNode (Node::Kind::ProtocolList);
153
- NodePointer type_list = Dem.createNode (Node::Kind::TypeList);
154
-
155
- proto_list->addChild (type_list, Dem);
152
+ NodePointer proto_list;
156
153
157
154
std::vector<const ProtocolDescriptor *> protocols;
158
155
protocols.reserve (exis->Protocols .NumProtocols );
159
156
for (unsigned i = 0 , e = exis->Protocols .NumProtocols ; i < e; ++i)
160
157
protocols.push_back (exis->Protocols [i]);
158
+
159
+ if (exis->getSuperclassConstraint ()) {
160
+ // If there is a superclass constraint, we mangle it specially.
161
+ proto_list = Dem.createNode (Node::Kind::ProtocolListWithClass);
162
+ } else if (exis->isClassBounded ()) {
163
+ // Check if the class constraint is implied by any of our
164
+ // protocols.
165
+ bool requiresClassImplicit = false ;
166
+
167
+ for (auto *protocol : protocols) {
168
+ if (protocol->Flags .getClassConstraint ()
169
+ == ProtocolClassConstraint::Class)
170
+ requiresClassImplicit = true ;
171
+ }
172
+
173
+ // If it was implied, we don't do anything special.
174
+ if (requiresClassImplicit)
175
+ proto_list = Dem.createNode (Node::Kind::ProtocolList);
176
+ // If the existential type has an explicit AnyObject constraint,
177
+ // we must mangle it as such.
178
+ else
179
+ proto_list = Dem.createNode (Node::Kind::ProtocolListWithAnyObject);
180
+ } else {
181
+ // Just a simple composition of protocols.
182
+ proto_list = Dem.createNode (Node::Kind::ProtocolList);
183
+ }
184
+
185
+ NodePointer type_list = Dem.createNode (Node::Kind::TypeList);
186
+
187
+ proto_list->addChild (type_list, Dem);
161
188
162
189
// Sort the protocols by their mangled names.
163
190
// The ordering in the existential type metadata is by metadata pointer,
@@ -198,7 +225,12 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
198
225
assert (protocolNode->getChild (0 )->getKind () == Node::Kind::Protocol);
199
226
type_list->addChild (protocolNode, Dem);
200
227
}
201
-
228
+
229
+ if (auto *superclass = exis->getSuperclassConstraint ()) {
230
+ auto superclassNode = _swift_buildDemanglingForMetadata (superclass, Dem);
231
+ proto_list->addChild (superclassNode, Dem);
232
+ }
233
+
202
234
return proto_list;
203
235
}
204
236
case MetadataKind::ExistentialMetatype: {
0 commit comments