TypeLookupErrorOr decodeMangledType()

in include/swift/Demangling/TypeDecoder.h [483:1285]


  TypeLookupErrorOr<BuiltType> decodeMangledType(NodePointer Node,
                                                 unsigned depth,
                                                 bool forRequirement = true) {
    if (depth > TypeDecoder::MaxDepth)
      return TypeLookupError("Mangled type is too complex");

    if (!Node)
      return TypeLookupError("Node is NULL");

    using NodeKind = Demangle::Node::Kind;
    switch (Node->getKind()) {
    case NodeKind::Global:
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children.");

      return decodeMangledType(Node->getChild(0), depth + 1);
    case NodeKind::TypeMangling:
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children.");

      return decodeMangledType(Node->getChild(0), depth + 1);
    case NodeKind::Type:
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children.");

      return decodeMangledType(Node->getChild(0), depth + 1,
                               forRequirement);
    case NodeKind::Class:
    {
#if SWIFT_OBJC_INTEROP
      if (auto mangledName = getObjCClassOrProtocolName(Node))
        return Builder.createObjCClassType(mangledName->str());
#endif
      LLVM_FALLTHROUGH;
    }
    case NodeKind::Enum:
    case NodeKind::Structure:
    case NodeKind::TypeAlias:
    case NodeKind::TypeSymbolicReference:
    {
      BuiltTypeDecl typeDecl = BuiltTypeDecl();
      BuiltType parent = BuiltType();
      bool typeAlias = false;
      if (auto error =
              decodeMangledTypeDecl(Node, depth, typeDecl, parent, typeAlias))
        return *error;

      if (typeAlias)
        return Builder.createTypeAliasType(typeDecl, parent);

      return Builder.createNominalType(typeDecl, parent);
    }

    case NodeKind::BoundGenericEnum:
    case NodeKind::BoundGenericStructure:
    case NodeKind::BoundGenericClass:
    case NodeKind::BoundGenericTypeAlias:
    case NodeKind::BoundGenericOtherNominalType: {
      if (Node->getNumChildren() < 2)
        return MAKE_NODE_TYPE_ERROR(Node,
                                    "fewer children (%zu) than required (2)",
                                    Node->getNumChildren());

      llvm::SmallVector<BuiltType, 8> args;

      const auto &genericArgs = Node->getChild(1);
      if (genericArgs->getKind() != NodeKind::TypeList)
        return MAKE_NODE_TYPE_ERROR0(genericArgs, "is not TypeList");

      for (auto genericArg : *genericArgs) {
        auto paramType = decodeMangledType(genericArg, depth + 1,
                                           /*forRequirement=*/false);
        if (paramType.isError())
          return paramType;
        args.push_back(paramType.getType());
      }

      auto ChildNode = Node->getChild(0);
      if (ChildNode->getKind() == NodeKind::Type &&
          ChildNode->getNumChildren() > 0)
        ChildNode = ChildNode->getChild(0);

#if SWIFT_OBJC_INTEROP
      if (auto mangledName = getObjCClassOrProtocolName(ChildNode))
        return Builder.createBoundGenericObjCClassType(mangledName->str(),
                                                       args);
#endif

      BuiltTypeDecl typeDecl = BuiltTypeDecl();
      BuiltType parent = BuiltType();
      bool typeAlias = false;
      if (auto error = decodeMangledTypeDecl(ChildNode, depth, typeDecl, parent,
                                             typeAlias))
        return *error;

      return Builder.createBoundGenericType(typeDecl, args, parent);
    }
    case NodeKind::BoundGenericProtocol: {
      // This is a special case. When you write a protocol typealias with a
      // concrete type base, for example:
      //
      // protocol P { typealias A<T> = ... }
      // struct S : P {}
      // let x: S.A<Int> = ...
      //
      // The mangling tree looks like this:
      //
      // BoundGenericProtocol ---> BoundGenericTypeAlias
      // |                         |
      // |                         |
      // --> Protocol: P           --> TypeAlias: A
      // |                         |
      // --> TypeList:             --> TypeList:
      //     |                         |
      //     --> Structure: S          --> Structure: Int
      //
      // When resolving the mangling tree to a decl, we strip off the
      // BoundGenericProtocol's *argument*, leaving behind only the
      // protocol reference.
      //
      // But when resolving it to a type, we want to *keep* the argument
      // so that the parent type becomes 'S' and not 'P'.
      if (Node->getNumChildren() < 2)
        return MAKE_NODE_TYPE_ERROR(Node,
                                    "fewer children (%zu) than required (2)",
                                    Node->getNumChildren());

      const auto &genericArgs = Node->getChild(1);
      if (genericArgs->getNumChildren() != 1)
        return MAKE_NODE_TYPE_ERROR(genericArgs,
                                    "expected 1 generic argument, saw %zu",
                                    genericArgs->getNumChildren());

      return decodeMangledType(genericArgs->getChild(0), depth + 1);
    }
    case NodeKind::BuiltinTypeName: {
      auto mangling = Demangle::mangleNode(Node);
      if (!mangling.isSuccess()) {
        return MAKE_NODE_TYPE_ERROR(Node,
                                    "failed to mangle node (%d:%u)",
                                    mangling.error().code,
                                    mangling.error().line);
      }
      return Builder.createBuiltinType(Node->getText().str(), mangling.result());
    }
    case NodeKind::Metatype:
    case NodeKind::ExistentialMetatype: {
      unsigned i = 0;
      llvm::Optional<ImplMetatypeRepresentation> repr;

      // Handle lowered metatypes in a hackish way. If the representation
      // was not thin, force the resulting typeref to have a non-empty
      // representation.
      if (Node->getNumChildren() >= 2) {
        auto reprNode = Node->getChild(i++);
        if (reprNode->getKind() != NodeKind::MetatypeRepresentation ||
            !reprNode->hasText())
          return MAKE_NODE_TYPE_ERROR0(reprNode, "wrong node kind or no text");
        if (reprNode->getText() == "@thin")
          repr = ImplMetatypeRepresentation::Thin;
        else if (reprNode->getText() == "@thick")
          repr = ImplMetatypeRepresentation::Thick;
        else if (reprNode->getText() == "@objc_metatype")
          repr = ImplMetatypeRepresentation::ObjC;
      } else if (Node->getNumChildren() < 1) {
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");
      }

      auto instance = decodeMangledType(Node->getChild(i), depth + 1);
      if (instance.isError())
        return instance;
      if (Node->getKind() == NodeKind::Metatype) {
        return Builder.createMetatypeType(instance.getType(), repr);
      } else if (Node->getKind() == NodeKind::ExistentialMetatype) {
        return Builder.createExistentialMetatypeType(instance.getType(), repr);
      } else {
        assert(false);
        return MAKE_NODE_TYPE_ERROR0(Node,
                                     "Metatype/ExistentialMetatype Node "
                                     "had a different kind when re-checked");
      }
    }
    case NodeKind::ProtocolList:
    case NodeKind::ProtocolListWithAnyObject:
    case NodeKind::ProtocolListWithClass: {
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");

      // Find the protocol list.
      llvm::SmallVector<BuiltProtocolDecl, 8> Protocols;
      auto TypeList = Node->getChild(0);
      if (TypeList->getKind() == NodeKind::ProtocolList &&
          TypeList->getNumChildren() >= 1) {
        TypeList = TypeList->getChild(0);
      }

      // Demangle the protocol list.
      for (auto componentType : *TypeList) {
        if (auto Protocol = decodeMangledProtocolType(componentType, depth + 1))
          Protocols.push_back(Protocol);
        else
          return MAKE_NODE_TYPE_ERROR0(componentType,
                                       "failed to decode protocol type");
      }

      // Superclass or AnyObject, if present.
      bool IsClassBound = false;
      auto Superclass = BuiltType();
      if (Node->getKind() == NodeKind::ProtocolListWithClass) {
        if (Node->getNumChildren() < 2)
          return MAKE_NODE_TYPE_ERROR(Node,
                                      "fewer children (%zu) than required (2)",
                                      Node->getNumChildren());

        auto superclassNode = Node->getChild(1);
        auto result = decodeMangledType(superclassNode, depth + 1);
        if (result.isError())
          return result;
        Superclass = result.getType();

        IsClassBound = true;
      } else if (Node->getKind() == NodeKind::ProtocolListWithAnyObject) {
        IsClassBound = true;
      }

      return Builder.createProtocolCompositionType(Protocols, Superclass,
                                                   IsClassBound,
                                                   forRequirement);
    }

    case NodeKind::Protocol:
    case NodeKind::ProtocolSymbolicReference: {
      if (auto Proto = decodeMangledProtocolType(Node, depth + 1)) {
        return Builder.createProtocolCompositionType(Proto, BuiltType(),
                                                     /*IsClassBound=*/false,
                                                     forRequirement);
      }

      return MAKE_NODE_TYPE_ERROR0(Node, "failed to decode protocol type");
    }
    case NodeKind::DynamicSelf: {
      if (Node->getNumChildren() != 1)
        return MAKE_NODE_TYPE_ERROR(Node, "expected 1 child, saw %zu",
                                    Node->getNumChildren());

      auto selfType = decodeMangledType(Node->getChild(0), depth + 1);
      if (selfType.isError())
        return selfType;

      return Builder.createDynamicSelfType(selfType.getType());
    }
    case NodeKind::DependentGenericParamType: {
      auto depth = Node->getChild(0)->getIndex();
      auto index = Node->getChild(1)->getIndex();
      return Builder.createGenericTypeParameterType(depth, index);
    }
    case NodeKind::EscapingObjCBlock:
    case NodeKind::ObjCBlock:
    case NodeKind::CFunctionPointer:
    case NodeKind::ThinFunctionType:
    case NodeKind::NoEscapeFunctionType:
    case NodeKind::AutoClosureType:
    case NodeKind::EscapingAutoClosureType:
    case NodeKind::FunctionType: {
      if (Node->getNumChildren() < 2)
        return MAKE_NODE_TYPE_ERROR(Node,
                                    "fewer children (%zu) than required (2)",
                                    Node->getNumChildren());

      FunctionTypeFlags flags;
      if (Node->getKind() == NodeKind::ObjCBlock ||
          Node->getKind() == NodeKind::EscapingObjCBlock) {
        flags = flags.withConvention(FunctionMetadataConvention::Block);
      } else if (Node->getKind() == NodeKind::CFunctionPointer) {
        flags =
          flags.withConvention(FunctionMetadataConvention::CFunctionPointer);
      } else if (Node->getKind() == NodeKind::ThinFunctionType) {
        flags = flags.withConvention(FunctionMetadataConvention::Thin);
      }

      unsigned firstChildIdx = 0;
      if (Node->getChild(firstChildIdx)->getKind() == NodeKind::ClangType) {
        // [TODO: synthesize-Clang-type-from-mangled-name] Use the first child
        // to create a ClangTypeInfo.
        ++firstChildIdx;
      }

      BuiltType globalActorType = BuiltType();
      if (Node->getChild(firstChildIdx)->getKind() ==
          NodeKind::GlobalActorFunctionType) {
        auto child = Node->getChild(firstChildIdx);
        if (child->getNumChildren() < 1) {
          return MAKE_NODE_TYPE_ERROR0(child,
                                       "Global actor node is missing child");
        }

        auto globalActorResult =
            decodeMangledType(child->getChild(0), depth + 1);
        if (globalActorResult.isError())
          return globalActorResult;

        globalActorType = globalActorResult.getType();
        ++firstChildIdx;
      }

      FunctionMetadataDifferentiabilityKind diffKind;
      if (Node->getChild(firstChildIdx)->getKind() ==
            NodeKind::DifferentiableFunctionType) {
        auto mangledDiffKind = (MangledDifferentiabilityKind)
            Node->getChild(firstChildIdx)->getIndex();
        switch (mangledDiffKind) {
        case MangledDifferentiabilityKind::NonDifferentiable:
          assert(false && "Unexpected case NonDifferentiable");
          break;
        case MangledDifferentiabilityKind::Forward:
          diffKind = FunctionMetadataDifferentiabilityKind::Forward;
          break;
        case MangledDifferentiabilityKind::Reverse:
          diffKind = FunctionMetadataDifferentiabilityKind::Reverse;
          break;
        case MangledDifferentiabilityKind::Normal:
          diffKind = FunctionMetadataDifferentiabilityKind::Normal;
          break;
        case MangledDifferentiabilityKind::Linear:
          diffKind = FunctionMetadataDifferentiabilityKind::Linear;
          break;
        }
        ++firstChildIdx;
      }

      bool isThrow = false;
      if (Node->getChild(firstChildIdx)->getKind()
            == NodeKind::ThrowsAnnotation) {
        isThrow = true;
        ++firstChildIdx;
      }

      bool isSendable = false;
      if (Node->getChild(firstChildIdx)->getKind()
            == NodeKind::ConcurrentFunctionType) {
        isSendable = true;
        ++firstChildIdx;
      }

      bool isAsync = false;
      if (Node->getChild(firstChildIdx)->getKind()
            == NodeKind::AsyncAnnotation) {
        isAsync = true;
        ++firstChildIdx;
      }

      flags = flags.withConcurrent(isSendable)
          .withAsync(isAsync).withThrows(isThrow)
          .withDifferentiable(diffKind.isDifferentiable());

      if (Node->getNumChildren() < firstChildIdx + 2)
        return MAKE_NODE_TYPE_ERROR(Node,
                                    "fewer children (%zu) than required (%u)",
                                    Node->getNumChildren(), firstChildIdx + 2);

      bool hasParamFlags = false;
      llvm::SmallVector<FunctionParam<BuiltType>, 8> parameters;
      if (!decodeMangledFunctionInputType(Node->getChild(firstChildIdx),
                                          depth + 1, parameters, hasParamFlags))
        return MAKE_NODE_TYPE_ERROR0(Node->getChild(firstChildIdx),
                                     "failed to decode function type");
      flags =
          flags.withNumParameters(parameters.size())
              .withParameterFlags(hasParamFlags)
              .withEscaping(
                          Node->getKind() == NodeKind::FunctionType ||
                          Node->getKind() == NodeKind::EscapingAutoClosureType ||
                          Node->getKind() == NodeKind::EscapingObjCBlock);

      auto result =
          decodeMangledType(Node->getChild(firstChildIdx + 1), depth + 1,
                            /*forRequirement=*/false);
      if (result.isError())
        return result;
      return Builder.createFunctionType(
          parameters, result.getType(), flags, diffKind, globalActorType);
    }
    case NodeKind::ImplFunctionType: {
      auto calleeConvention = ImplParameterConvention::Direct_Unowned;
      llvm::SmallVector<ImplFunctionParam<BuiltType>, 8> parameters;
      llvm::SmallVector<ImplFunctionResult<BuiltType>, 8> results;
      llvm::SmallVector<ImplFunctionResult<BuiltType>, 8> errorResults;
      ImplFunctionTypeFlags flags;

      for (unsigned i = 0; i < Node->getNumChildren(); i++) {
        auto child = Node->getChild(i);

        if (child->getKind() == NodeKind::ImplConvention) {
          if (!child->hasText())
            return MAKE_NODE_TYPE_ERROR0(child, "expected text");

          if (child->getText() == "@convention(thin)") {
            flags =
              flags.withRepresentation(ImplFunctionRepresentation::Thin);
          } else if (child->getText() == "@callee_guaranteed") {
            calleeConvention = ImplParameterConvention::Direct_Guaranteed;
          }
        } else if (child->getKind() == NodeKind::ImplFunctionConvention) {
          if (child->getNumChildren() == 0)
            return MAKE_NODE_TYPE_ERROR0(child, "expected grandchildren");
          if ((child->getFirstChild()->getKind() !=
               NodeKind::ImplFunctionConventionName) ||
              !child->getFirstChild()->hasText())
            return MAKE_NODE_TYPE_ERROR0(child, "expected convention name");

          // [TODO: synthesize-Clang-type-from-mangled-name] If there are two
          // grand-children, the second is going to be the mangled Clang type.
          StringRef text = child->getFirstChild()->getText();
          if (text == "c") {
            flags =
              flags.withRepresentation(ImplFunctionRepresentation::CFunctionPointer);
          } else if (text == "block") {
            flags =
              flags.withRepresentation(ImplFunctionRepresentation::Block);
          }
        } else if (child->getKind() == NodeKind::ImplFunctionAttribute) {
          if (!child->hasText())
            return MAKE_NODE_TYPE_ERROR0(child, "expected text");
          if (child->getText() == "@Sendable") {
            flags = flags.withConcurrent();
          } else if (child->getText() == "@async") {
            flags = flags.withAsync();
          }
        } else if (child->getKind() == NodeKind::ImplDifferentiabilityKind) {
          ImplFunctionDifferentiabilityKind implDiffKind;
          switch ((MangledDifferentiabilityKind)child->getIndex()) {
          #define SIMPLE_CASE(CASE) \
              case MangledDifferentiabilityKind::CASE: \
                implDiffKind = ImplFunctionDifferentiabilityKind::CASE; break;
          SIMPLE_CASE(NonDifferentiable)
          SIMPLE_CASE(Normal)
          SIMPLE_CASE(Linear)
          SIMPLE_CASE(Forward)
          SIMPLE_CASE(Reverse)
          #undef SIMPLE_CASE
          }
          flags = flags.withDifferentiabilityKind(implDiffKind);
        } else if (child->getKind() == NodeKind::ImplEscaping) {
          flags = flags.withEscaping();
        } else if (child->getKind() == NodeKind::ImplParameter) {
          if (decodeImplFunctionParam(child, depth + 1, parameters))
            return MAKE_NODE_TYPE_ERROR0(child,
                                         "failed to decode function parameter");
        } else if (child->getKind() == NodeKind::ImplResult) {
          if (decodeImplFunctionParam(child, depth + 1, results))
            return MAKE_NODE_TYPE_ERROR0(child,
                                         "failed to decode function parameter");
        } else if (child->getKind() == NodeKind::ImplErrorResult) {
          if (decodeImplFunctionPart(child, depth + 1, errorResults))
            return MAKE_NODE_TYPE_ERROR0(child,
                                         "failed to decode function part");
        } else {
          return MAKE_NODE_TYPE_ERROR0(child, "unexpected kind");
        }
      }

      llvm::Optional<ImplFunctionResult<BuiltType>> errorResult;
      switch (errorResults.size()) {
      case 0:
        break;
      case 1:
        errorResult = errorResults.front();
        break;
      default:
        return MAKE_NODE_TYPE_ERROR(Node, "got %zu errors",
                                    errorResults.size());
      }

      // TODO: Some cases not handled above, but *probably* they cannot
      // appear as the types of values in SIL (yet?):
      // - functions with yield returns
      // - functions with generic signatures
      // - foreign error conventions
      return Builder.createImplFunctionType(calleeConvention,
                                            parameters, results,
                                            errorResult, flags);
    }

    case NodeKind::ArgumentTuple:
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");

      return decodeMangledType(Node->getChild(0), depth + 1);

    case NodeKind::ReturnType:
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");

      return decodeMangledType(Node->getChild(0), depth + 1,
                               /*forRequirement=*/false);

    case NodeKind::Tuple: {
      llvm::SmallVector<BuiltType, 8> elements;
      std::string labels;
      for (auto &element : *Node) {
        if (element->getKind() != NodeKind::TupleElement)
          return MAKE_NODE_TYPE_ERROR0(Node, "unexpected kind");

        // If the tuple element is labeled, add its label to 'labels'.
        unsigned typeChildIndex = 0;
        if (element->getChild(typeChildIndex)->getKind() == NodeKind::VariadicMarker) {
          return MAKE_NODE_TYPE_ERROR0(element->getChild(typeChildIndex),
                                       "no children");
        }
        if (element->getChild(typeChildIndex)->getKind() == NodeKind::TupleElementName) {
          // Add spaces to terminate all the previous labels if this
          // is the first we've seen.
          if (labels.empty()) labels.append(elements.size(), ' ');

          // Add the label and its terminator.
          labels += element->getChild(typeChildIndex)->getText();
          labels += ' ';
          typeChildIndex++;

        // Otherwise, add a space if a previous element had a label.
        } else if (!labels.empty()) {
          labels += ' ';
        }

        // Decode the element type.
        auto elementType =
            decodeMangledType(element->getChild(typeChildIndex), depth + 1,
                              /*forRequirement=*/false);
        if (elementType.isError())
          return elementType;

        elements.push_back(elementType.getType());
      }
      return Builder.createTupleType(elements, std::move(labels));
    }
    case NodeKind::TupleElement:
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");

      if (Node->getChild(0)->getKind() == NodeKind::TupleElementName) {
        if (Node->getNumChildren() < 2)
          return MAKE_NODE_TYPE_ERROR(Node,
                                      "fewer children (%zu) than required (2)",
                                      Node->getNumChildren());

        return decodeMangledType(Node->getChild(1), depth + 1,
                                 /*forRequirement=*/false);
      }
      return decodeMangledType(Node->getChild(0), depth + 1,
                               /*forRequirement=*/false);

    case NodeKind::DependentGenericType: {
      if (Node->getNumChildren() < 2)
        return MAKE_NODE_TYPE_ERROR(Node,
                                    "fewer children (%zu) than required (2)",
                                    Node->getNumChildren());

      return decodeMangledType(Node->getChild(1), depth + 1);
    }
    case NodeKind::DependentMemberType: {
      if (Node->getNumChildren() < 2)
        return MAKE_NODE_TYPE_ERROR(Node,
                                    "fewer children (%zu) than required (2)",
                                    Node->getNumChildren());

      auto base = decodeMangledType(Node->getChild(0), depth + 1);
      if (base.isError())
        return base;
      auto assocTypeChild = Node->getChild(1);
      auto member = assocTypeChild->getFirstChild()->getText();
      if (assocTypeChild->getNumChildren() < 2)
        return Builder.createDependentMemberType(member.str(), base.getType());

      auto protocol =
          decodeMangledProtocolType(assocTypeChild->getChild(1), depth + 1);
      if (!protocol)
        return BuiltType();
      return Builder.createDependentMemberType(member.str(), base.getType(),
                                               protocol);
    }
    case NodeKind::DependentAssociatedTypeRef: {
      if (Node->getNumChildren() < 2)
        return MAKE_NODE_TYPE_ERROR(Node,
                                    "fewer children (%zu) than required (2)",
                                    Node->getNumChildren());

      return decodeMangledType(Node->getChild(1), depth + 1);
    }
    case NodeKind::Unowned: {
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");

      auto base = decodeMangledType(Node->getChild(0), depth + 1);
      if (base.isError())
        return base;
      return Builder.createUnownedStorageType(base.getType());
    }
    case NodeKind::Unmanaged: {
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");

      auto base = decodeMangledType(Node->getChild(0), depth + 1);
      if (base.isError())
        return base;
      return Builder.createUnmanagedStorageType(base.getType());
    }
    case NodeKind::Weak: {
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");

      auto base = decodeMangledType(Node->getChild(0), depth + 1);
      if (base.isError())
        return base;
      return Builder.createWeakStorageType(base.getType());
    }
    case NodeKind::SILBoxType: {
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");

      auto base = decodeMangledType(Node->getChild(0), depth + 1);
      if (base.isError())
        return base;
      return Builder.createSILBoxType(base.getType());
    }
    case NodeKind::SILBoxTypeWithLayout: {
      llvm::SmallVector<Field, 4> fields;
      llvm::SmallVector<BuiltSubstitution, 4> substitutions;
      llvm::SmallVector<BuiltRequirement, 4> requirements;

      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");

      auto fieldsNode = Node->getChild(0);
      if (fieldsNode->getKind() != NodeKind::SILBoxLayout)
        return MAKE_NODE_TYPE_ERROR0(fieldsNode, "expected layout");
      for (auto *fieldNode : *fieldsNode) {
        bool isMutable;
        switch (fieldNode->getKind()) {
        case NodeKind::SILBoxMutableField: isMutable = true; break;
        case NodeKind::SILBoxImmutableField: isMutable = false; break;
        default:
          return MAKE_NODE_TYPE_ERROR0(fieldNode, "unhandled field type");
        }
        if (fieldNode->getNumChildren() < 1)
          return MAKE_NODE_TYPE_ERROR0(fieldNode, "no children");
        auto type = decodeMangledType(fieldNode->getChild(0), depth + 1);
        if (type.isError())
          return type;
        fields.emplace_back(type.getType(), isMutable);
      }

      if (Node->getNumChildren() > 1) {
        auto *substNode = Node->getChild(2);
        if (substNode->getKind() != NodeKind::TypeList)
          return MAKE_NODE_TYPE_ERROR0(substNode, "expected type list");

        auto *dependentGenericSignatureNode = Node->getChild(1);
        if (dependentGenericSignatureNode->getKind() !=
            NodeKind::DependentGenericSignature)
          return MAKE_NODE_TYPE_ERROR0(dependentGenericSignatureNode,
                                       "expected dependent generic signature");
        if (dependentGenericSignatureNode->getNumChildren() < 1)
          return MAKE_NODE_TYPE_ERROR(
              dependentGenericSignatureNode,
              "fewer children (%zu) than required (1)",
              dependentGenericSignatureNode->getNumChildren());
        decodeRequirement<BuiltType, BuiltRequirement, BuiltLayoutConstraint,
                          BuilderType>(dependentGenericSignatureNode,
                                       requirements,
                                       Builder /*,
[&](NodePointer Node) -> BuiltType {
return decodeMangledType(Node, depth + 1).getType();
},
[&](LayoutConstraintKind Kind) -> BuiltLayoutConstraint {
return {}; // Not implemented!
},
[&](LayoutConstraintKind Kind, unsigned SizeInBits,
unsigned Alignment) -> BuiltLayoutConstraint {
return {}; // Not Implemented!
}*/);
        // The number of generic parameters at each depth are in a mini
        // state machine and come first.
        llvm::SmallVector<unsigned, 4> genericParamsAtDepth;
        for (auto *reqNode : *dependentGenericSignatureNode)
          if (reqNode->getKind() == NodeKind::DependentGenericParamCount)
            if (reqNode->hasIndex())
              genericParamsAtDepth.push_back(reqNode->getIndex());
        unsigned paramDepth = 0;
        unsigned index = 0;
        for (auto *subst : *substNode) {
          if (paramDepth >= genericParamsAtDepth.size())
            return MAKE_NODE_TYPE_ERROR0(
                dependentGenericSignatureNode,
                "more substitutions than generic params");
          while (index >= genericParamsAtDepth[paramDepth])
            ++paramDepth, index = 0;
          auto substTy = decodeMangledType(subst, depth + 1,
                                           /*forRequirement=*/false);
          if (substTy.isError())
            return substTy;
          substitutions.emplace_back(
              Builder.createGenericTypeParameterType(paramDepth, index),
              substTy.getType());
          ++index;
        }
      }

      return Builder.createSILBoxTypeWithLayout(fields, substitutions,
                                                requirements);
    }
    case NodeKind::SugaredOptional: {
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");

      auto base = decodeMangledType(Node->getChild(0), depth + 1);
      if (base.isError())
        return base;

      return Builder.createOptionalType(base.getType());
    }
    case NodeKind::SugaredArray: {
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");

      auto base = decodeMangledType(Node->getChild(0), depth + 1);
      if (base.isError())
        return base;

      return Builder.createArrayType(base.getType());
    }
    case NodeKind::SugaredDictionary: {
      if (Node->getNumChildren() < 2)
        return MAKE_NODE_TYPE_ERROR(Node,
                                    "fewer children (%zu) than required (2)",
                                    Node->getNumChildren());

      auto key = decodeMangledType(Node->getChild(0), depth + 1);
      if (key.isError())
        return key;

      auto value = decodeMangledType(Node->getChild(1), depth + 1);
      if (value.isError())
        return value;

      return Builder.createDictionaryType(key.getType(), value.getType());
    }
    case NodeKind::SugaredParen: {
      if (Node->getNumChildren() < 1)
        return MAKE_NODE_TYPE_ERROR0(Node, "no children");

      auto base = decodeMangledType(Node->getChild(0), depth + 1);
      if (base.isError())
        return base;

      return Builder.createParenType(base.getType());
    }
    case NodeKind::OpaqueType: {
      if (Node->getNumChildren() < 3)
        return MAKE_NODE_TYPE_ERROR(Node,
                                    "fewer children (%zu) than required (3)",
                                    Node->getNumChildren());
      auto descriptor = Node->getChild(0);
      auto ordinalNode = Node->getChild(1);

      if (ordinalNode->getKind() != NodeKind::Index
          || !ordinalNode->hasIndex())
        return MAKE_NODE_TYPE_ERROR0(ordinalNode,
                                     "unexpected kind or no index");
      auto ordinal = ordinalNode->getIndex();

      std::vector<BuiltType> genericArgsBuf;
      std::vector<unsigned> genericArgsLevels;
      auto boundGenerics = Node->getChild(2);
      for (unsigned i = 0; i < boundGenerics->getNumChildren(); ++i) {
        genericArgsLevels.push_back(genericArgsBuf.size());
        auto genericsNode = boundGenerics->getChild(i);
        if (genericsNode->getKind() != NodeKind::TypeList)
          break;
        for (auto argNode : *genericsNode) {
          auto arg = decodeMangledType(argNode, depth + 1,
                                       /*forRequirement=*/false);
          if (arg.isError())
            return arg;
          genericArgsBuf.push_back(arg.getType());
        }
      }
      genericArgsLevels.push_back(genericArgsBuf.size());
      std::vector<llvm::ArrayRef<BuiltType>> genericArgs;
      for (unsigned i = 0; i < genericArgsLevels.size() - 1; ++i) {
        auto start = genericArgsLevels[i], end = genericArgsLevels[i+1];
        genericArgs.emplace_back(genericArgsBuf.data() + start,
                                 end - start);
      }
      
      return Builder.resolveOpaqueType(descriptor, genericArgs, ordinal);
    }
    // TODO: Handle OpaqueReturnType, when we're in the middle of reconstructing
    // the defining decl
    default:

      return MAKE_NODE_TYPE_ERROR0(Node, "unexpected kind");
    }
  }