@@ -567,65 +567,66 @@ class TypeRefBuilder {
567
567
return nullptr ;
568
568
}
569
569
570
- const BoundGenericTypeRef *createBoundGenericTypeReconstructingParent (
571
- const NodePointer node, const TypeRefDecl &decl, size_t shapeIndex,
572
- const llvm::ArrayRef<const TypeRef *> &args, size_t argsIndex) {
573
- if (!node || !node->hasChildren ())
574
- return nullptr ;
575
-
576
- auto maybeGenericParamsPerLevel = decl.genericParamsPerLevel ;
577
- if (!maybeGenericParamsPerLevel)
578
- return nullptr ;
579
-
580
- auto genericParamsPerLevel = *maybeGenericParamsPerLevel;
581
-
582
- auto kind = node->getKind ();
583
- // Kinds who have a "BoundGeneric..." variant.
584
- if (kind != Node::Kind::Class && kind != Node::Kind::Structure &&
585
- kind != Node::Kind::Enum)
586
- return nullptr ;
587
- auto mangling = Demangle::mangleNode (node);
588
- if (!mangling.isSuccess ())
589
- return nullptr ;
590
-
591
- if (shapeIndex >= genericParamsPerLevel.size ())
592
- return nullptr ;
593
-
594
- auto numGenericArgs = genericParamsPerLevel[shapeIndex];
595
-
596
- auto startOffsetFromEnd = argsIndex + numGenericArgs;
597
- auto endOffsetFromEnd = argsIndex;
598
- if (startOffsetFromEnd > args.size () || endOffsetFromEnd > args.size ())
599
- return nullptr ;
600
-
601
- std::vector<const TypeRef *> genericParams (
602
- args.end () - startOffsetFromEnd, args.end () - endOffsetFromEnd);
603
-
604
- const BoundGenericTypeRef *parent = nullptr ;
605
- if (node->hasChildren ()) {
606
- // Skip over nodes that are not of type class, enum or struct
607
- auto parentNode = node->getFirstChild ();
608
- while (parentNode->getKind () != Node::Kind::Class &&
609
- parentNode->getKind () != Node::Kind::Structure &&
610
- parentNode->getKind () != Node::Kind::Enum) {
611
- if (parentNode->hasChildren ()) {
612
- parentNode = parentNode->getFirstChild ();
613
- } else {
614
- parentNode = nullptr ;
615
- break ;
616
- }
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.
573
+ const BoundGenericTypeRef *reconstructParentsOfBoundGenericType (
574
+ const NodePointer startNode,
575
+ const std::vector<size_t > &genericParamsPerLevel,
576
+ const llvm::ArrayRef<const TypeRef *> &args)
577
+ {
578
+ // Collect the first N parents that potentially have generic args
579
+ // (Ignore the last genericParamPerLevel, which
580
+ // applies to the startNode itself.)
581
+ std::vector<NodePointer> nodes;
582
+ NodePointer node = startNode;
583
+ while (nodes.size () < genericParamsPerLevel.size () - 1 ) {
584
+ if (!node || !node->hasChildren ()) {
585
+ return nullptr ;
617
586
}
618
- if (parentNode) {
619
- if (shapeIndex > 0 )
620
- parent = createBoundGenericTypeReconstructingParent (
621
- parentNode, decl, --shapeIndex, args, argsIndex + numGenericArgs);
622
- else
623
- return nullptr ;
587
+ node = node->getFirstChild ();
588
+ switch (node->getKind ()) {
589
+ case Node::Kind::Class:
590
+ case Node::Kind::Structure:
591
+ case Node::Kind::Enum:
592
+ nodes.push_back (node);
593
+ break ;
594
+ default :
595
+ break ;
624
596
}
625
597
}
598
+ assert (nodes.size () == genericParamsPerLevel.size () - 1 );
599
+
600
+ // We're now going to build the type tree from the
601
+ // outermost parent in, which matches the order of
602
+ // the generic parameter list and genericParamsPerLevel.
603
+ std::reverse (nodes.begin (), nodes.end ());
604
+
605
+ // Walk the list of parent types together with
606
+ // the generic argument list...
607
+ const BoundGenericTypeRef *typeref = nullptr ;
608
+ auto argBegin = args.begin ();
609
+ for (size_t i = 0 ; i < nodes.size (); i++) {
610
+ // Get the mangling for this node
611
+ auto mangling = Demangle::mangleNode (nodes[i]);
612
+ if (!mangling.isSuccess ()) {
613
+ return nullptr ;
614
+ }
626
615
627
- return BoundGenericTypeRef::create (*this , mangling.result (), genericParams,
628
- parent);
616
+ // Use the next N params for this node
617
+ auto numGenericArgs = genericParamsPerLevel[i];
618
+ // Skip nodes that don't have any actual type params.
619
+ if (numGenericArgs == 0 ) {
620
+ continue ;
621
+ }
622
+ auto argEnd = argBegin + numGenericArgs;
623
+ std::vector<const TypeRef *> params (argBegin, argEnd);
624
+ argBegin = argEnd;
625
+
626
+ // Extend the typeref list towards the innermost type
627
+ typeref = BoundGenericTypeRef::create (*this , mangling.result (), params, typeref);
628
+ }
629
+ return typeref;
629
630
}
630
631
631
632
const BoundGenericTypeRef *
@@ -634,17 +635,58 @@ class TypeRefBuilder {
634
635
if (!builtTypeDecl)
635
636
return nullptr ;
636
637
637
- if (!builtTypeDecl->genericParamsPerLevel )
638
+ // If there aren't generic params on the parent types, we just emit
639
+ // a single BG typeref with all the generic args
640
+ auto maybeGenericParamsPerLevel = builtTypeDecl->genericParamsPerLevel ;
641
+ if (!maybeGenericParamsPerLevel) {
638
642
return BoundGenericTypeRef::create (*this , builtTypeDecl->mangledName , args, nullptr );
643
+ }
639
644
640
-
645
+ // Otherwise, work from a full demangle tree to produce a
646
+ // typeref that includes information about parent generic args
641
647
auto node = Dem.demangleType (builtTypeDecl->mangledName );
642
- if (!node || !node->hasChildren () || node->getKind () != Node::Kind::Type)
648
+ if (!node || !node->hasChildren () || node->getKind () != Node::Kind::Type) {
649
+ return nullptr ;
650
+ }
651
+ auto startNode = node->getFirstChild ();
652
+ auto mangling = Demangle::mangleNode (startNode);
653
+ if (!mangling.isSuccess ()) {
643
654
return nullptr ;
655
+ }
656
+
657
+ // Sanity: Verify that the generic params per level add
658
+ // up exactly to the number of args we were provided, and
659
+ // that we don't have a rediculous number of either one
660
+ auto genericParamsPerLevel = *maybeGenericParamsPerLevel;
661
+ if (genericParamsPerLevel.size () > 1000 || args.size () > 1000 ) {
662
+ return nullptr ;
663
+ }
664
+ size_t totalParams = 0 ;
665
+ for (size_t i = 0 ; i < genericParamsPerLevel.size (); i++) {
666
+ if (genericParamsPerLevel[i] > args.size ()) {
667
+ return nullptr ;
668
+ }
669
+ totalParams += genericParamsPerLevel[i];
670
+ }
671
+ if (totalParams != args.size ()) {
672
+ return nullptr ;
673
+ }
644
674
645
- auto type = node->getFirstChild ();
646
- return createBoundGenericTypeReconstructingParent (
647
- type, *builtTypeDecl, builtTypeDecl->genericParamsPerLevel ->size () - 1 , args, 0 );
675
+ // Reconstruct all parents that have non-zero generic params
676
+ auto parents = reconstructParentsOfBoundGenericType (startNode, genericParamsPerLevel, args);
677
+
678
+ // Collect the final set of generic params for the
679
+ // innermost type. Note: This will sometimes be empty:
680
+ // consider `Foo<Int, String>.Bar.Baz<Double>.Quux`
681
+ // which has 2 parents in the parent list
682
+ // (`Foo<Int,String>`, `Baz<Double>`), and the
683
+ // startNode is `Quux` with no params.
684
+ auto numGenericArgs = genericParamsPerLevel[genericParamsPerLevel.size () - 1 ];
685
+ auto argBegin = args.end () - numGenericArgs;
686
+ std::vector<const TypeRef *> params (argBegin, args.end ());
687
+
688
+ // Build and return the top typeref
689
+ return BoundGenericTypeRef::create (*this , mangling.result (), params, parents);
648
690
}
649
691
650
692
const BoundGenericTypeRef *
0 commit comments