NodePointer Remangler::getUnspecialized(Node *node) { switch (node->getKind()) { case Node::Kind::Structure: case Node::Kind::Enum: case Node::Kind::Class: { NodePointer result = NodeFactory::create(node->getKind()); NodePointer parentOrModule = node->getChild(0); if (isSpecialized(parentOrModule.get())) result->addChild(getUnspecialized(parentOrModule.get())); else result->addChild(parentOrModule); result->addChild(node->getChild(1)); return result; } case Node::Kind::BoundGenericStructure: case Node::Kind::BoundGenericEnum: case Node::Kind::BoundGenericClass: { NodePointer unboundType = node->getChild(0); assert(unboundType->getKind() == Node::Kind::Type); NodePointer nominalType = unboundType->getChild(0); if (isSpecialized(nominalType.get())) return getUnspecialized(nominalType.get()); else return nominalType; } default: unreachable("bad nominal type kind"); } }
void Remangler::mangleGenericArgs(Node *node, EntityContext &ctx) { switch (node->getKind()) { case Node::Kind::Structure: case Node::Kind::Enum: case Node::Kind::Class: { NodePointer parentOrModule = node->getChild(0); mangleGenericArgs(parentOrModule.get(), ctx); // No generic arguments at this level Out << '_'; break; } case Node::Kind::BoundGenericStructure: case Node::Kind::BoundGenericEnum: case Node::Kind::BoundGenericClass: { NodePointer unboundType = node->getChild(0); assert(unboundType->getKind() == Node::Kind::Type); NodePointer nominalType = unboundType->getChild(0); NodePointer parentOrModule = nominalType->getChild(0); mangleGenericArgs(parentOrModule.get(), ctx); mangleTypeList(node->getChild(1).get()); break; } default: break; } }
/// The top-level interface to the remangler. std::string Demangle::mangleNode(const NodePointer &node) { if (!node) return ""; DemanglerPrinter printer; Remangler(printer).mangle(node.get()); return std::move(printer).str(); }
void Remangler::mangleAnyNominalType(Node *node, EntityContext &ctx) { if (isSpecialized(node)) { Out << 'G'; NodePointer unboundType = getUnspecialized(node); TemporaryNodes.push_back(unboundType); mangleAnyNominalType(unboundType.get(), ctx); mangleGenericArgs(node, ctx); return; } switch (node->getKind()) { case Node::Kind::Structure: mangleNominalType(node, 'V', ctx); break; case Node::Kind::Enum: mangleNominalType(node, 'O', ctx); break; case Node::Kind::Class: mangleNominalType(node, 'C', ctx); break; default: unreachable("bad nominal type kind"); } }
/// The top-level interface to the remangler. std::string Demangle::mangleNode(const NodePointer &node) { if (!node) return ""; std::string str; DemanglerPrinter printer(str); Remangler(printer).mangle(node.get()); return str; }