@@ -567,61 +567,95 @@ class TypeRefBuilder {
567567 return nullptr ;
568568 }
569569
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.
572573 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+ }
587598 }
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+ }
588617
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);
602634 }
603635
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 ()) {
609640 return nullptr ;
641+ }
610642
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
615653 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);
622656
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 );
625659 }
626660
627661 const BoundGenericTypeRef *
@@ -630,16 +664,23 @@ class TypeRefBuilder {
630664 if (!builtTypeDecl)
631665 return nullptr ;
632666
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) {
634671 return BoundGenericTypeRef::create (*this , builtTypeDecl->mangledName , args, nullptr );
672+ }
635673
674+ // Otherwise, work from a full demangle tree to produce a
675+ // typeref that includes all parents that have generic params
636676 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 {
638682 return nullptr ;
639-
640- auto type = node->getFirstChild ();
641- return createBoundGenericTypeReconstructingParent (
642- type, *builtTypeDecl, builtTypeDecl->genericParamsPerLevel ->size () - 1 , args, 0 );
683+ }
643684 }
644685
645686 const BoundGenericTypeRef *
0 commit comments