@@ -570,16 +570,15 @@ class TypeRefBuilder {
570
570
// Construct a bound generic type ref along with the parent type info
571
571
// The parent list contains every parent type with at least 1 generic
572
572
// type parameter.
573
- const BoundGenericTypeRef *createBoundGenericTypeReconstructingParent (
573
+ const BoundGenericTypeRef *reconstructParentsOfBoundGenericType (
574
574
const NodePointer startNode,
575
575
const std::vector<size_t > &genericParamsPerLevel,
576
576
const llvm::ArrayRef<const TypeRef *> &args)
577
577
{
578
- // Collect all the relevant nodes, including the current node
578
+ // Collect the first N parents that potentially have generic args
579
+ // (Ignore the last genericParamPerLevel, which
580
+ // applies to the startNode itself.)
579
581
std::vector<NodePointer> nodes;
580
-
581
- // Iterate our parents, collecting the first N parents
582
- // that potentially have generic args
583
582
NodePointer node = startNode;
584
583
while (nodes.size () < genericParamsPerLevel.size () - 1 ) {
585
584
if (!node || !node->hasChildren ()) {
@@ -607,7 +606,6 @@ class TypeRefBuilder {
607
606
// the generic argument list...
608
607
const BoundGenericTypeRef *typeref = nullptr ;
609
608
auto argBegin = args.begin ();
610
- size_t totalArgs = 0 ;
611
609
for (size_t i = 0 ; i < nodes.size (); i++) {
612
610
// Get the mangling for this node
613
611
auto mangling = Demangle::mangleNode (nodes[i]);
@@ -621,41 +619,14 @@ class TypeRefBuilder {
621
619
if (numGenericArgs == 0 ) {
622
620
continue ;
623
621
}
624
- if (numGenericArgs > args.size () || totalArgs + numGenericArgs > args.size ()) {
625
- return nullptr ;
626
- }
627
622
auto argEnd = argBegin + numGenericArgs;
628
- totalArgs += numGenericArgs;
629
623
std::vector<const TypeRef *> params (argBegin, argEnd);
630
624
argBegin = argEnd;
631
625
632
- // Extend the typeref up one level
626
+ // Extend the typeref list towards the innermost type
633
627
typeref = BoundGenericTypeRef::create (*this , mangling.result (), params, typeref);
634
628
}
635
-
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 ()) {
640
- return nullptr ;
641
- }
642
-
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
653
- return nullptr ;
654
- }
655
- std::vector<const TypeRef *> params (argBegin, argEnd);
656
-
657
- // Build and return the top typeref
658
- return BoundGenericTypeRef::create (*this , mangling.result (), params, typeref);
629
+ return typeref;
659
630
}
660
631
661
632
const BoundGenericTypeRef *
@@ -672,15 +643,50 @@ class TypeRefBuilder {
672
643
}
673
644
674
645
// Otherwise, work from a full demangle tree to produce a
675
- // typeref that includes all parents that have generic params
646
+ // typeref that includes information about parent generic args
676
647
auto node = Dem.demangleType (builtTypeDecl->mangledName );
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 {
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 ()) {
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 ()) {
682
672
return nullptr ;
683
673
}
674
+
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);
684
690
}
685
691
686
692
const BoundGenericTypeRef *
0 commit comments