@@ -397,6 +397,54 @@ class MetadataReader {
397
397
{RemoteAddress (MetadataAddress), RemoteAddress (StartOfValue)});
398
398
}
399
399
400
+ // / Read a protocol from a reference to said protocol.
401
+ template <typename Resolver>
402
+ typename Resolver::Result readProtocol (
403
+ const TargetProtocolDescriptorRef<Runtime> &ProtocolAddress,
404
+ Demangler &dem,
405
+ Resolver resolver) {
406
+ #if SWIFT_OBJC_INTEROP
407
+ // Check whether we have an Objective-C protocol.
408
+ if (ProtocolAddress.isObjC ()) {
409
+ auto Name = readObjCProtocolName (ProtocolAddress.getObjCProtocol ());
410
+ StringRef NameStr (Name);
411
+
412
+ // If this is a Swift-defined protocol, demangle it.
413
+ if (NameStr.startswith (" _TtP" )) {
414
+ auto Demangled = dem.demangleSymbol (NameStr);
415
+ if (!Demangled)
416
+ return resolver.failure ();
417
+
418
+ // FIXME: This appears in _swift_buildDemanglingForMetadata().
419
+ while (Demangled->getKind () == Node::Kind::Global ||
420
+ Demangled->getKind () == Node::Kind::TypeMangling ||
421
+ Demangled->getKind () == Node::Kind::Type ||
422
+ Demangled->getKind () == Node::Kind::ProtocolList ||
423
+ Demangled->getKind () == Node::Kind::TypeList ||
424
+ Demangled->getKind () == Node::Kind::Type) {
425
+ if (Demangled->getNumChildren () != 1 )
426
+ return resolver.failure ();
427
+ Demangled = Demangled->getFirstChild ();
428
+ }
429
+
430
+ return resolver.swiftProtocol (Demangled);
431
+ }
432
+
433
+ // Otherwise, this is an imported protocol.
434
+ return resolver.objcProtocol (NameStr);
435
+ }
436
+ #endif
437
+
438
+ // Swift-native protocol.
439
+ auto Demangled =
440
+ readDemanglingForContextDescriptor (ProtocolAddress.getSwiftProtocol (),
441
+ dem);
442
+ if (!Demangled)
443
+ return resolver.failure ();
444
+
445
+ return resolver.swiftProtocol (Demangled);
446
+ }
447
+
400
448
// / Given a remote pointer to metadata, attempt to turn it into a type.
401
449
BuiltType readTypeFromMetadata (StoredPointer MetadataAddress,
402
450
bool skipArtificialSubclasses = false ) {
@@ -493,64 +541,34 @@ class MetadataReader {
493
541
HasExplicitAnyObject = true ;
494
542
}
495
543
496
- std::vector<BuiltProtocolDecl> Protocols;
497
- for (auto ProtocolAddress : Exist->getProtocols ()) {
498
- #if SWIFT_OBJC_INTEROP
499
- // Check whether we have an Objective-C protocol.
500
- if (ProtocolAddress.isObjC ()) {
501
- auto Name =
502
- readObjCProtocolName (ProtocolAddress.getObjCProtocol ());
503
- StringRef NameStr (Name);
504
-
505
- // If this is a Swift-defined protocol, demangle it.
506
- if (NameStr.startswith (" _TtP" )) {
507
- Demangle::Context DCtx;
508
- auto Demangled = DCtx.demangleSymbolAsNode (NameStr);
509
- if (!Demangled)
510
- return BuiltType ();
511
-
512
- // FIXME: This appears in _swift_buildDemanglingForMetadata().
513
- while (Demangled->getKind () == Node::Kind::Global ||
514
- Demangled->getKind () == Node::Kind::TypeMangling ||
515
- Demangled->getKind () == Node::Kind::Type ||
516
- Demangled->getKind () == Node::Kind::ProtocolList ||
517
- Demangled->getKind () == Node::Kind::TypeList ||
518
- Demangled->getKind () == Node::Kind::Type) {
519
- if (Demangled->getNumChildren () != 1 )
520
- return BuiltType ();
521
- Demangled = Demangled->getFirstChild ();
522
- }
523
-
524
- auto Protocol = Builder.createProtocolDecl (Demangled);
525
- if (!Protocol)
526
- return BuiltType ();
527
-
528
- Protocols.push_back (Protocol);
529
- continue ;
530
- }
544
+ // / Resolver to turn a protocol reference into a protocol declaration.
545
+ struct ProtocolResolver {
546
+ using Result = BuiltProtocolDecl;
531
547
532
- // Otherwise, this is an imported protocol.
533
- auto Protocol = Builder.createObjCProtocolDecl (NameStr);
534
- if (!Protocol)
535
- return BuiltType ();
548
+ BuilderType &builder;
536
549
537
- Protocols. push_back (Protocol);
538
- continue ;
550
+ BuiltProtocolDecl failure () const {
551
+ return BuiltProtocolDecl () ;
539
552
}
540
- #endif
541
553
542
- // Swift-native protocol.
543
- Demangle::Demangler Dem;
544
- auto Demangled = readDemanglingForContextDescriptor (
545
- ProtocolAddress.getSwiftProtocol (), Dem);
546
- if (!Demangled)
547
- return BuiltType ();
554
+ BuiltProtocolDecl swiftProtocol (Demangle::Node *node) {
555
+ return builder.createProtocolDecl (node);
556
+ }
548
557
549
- auto Protocol = Builder.createProtocolDecl (Demangled);
550
- if (!Protocol)
551
- return BuiltType ();
558
+ #if SWIFT_OBJC_INTEROP
559
+ BuiltProtocolDecl objcProtocol (StringRef name) {
560
+ return builder.createObjCProtocolDecl (name);
561
+ }
562
+ #endif
563
+ } resolver{Builder};
552
564
553
- Protocols.push_back (Protocol);
565
+ Demangler dem;
566
+ std::vector<BuiltProtocolDecl> Protocols;
567
+ for (auto ProtocolAddress : Exist->getProtocols ()) {
568
+ if (auto Protocol = readProtocol (ProtocolAddress, dem, resolver))
569
+ Protocols.push_back (Protocol);
570
+ else
571
+ return BuiltType ();
554
572
}
555
573
auto BuiltExist = Builder.createProtocolCompositionType (
556
574
Protocols, SuperclassType, HasExplicitAnyObject);
0 commit comments