@@ -473,11 +473,109 @@ TypeSystemSwiftTypeRef::GetClangTypeNode(CompilerType clang_type,
473
473
return pointee ? GetPointerTo (dem, nominal) : nominal;
474
474
}
475
475
476
- // / Return a pair of modulename, type name for the outermost nominal type.
477
- static std::optional<std::pair<StringRef, StringRef>>
478
- GetNominal (swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node) {
476
+ bool
477
+ TypeSystemSwiftTypeRef::IsBuiltinType (CompilerType type) {
478
+ assert (type.GetTypeSystem ().isa_and_nonnull <TypeSystemSwift>() &&
479
+ " Unexpected type system!" );
480
+ Demangler dem;
481
+ auto *node = GetDemangledType (dem, type.GetMangledTypeName ());
479
482
if (!node)
483
+ return false ;
484
+ return node->getKind () == Node::Kind::BuiltinTypeName;
485
+ }
486
+
487
+ std::optional<std::pair<NodePointer, NodePointer>>
488
+ ExtractTypeNode (NodePointer node) {
489
+ // A type node is expected to have two children.
490
+ if (node->getNumChildren () != 2 )
491
+ return {};
492
+
493
+ auto *first = node->getChild (0 );
494
+ auto *second = node->getChild (1 );
495
+
496
+ // The second child of a type node is expected to be its identifier.
497
+ if (second->getKind () != Node::Kind::Identifier)
498
+ return {};
499
+ return {{first, second}};
500
+ }
501
+
502
+ static std::optional<llvm::StringRef>
503
+ ExtractIdentifierFromLocalDeclName (NodePointer node) {
504
+ assert (node->getKind () == Node::Kind::LocalDeclName &&
505
+ " Expected LocalDeclName node!" );
506
+
507
+ if (node->getNumChildren () != 2 ) {
508
+ assert (false && " Local decl name node should have 2 children!" );
509
+ return {};
510
+ }
511
+
512
+ auto *first = node->getChild (0 );
513
+ auto *second = node->getChild (1 );
514
+
515
+ assert (first->getKind () == Node::Kind::Number && " Expected number node!" );
516
+
517
+ if (second->getKind () == Node::Kind::Identifier) {
518
+ if (!second->hasText ()) {
519
+ assert (false && " Identifier should have text!" );
520
+ return {};
521
+ }
522
+ return second->getText ();
523
+ }
524
+ assert (false && " Expected second child of local decl name to be its "
525
+ " identifier!" );
526
+ return {};
527
+ }
528
+
529
+ static std::optional<std::pair<StringRef, StringRef>>
530
+ ExtractIdentifiersFromPrivateDeclName (NodePointer node) {
531
+ assert (node->getKind () == Node::Kind::PrivateDeclName && " Expected PrivateDeclName node!" );
532
+
533
+ if (node->getNumChildren () != 2 ) {
534
+ assert (false && " Private decl name node should have 2 children!" );
535
+ return {};
536
+ }
537
+
538
+ auto *private_discriminator = node->getChild (0 );
539
+ auto *type_name = node->getChild (1 );
540
+
541
+ if (private_discriminator->getKind () != Node::Kind::Identifier) {
542
+ assert (
543
+ false &&
544
+ " Expected first child of private decl name node to be an identifier!" );
480
545
return {};
546
+ }
547
+ if (type_name->getKind () != Node::Kind::Identifier) {
548
+ assert (
549
+ false &&
550
+ " Expected second child of private decl name node to be an identifier!" );
551
+ return {};
552
+ }
553
+
554
+ if (!private_discriminator->hasText () || !type_name->hasText ()) {
555
+ assert (false && " Identifier nodes should have text!" );
556
+ return {};
557
+ }
558
+
559
+ return {{private_discriminator->getText (), type_name->getText ()}};
560
+ }
561
+ // / Builds the decl context of a given node. The decl context is the context in
562
+ // / where this type is defined. For example, give a module A with the following
563
+ // / code:
564
+ // /
565
+ // / struct B {
566
+ // / class C {
567
+ // / ...
568
+ // / }
569
+ // / }
570
+ // /
571
+ // / The decl context of C would be:
572
+ // / <Module A>
573
+ // / <AnyType B>
574
+ // / <AnyType C>
575
+ static bool BuildDeclContext (swift::Demangle::NodePointer node,
576
+ std::vector<CompilerContext> &context) {
577
+ if (!node)
578
+ return false ;
481
579
using namespace swift ::Demangle;
482
580
switch (node->getKind ()) {
483
581
case Node::Kind::Structure:
@@ -489,14 +587,34 @@ GetNominal(swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node) {
489
587
case Node::Kind::ProtocolListWithAnyObject:
490
588
case Node::Kind::TypeAlias: {
491
589
if (node->getNumChildren () != 2 )
492
- return {};
493
- auto *m = node->getChild (0 );
494
- if (!m || m->getKind () != Node::Kind::Module || !m->hasText ())
495
- return {};
496
- auto *n = node->getChild (1 );
497
- if (!n || n->getKind () != Node::Kind::Identifier || !n->hasText ())
498
- return {};
499
- return {{m->getText (), n->getText ()}};
590
+ return false ;
591
+ auto *first = node->getChild (0 );
592
+ if (!first)
593
+ return false ;
594
+ if (first->getKind () == Node::Kind::Module) {
595
+ assert (first->hasText () && " Module node should have text!" );
596
+ context.push_back (
597
+ {CompilerContextKind::Module, ConstString (first->getText ())});
598
+ } else {
599
+ // If the node's kind is not a module, this is probably a nested type, so
600
+ // build the decl context for the parent type first.
601
+ if (!BuildDeclContext (first, context))
602
+ return false ;
603
+ }
604
+
605
+ auto *second = node->getChild (1 );
606
+ if (!second)
607
+ return false ;
608
+
609
+ if (second->getKind () == Node::Kind::Identifier) {
610
+ assert (second->hasText () && " Identifier node should have text!" );
611
+ context.push_back (
612
+ {CompilerContextKind::AnyType, ConstString (second->getText ())});
613
+ return true ;
614
+ }
615
+ // If the second child is not an identifier, it could be a private decl
616
+ // name or a local decl name.
617
+ return BuildDeclContext (second, context);
500
618
}
501
619
case Node::Kind::BoundGenericClass:
502
620
case Node::Kind::BoundGenericEnum:
@@ -509,36 +627,91 @@ GetNominal(swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node) {
509
627
auto *type = node->getChild (0 );
510
628
if (!type || type->getKind () != Node::Kind::Type || !type->hasChildren ())
511
629
return {};
512
- return GetNominal (dem, type->getFirstChild ());
630
+ return BuildDeclContext (type->getFirstChild (), context);
631
+ }
632
+ case Node::Kind::Function: {
633
+ if (node->getNumChildren () != 3 )
634
+ return false ;
635
+
636
+ auto *first = node->getChild (0 );
637
+ auto *second = node->getChild (1 );
638
+
639
+ if (first->getKind () == Node::Kind::Module) {
640
+ if (!first->hasText ()) {
641
+ assert (false && " Module should have text!" );
642
+ return false ;
643
+ }
644
+ context.push_back (
645
+ {CompilerContextKind::Module, ConstString (first->getText ())});
646
+ } else if (!BuildDeclContext (first, context))
647
+ return false ;
648
+
649
+ if (second->getKind () == Node::Kind::Identifier) {
650
+ if (!second->hasText ()) {
651
+ assert (false && " Identifier should have text!" );
652
+ return false ;
653
+ }
654
+ context.push_back (
655
+ {CompilerContextKind::Function, ConstString (second->getText ())});
656
+ } else if (!BuildDeclContext (second, context))
657
+ return false ;
658
+
659
+ return true ;
660
+ }
661
+ case Node::Kind::LocalDeclName: {
662
+ std::optional<llvm::StringRef> identifier =
663
+ ExtractIdentifierFromLocalDeclName (node);
664
+ if (!identifier)
665
+ return false ;
666
+
667
+ context.push_back (
668
+ {CompilerContextKind::AnyDeclContext, ConstString (*identifier)});
669
+ return true ;
670
+ }
671
+
672
+ case Node::Kind::PrivateDeclName: {
673
+ auto discriminator_and_type_name =
674
+ ExtractIdentifiersFromPrivateDeclName (node);
675
+
676
+ if (!discriminator_and_type_name)
677
+ return false ;
678
+ auto &[private_discriminator, type_name] = *discriminator_and_type_name;
679
+
680
+ context.push_back (
681
+ {CompilerContextKind::Namespace, ConstString (private_discriminator)});
682
+ context.push_back (
683
+ {CompilerContextKind::AnyDeclContext, ConstString (type_name)});
684
+ return true ;
513
685
}
514
686
default :
515
687
break ;
516
688
}
517
- return {};
518
- }
519
-
520
- bool
521
- TypeSystemSwiftTypeRef::IsBuiltinType (CompilerType type) {
522
- assert (type.GetTypeSystem ().isa_and_nonnull <TypeSystemSwift>() &&
523
- " Unexpected type system!" );
524
- Demangler dem;
525
- auto *node = GetDemangledType (dem, type.GetMangledTypeName ());
526
- if (!node)
527
- return false ;
528
- return node->getKind () == Node::Kind::BuiltinTypeName;
689
+ return false ;
529
690
}
530
691
531
- // / Return a pair of module name and type name, given a mangled name.
532
- static std::optional<std::pair<StringRef, StringRef>>
533
- GetNominal (llvm::StringRef mangled_name, swift::Demangle::Demangler &dem) {
692
+ // / Builds the decl context of a given swift type. See the documentation in the
693
+ // / other implementation of BuildDeclContext for more details.
694
+ static std::optional<std::vector<CompilerContext>>
695
+ BuildDeclContext (llvm::StringRef mangled_name,
696
+ swift::Demangle::Demangler &dem) {
697
+ std::vector<CompilerContext> context;
534
698
auto *node = GetDemangledType (dem, mangled_name);
699
+
535
700
// / Builtin names belong to the builtin module, and are stored only with their
536
701
// / mangled name.
537
- if (node->getKind () == Node::Kind::BuiltinTypeName)
538
- return {{" Builtin" , mangled_name}};
702
+ if (node->getKind () == Node::Kind::BuiltinTypeName) {
703
+ context.push_back ({CompilerContextKind::Module, ConstString (" Builtin" )});
704
+ context.push_back (
705
+ {CompilerContextKind::AnyType, ConstString (mangled_name)});
706
+ return std::move (context);
707
+ }
539
708
540
- return GetNominal (dem, node);
709
+ auto success = BuildDeclContext (node, context);
710
+ if (success)
711
+ return std::move (context);
712
+ return {};
541
713
}
714
+
542
715
// / Detect the AnyObject type alias.
543
716
static bool IsAnyObjectTypeAlias (swift::Demangle::NodePointer node) {
544
717
using namespace swift ::Demangle;
@@ -630,10 +803,6 @@ TypeSystemSwiftTypeRef::ResolveTypeAlias(swift::Demangle::Demangler &dem,
630
803
ConstString mangled (mangling.result ());
631
804
632
805
auto resolve_clang_type = [&]() -> CompilerType {
633
- auto maybe_module_and_type_names = GetNominal (dem, node);
634
- if (!maybe_module_and_type_names)
635
- return {};
636
-
637
806
// This is an imported Objective-C type; look it up in the debug info.
638
807
llvm::SmallVector<CompilerContext, 2 > decl_context;
639
808
if (!IsClangImportedType (node, decl_context))
@@ -1885,20 +2054,14 @@ TypeSystemSwiftTypeRef::FindTypeInModule(opaque_compiler_type_t opaque_type) {
1885
2054
return {};
1886
2055
1887
2056
swift::Demangle::Demangler dem;
1888
- auto module_type = GetNominal (AsMangledName (opaque_type), dem);
1889
- if (!module_type )
2057
+ auto context = BuildDeclContext (AsMangledName (opaque_type), dem);
2058
+ if (!context )
1890
2059
return {};
1891
2060
// DW_AT_linkage_name is not part of the accelerator table, so
1892
- // we need to search by module+name.
1893
- ConstString module (module_type->first );
1894
- ConstString type (module_type->second );
1895
- llvm::SmallVector<CompilerContext, 2 > decl_context;
1896
- if (!module .IsEmpty ())
1897
- decl_context.push_back ({CompilerContextKind::Module, module });
1898
- decl_context.push_back ({CompilerContextKind::AnyType, type});
2061
+ // we need to search by decl context.
1899
2062
1900
- TypeQuery query (decl_context , TypeQueryOptions::e_find_one |
1901
- TypeQueryOptions::e_module_search);
2063
+ TypeQuery query (*context , TypeQueryOptions::e_find_one |
2064
+ TypeQueryOptions::e_module_search);
1902
2065
query.SetLanguages (TypeSystemSwift::GetSupportedLanguagesForTypes ());
1903
2066
1904
2067
TypeResults results;
0 commit comments