@@ -567,61 +567,95 @@ class TypeRefBuilder {
567
567
return nullptr ;
568
568
}
569
569
570
- // Recursively constructs TypeRef for a bound generic, including
571
- // the enclosing (parent) generic contexts
570
+ // Construct a bound generic type ref along with the parent type info
571
+ // The parent list contains every parent type with at least 1 generic
572
+ // type parameter.
572
573
const BoundGenericTypeRef *createBoundGenericTypeReconstructingParent (
573
- const NodePointer node, const TypeRefDecl &decl, size_t shapeIndex,
574
- const llvm::ArrayRef<const TypeRef *> &args, size_t argsIndex) {
575
- if (!node || !node->hasChildren ())
576
- return nullptr ;
577
- NodePointer parentNode = node->getFirstChild ();
578
-
579
- // If this node can't possibly be generic, skip it and
580
- // return results for our parent instead
581
- auto kind = node->getKind ();
582
- if (kind != Node::Kind::Class
583
- && kind != Node::Kind::Structure
584
- && kind != Node::Kind::Enum) {
585
- return createBoundGenericTypeReconstructingParent (
586
- parentNode, decl, --shapeIndex, args, argsIndex);
574
+ const NodePointer startNode,
575
+ const std::vector<size_t > &genericParamsPerLevel,
576
+ const llvm::ArrayRef<const TypeRef *> &args)
577
+ {
578
+ // Collect all the relevant nodes, including the current node
579
+ std::vector<NodePointer> nodes;
580
+
581
+ // Iterate our parents, collecting the first N parents
582
+ // that potentially have generic args
583
+ NodePointer node = startNode;
584
+ while (nodes.size () < genericParamsPerLevel.size () - 1 ) {
585
+ if (!node || !node->hasChildren ()) {
586
+ return nullptr ;
587
+ }
588
+ node = node->getFirstChild ();
589
+ switch (node->getKind ()) {
590
+ case Node::Kind::Class:
591
+ case Node::Kind::Structure:
592
+ case Node::Kind::Enum:
593
+ nodes.push_back (node);
594
+ break ;
595
+ default :
596
+ break ;
597
+ }
587
598
}
599
+ assert (nodes.size () == genericParamsPerLevel.size () - 1 );
600
+
601
+ // We're now going to build the type tree from the
602
+ // outermost parent in, which matches the order of
603
+ // the generic parameter list and genericParamsPerLevel.
604
+ std::reverse (nodes.begin (), nodes.end ());
605
+
606
+ // Walk the list of parent types together with
607
+ // the generic argument list...
608
+ const BoundGenericTypeRef *typeref = nullptr ;
609
+ auto argBegin = args.begin ();
610
+ size_t totalArgs = 0 ;
611
+ for (size_t i = 0 ; i < nodes.size (); i++) {
612
+ // Get the mangling for this node
613
+ auto mangling = Demangle::mangleNode (nodes[i]);
614
+ if (!mangling.isSuccess ()) {
615
+ return nullptr ;
616
+ }
588
617
589
- // How many generic args are at this level?
590
- auto maybeGenericParamsPerLevel = decl.genericParamsPerLevel ;
591
- if (!maybeGenericParamsPerLevel)
592
- return nullptr ;
593
- auto genericParamsPerLevel = *maybeGenericParamsPerLevel;
594
- if (shapeIndex >= genericParamsPerLevel.size ())
595
- return nullptr ;
596
- auto numGenericArgs = genericParamsPerLevel[shapeIndex];
597
-
598
- // Nodes with no generic args can be replaced with their parent
599
- if (numGenericArgs == 0 ) {
600
- return createBoundGenericTypeReconstructingParent (
601
- parentNode, decl, --shapeIndex, args, argsIndex);
618
+ // Use the next N params for this node
619
+ auto numGenericArgs = genericParamsPerLevel[i];
620
+ // Skip nodes that don't have any actual type params.
621
+ if (numGenericArgs == 0 ) {
622
+ continue ;
623
+ }
624
+ if (numGenericArgs > args.size () || totalArgs + numGenericArgs > args.size ()) {
625
+ return nullptr ;
626
+ }
627
+ auto argEnd = argBegin + numGenericArgs;
628
+ totalArgs += numGenericArgs;
629
+ std::vector<const TypeRef *> params (argBegin, argEnd);
630
+ argBegin = argEnd;
631
+
632
+ // Extend the typeref up one level
633
+ typeref = BoundGenericTypeRef::create (*this , mangling.result (), params, typeref);
602
634
}
603
635
604
- // Collect args for the BoundGenericTypeRef::create() call:
605
-
606
- // * Mangling
607
- auto mangling = Demangle::mangleNode (node);
608
- if (!mangling.isSuccess ())
636
+ // Now let's stack the startNode on top of the parent list
637
+ // to obtain the final full typeref:
638
+ auto mangling = Demangle::mangleNode (startNode);
639
+ if (!mangling.isSuccess ()) {
609
640
return nullptr ;
641
+ }
610
642
611
- // * Generic params for this node
612
- auto startOffsetFromEnd = argsIndex + numGenericArgs;
613
- auto endOffsetFromEnd = argsIndex;
614
- if (startOffsetFromEnd > args.size () || endOffsetFromEnd > args.size ())
643
+ // Collect the final set of generic params for the
644
+ // startNode. Note: This will sometimes be empty:
645
+ // consider `Foo<Int, String>.Bar.Baz<Double>.Quux`
646
+ // which has 2 parents in the parent list
647
+ // (`Foo<Int,String>`, `Baz<Double>`), and the
648
+ // startNode is `Quux` with no params.
649
+ auto numGenericArgs = genericParamsPerLevel[genericParamsPerLevel.size () - 1 ];
650
+ auto argEnd = argBegin + numGenericArgs;
651
+ if (argEnd != args.end ()) {
652
+ // This node should exactly consume the remaining args
615
653
return nullptr ;
616
- std::vector<const TypeRef *> genericParams (
617
- args.end () - startOffsetFromEnd, args.end () - endOffsetFromEnd);
618
-
619
- // * Reconstructed parent
620
- auto parent = createBoundGenericTypeReconstructingParent (
621
- parentNode, decl, --shapeIndex, args, argsIndex + numGenericArgs);
654
+ }
655
+ std::vector<const TypeRef *> params (argBegin, argEnd);
622
656
623
- return BoundGenericTypeRef::create (* this , mangling. result (), genericParams,
624
- parent );
657
+ // Build and return the top typeref
658
+ return BoundGenericTypeRef::create (* this , mangling. result (), params, typeref );
625
659
}
626
660
627
661
const BoundGenericTypeRef *
@@ -630,16 +664,23 @@ class TypeRefBuilder {
630
664
if (!builtTypeDecl)
631
665
return nullptr ;
632
666
633
- if (!builtTypeDecl->genericParamsPerLevel )
667
+ // If there aren't generic params on the parent types, we just emit
668
+ // a single BG typeref with all the generic args
669
+ auto maybeGenericParamsPerLevel = builtTypeDecl->genericParamsPerLevel ;
670
+ if (!maybeGenericParamsPerLevel) {
634
671
return BoundGenericTypeRef::create (*this , builtTypeDecl->mangledName , args, nullptr );
672
+ }
635
673
674
+ // Otherwise, work from a full demangle tree to produce a
675
+ // typeref that includes all parents that have generic params
636
676
auto node = Dem.demangleType (builtTypeDecl->mangledName );
637
- if (!node || !node->hasChildren () || node->getKind () != Node::Kind::Type)
677
+ if (node && node->hasChildren () && node->getKind () == Node::Kind::Type) {
678
+ auto type = node->getFirstChild ();
679
+ auto genericParamsPerLevel = *maybeGenericParamsPerLevel;
680
+ return createBoundGenericTypeReconstructingParent (type, genericParamsPerLevel, args);
681
+ } else {
638
682
return nullptr ;
639
-
640
- auto type = node->getFirstChild ();
641
- return createBoundGenericTypeReconstructingParent (
642
- type, *builtTypeDecl, builtTypeDecl->genericParamsPerLevel ->size () - 1 , args, 0 );
683
+ }
643
684
}
644
685
645
686
const BoundGenericTypeRef *
0 commit comments