//===--- Remangler.cpp - Swift re-mangling from a demangling tree ---------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // This file implements the remangler, which turns a demangling parse // tree back into a mangled string. This is useful for tools which // want to extract subtrees from mangled strings. // //===----------------------------------------------------------------------===// #include "DemanglerAssert.h" #include "RemanglerBase.h" #include "swift/AST/Ownership.h" #include "swift/Demangling/Demangler.h" #include "swift/Demangling/ManglingMacros.h" #include "swift/Demangling/ManglingUtils.h" #include "swift/Demangling/Punycode.h" #include "swift/Strings.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include #include using namespace swift; using namespace Demangle; using namespace Mangle; static char getCharOfNodeText(Node *node, unsigned idx) { switch (node->getKind()) { case Node::Kind::InfixOperator: case Node::Kind::PrefixOperator: case Node::Kind::PostfixOperator: return Mangle::translateOperatorChar(node->getText()[idx]); default: return node->getText()[idx]; } } bool SubstitutionEntry::identifierEquals(Node *lhs, Node *rhs) { unsigned length = lhs->getText().size(); if (rhs->getText().size() != length) return false; // The fast path. if (lhs->getKind() == rhs->getKind()) return lhs->getText() == rhs->getText(); // The slow path. for (unsigned i = 0; i < length; ++i) { if (getCharOfNodeText(lhs, i) != getCharOfNodeText(rhs, i)) return false; } return true; } bool SubstitutionEntry::deepEquals(Node *lhs, Node *rhs) const { if (!lhs->isSimilarTo(rhs)) return false; for (auto li = lhs->begin(), ri = rhs->begin(), le = lhs->end(); li != le; ++li, ++ri) { if (!deepEquals(*li, *ri)) return false; } return true; } static inline size_t combineHash(size_t currentHash, size_t newValue) { return 33 * currentHash + newValue; } /// Calculate the hash for a node. size_t RemanglerBase::hashForNode(Node *node, bool treatAsIdentifier) { size_t hash = 0; if (treatAsIdentifier) { hash = combineHash(hash, (size_t)Node::Kind::Identifier); assert(node->hasText()); switch (node->getKind()) { case Node::Kind::InfixOperator: case Node::Kind::PrefixOperator: case Node::Kind::PostfixOperator: for (char c : node->getText()) { hash = combineHash(hash, (unsigned char)translateOperatorChar(c)); } return hash; default: break; } } else { hash = combineHash(hash, (size_t) node->getKind()); } if (node->hasIndex()) { hash = combineHash(hash, node->getIndex()); } else if (node->hasText()) { for (char c : node->getText()) { hash = combineHash(hash, (unsigned char) c); } } for (Node *child : *node) { SubstitutionEntry entry = entryForNode(child, treatAsIdentifier); hash = combineHash(hash, entry.hash()); } return hash; } /// Rotate a size_t by N bits static inline size_t rotate(size_t value, size_t shift) { const size_t bits = sizeof(size_t) * 8; return (value >> shift) | (value << (bits - shift)); } /// Compute a hash value from a node *pointer*. /// Used for look-ups in HashHash. The numbers in here were determined /// experimentally. static inline size_t nodeHash(Node *node) { // Multiply by a magic number const size_t nodePrime = ((size_t)node) * 2043; // We rotate by a different amount because the alignment of Node // changes depending on the machine's pointer size switch (sizeof(size_t)) { case 4: return rotate(nodePrime, 11); case 8: return rotate(nodePrime, 12); case 16: return rotate(nodePrime, 13); default: return rotate(nodePrime, 12); } } /// Construct a SubstitutionEntry for a given node. /// This will look in the HashHash to see if we already know the hash /// (which avoids recursive hashing on the Node tree). SubstitutionEntry RemanglerBase::entryForNode(Node *node, bool treatAsIdentifier) { const size_t ident = treatAsIdentifier ? 4 : 0; const size_t hash = nodeHash(node) + ident; // Use linear probing with a limit for (size_t n = 0; n < HashHashMaxProbes; ++n) { const size_t ndx = (hash + n) & (HashHashCapacity - 1); SubstitutionEntry entry = HashHash[ndx]; if (entry.isEmpty()) { size_t entryHash = hashForNode(node, treatAsIdentifier); entry.setNode(node, treatAsIdentifier, entryHash); HashHash[ndx] = entry; return entry; } else if (entry.matches(node, treatAsIdentifier)) { return entry; } } // Hash table is full at this hash value SubstitutionEntry entry; size_t entryHash = hashForNode(node, treatAsIdentifier); entry.setNode(node, treatAsIdentifier, entryHash); return entry; } // Find a substitution and return its index. // Returns -1 if no substitution is found. int RemanglerBase::findSubstitution(const SubstitutionEntry &entry) { // First search in InlineSubstitutions. SubstitutionEntry *result = std::find(InlineSubstitutions, InlineSubstitutions + NumInlineSubsts, entry); if (result != InlineSubstitutions + NumInlineSubsts) return result - InlineSubstitutions; // Then search in OverflowSubstitutions. auto it = OverflowSubstitutions.find(entry); if (it == OverflowSubstitutions.end()) return -1; return it->second; } void RemanglerBase::addSubstitution(const SubstitutionEntry &entry) { assert(findSubstitution(entry) < 0); if (NumInlineSubsts < InlineSubstCapacity) { // There is still free space in NumInlineSubsts. assert(OverflowSubstitutions.empty()); InlineSubstitutions[NumInlineSubsts++] = entry; return; } // We have to add the entry to OverflowSubstitutions. unsigned Idx = OverflowSubstitutions.size() + InlineSubstCapacity; auto result = OverflowSubstitutions.insert({entry, Idx}); assert(result.second); (void) result; } namespace { class Remangler : public RemanglerBase { template friend void Mangle::mangleIdentifier(Mangler &M, StringRef ident); friend class Mangle::SubstitutionMerging; const ManglingFlavor Flavor = ManglingFlavor::Default; const bool UsePunycode = true; Vector Words; Vector SubstWordsInIdent; static const size_t MaxNumWords = 26; static const unsigned MaxDepth = 1024; SubstitutionMerging SubstMerging; // A callback for resolving symbolic references. SymbolicResolver Resolver; void addSubstWordsInIdent(const WordReplacement &repl) { SubstWordsInIdent.push_back(repl, Factory); } void addWord(const SubstitutionWord &word) { Words.push_back(word, Factory); } template friend void mangleIdentifier(Mangler &M, StringRef ident); class EntityContext { bool AsContext = false; public: class ManglingContextRAII { EntityContext &Ctx; bool SavedValue; public: ManglingContextRAII(EntityContext &ctx) : Ctx(ctx), SavedValue(ctx.AsContext) { ctx.AsContext = true; } ~ManglingContextRAII() { Ctx.AsContext = SavedValue; } }; }; // ###TODO: Consider fixing some of these asserts() to return errors somehow Node *getSingleChild(Node *node) { assert(node->getNumChildren() == 1); return node->getFirstChild(); } Node *getSingleChild(Node *node, Node::Kind kind) { Node *Child = getSingleChild(node); assert(Child->getKind() == kind); return Child; } Node *skipType(Node *node) { if (node->getKind() == Node::Kind::Type) return getSingleChild(node); return node; } Node *getChildOfType(Node *node) { assert(node->getKind() == Node::Kind::Type); return getSingleChild(node); } // Cannot fail void mangleIndex(Node::IndexType value) { if (value == 0) { Buffer << '_'; } else { Buffer << (value - 1) << '_'; } } ManglingError mangleDependentConformanceIndex(Node *node, unsigned depth); ManglingError mangleChildNodes(Node *node, unsigned depth) { return mangleNodes(node->begin(), node->end(), depth); } ManglingError mangleChildNodesReversed(Node *node, unsigned depth) { for (size_t Idx = 0, Num = node->getNumChildren(); Idx < Num; ++Idx) { RETURN_IF_ERROR(mangleChildNode(node, Num - Idx - 1, depth)); } return ManglingError::Success; } void mangleListSeparator(bool &isFirstListItem) { if (isFirstListItem) { Buffer << '_'; isFirstListItem = false; } } void mangleEndOfList(bool isFirstListItem) { if (isFirstListItem) Buffer << 'y'; } ManglingError mangleNodes(Node::iterator i, Node::iterator e, unsigned depth) { for (; i != e; ++i) { RETURN_IF_ERROR(mangle(*i, depth)); } return ManglingError::Success; } ManglingError mangleSingleChildNode(Node *node, unsigned depth) { if (node->getNumChildren() != 1) return MANGLING_ERROR(ManglingError::MultipleChildNodes, node); return mangle(*node->begin(), depth); } ManglingError mangleChildNode(Node *node, unsigned index, unsigned depth) { if (index < node->getNumChildren()) return mangle(node->begin()[index], depth); return ManglingError::Success; } ManglingError manglePureProtocol(Node *Proto, unsigned depth) { Proto = skipType(Proto); if (mangleStandardSubstitution(Proto)) return ManglingError::Success; return mangleChildNodes(Proto, depth); } ManglingError mangleProtocolList(Node *protocols, Node *superclass, bool hasExplicitAnyObject, unsigned depth); bool trySubstitution(Node *node, SubstitutionEntry &entry, bool treatAsIdentifier = false); void mangleIdentifierImpl(Node *node, bool isOperator); bool mangleStandardSubstitution(Node *node); // Cannot fail void mangleDependentGenericParamIndex(Node *node, const char *nonZeroPrefix = "", char zeroOp = 'z'); ManglingErrorOr> mangleConstrainedType(Node *node, unsigned depth); ManglingError mangleFunctionSignature(Node *FuncType, unsigned depth) { return mangleChildNodesReversed(FuncType, depth); } ManglingError mangleGenericSpecializationNode(Node *node, char specKind, unsigned depth); ManglingError mangleAnyNominalType(Node *node, unsigned depth); ManglingError mangleAnyGenericType(Node *node, StringRef TypeOp, unsigned depth); ManglingError mangleGenericArgs(Node *node, char &Separator, unsigned depth, bool fullSubstitutionMap = false); ManglingError mangleAnyConstructor(Node *node, char kindOp, unsigned depth); ManglingError mangleAbstractStorage(Node *node, StringRef accessorCode, unsigned depth); ManglingError mangleAnyProtocolConformance(Node *node, unsigned depth); ManglingError mangleKeyPathThunkHelper(Node *node, StringRef op, unsigned depth); ManglingError mangleSILThunkIdentity(Node *node, StringRef op, unsigned depth); ManglingError mangleAutoDiffFunctionOrSimpleThunk(Node *node, StringRef op, unsigned depth); #define NODE(ID) ManglingError mangle##ID(Node *node, unsigned depth); #define CONTEXT_NODE(ID) \ ManglingError mangle##ID(Node *node, unsigned depth); \ // ManglingError mangle##ID(Node *node, unsigned depth, EntityContext &ctx); #include "swift/Demangling/DemangleNodes.def" public: Remangler(SymbolicResolver Resolver, NodeFactory &Factory, ManglingFlavor Flavor) : RemanglerBase(Factory), Flavor(Flavor), Resolver(Resolver) {} ManglingError mangle(Node *node, unsigned depth) { if (depth > Remangler::MaxDepth) { return MANGLING_ERROR(ManglingError::TooComplex, node); } switch (node->getKind()) { #define NODE(ID) \ case Node::Kind::ID: \ return mangle##ID(node, depth); #include "swift/Demangling/DemangleNodes.def" } return MANGLING_ERROR(ManglingError::BadNodeKind, node); } }; bool Remangler::trySubstitution(Node *node, SubstitutionEntry &entry, bool treatAsIdentifier) { if (mangleStandardSubstitution(node)) return true; // Go ahead and initialize the substitution entry. entry = entryForNode(node, treatAsIdentifier); int Idx = findSubstitution(entry); if (Idx < 0) return false; if (Idx >= 26) { Buffer << 'A'; mangleIndex(Idx - 26); return true; } char SubstChar = Idx + 'A'; StringRef Subst(&SubstChar, 1); if (!SubstMerging.tryMergeSubst(*this, Subst, /*isStandardSubst*/ false)) { Buffer << 'A' << Subst; } return true; } void Remangler::mangleIdentifierImpl(Node *node, bool isOperator) { SubstitutionEntry entry; if (trySubstitution(node, entry, /*treatAsIdentifier*/ true)) return; if (isOperator) { Mangle::mangleIdentifier(*this, Mangle::translateOperator(node->getText())); } else { Mangle::mangleIdentifier(*this, node->getText()); } addSubstitution(entry); } bool Remangler::mangleStandardSubstitution(Node *node) { if (node->getKind() != Node::Kind::Structure && node->getKind() != Node::Kind::Class && node->getKind() != Node::Kind::Enum && node->getKind() != Node::Kind::Protocol) return false; Node *context = node->getFirstChild(); if (context->getKind() != Node::Kind::Module || context->getText() != STDLIB_NAME) return false; // Ignore private stdlib names if (node->getChild(1)->getKind() != Node::Kind::Identifier) return false; if (auto Subst = getStandardTypeSubst( node->getChild(1)->getText(), /*allowConcurrencyManglings=*/true)) { if (!SubstMerging.tryMergeSubst(*this, *Subst, /*isStandardSubst*/ true)) { Buffer << 'S' << *Subst; } return true; } return false; } void Remangler::mangleDependentGenericParamIndex(Node *node, const char *nonZeroPrefix, char zeroOp) { if (node->getKind() == Node::Kind::ConstrainedExistentialSelf) { Buffer << 's'; return; } auto paramDepth = node->getChild(0)->getIndex(); auto index = node->getChild(1)->getIndex(); if (paramDepth != 0) { Buffer << nonZeroPrefix << 'd'; mangleIndex(paramDepth - 1); mangleIndex(index); return; } if (index != 0) { Buffer << nonZeroPrefix; mangleIndex(index - 1); return; } // depth == index == 0 Buffer << zeroOp; } ManglingErrorOr> Remangler::mangleConstrainedType(Node *node, unsigned depth) { if (node->getKind() == Node::Kind::Type) node = getChildOfType(node); SubstitutionEntry entry; if (trySubstitution(node, entry)) return std::pair{-1, nullptr}; Vector Chain; while (node->getKind() == Node::Kind::DependentMemberType) { Chain.push_back(node->getChild(1), Factory); node = getChildOfType(node->getFirstChild()); } if (node->getKind() != Node::Kind::DependentGenericParamType && node->getKind() != Node::Kind::ConstrainedExistentialSelf) { RETURN_IF_ERROR(mangle(node, depth + 1)); if (!Chain.size()) return std::pair{-1, nullptr}; node = nullptr; } const char *ListSeparator = (Chain.size() > 1 ? "_" : ""); for (unsigned i = 1, n = Chain.size(); i <= n; ++i) { Node *DepAssocTyRef = Chain[n - i]; RETURN_IF_ERROR(mangle(DepAssocTyRef, depth + 1)); Buffer << ListSeparator; ListSeparator = ""; } if (!Chain.empty()) addSubstitution(entry); return std::pair{(int)Chain.size(), node}; } ManglingError Remangler::mangleAnyGenericType(Node *node, StringRef TypeOp, unsigned depth) { SubstitutionEntry entry; if (!trySubstitution(node, entry)) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << TypeOp; addSubstitution(entry); } return ManglingError::Success; } ManglingError Remangler::mangleAnyNominalType(Node *node, unsigned depth) { if (depth > Remangler::MaxDepth) { return MANGLING_ERROR(ManglingError::TooComplex, node); } if (isSpecialized(node)) { SubstitutionEntry entry; if (trySubstitution(node, entry)) return ManglingError::Success; auto unspec = getUnspecialized(node, Factory); if (!unspec.isSuccess()) return unspec.error(); NodePointer unboundType = unspec.result(); RETURN_IF_ERROR(mangleAnyNominalType(unboundType, depth + 1)); char Separator = 'y'; RETURN_IF_ERROR(mangleGenericArgs(node, Separator, depth + 1)); if (node->getNumChildren() == 3) { // Retroactive conformances. auto listNode = node->getChild(2); for (size_t Idx = 0, Num = listNode->getNumChildren(); Idx < Num; ++Idx) { RETURN_IF_ERROR(mangle(listNode->getChild(Idx), depth + 1)); } } Buffer << 'G'; addSubstitution(entry); return ManglingError::Success; } switch (node->getKind()) { case Node::Kind::Structure: return mangleAnyGenericType(node, "V", depth); case Node::Kind::Enum: return mangleAnyGenericType(node, "O", depth); case Node::Kind::Class: return mangleAnyGenericType(node, "C", depth); case Node::Kind::OtherNominalType: return mangleAnyGenericType(node, "XY", depth); case Node::Kind::TypeAlias: return mangleAnyGenericType(node, "a", depth); case Node::Kind::TypeSymbolicReference: return mangleTypeSymbolicReference(node, depth); default: return MANGLING_ERROR(ManglingError::BadNominalTypeKind, node); } } ManglingError Remangler::mangleGenericArgs(Node *node, char &Separator, unsigned depth, bool fullSubstitutionMap) { switch (node->getKind()) { case Node::Kind::Protocol: // A protocol cannot be the parent of a nominal type, so this case should // never be hit by valid swift code. But the indexer might generate a URL // from invalid swift code, which has a bound generic inside a protocol. // The ASTMangler treats a protocol like any other nominal type in this // case, so we also support it in the remangler. case Node::Kind::Structure: case Node::Kind::Enum: case Node::Kind::Class: case Node::Kind::TypeAlias: if (node->getKind() == Node::Kind::TypeAlias) fullSubstitutionMap = true; RETURN_IF_ERROR(mangleGenericArgs(node->getChild(0), Separator, depth + 1, fullSubstitutionMap)); Buffer << Separator; Separator = '_'; break; case Node::Kind::Function: case Node::Kind::Getter: case Node::Kind::Setter: case Node::Kind::WillSet: case Node::Kind::DidSet: case Node::Kind::ReadAccessor: case Node::Kind::ModifyAccessor: case Node::Kind::UnsafeAddressor: case Node::Kind::UnsafeMutableAddressor: case Node::Kind::Allocator: case Node::Kind::Constructor: case Node::Kind::Destructor: case Node::Kind::Variable: case Node::Kind::Subscript: case Node::Kind::ExplicitClosure: case Node::Kind::ImplicitClosure: case Node::Kind::DefaultArgumentInitializer: case Node::Kind::Initializer: case Node::Kind::PropertyWrapperBackingInitializer: case Node::Kind::PropertyWrapperInitFromProjectedValue: case Node::Kind::Static: if (!fullSubstitutionMap) break; RETURN_IF_ERROR(mangleGenericArgs(node->getChild(0), Separator, depth + 1, fullSubstitutionMap)); if (Demangle::nodeConsumesGenericArgs(node)) { Buffer << Separator; Separator = '_'; } break; case Node::Kind::BoundGenericOtherNominalType: case Node::Kind::BoundGenericStructure: case Node::Kind::BoundGenericEnum: case Node::Kind::BoundGenericClass: case Node::Kind::BoundGenericProtocol: case Node::Kind::BoundGenericTypeAlias: { if (node->getKind() == Node::Kind::BoundGenericTypeAlias) fullSubstitutionMap = true; NodePointer unboundType = node->getChild(0); DEMANGLER_ASSERT(unboundType->getKind() == Node::Kind::Type, node); NodePointer nominalType = unboundType->getChild(0); if (nominalType->getKind() == Node::Kind::TypeSymbolicReference) { NodePointer resolvedUnboundType = Resolver(SymbolicReferenceKind::Context, (const void *)nominalType->getIndex()); nominalType = resolvedUnboundType->getChild(0); } NodePointer parentOrModule = nominalType->getChild(0); RETURN_IF_ERROR(mangleGenericArgs(parentOrModule, Separator, depth + 1, fullSubstitutionMap)); Buffer << Separator; Separator = '_'; RETURN_IF_ERROR(mangleChildNodes(node->getChild(1), depth + 1)); break; } case Node::Kind::ConstrainedExistential: { Buffer << Separator; Separator = '_'; RETURN_IF_ERROR(mangleChildNodes(node->getChild(1), depth + 1)); break; } case Node::Kind::BoundGenericFunction: { fullSubstitutionMap = true; NodePointer unboundFunction = node->getChild(0); DEMANGLER_ASSERT(unboundFunction->getKind() == Node::Kind::Function || unboundFunction->getKind() == Node::Kind::Constructor, node); NodePointer parentOrModule = unboundFunction->getChild(0); RETURN_IF_ERROR(mangleGenericArgs(parentOrModule, Separator, depth + 1, fullSubstitutionMap)); Buffer << Separator; Separator = '_'; RETURN_IF_ERROR(mangleChildNodes(node->getChild(1), depth + 1)); break; } case Node::Kind::Extension: RETURN_IF_ERROR(mangleGenericArgs(node->getChild(1), Separator, depth + 1, fullSubstitutionMap)); break; default: break; } return ManglingError::Success; } ManglingError Remangler::mangleAbstractStorage(Node *node, StringRef accessorCode, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); switch (node->getKind()) { case Node::Kind::Subscript: Buffer << "i"; break; case Node::Kind::Variable: Buffer << "v"; break; default: return MANGLING_ERROR(ManglingError::NotAStorageNode, node); } Buffer << accessorCode; return ManglingError::Success; } ManglingError Remangler::mangleAllocator(Node *node, unsigned depth) { return mangleAnyConstructor(node, 'C', depth + 1); } ManglingError Remangler::mangleArgumentTuple(Node *node, unsigned depth) { Node *Child = skipType(node->getChild(0)); if (Child->getKind() == Node::Kind::Tuple && Child->getNumChildren() == 0) { Buffer << 'y'; return ManglingError::Success; } return mangle(Child, depth + 1); } ManglingError Remangler::mangleAssociatedType(Node *node, unsigned depth) { return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleAssociatedTypeRef(Node *node, unsigned depth) { SubstitutionEntry entry; if (trySubstitution(node, entry)) return ManglingError::Success; RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "Qa"; addSubstitution(entry); return ManglingError::Success; } ManglingError Remangler::mangleAssociatedTypeDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "Tl"; return ManglingError::Success; } ManglingError Remangler::mangleAssociatedConformanceDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1)); RETURN_IF_ERROR(mangle(node->getChild(1), depth + 1)); RETURN_IF_ERROR(manglePureProtocol(node->getChild(2), depth + 1)); Buffer << "Tn"; return ManglingError::Success; } ManglingError Remangler::mangleDefaultAssociatedConformanceAccessor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1)); RETURN_IF_ERROR(mangle(node->getChild(1), depth + 1)); RETURN_IF_ERROR(manglePureProtocol(node->getChild(2), depth + 1)); Buffer << "TN"; return ManglingError::Success; } ManglingError Remangler::mangleBaseConformanceDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1)); RETURN_IF_ERROR(manglePureProtocol(node->getChild(1), depth + 1)); Buffer << "Tb"; return ManglingError::Success; } ManglingError Remangler::mangleAssociatedTypeMetadataAccessor(Node *node, unsigned depth) { RETURN_IF_ERROR( mangleChildNodes(node, depth + 1)); // protocol conformance, identifier Buffer << "Wt"; return ManglingError::Success; } ManglingError Remangler::mangleDefaultAssociatedTypeMetadataAccessor(Node *node, unsigned depth) { RETURN_IF_ERROR( mangleChildNodes(node, depth + 1)); // protocol conformance, identifier Buffer << "TM"; return ManglingError::Success; } ManglingError Remangler::mangleAssociatedTypeWitnessTableAccessor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes( node, depth + 1)); // protocol conformance, type, protocol Buffer << "WT"; return ManglingError::Success; } ManglingError Remangler::mangleBaseWitnessTableAccessor(Node *node, unsigned depth) { RETURN_IF_ERROR( mangleChildNodes(node, depth + 1)); // protocol conformance, protocol Buffer << "Wb"; return ManglingError::Success; } ManglingError Remangler::mangleAutoClosureType(Node *node, unsigned depth) { RETURN_IF_ERROR( mangleChildNodesReversed(node, depth + 1)); // argument tuple, result type Buffer << "XK"; return ManglingError::Success; } ManglingError Remangler::mangleEscapingAutoClosureType(Node *node, unsigned depth) { RETURN_IF_ERROR( mangleChildNodesReversed(node, depth + 1)); // argument tuple, result type Buffer << "XA"; return ManglingError::Success; } ManglingError Remangler::mangleNoEscapeFunctionType(Node *node, unsigned depth) { RETURN_IF_ERROR( mangleChildNodesReversed(node, depth + 1)); // argument tuple, result type Buffer << "XE"; return ManglingError::Success; } ManglingError Remangler::mangleBoundGenericClass(Node *node, unsigned depth) { return mangleAnyNominalType(node, depth + 1); } ManglingError Remangler::mangleBoundGenericEnum(Node *node, unsigned depth) { Node *Enum = node->getChild(0)->getChild(0); DEMANGLER_ASSERT(Enum->getKind() == Node::Kind::Enum, node); Node *Mod = Enum->getChild(0); Node *Id = Enum->getChild(1); if (Mod->getKind() == Node::Kind::Module && Mod->getText() == STDLIB_NAME && Id->getKind() == Node::Kind::Identifier && Id->getText() == "Optional") { SubstitutionEntry entry; if (trySubstitution(node, entry)) return ManglingError::Success; RETURN_IF_ERROR(mangleSingleChildNode(node->getChild(1), depth + 1)); Buffer << "Sg"; addSubstitution(entry); return ManglingError::Success; } return mangleAnyNominalType(node, depth + 1); } ManglingError Remangler::mangleBoundGenericStructure(Node *node, unsigned depth) { return mangleAnyNominalType(node, depth + 1); } ManglingError Remangler::mangleBoundGenericOtherNominalType(Node *node, unsigned depth) { return mangleAnyNominalType(node, depth + 1); } ManglingError Remangler::mangleBoundGenericProtocol(Node *node, unsigned depth) { return mangleAnyNominalType(node, depth + 1); } ManglingError Remangler::mangleBoundGenericTypeAlias(Node *node, unsigned depth) { return mangleAnyNominalType(node, depth + 1); } ManglingError Remangler::mangleBoundGenericFunction(Node *node, unsigned depth) { SubstitutionEntry entry; if (trySubstitution(node, entry)) return ManglingError::Success; auto unspec = getUnspecialized(node, Factory); if (!unspec.isSuccess()) return unspec.error(); NodePointer unboundFunction = unspec.result(); RETURN_IF_ERROR(mangleFunction(unboundFunction, depth + 1)); char Separator = 'y'; RETURN_IF_ERROR(mangleGenericArgs(node, Separator, depth + 1)); Buffer << 'G'; addSubstitution(entry); return ManglingError::Success; } ManglingError Remangler::mangleBuiltinFixedArray(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "BV"; return ManglingError::Success; } ManglingError Remangler::mangleBuiltinTypeName(Node *node, unsigned depth) { Buffer << 'B'; StringRef text = node->getText(); if (text == BUILTIN_TYPE_NAME_BRIDGEOBJECT) { Buffer << 'b'; } else if (text == BUILTIN_TYPE_NAME_UNSAFEVALUEBUFFER) { Buffer << 'B'; } else if (text == BUILTIN_TYPE_NAME_UNKNOWNOBJECT) { Buffer << 'O'; } else if (text == BUILTIN_TYPE_NAME_NATIVEOBJECT) { Buffer << 'o'; } else if (text == BUILTIN_TYPE_NAME_RAWPOINTER) { Buffer << 'p'; } else if (text == BUILTIN_TYPE_NAME_RAWUNSAFECONTINUATION) { Buffer << 'c'; } else if (text == BUILTIN_TYPE_NAME_JOB) { Buffer << 'j'; } else if (text == BUILTIN_TYPE_NAME_DEFAULTACTORSTORAGE) { Buffer << 'D'; } else if (text == BUILTIN_TYPE_NAME_NONDEFAULTDISTRIBUTEDACTORSTORAGE) { Buffer << 'd'; } else if (text == BUILTIN_TYPE_NAME_EXECUTOR) { Buffer << 'e'; } else if (text == BUILTIN_TYPE_NAME_SILTOKEN) { Buffer << 't'; } else if (text == BUILTIN_TYPE_NAME_INTLITERAL) { Buffer << 'I'; } else if (text == BUILTIN_TYPE_NAME_WORD) { Buffer << 'w'; } else if (text == BUILTIN_TYPE_NAME_PACKINDEX) { Buffer << 'P'; } else if (text.consume_front(BUILTIN_TYPE_NAME_INT)) { Buffer << 'i' << text << '_'; } else if (text.consume_front(BUILTIN_TYPE_NAME_FLOAT)) { Buffer << 'f' << text << '_'; } else if (text.consume_front(BUILTIN_TYPE_NAME_VEC)) { // Avoid using StringRef::split because its definition is not // provided in the header so that it requires linking with libSupport.a. size_t splitIdx = text.find('x'); auto element = text.substr(splitIdx).substr(1); if (element == "RawPointer") { Buffer << 'p'; } else if (element.consume_front("FPIEEE")) { Buffer << 'f' << element << '_'; } else if (element.consume_front("Int")) { Buffer << 'i' << element << '_'; } else { return MANGLING_ERROR(ManglingError::UnexpectedBuiltinVectorType, node); } Buffer << "Bv" << text.substr(0, splitIdx) << '_'; } else { return MANGLING_ERROR(ManglingError::UnexpectedBuiltinType, node); } return ManglingError::Success; } ManglingError Remangler::mangleBuiltinTupleType(Node *node, unsigned depth) { Buffer << "BT"; return ManglingError::Success; } ManglingError Remangler::mangleCFunctionPointer(Node *node, unsigned depth) { if (node->getNumChildren() > 0 && node->getFirstChild()->getKind() == Node::Kind::ClangType) { for (size_t Idx = node->getNumChildren() - 1; Idx >= 1; --Idx) { RETURN_IF_ERROR(mangleChildNode(node, Idx, depth + 1)); } Buffer << "XzC"; return mangleClangType(node->getFirstChild(), depth + 1); } RETURN_IF_ERROR( mangleChildNodesReversed(node, depth + 1)); // argument tuple, result type Buffer << "XC"; return ManglingError::Success; } ManglingError Remangler::mangleClass(Node *node, unsigned depth) { return mangleAnyNominalType(node, depth + 1); } ManglingError Remangler::mangleAnyConstructor(Node *node, char kindOp, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "f" << kindOp; return ManglingError::Success; } ManglingError Remangler::mangleConstructor(Node *node, unsigned depth) { return mangleAnyConstructor(node, 'c', depth); } ManglingError Remangler::mangleCoroutineContinuationPrototype(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "TC"; return ManglingError::Success; } ManglingError Remangler::manglePredefinedObjCAsyncCompletionHandlerImpl(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "TZ"; return ManglingError::Success; } ManglingError Remangler::mangleObjCAsyncCompletionHandlerImpl(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); if (node->getNumChildren() == 4) RETURN_IF_ERROR(mangleChildNode(node, 3, depth + 1)); Buffer << "Tz"; return mangleChildNode(node, 2, depth + 1); } ManglingError Remangler::mangleDeallocator(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "fD"; return ManglingError::Success; } ManglingError Remangler::mangleIsolatedDeallocator(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "fZ"; return ManglingError::Success; } ManglingError Remangler::mangleDeclContext(Node *node, unsigned depth) { return mangleSingleChildNode(node, depth + 1); } ManglingError Remangler::mangleDefaultArgumentInitializer(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); Buffer << "fA"; return mangleChildNode(node, 1, depth + 1); } ManglingError Remangler::mangleAsyncFunctionPointer(Node *node, unsigned depth) { Buffer << "Tu"; return ManglingError::Success; } ManglingError Remangler::mangleDependentAssociatedTypeRef(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleIdentifier(node->getFirstChild(), depth)); if (node->getNumChildren() > 1) return mangleChildNode(node, 1, depth + 1); return ManglingError::Success; } ManglingError Remangler::mangleDependentGenericConformanceRequirement(Node *node, unsigned depth) { DEMANGLER_ASSERT(node->getNumChildren() == 2, node); Node *ProtoOrClass = node->getChild(1); DEMANGLER_ASSERT(ProtoOrClass->hasChildren(), ProtoOrClass); if (ProtoOrClass->getFirstChild()->getKind() == Node::Kind::Protocol) { RETURN_IF_ERROR(manglePureProtocol(ProtoOrClass, depth + 1)); auto Mangling = mangleConstrainedType(node->getChild(0), depth + 1); if (!Mangling.isSuccess()) return Mangling.error(); auto NumMembersAndParamIdx = Mangling.result(); DEMANGLER_ASSERT( NumMembersAndParamIdx.first < 0 || NumMembersAndParamIdx.second, node); switch (NumMembersAndParamIdx.first) { case -1: Buffer << "RQ"; return ManglingError::Success; // substitution case 0: Buffer << "R"; break; case 1: Buffer << "Rp"; break; default: Buffer << "RP"; break; } mangleDependentGenericParamIndex(NumMembersAndParamIdx.second); return ManglingError::Success; } RETURN_IF_ERROR(mangle(ProtoOrClass, depth + 1)); auto Mangling = mangleConstrainedType(node->getChild(0), depth + 1); if (!Mangling.isSuccess()) return Mangling.error(); auto NumMembersAndParamIdx = Mangling.result(); DEMANGLER_ASSERT( NumMembersAndParamIdx.first < 0 || NumMembersAndParamIdx.second, node); switch (NumMembersAndParamIdx.first) { case -1: Buffer << "RB"; return ManglingError::Success; // substitution case 0: Buffer << "Rb"; break; case 1: Buffer << "Rc"; break; default: Buffer << "RC"; break; } mangleDependentGenericParamIndex(NumMembersAndParamIdx.second); return ManglingError::Success; } ManglingError Remangler::mangleDependentGenericInverseConformanceRequirement( Node *node, unsigned depth) { DEMANGLER_ASSERT(node->getNumChildren() == 2, node); auto Mangling = mangleConstrainedType(node->getChild(0), depth + 1); if (!Mangling.isSuccess()) { return Mangling.error(); } auto NumMembersAndParamIdx = Mangling.result(); DEMANGLER_ASSERT( NumMembersAndParamIdx.first < 0 || NumMembersAndParamIdx.second, node); switch (NumMembersAndParamIdx.first) { case -1: Buffer << "RI"; mangleIndex(node->getChild(1)->getIndex()); return ManglingError::Success; // substitution case 0: Buffer << "Ri"; break; case 1: Buffer << "Rj"; break; default: Buffer << "RJ"; break; } mangleIndex(node->getChild(1)->getIndex()); mangleDependentGenericParamIndex(NumMembersAndParamIdx.second); return ManglingError::Success; } ManglingError Remangler::mangleDependentGenericParamCount(Node *node, unsigned depth) { // handled inline in DependentGenericSignature return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleDependentGenericParamType(Node *node, unsigned depth) { if (node->getChild(0)->getIndex() == 0 && node->getChild(1)->getIndex() == 0) { Buffer << 'x'; return ManglingError::Success; } Buffer << 'q'; mangleDependentGenericParamIndex(node); return ManglingError::Success; } ManglingError Remangler::mangleDependentGenericSameTypeRequirement(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); auto Mangling = mangleConstrainedType(node->getChild(0), depth + 1); if (!Mangling.isSuccess()) return Mangling.error(); auto NumMembersAndParamIdx = Mangling.result(); DEMANGLER_ASSERT( NumMembersAndParamIdx.first < 0 || NumMembersAndParamIdx.second, node); switch (NumMembersAndParamIdx.first) { case -1: Buffer << "RS"; return ManglingError::Success; // substitution case 0: Buffer << "Rs"; break; case 1: Buffer << "Rt"; break; default: Buffer << "RT"; break; } mangleDependentGenericParamIndex(NumMembersAndParamIdx.second); return ManglingError::Success; } ManglingError Remangler::mangleDependentGenericSameShapeRequirement(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); auto Mangling = mangleConstrainedType(node->getChild(0), depth + 1); if (!Mangling.isSuccess()) return Mangling.error(); auto NumMembersAndParamIdx = Mangling.result(); DEMANGLER_ASSERT( NumMembersAndParamIdx.first < 0 || NumMembersAndParamIdx.second, node); switch (NumMembersAndParamIdx.first) { case 0: Buffer << "Rh"; break; default: assert(false && "Invalid same-shape requirement"); return ManglingError::AssertionFailed; } mangleDependentGenericParamIndex(NumMembersAndParamIdx.second); return ManglingError::Success; } ManglingError Remangler::mangleDependentGenericLayoutRequirement(Node *node, unsigned depth) { auto Mangling = mangleConstrainedType(node->getChild(0), depth + 1); if (!Mangling.isSuccess()) return Mangling.error(); auto NumMembersAndParamIdx = Mangling.result(); DEMANGLER_ASSERT( NumMembersAndParamIdx.first < 0 || NumMembersAndParamIdx.second, node); switch (NumMembersAndParamIdx.first) { case -1: Buffer << "RL"; break; // substitution case 0: Buffer << "Rl"; break; case 1: Buffer << "Rm"; break; default: Buffer << "RM"; break; } // If not a substitution, mangle the dependent generic param index. if (NumMembersAndParamIdx.first != -1) mangleDependentGenericParamIndex(NumMembersAndParamIdx.second); DEMANGLER_ASSERT(node->getChild(1)->getKind() == Node::Kind::Identifier, node); DEMANGLER_ASSERT(node->getChild(1)->getText().size() == 1, node); Buffer << node->getChild(1)->getText()[0]; if (node->getNumChildren() >= 3) RETURN_IF_ERROR(mangleChildNode(node, 2, depth + 1)); if (node->getNumChildren() >= 4) RETURN_IF_ERROR(mangleChildNode(node, 3, depth + 1)); return ManglingError::Success; } ManglingError Remangler::mangleDependentGenericSignature(Node *node, unsigned depth) { size_t ParamCountEnd = 0; for (size_t Idx = 0, Num = node->getNumChildren(); Idx < Num; ++Idx) { Node *Child = node->getChild(Idx); if (Child->getKind() == Node::Kind::DependentGenericParamCount) { ParamCountEnd = Idx + 1; } else { // requirement RETURN_IF_ERROR(mangleChildNode(node, Idx, depth + 1)); } } // If there's only one generic param, mangle nothing. if (ParamCountEnd == 1 && node->getChild(0)->getIndex() == 1) { Buffer << 'l'; return ManglingError::Success; } // Remangle generic params. Buffer << 'r'; for (size_t Idx = 0; Idx < ParamCountEnd; ++Idx) { Node *Count = node->getChild(Idx); if (Count->getIndex() > 0) { mangleIndex(Count->getIndex() - 1); } else { Buffer << 'z'; } } Buffer << 'l'; return ManglingError::Success; } ManglingError Remangler::mangleDependentGenericParamPackMarker(Node *node, unsigned depth) { DEMANGLER_ASSERT(node->getNumChildren() == 1, node); DEMANGLER_ASSERT(node->getChild(0)->getKind() == Node::Kind::Type, node); Buffer << "Rv"; mangleDependentGenericParamIndex(node->getChild(0)->getChild(0)); return ManglingError::Success; } ManglingError Remangler::mangleDependentGenericType(Node *node, unsigned depth) { RETURN_IF_ERROR( mangleChildNodesReversed(node, depth + 1)); // type, generic signature Buffer << 'u'; return ManglingError::Success; } ManglingError Remangler::mangleDependentMemberType(Node *node, unsigned depth) { auto Mangling = mangleConstrainedType(node, depth + 1); if (!Mangling.isSuccess()) return Mangling.error(); auto NumMembersAndParamIdx = Mangling.result(); switch (NumMembersAndParamIdx.first) { case -1: break; // substitution case 0: return MANGLING_ERROR(ManglingError::WrongDependentMemberType, node); case 1: Buffer << 'Q'; if (auto dependentBase = NumMembersAndParamIdx.second) { mangleDependentGenericParamIndex(dependentBase, "y", 'z'); } else { Buffer << 'x'; } break; default: Buffer << 'Q'; if (auto dependentBase = NumMembersAndParamIdx.second) { mangleDependentGenericParamIndex(dependentBase, "Y", 'Z'); } else { Buffer << 'X'; } break; } return ManglingError::Success; } ManglingError Remangler::mangleDependentPseudogenericSignature(Node *node, unsigned depth) { return mangleDependentGenericSignature(node, depth + 1); } ManglingError Remangler::mangleDestructor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "fd"; return ManglingError::Success; } ManglingError Remangler::mangleDidSet(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "W", depth + 1); } ManglingError Remangler::mangleDirectness(Node *node, unsigned depth) { switch (node->getIndex()) { case unsigned(Directness::Direct): Buffer << 'd'; break; case unsigned(Directness::Indirect): Buffer << 'i'; break; default: return MANGLING_ERROR(ManglingError::BadDirectness, node); } return ManglingError::Success; } ManglingError Remangler::mangleDynamicAttribute(Node *node, unsigned depth) { Buffer << "TD"; return ManglingError::Success; } ManglingError Remangler::mangleDirectMethodReferenceAttribute(Node *node, unsigned depth) { Buffer << "Td"; return ManglingError::Success; } ManglingError Remangler::mangleDynamicSelf(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); // type Buffer << "XD"; return ManglingError::Success; } ManglingError Remangler::mangleEnum(Node *node, unsigned depth) { return mangleAnyNominalType(node, depth + 1); } ManglingError Remangler::mangleErrorType(Node *node, unsigned depth) { Buffer << "Xe"; return ManglingError::Success; } ManglingError Remangler::mangleConstrainedExistential(Node *node, unsigned int depth) { RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); Buffer << "XP"; return ManglingError::Success; } ManglingError Remangler::mangleConstrainedExistentialRequirementList(Node *node, unsigned int depth) { assert(node->getNumChildren() > 0); bool FirstElem = true; for (size_t Idx = 0, Num = node->getNumChildren(); Idx < Num; ++Idx) { RETURN_IF_ERROR(mangleChildNode(node, Idx, depth + 1)); mangleListSeparator(FirstElem); } return ManglingError::Success; } ManglingError Remangler::mangleConstrainedExistentialSelf(Node *node, unsigned int depth) { Buffer << "s"; return ManglingError::Success; } ManglingError Remangler::mangleExistentialMetatype(Node *node, unsigned depth) { if (node->getFirstChild()->getKind() == Node::Kind::MetatypeRepresentation) { RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); Buffer << "Xm"; return mangleChildNode(node, 0, depth + 1); } else { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Xp"; } return ManglingError::Success; } ManglingError Remangler::mangleExplicitClosure(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); // context RETURN_IF_ERROR(mangleChildNode(node, 2, depth + 1)); // type Buffer << "fU"; return mangleChildNode(node, 1, depth + 1); // index } ManglingError Remangler::mangleExtension(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); if (node->getNumChildren() == 3) RETURN_IF_ERROR(mangleChildNode(node, 2, depth + 1)); // generic signature Buffer << 'E'; return ManglingError::Success; } ManglingError Remangler::mangleAnonymousContext(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); if (node->getNumChildren() >= 3) RETURN_IF_ERROR(mangleTypeList(node->getChild(2), depth + 1)); else Buffer << 'y'; Buffer << "XZ"; return ManglingError::Success; } ManglingError Remangler::mangleFieldOffset(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); // variable Buffer << "Wv"; return mangleChildNode(node, 0, depth + 1); // directness } ManglingError Remangler::mangleEnumCase(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); // enum case Buffer << "WC"; return ManglingError::Success; } ManglingError Remangler::mangleFullTypeMetadata(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mf"; return ManglingError::Success; } ManglingError Remangler::mangleFunction(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); // context RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); // name bool hasLabels = node->getChild(2)->getKind() == Node::Kind::LabelList; Node *FuncType = getSingleChild(node->getChild(hasLabels ? 3 : 2)); if (hasLabels) RETURN_IF_ERROR(mangleChildNode(node, 2, depth + 1)); // parameter labels if (FuncType->getKind() == Node::Kind::DependentGenericType) { RETURN_IF_ERROR(mangleFunctionSignature( getSingleChild(FuncType->getChild(1)), depth + 1)); RETURN_IF_ERROR( mangleChildNode(FuncType, 0, depth + 1)); // generic signature } else { RETURN_IF_ERROR(mangleFunctionSignature(FuncType, depth + 1)); } Buffer << "F"; return ManglingError::Success; } ManglingError Remangler::mangleFunctionSignatureSpecialization(Node *node, unsigned depth) { for (NodePointer Param : *node) { if (Param->getKind() == Node::Kind::FunctionSignatureSpecializationParam && Param->getNumChildren() > 0) { Node *KindNd = Param->getChild(0); switch (FunctionSigSpecializationParamKind(KindNd->getIndex())) { case FunctionSigSpecializationParamKind::ConstantPropFunction: case FunctionSigSpecializationParamKind::ConstantPropGlobal: RETURN_IF_ERROR(mangleIdentifier(Param->getChild(1), depth + 1)); break; case FunctionSigSpecializationParamKind::ConstantPropString: { NodePointer TextNd = Param->getChild(2); StringRef Text = TextNd->getText(); if (!Text.empty() && (isDigit(Text[0]) || Text[0] == '_')) { std::string Buffer = "_"; Buffer.append(Text.data(), Text.size()); TextNd = Factory.createNode(Node::Kind::Identifier, Buffer); } RETURN_IF_ERROR(mangleIdentifier(TextNd, depth + 1)); break; } case FunctionSigSpecializationParamKind::ClosureProp: case FunctionSigSpecializationParamKind::ConstantPropKeyPath: RETURN_IF_ERROR(mangleIdentifier(Param->getChild(1), depth + 1)); for (unsigned i = 2, e = Param->getNumChildren(); i != e; ++i) { RETURN_IF_ERROR(mangleType(Param->getChild(i), depth + 1)); } break; default: break; } } } Buffer << "Tf"; bool returnValMangled = false; for (NodePointer Child : *node) { if (Child->getKind() == Node::Kind::FunctionSignatureSpecializationReturn) { Buffer << '_'; returnValMangled = true; } RETURN_IF_ERROR(mangle(Child, depth + 1)); if (Child->getKind() == Node::Kind::SpecializationPassID && node->hasIndex()) { Buffer << node->getIndex(); } } if (!returnValMangled) Buffer << "_n"; return ManglingError::Success; } ManglingError Remangler::mangleFunctionSignatureSpecializationReturn(Node *node, unsigned depth) { return mangleFunctionSignatureSpecializationParam(node, depth + 1); } ManglingError Remangler::mangleFunctionSignatureSpecializationParam(Node *node, unsigned depth) { if (!node->hasChildren()) { Buffer << 'n'; return ManglingError::Success; } // The first child is always a kind that specifies the type of param that we // have. Node *KindNd = node->getChild(0); unsigned kindValue = KindNd->getIndex(); auto kind = FunctionSigSpecializationParamKind(kindValue); switch (kind) { case FunctionSigSpecializationParamKind::ConstantPropFunction: Buffer << "pf"; break; case FunctionSigSpecializationParamKind::ConstantPropGlobal: Buffer << "pg"; break; case FunctionSigSpecializationParamKind::ConstantPropInteger: Buffer << "pi" << node->getChild(1)->getText(); break; case FunctionSigSpecializationParamKind::ConstantPropFloat: Buffer << "pd" << node->getChild(1)->getText(); break; case FunctionSigSpecializationParamKind::ConstantPropString: { Buffer << "ps"; StringRef encodingStr = node->getChild(1)->getText(); if (encodingStr == "u8") { Buffer << 'b'; } else if (encodingStr == "u16") { Buffer << 'w'; } else if (encodingStr == "objc") { Buffer << 'c'; } else { return MANGLING_ERROR(ManglingError::UnknownEncoding, node); } break; } case FunctionSigSpecializationParamKind::ConstantPropKeyPath: Buffer << "pk"; break; case FunctionSigSpecializationParamKind::ClosureProp: Buffer << 'c'; break; case FunctionSigSpecializationParamKind::BoxToValue: Buffer << 'i'; break; case FunctionSigSpecializationParamKind::BoxToStack: Buffer << 's'; break; case FunctionSigSpecializationParamKind::InOutToOut: Buffer << 'r'; break; case FunctionSigSpecializationParamKind::SROA: Buffer << 'x'; break; default: if (kindValue & unsigned( FunctionSigSpecializationParamKind::ExistentialToGeneric)) { Buffer << 'e'; if (kindValue & unsigned(FunctionSigSpecializationParamKind::Dead)) Buffer << 'D'; if (kindValue & unsigned(FunctionSigSpecializationParamKind::OwnedToGuaranteed)) Buffer << 'G'; if (kindValue & unsigned(FunctionSigSpecializationParamKind::GuaranteedToOwned)) Buffer << 'O'; } else if (kindValue & unsigned(FunctionSigSpecializationParamKind::Dead)) { Buffer << 'd'; if (kindValue & unsigned(FunctionSigSpecializationParamKind::OwnedToGuaranteed)) Buffer << 'G'; if (kindValue & unsigned(FunctionSigSpecializationParamKind::GuaranteedToOwned)) Buffer << 'O'; } else if (kindValue & unsigned(FunctionSigSpecializationParamKind::OwnedToGuaranteed)) { Buffer << 'g'; } else if (kindValue & unsigned( FunctionSigSpecializationParamKind::GuaranteedToOwned)) { Buffer << 'o'; } if (kindValue & unsigned(FunctionSigSpecializationParamKind::SROA)) Buffer << 'X'; break; } return ManglingError::Success; } ManglingError Remangler::mangleFunctionSignatureSpecializationParamKind(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleFunctionSignatureSpecializationParamPayload(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleFunctionType(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleFunctionSignature(node, depth + 1)); Buffer << 'c'; return ManglingError::Success; } ManglingError Remangler::mangleGenericProtocolWitnessTable(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "WG"; return ManglingError::Success; } ManglingError Remangler::mangleGenericProtocolWitnessTableInstantiationFunction( Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "WI"; return ManglingError::Success; } ManglingError Remangler::mangleResilientProtocolWitnessTable(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Wr"; return ManglingError::Success; } ManglingError Remangler::mangleGenericPartialSpecialization(Node *node, unsigned depth) { for (NodePointer Child : *node) { if (Child->getKind() == Node::Kind::GenericSpecializationParam) { RETURN_IF_ERROR(mangleChildNode(Child, 0, depth + 1)); break; } } Buffer << (node->getKind() == Node::Kind::GenericPartialSpecializationNotReAbstracted ? "TP" : "Tp"); for (NodePointer Child : *node) { if (Child->getKind() != Node::Kind::GenericSpecializationParam) RETURN_IF_ERROR(mangle(Child, depth + 1)); } return ManglingError::Success; } ManglingError Remangler::mangleGenericPartialSpecializationNotReAbstracted(Node *node, unsigned depth) { return mangleGenericPartialSpecialization(node, depth + 1); } ManglingError Remangler::mangleGenericSpecializationNode(Node *node, char specKind, unsigned depth) { bool FirstParam = true; for (NodePointer Child : *node) { if (Child->getKind() == Node::Kind::GenericSpecializationParam) { RETURN_IF_ERROR(mangleChildNode(Child, 0, depth + 1)); mangleListSeparator(FirstParam); } } DEMANGLER_ASSERT( !FirstParam && "generic specialization with no substitutions", node); Buffer << 'T'; for (NodePointer Child : *node) { if (Child->getKind() == Node::Kind::DroppedArgument) RETURN_IF_ERROR(mangle(Child, depth + 1)); } Buffer << specKind; for (NodePointer Child : *node) { if (Child->getKind() != Node::Kind::GenericSpecializationParam && Child->getKind() != Node::Kind::DroppedArgument) { RETURN_IF_ERROR(mangle(Child, depth + 1)); } } return ManglingError::Success; } ManglingError Remangler::mangleGenericSpecialization(Node *node, unsigned depth) { return mangleGenericSpecializationNode(node, 'g', depth + 1); } ManglingError Remangler::mangleGenericSpecializationPrespecialized(Node *node, unsigned depth) { return mangleGenericSpecializationNode(node, 's', depth + 1); } ManglingError Remangler::mangleGenericSpecializationNotReAbstracted(Node *node, unsigned depth) { return mangleGenericSpecializationNode(node, 'G', depth + 1); } ManglingError Remangler::mangleGenericSpecializationInResilienceDomain(Node *node, unsigned depth) { return mangleGenericSpecializationNode(node, 'B', depth + 1); } ManglingError Remangler::mangleInlinedGenericFunction(Node *node, unsigned depth) { return mangleGenericSpecializationNode(node, 'i', depth + 1); } ManglingError Remangler::mangleGenericSpecializationParam(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleGenericTypeMetadataPattern(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "MP"; return ManglingError::Success; } ManglingError Remangler::mangleGenericTypeParamDecl(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "fp"; return ManglingError::Success; } ManglingError Remangler::mangleGetter(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "g", depth + 1); } ManglingError Remangler::mangleGlobal(Node *node, unsigned depth) { switch (Flavor) { case ManglingFlavor::Default: Buffer << MANGLING_PREFIX_STR; break; case ManglingFlavor::Embedded: Buffer << MANGLING_PREFIX_EMBEDDED_STR; break; } bool mangleInReverseOrder = false; for (auto Iter = node->begin(), End = node->end(); Iter != End; ++Iter) { Node *Child = *Iter; switch (Child->getKind()) { case Node::Kind::FunctionSignatureSpecialization: case Node::Kind::GenericSpecialization: case Node::Kind::GenericSpecializationPrespecialized: case Node::Kind::GenericSpecializationNotReAbstracted: case Node::Kind::GenericSpecializationInResilienceDomain: case Node::Kind::InlinedGenericFunction: case Node::Kind::GenericPartialSpecialization: case Node::Kind::GenericPartialSpecializationNotReAbstracted: case Node::Kind::OutlinedBridgedMethod: case Node::Kind::OutlinedVariable: case Node::Kind::OutlinedReadOnlyObject: case Node::Kind::ObjCAttribute: case Node::Kind::NonObjCAttribute: case Node::Kind::DynamicAttribute: case Node::Kind::VTableAttribute: case Node::Kind::DirectMethodReferenceAttribute: case Node::Kind::MergedFunction: case Node::Kind::DistributedThunk: case Node::Kind::DistributedAccessor: case Node::Kind::DynamicallyReplaceableFunctionKey: case Node::Kind::DynamicallyReplaceableFunctionImpl: case Node::Kind::DynamicallyReplaceableFunctionVar: case Node::Kind::AsyncFunctionPointer: case Node::Kind::AsyncAwaitResumePartialFunction: case Node::Kind::AsyncSuspendResumePartialFunction: case Node::Kind::AccessibleFunctionRecord: case Node::Kind::BackDeploymentThunk: case Node::Kind::BackDeploymentFallback: case Node::Kind::HasSymbolQuery: mangleInReverseOrder = true; break; default: RETURN_IF_ERROR(mangle(Child, depth + 1)); if (mangleInReverseOrder) { auto ReverseIter = Iter; while (ReverseIter != node->begin()) { --ReverseIter; RETURN_IF_ERROR(mangle(*ReverseIter, depth + 1)); } mangleInReverseOrder = false; } break; } } return ManglingError::Success; } ManglingError Remangler::mangleGlobalGetter(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "G", depth + 1); } ManglingError Remangler::mangleIdentifier(Node *node, unsigned depth) { mangleIdentifierImpl(node, /*isOperator*/ false); return ManglingError::Success; } ManglingError Remangler::mangleIndex(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleUnknownIndex(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleIVarInitializer(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "fe"; return ManglingError::Success; } ManglingError Remangler::mangleIVarDestroyer(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "fE"; return ManglingError::Success; } ManglingError Remangler::mangleImplDifferentiabilityKind(Node *node, unsigned depth) { Buffer << (char)node->getIndex(); return ManglingError::Success; } ManglingError Remangler::mangleImplEscaping(Node *node, unsigned depth) { Buffer << 'e'; return ManglingError::Success; } ManglingError Remangler::mangleImplErasedIsolation(Node *node, unsigned depth) { Buffer << 'A'; return ManglingError::Success; } ManglingError Remangler::mangleImplSendingResult(Node *node, unsigned depth) { Buffer << 'T'; return ManglingError::Success; } ManglingError Remangler::mangleImplConvention(Node *node, unsigned depth) { char ConvCh = llvm::StringSwitch(node->getText()) .Case("@callee_unowned", 'y') .Case("@callee_guaranteed", 'g') .Case("@callee_owned", 'x') .Default(0); if (!ConvCh) return MANGLING_ERROR(ManglingError::InvalidImplCalleeConvention, node); Buffer << ConvCh; return ManglingError::Success; } ManglingError Remangler::mangleImplParameterResultDifferentiability(Node *node, unsigned depth) { DEMANGLER_ASSERT(node->hasText(), node); // Empty string represents default differentiability. if (node->getText().empty()) return ManglingError::Success; char diffChar = llvm::StringSwitch(node->getText()) .Case("@noDerivative", 'w') .Default(0); if (!diffChar) return MANGLING_ERROR(ManglingError::InvalidImplDifferentiability, node); Buffer << diffChar; return ManglingError::Success; } ManglingError Remangler::mangleImplParameterSending(Node *node, unsigned depth) { DEMANGLER_ASSERT(node->hasText(), node); char diffChar = llvm::StringSwitch(node->getText()).Case("sending", 'T').Default(0); if (!diffChar) return MANGLING_ERROR(ManglingError::InvalidImplParameterSending, node); Buffer << diffChar; return ManglingError::Success; } ManglingError Remangler::mangleImplFunctionAttribute(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleImplFunctionConvention(Node *node, unsigned depth) { StringRef text = (node->getNumChildren() > 0 && node->getFirstChild()->hasText()) ? node->getFirstChild()->getText() : ""; char FuncAttr = llvm::StringSwitch(text) .Case("block", 'B') .Case("c", 'C') .Case("method", 'M') .Case("objc_method", 'O') .Case("closure", 'K') .Case("witness_method", 'W') .Default(0); DEMANGLER_ASSERT(FuncAttr && "invalid impl function convention", node); if ((FuncAttr == 'B' || FuncAttr == 'C') && node->getNumChildren() > 1 && node->getChild(1)->getKind() == Node::Kind::ClangType) { Buffer << 'z' << FuncAttr; return mangleClangType(node->getChild(1), depth + 1); } Buffer << FuncAttr; return ManglingError::Success; } ManglingError Remangler::mangleImplFunctionConventionName(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleClangType(Node *node, unsigned depth) { Buffer << node->getText().size() << node->getText(); return ManglingError::Success; } ManglingError Remangler::mangleImplInvocationSubstitutions(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleImplPatternSubstitutions(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleImplCoroutineKind(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) { const char *PseudoGeneric = ""; Node *GenSig = nullptr; Node *PatternSubs = nullptr; Node *InvocationSubs = nullptr; for (NodePointer Child : *node) { switch (Child->getKind()) { case Node::Kind::ImplParameter: case Node::Kind::ImplResult: case Node::Kind::ImplYield: case Node::Kind::ImplErrorResult: // Mangle type. Type should be the last child. DEMANGLER_ASSERT(Child->getNumChildren() == 2 || Child->getNumChildren() == 3 || Child->getNumChildren() == 4, node); RETURN_IF_ERROR(mangle(Child->getLastChild(), depth + 1)); break; case Node::Kind::DependentPseudogenericSignature: PseudoGeneric = "P"; LLVM_FALLTHROUGH; case Node::Kind::DependentGenericSignature: GenSig = Child; break; case Node::Kind::ImplPatternSubstitutions: PatternSubs = Child; break; case Node::Kind::ImplInvocationSubstitutions: InvocationSubs = Child; break; default: break; } } if (GenSig) RETURN_IF_ERROR(mangle(GenSig, depth + 1)); if (InvocationSubs) { Buffer << 'y'; RETURN_IF_ERROR(mangleChildNodes(InvocationSubs->getChild(0), depth + 1)); if (InvocationSubs->getNumChildren() >= 2) { RETURN_IF_ERROR( mangleRetroactiveConformance(InvocationSubs->getChild(1), depth + 1)); } } if (PatternSubs) { RETURN_IF_ERROR(mangle(PatternSubs->getChild(0), depth + 1)); Buffer << 'y'; RETURN_IF_ERROR(mangleChildNodes(PatternSubs->getChild(1), depth + 1)); if (PatternSubs->getNumChildren() >= 3) { NodePointer retroactiveConf = PatternSubs->getChild(2); if (retroactiveConf->getKind() == Node::Kind::TypeList) { RETURN_IF_ERROR(mangleChildNodes(retroactiveConf, depth + 1)); } else { RETURN_IF_ERROR( mangleRetroactiveConformance(retroactiveConf, depth + 1)); } } } Buffer << 'I'; if (PatternSubs) Buffer << 's'; if (InvocationSubs) Buffer << 'I'; Buffer << PseudoGeneric; for (NodePointer Child : *node) { switch (Child->getKind()) { case Node::Kind::ImplDifferentiabilityKind: Buffer << (char)Child->getIndex(); break; case Node::Kind::ImplEscaping: Buffer << 'e'; break; case Node::Kind::ImplErasedIsolation: Buffer << 'A'; break; case Node::Kind::ImplSendingResult: Buffer << 'T'; break; case Node::Kind::ImplConvention: { char ConvCh = llvm::StringSwitch(Child->getText()) .Case("@callee_unowned", 'y') .Case("@callee_guaranteed", 'g') .Case("@callee_owned", 'x') .Case("@convention(thin)", 't') .Default(0); if (!ConvCh) return MANGLING_ERROR(ManglingError::InvalidImplCalleeConvention, Child); Buffer << ConvCh; break; } case Node::Kind::ImplFunctionConvention: { RETURN_IF_ERROR(mangleImplFunctionConvention(Child, depth + 1)); break; } case Node::Kind::ImplCoroutineKind: { char CoroAttr = llvm::StringSwitch(Child->getText()) .Case("yield_once", 'A') .Case("yield_once_2", 'I') .Case("yield_many", 'G') .Default(0); if (!CoroAttr) { return MANGLING_ERROR(ManglingError::InvalidImplCoroutineKind, Child); } Buffer << CoroAttr; break; } case Node::Kind::ImplFunctionAttribute: { char FuncAttr = llvm::StringSwitch(Child->getText()) .Case("@Sendable", 'h') .Case("@async", 'H') .Case("sending-result", 'T') .Default(0); if (!FuncAttr) { return MANGLING_ERROR(ManglingError::InvalidImplFunctionAttribute, Child); } Buffer << FuncAttr; break; } case Node::Kind::ImplYield: Buffer << 'Y'; LLVM_FALLTHROUGH; case Node::Kind::ImplParameter: { // Mangle parameter convention. char ConvCh = llvm::StringSwitch(Child->getFirstChild()->getText()) .Case("@in", 'i') .Case("@inout", 'l') .Case("@inout_aliasable", 'b') .Case("@in_guaranteed", 'n') .Case("@in_cxx", 'X') .Case("@in_constant", 'c') .Case("@owned", 'x') .Case("@guaranteed", 'g') .Case("@deallocating", 'e') .Case("@unowned", 'y') .Case("@pack_guaranteed", 'p') .Case("@pack_owned", 'v') .Case("@pack_inout", 'm') .Default(0); if (!ConvCh) { return MANGLING_ERROR(ManglingError::InvalidImplParameterConvention, Child->getFirstChild()); } Buffer << ConvCh; // Mangle parameter differentiability, if it exists. if (Child->getNumChildren() == 3) { RETURN_IF_ERROR(mangleImplParameterResultDifferentiability( Child->getChild(1), depth + 1)); } else if (Child->getNumChildren() == 4) { RETURN_IF_ERROR(mangleImplParameterResultDifferentiability( Child->getChild(1), depth + 1)); RETURN_IF_ERROR( mangleImplParameterSending(Child->getChild(2), depth + 1)); } break; } case Node::Kind::ImplErrorResult: Buffer << 'z'; LLVM_FALLTHROUGH; case Node::Kind::ImplResult: { char ConvCh = llvm::StringSwitch(Child->getFirstChild()->getText()) .Case("@out", 'r') .Case("@owned", 'o') .Case("@unowned", 'd') .Case("@unowned_inner_pointer", 'u') .Case("@autoreleased", 'a') .Case("@pack_out", 'k') .Default(0); if (!ConvCh) { return MANGLING_ERROR(ManglingError::InvalidImplParameterConvention, Child->getFirstChild()); } Buffer << ConvCh; // Mangle result differentiability, if it exists. if (Child->getNumChildren() == 3) { RETURN_IF_ERROR(mangleImplParameterResultDifferentiability( Child->getChild(1), depth + 1)); } else if (Child->getNumChildren() == 4) { RETURN_IF_ERROR(mangleImplParameterResultDifferentiability( Child->getChild(1), depth + 1)); RETURN_IF_ERROR( mangleImplParameterSending(Child->getChild(2), depth + 1)); } break; } default: break; } } Buffer << '_'; return ManglingError::Success; } ManglingError Remangler::mangleImplicitClosure(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); // context RETURN_IF_ERROR(mangleChildNode(node, 2, depth + 1)); // type Buffer << "fu"; return mangleChildNode(node, 1, depth + 1); // index } ManglingError Remangler::mangleImplParameter(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleImplResult(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleImplYield(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleImplErrorResult(Node *node, unsigned depth) { // handled inline return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleInOut(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << 'z'; return ManglingError::Success; } ManglingError Remangler::mangleIsolated(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Yi"; return ManglingError::Success; } ManglingError Remangler::mangleSending(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Yu"; return ManglingError::Success; } ManglingError Remangler::mangleCompileTimeConst(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Yt"; return ManglingError::Success; } ManglingError Remangler::mangleShared(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << 'h'; return ManglingError::Success; } ManglingError Remangler::mangleOwned(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << 'n'; return ManglingError::Success; } ManglingError Remangler::mangleNoDerivative(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Yk"; return ManglingError::Success; } ManglingError Remangler::mangleInfixOperator(Node *node, unsigned depth) { mangleIdentifierImpl(node, /*isOperator*/ true); Buffer << "oi"; return ManglingError::Success; } ManglingError Remangler::mangleInitializer(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "fi"; return ManglingError::Success; } ManglingError Remangler::mangleInitAccessor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "i", depth + 1); } ManglingError Remangler::manglePropertyWrapperBackingInitializer(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "fP"; return ManglingError::Success; } ManglingError Remangler::manglePropertyWrapperInitFromProjectedValue(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "fW"; return ManglingError::Success; } ManglingError Remangler::mangleLazyProtocolWitnessTableAccessor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "Wl"; return ManglingError::Success; } ManglingError Remangler::mangleLazyProtocolWitnessTableCacheVariable(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WL"; return ManglingError::Success; } ManglingError Remangler::mangleLocalDeclName(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); // identifier Buffer << 'L'; return mangleChildNode(node, 0, depth + 1); // index } ManglingError Remangler::mangleMaterializeForSet(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "m", depth + 1); } ManglingError Remangler::mangleMetatype(Node *node, unsigned depth) { if (node->getFirstChild()->getKind() == Node::Kind::MetatypeRepresentation) { RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); Buffer << "XM"; RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); } else { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << 'm'; } return ManglingError::Success; } ManglingError Remangler::mangleMetatypeRepresentation(Node *node, unsigned depth) { auto text = node->getText(); if (text == "@thin") { Buffer << 't'; } else if (text == "@thick") { Buffer << 'T'; } else if (text == "@objc_metatype") { Buffer << 'o'; } else { return MANGLING_ERROR(ManglingError::InvalidMetatypeRepresentation, node); } return ManglingError::Success; } ManglingError Remangler::mangleMetaclass(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "Mm"; return ManglingError::Success; } ManglingError Remangler::mangleModifyAccessor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "M", depth + 1); } ManglingError Remangler::mangleModify2Accessor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "x", depth + 1); } ManglingError Remangler::mangleModule(Node *node, unsigned depth) { auto text = node->getText(); if (text == STDLIB_NAME) { Buffer << 's'; } else if (text == MANGLING_MODULE_OBJC) { Buffer << "So"; } else if (text == MANGLING_MODULE_CLANG_IMPORTER) { Buffer << "SC"; } else { return mangleIdentifier(node, depth); } return ManglingError::Success; } ManglingError Remangler::mangleNativeOwningAddressor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "lo", depth + 1); } ManglingError Remangler::mangleNativeOwningMutableAddressor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "ao", depth + 1); } ManglingError Remangler::mangleNativePinningAddressor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "lp", depth + 1); } ManglingError Remangler::mangleNativePinningMutableAddressor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "aP", depth + 1); } ManglingError Remangler::mangleClassMetadataBaseOffset(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mo"; return ManglingError::Success; } ManglingError Remangler::mangleNominalTypeDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mn"; return ManglingError::Success; } ManglingError Remangler::mangleNominalTypeDescriptorRecord(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Hn"; return ManglingError::Success; } ManglingError Remangler::mangleOpaqueTypeDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "MQ"; return ManglingError::Success; } ManglingError Remangler::mangleOpaqueTypeDescriptorRecord(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Ho"; return ManglingError::Success; } ManglingError Remangler::mangleOpaqueTypeDescriptorAccessor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mg"; return ManglingError::Success; } ManglingError Remangler::mangleOpaqueTypeDescriptorAccessorImpl(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mh"; return ManglingError::Success; } ManglingError Remangler::mangleOpaqueTypeDescriptorAccessorKey(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mj"; return ManglingError::Success; } ManglingError Remangler::mangleOpaqueTypeDescriptorAccessorVar(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mk"; return ManglingError::Success; } ManglingError Remangler::manglePropertyDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "MV"; return ManglingError::Success; } ManglingError Remangler::mangleNonObjCAttribute(Node *node, unsigned depth) { Buffer << "TO"; return ManglingError::Success; } ManglingError Remangler::mangleTuple(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleTypeList(node, depth + 1)); Buffer << 't'; return ManglingError::Success; } ManglingError Remangler::manglePack(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleTypeList(node, depth + 1)); Buffer << "QP"; return ManglingError::Success; } ManglingError Remangler::mangleSILPackDirect(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleTypeList(node, depth + 1)); Buffer << "QSd"; return ManglingError::Success; } ManglingError Remangler::mangleSILPackIndirect(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleTypeList(node, depth + 1)); Buffer << "QSi"; return ManglingError::Success; } ManglingError Remangler::manglePackExpansion(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "Qp"; return ManglingError::Success; } ManglingError Remangler::manglePackElement(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); Buffer << "Qe"; RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); return ManglingError::Success; } ManglingError Remangler::manglePackElementLevel(Node *node, unsigned depth) { mangleIndex(node->getIndex()); return ManglingError::Success; } ManglingError Remangler::mangleNumber(Node *node, unsigned depth) { mangleIndex(node->getIndex()); return ManglingError::Success; } ManglingError Remangler::mangleObjCAttribute(Node *node, unsigned depth) { Buffer << "To"; return ManglingError::Success; } ManglingError Remangler::mangleObjCBlock(Node *node, unsigned depth) { if (node->getNumChildren() > 0 && node->getFirstChild()->getKind() == Node::Kind::ClangType) { for (size_t Idx = node->getNumChildren() - 1; Idx >= 1; --Idx) { RETURN_IF_ERROR(mangleChildNode(node, Idx, depth + 1)); } Buffer << "XzB"; return mangleClangType(node->getFirstChild(), depth + 1); } RETURN_IF_ERROR(mangleChildNodesReversed(node, depth + 1)); Buffer << "XB"; return ManglingError::Success; } ManglingError Remangler::mangleEscapingObjCBlock(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodesReversed(node, depth + 1)); Buffer << "XL"; return ManglingError::Success; } ManglingError Remangler::mangleOwningAddressor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "lO", depth + 1); } ManglingError Remangler::mangleOwningMutableAddressor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "aO", depth + 1); } ManglingError Remangler::manglePartialApplyForwarder(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodesReversed(node, depth + 1)); Buffer << "TA"; return ManglingError::Success; } ManglingError Remangler::manglePartialApplyObjCForwarder(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodesReversed(node, depth + 1)); Buffer << "Ta"; return ManglingError::Success; } ManglingError Remangler::mangleMergedFunction(Node *node, unsigned depth) { Buffer << "Tm"; return ManglingError::Success; } ManglingError Remangler::mangleDistributedThunk(Node *node, unsigned depth) { Buffer << "TE"; return ManglingError::Success; } ManglingError Remangler::mangleDistributedAccessor(Node *node, unsigned depth) { Buffer << "TF"; return ManglingError::Success; } ManglingError Remangler::mangleDynamicallyReplaceableFunctionImpl(Node *node, unsigned depth) { Buffer << "TI"; return ManglingError::Success; } ManglingError Remangler::mangleDynamicallyReplaceableFunctionKey(Node *node, unsigned depth) { Buffer << "Tx"; return ManglingError::Success; } ManglingError Remangler::mangleDynamicallyReplaceableFunctionVar(Node *node, unsigned depth) { Buffer << "TX"; return ManglingError::Success; } ManglingError Remangler::mangleAsyncAwaitResumePartialFunction(Node *node, unsigned depth) { Buffer << "TQ"; return mangleChildNode(node, 0, depth + 1); } ManglingError Remangler::mangleAsyncSuspendResumePartialFunction(Node *node, unsigned depth) { Buffer << "TY"; return mangleChildNode(node, 0, depth + 1); } ManglingError Remangler::manglePostfixOperator(Node *node, unsigned depth) { mangleIdentifierImpl(node, /*isOperator*/ true); Buffer << "oP"; return ManglingError::Success; } ManglingError Remangler::manglePrefixOperator(Node *node, unsigned depth) { mangleIdentifierImpl(node, /*isOperator*/ true); Buffer << "op"; return ManglingError::Success; } ManglingError Remangler::manglePrivateDeclName(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodesReversed(node, depth + 1)); Buffer << (node->getNumChildren() == 1 ? "Ll" : "LL"); return ManglingError::Success; } ManglingError Remangler::mangleProtocol(Node *node, unsigned depth) { return mangleAnyGenericType(node, "P", depth + 1); } ManglingError Remangler::mangleRetroactiveConformance(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleAnyProtocolConformance(node->getChild(1), depth + 1)); Buffer << 'g'; mangleIndex(node->getChild(0)->getIndex()); return ManglingError::Success; } ManglingError Remangler::mangleProtocolConformance(Node *node, unsigned depth) { Node *Ty = getChildOfType(node->getChild(0)); Node *GenSig = nullptr; if (Ty->getKind() == Node::Kind::DependentGenericType) { GenSig = Ty->getFirstChild(); Ty = Ty->getChild(1); } RETURN_IF_ERROR(mangle(Ty, depth + 1)); if (node->getNumChildren() == 4) RETURN_IF_ERROR(mangleChildNode(node, 3, depth + 1)); RETURN_IF_ERROR(manglePureProtocol(node->getChild(1), depth + 1)); RETURN_IF_ERROR(mangleChildNode(node, 2, depth + 1)); if (GenSig) RETURN_IF_ERROR(mangle(GenSig, depth + 1)); return ManglingError::Success; } ManglingError Remangler::mangleProtocolConformanceRefInTypeModule(Node *node, unsigned depth) { RETURN_IF_ERROR(manglePureProtocol(node->getChild(0), depth + 1)); Buffer << "HP"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolConformanceRefInProtocolModule(Node *node, unsigned depth) { RETURN_IF_ERROR(manglePureProtocol(node->getChild(0), depth + 1)); Buffer << "Hp"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolConformanceRefInOtherModule(Node *node, unsigned depth) { RETURN_IF_ERROR(manglePureProtocol(node->getChild(0), depth + 1)); return mangleChildNode(node, 1, depth + 1); } ManglingError Remangler::mangleConcreteProtocolConformance(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1)); RETURN_IF_ERROR(mangle(node->getChild(1), depth + 1)); if (node->getNumChildren() > 2) { RETURN_IF_ERROR( mangleAnyProtocolConformanceList(node->getChild(2), depth + 1)); } else { Buffer << "y"; } Buffer << "HC"; return ManglingError::Success; } ManglingError Remangler::manglePackProtocolConformance(Node *node, unsigned depth) { RETURN_IF_ERROR( mangleAnyProtocolConformanceList(node->getChild(0), depth + 1)); Buffer << "HX"; return ManglingError::Success; } ManglingError Remangler::mangleDependentProtocolConformanceRoot(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1)); RETURN_IF_ERROR(manglePureProtocol(node->getChild(1), depth + 1)); Buffer << "HD"; return mangleDependentConformanceIndex(node->getChild(2), depth + 1); } ManglingError Remangler::mangleDependentProtocolConformanceInherited(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleAnyProtocolConformance(node->getChild(0), depth + 1)); RETURN_IF_ERROR(manglePureProtocol(node->getChild(1), depth + 1)); Buffer << "HI"; return mangleDependentConformanceIndex(node->getChild(2), depth + 1); } ManglingError Remangler::mangleDependentAssociatedConformance(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1)); return manglePureProtocol(node->getChild(1), depth + 1); } ManglingError Remangler::mangleDependentProtocolConformanceAssociated(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleAnyProtocolConformance(node->getChild(0), depth + 1)); RETURN_IF_ERROR( mangleDependentAssociatedConformance(node->getChild(1), depth + 1)); Buffer << "HA"; return mangleDependentConformanceIndex(node->getChild(2), depth + 1); } ManglingError Remangler::mangleDependentConformanceIndex(Node *node, unsigned depth) { DEMANGLER_ASSERT(node->getKind() == Node::Kind::Index || node->getKind() == Node::Kind::UnknownIndex, node); DEMANGLER_ASSERT(node->hasIndex() == (node->getKind() == Node::Kind::Index), node); mangleIndex(node->hasIndex() ? node->getIndex() + 2 : 1); return ManglingError::Success; } ManglingError Remangler::mangleAnyProtocolConformance(Node *node, unsigned depth) { switch (node->getKind()) { case Node::Kind::ConcreteProtocolConformance: return mangleConcreteProtocolConformance(node, depth + 1); case Node::Kind::PackProtocolConformance: return manglePackProtocolConformance(node, depth + 1); case Node::Kind::DependentProtocolConformanceRoot: return mangleDependentProtocolConformanceRoot(node, depth + 1); case Node::Kind::DependentProtocolConformanceInherited: return mangleDependentProtocolConformanceInherited(node, depth + 1); case Node::Kind::DependentProtocolConformanceAssociated: return mangleDependentProtocolConformanceAssociated(node, depth + 1); default: // Should this really succeed?! return ManglingError::Success; } } ManglingError Remangler::mangleAnyProtocolConformanceList(Node *node, unsigned depth) { bool firstElem = true; for (NodePointer child : *node) { RETURN_IF_ERROR(mangleAnyProtocolConformance(child, depth + 1)); mangleListSeparator(firstElem); } mangleEndOfList(firstElem); return ManglingError::Success; } ManglingError Remangler::mangleProtocolDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(manglePureProtocol(getSingleChild(node), depth + 1)); Buffer << "Mp"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolDescriptorRecord(Node *node, unsigned depth) { RETURN_IF_ERROR(manglePureProtocol(getSingleChild(node), depth + 1)); Buffer << "Hr"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolRequirementsBaseDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(manglePureProtocol(getSingleChild(node), depth + 1)); Buffer << "TL"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolSelfConformanceDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(manglePureProtocol(node->getChild(0), depth + 1)); Buffer << "MS"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolConformanceDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleProtocolConformance(node->getChild(0), depth + 1)); Buffer << "Mc"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolConformanceDescriptorRecord(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleProtocolConformance(node->getChild(0), depth + 1)); Buffer << "Hc"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolList(Node *node, Node *superclass, bool hasExplicitAnyObject, unsigned depth) { auto *protocols = getSingleChild(node, Node::Kind::TypeList); bool FirstElem = true; for (NodePointer Child : *protocols) { RETURN_IF_ERROR(manglePureProtocol(Child, depth + 1)); mangleListSeparator(FirstElem); } mangleEndOfList(FirstElem); if (superclass) { RETURN_IF_ERROR(mangleType(superclass, depth + 1)); Buffer << "Xc"; return ManglingError::Success; } else if (hasExplicitAnyObject) { Buffer << "Xl"; return ManglingError::Success; } Buffer << 'p'; return ManglingError::Success; } ManglingError Remangler::mangleProtocolList(Node *node, unsigned depth) { return mangleProtocolList(node, nullptr, false, depth + 1); } ManglingError Remangler::mangleProtocolListWithClass(Node *node, unsigned depth) { return mangleProtocolList(node->getChild(0), node->getChild(1), false, depth + 1); } ManglingError Remangler::mangleProtocolListWithAnyObject(Node *node, unsigned depth) { return mangleProtocolList(node->getChild(0), nullptr, true, depth + 1); } ManglingError Remangler::mangleProtocolSelfConformanceWitness(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "TS"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolWitness(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "TW"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolSelfConformanceWitnessTable(Node *node, unsigned depth) { RETURN_IF_ERROR(manglePureProtocol(node->getChild(0), depth + 1)); Buffer << "WS"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolWitnessTable(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "WP"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolWitnessTablePattern(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Wp"; return ManglingError::Success; } ManglingError Remangler::mangleProtocolWitnessTableAccessor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Wa"; return ManglingError::Success; } ManglingError Remangler::mangleReabstractionThunk(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodesReversed(node, depth + 1)); Buffer << "Tr"; return ManglingError::Success; } ManglingError Remangler::mangleReabstractionThunkHelper(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodesReversed(node, depth + 1)); Buffer << "TR"; return ManglingError::Success; } ManglingError Remangler::mangleReabstractionThunkHelperWithSelf(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodesReversed(node, depth + 1)); Buffer << "Ty"; return ManglingError::Success; } ManglingError Remangler::mangleReabstractionThunkHelperWithGlobalActor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "TU"; return ManglingError::Success; } ManglingError Remangler::mangleAutoDiffFunctionOrSimpleThunk(Node *node, StringRef op, unsigned depth) { auto childIt = node->begin(); while (childIt != node->end() && (*childIt)->getKind() != Node::Kind::AutoDiffFunctionKind) RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); Buffer << op; RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); // kind RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); // parameter indices Buffer << 'p'; RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); // result indices Buffer << 'r'; return ManglingError::Success; } ManglingError Remangler::mangleAutoDiffFunction(Node *node, unsigned depth) { return mangleAutoDiffFunctionOrSimpleThunk(node, "TJ", depth + 1); } ManglingError Remangler::mangleAutoDiffDerivativeVTableThunk(Node *node, unsigned depth) { return mangleAutoDiffFunctionOrSimpleThunk(node, "TJV", depth + 1); } ManglingError Remangler::mangleAutoDiffSelfReorderingReabstractionThunk(Node *node, unsigned depth) { auto childIt = node->begin(); RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); // from type RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); // to type if ((*childIt)->getKind() == Node::Kind::DependentGenericSignature) RETURN_IF_ERROR(mangleDependentGenericSignature(*childIt++, depth + 1)); Buffer << "TJO"; return mangle(*childIt++, depth + 1); // kind } ManglingError Remangler::mangleAutoDiffSubsetParametersThunk(Node *node, unsigned depth) { auto childIt = node->begin(); while (childIt != node->end() && (*childIt)->getKind() != Node::Kind::AutoDiffFunctionKind) RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); Buffer << "TJS"; RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); // kind RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); // parameter indices Buffer << 'p'; RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); // result indices Buffer << 'r'; RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); // to parameter indices Buffer << 'P'; return ManglingError::Success; } ManglingError Remangler::mangleAutoDiffFunctionKind(Node *node, unsigned depth) { Buffer << (char)node->getIndex(); return ManglingError::Success; } ManglingError Remangler::mangleDifferentiabilityWitness(Node *node, unsigned depth) { auto childIt = node->begin(); while (childIt != node->end() && (*childIt)->getKind() != Node::Kind::Index) RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); if (node->getLastChild()->getKind() == Node::Kind::DependentGenericSignature) RETURN_IF_ERROR(mangle(node->getLastChild(), depth + 1)); Buffer << "WJ" << (char)(*childIt++)->getIndex(); RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); // parameter indices Buffer << 'p'; RETURN_IF_ERROR(mangle(*childIt++, depth + 1)); // result indices Buffer << 'r'; return ManglingError::Success; } ManglingError Remangler::mangleIndexSubset(Node *node, unsigned depth) { Buffer << node->getText(); return ManglingError::Success; } ManglingError Remangler::mangleReadAccessor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "r", depth + 1); } ManglingError Remangler::mangleRead2Accessor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "y", depth + 1); } ManglingError Remangler::mangleKeyPathThunkHelper(Node *node, StringRef op, unsigned depth) { for (NodePointer Child : *node) if (Child->getKind() != Node::Kind::IsSerialized) RETURN_IF_ERROR(mangle(Child, depth + 1)); Buffer << op; for (NodePointer Child : *node) if (Child->getKind() == Node::Kind::IsSerialized) RETURN_IF_ERROR(mangle(Child, depth + 1)); return ManglingError::Success; } ManglingError Remangler::mangleKeyPathGetterThunkHelper(Node *node, unsigned depth) { return mangleKeyPathThunkHelper(node, "TK", depth + 1); } ManglingError Remangler::mangleKeyPathSetterThunkHelper(Node *node, unsigned depth) { return mangleKeyPathThunkHelper(node, "Tk", depth + 1); } ManglingError Remangler::mangleKeyPathEqualsThunkHelper(Node *node, unsigned depth) { return mangleKeyPathThunkHelper(node, "TH", depth + 1); } ManglingError Remangler::mangleKeyPathHashThunkHelper(Node *node, unsigned depth) { return mangleKeyPathThunkHelper(node, "Th", depth + 1); } ManglingError Remangler::mangleReturnType(Node *node, unsigned depth) { return mangleArgumentTuple(node, depth + 1); } ManglingError Remangler::mangleRelatedEntityDeclName(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); NodePointer kindNode = node->getFirstChild(); if (kindNode->getText().size() != 1) return MANGLING_ERROR(ManglingError::MultiByteRelatedEntity, kindNode); Buffer << "L" << kindNode->getText(); return ManglingError::Success; } ManglingError Remangler::mangleSILBoxType(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Xb"; return ManglingError::Success; } ManglingError Remangler::mangleSetter(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "s", depth + 1); } ManglingError Remangler::mangleSpecializationPassID(Node *node, unsigned depth) { Buffer << node->getIndex(); return ManglingError::Success; } ManglingError Remangler::mangleIsSerialized(Node *node, unsigned depth) { Buffer << 'q'; return ManglingError::Success; } ManglingError Remangler::mangleAsyncRemoved(Node *node, unsigned depth) { Buffer << 'a'; return ManglingError::Success; } ManglingError Remangler::mangleDroppedArgument(Node *node, unsigned depth) { Buffer << "t"; int n = node->getIndex(); if (n > 0) Buffer << (n-1); return ManglingError::Success; } ManglingError Remangler::mangleStatic(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << 'Z'; return ManglingError::Success; } ManglingError Remangler::mangleOtherNominalType(Node *node, unsigned depth) { return mangleAnyNominalType(node, depth + 1); } ManglingError Remangler::mangleStructure(Node *node, unsigned depth) { return mangleAnyNominalType(node, depth + 1); } ManglingError Remangler::mangleSubscript(Node *node, unsigned depth) { return mangleAbstractStorage(node, "p", depth + 1); } ManglingError Remangler::mangleMacro(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "fm"; return ManglingError::Success; } ManglingError Remangler::mangleFreestandingMacroExpansion( Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); if (auto privateDiscriminator = node->getChild(3)) RETURN_IF_ERROR(mangle(privateDiscriminator, depth + 1)); RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); Buffer << "fMf"; return mangleChildNode(node, 2, depth + 1); } #define FREESTANDING_MACRO_ROLE(Name, Description) #define ATTACHED_MACRO_ROLE(Name, Description, MangledChar) \ ManglingError Remangler::mangle##Name##AttachedMacroExpansion( \ Node *node, unsigned depth) { \ RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); \ RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); \ RETURN_IF_ERROR(mangleChildNode(node, 2, depth + 1)); \ Buffer << "fM" MangledChar; \ return mangleChildNode(node, 3, depth + 1); \ } #include "swift/Basic/MacroRoles.def" ManglingError Remangler::mangleMacroExpansionLoc( Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); auto line = node->getChild(2)->getIndex(); auto col = node->getChild(3)->getIndex(); Buffer << "fMX"; mangleIndex(line); mangleIndex(col); return ManglingError::Success; } ManglingError Remangler::mangleMacroExpansionUniqueName( Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); if (auto privateDiscriminator = node->getChild(3)) RETURN_IF_ERROR(mangle(privateDiscriminator, depth + 1)); RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); Buffer << "fMu"; return mangleChildNode(node, 2, depth + 1); } ManglingError Remangler::mangleSuffix(Node *node, unsigned depth) { // Just add the suffix back on. Buffer << node->getText(); return ManglingError::Success; } ManglingError Remangler::mangleThinFunctionType(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleFunctionSignature(node, depth + 1)); Buffer << "Xf"; return ManglingError::Success; } ManglingError Remangler::mangleTupleElement(Node *node, unsigned depth) { return mangleChildNodesReversed(node, depth + 1); // tuple type, element name? } ManglingError Remangler::mangleTupleElementName(Node *node, unsigned depth) { return mangleIdentifier(node, depth + 1); } ManglingError Remangler::mangleType(Node *node, unsigned depth) { return mangleSingleChildNode(node, depth + 1); } ManglingError Remangler::mangleTypeAlias(Node *node, unsigned depth) { return mangleAnyNominalType(node, depth + 1); } ManglingError Remangler::mangleTypeList(Node *node, unsigned depth) { bool FirstElem = true; for (size_t Idx = 0, Num = node->getNumChildren(); Idx < Num; ++Idx) { RETURN_IF_ERROR(mangleChildNode(node, Idx, depth + 1)); mangleListSeparator(FirstElem); } mangleEndOfList(FirstElem); return ManglingError::Success; } ManglingError Remangler::mangleLabelList(Node *node, unsigned depth) { if (node->getNumChildren() == 0) Buffer << 'y'; else RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); return ManglingError::Success; } ManglingError Remangler::mangleTypeMangling(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << 'D'; return ManglingError::Success; } ManglingError Remangler::mangleTypeMetadata(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "N"; return ManglingError::Success; } ManglingError Remangler::mangleTypeMetadataAccessFunction(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Ma"; return ManglingError::Success; } ManglingError Remangler::mangleTypeMetadataInstantiationCache(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "MI"; return ManglingError::Success; } ManglingError Remangler::mangleTypeMetadataInstantiationFunction(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mi"; return ManglingError::Success; } ManglingError Remangler::mangleTypeMetadataSingletonInitializationCache(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Ml"; return ManglingError::Success; } ManglingError Remangler::mangleTypeMetadataCompletionFunction(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mr"; return ManglingError::Success; } ManglingError Remangler::mangleTypeMetadataDemanglingCache(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "MD"; return ManglingError::Success; } ManglingError Remangler::mangleTypeMetadataLazyCache(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "ML"; return ManglingError::Success; } ManglingError Remangler::mangleUncurriedFunctionType(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleFunctionSignature(node, depth + 1)); // Mangle as regular function type (there is no "uncurried function type" // in the new mangling scheme). Buffer << 'c'; return ManglingError::Success; } ManglingError Remangler::mangleUnsafeAddressor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "lu", depth + 1); } ManglingError Remangler::mangleUnsafeMutableAddressor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "au", depth + 1); } ManglingError Remangler::mangleValueWitness(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); // type const char *Code = nullptr; switch (ValueWitnessKind(node->getFirstChild()->getIndex())) { #define VALUE_WITNESS(MANGLING, NAME) \ case ValueWitnessKind::NAME: Code = #MANGLING; break; #include "swift/Demangling/ValueWitnessMangling.def" } Buffer << 'w' << Code; return ManglingError::Success; } ManglingError Remangler::mangleValueWitnessTable(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "WV"; return ManglingError::Success; } ManglingError Remangler::mangleVariable(Node *node, unsigned depth) { return mangleAbstractStorage(node, "p", depth + 1); } ManglingError Remangler::mangleVTableAttribute(Node *node, unsigned depth) { // Old-fashioned vtable thunk in new mangling format return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleVTableThunk(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "TV"; return ManglingError::Success; } #define REF_STORAGE(Name, ...) \ ManglingError Remangler::mangle##Name(Node *node, unsigned depth) { \ RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); \ Buffer << manglingOf(ReferenceOwnership::Name); \ return ManglingError::Success; \ } #include "swift/AST/ReferenceStorage.def" ManglingError Remangler::mangleWillSet(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "w", depth + 1); } ManglingError Remangler::mangleReflectionMetadataBuiltinDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "MB"; return ManglingError::Success; } ManglingError Remangler::mangleReflectionMetadataFieldDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "MF"; return ManglingError::Success; } ManglingError Remangler::mangleReflectionMetadataAssocTypeDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR( mangleSingleChildNode(node, depth + 1)); // protocol-conformance Buffer << "MA"; return ManglingError::Success; } ManglingError Remangler::mangleReflectionMetadataSuperclassDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR( mangleSingleChildNode(node, depth + 1)); // protocol-conformance Buffer << "MC"; return ManglingError::Success; } ManglingError Remangler::mangleCurryThunk(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Tc"; return ManglingError::Success; } ManglingError Remangler::mangleSILThunkIdentity(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); // type // TT is for a thunk that is for a thunk inst... I is for identity. Buffer << "TT" << "I"; return ManglingError::Success; } ManglingError Remangler::mangleSILThunkHopToMainActorIfNeeded(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); // type Buffer << "TT" << "H"; return ManglingError::Success; } ManglingError Remangler::mangleDispatchThunk(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Tj"; return ManglingError::Success; } ManglingError Remangler::mangleMethodDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Tq"; return ManglingError::Success; } ManglingError Remangler::mangleMethodLookupFunction(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mu"; return ManglingError::Success; } ManglingError Remangler::mangleObjCMetadataUpdateFunction(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "MU"; return ManglingError::Success; } ManglingError Remangler::mangleObjCResilientClassStub(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Ms"; return ManglingError::Success; } ManglingError Remangler::mangleFullObjCResilientClassStub(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mt"; return ManglingError::Success; } ManglingError Remangler::mangleConcurrentFunctionType(Node *node, unsigned depth) { Buffer << "Yb"; return ManglingError::Success; } ManglingError Remangler::mangleAsyncAnnotation(Node *node, unsigned depth) { Buffer << "Ya"; return ManglingError::Success; } ManglingError Remangler::mangleDifferentiableFunctionType(Node *node, unsigned depth) { Buffer << "Yj" << (char)node->getIndex(); // differentiability kind return ManglingError::Success; } ManglingError Remangler::mangleGlobalActorFunctionType(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "Yc"; return ManglingError::Success; } ManglingError Remangler::mangleIsolatedAnyFunctionType(Node *node, unsigned depth) { Buffer << "YA"; return ManglingError::Success; } ManglingError Remangler::mangleSendingResultFunctionType(Node *node, unsigned depth) { Buffer << "YT"; return ManglingError::Success; } ManglingError Remangler::mangleThrowsAnnotation(Node *node, unsigned depth) { Buffer << 'K'; return ManglingError::Success; } ManglingError Remangler::mangleTypedThrowsAnnotation(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "YK"; return ManglingError::Success; } ManglingError Remangler::mangleEmptyList(Node *node, unsigned depth) { Buffer << 'y'; return ManglingError::Success; } ManglingError Remangler::mangleFirstElementMarker(Node *node, unsigned depth) { Buffer << '_'; return ManglingError::Success; } ManglingError Remangler::mangleVariadicMarker(Node *node, unsigned depth) { Buffer << 'd'; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedCopy(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOy"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedConsume(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOe"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedRetain(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOr"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedRelease(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOs"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedInitializeWithTake(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOb"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedInitializeWithCopy(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOc"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedAssignWithTake(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOd"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedAssignWithCopy(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOf"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedDestroy(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOh"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedInitializeWithCopyNoValueWitness(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOC"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedAssignWithTakeNoValueWitness(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOD"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedAssignWithCopyNoValueWitness(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOF"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedDestroyNoValueWitness(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOH"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedEnumGetTag(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WOg"; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedEnumProjectDataForLoad(Node *node, unsigned depth) { if (node->getNumChildren() == 2) { auto ty = node->getChild(0); RETURN_IF_ERROR(mangle(ty, depth + 1)); Buffer << "WOj"; mangleIndex(node->getChild(1)->getIndex()); return ManglingError::Success; } else { auto ty = node->getChild(0); RETURN_IF_ERROR(mangle(ty, depth + 1)); auto sig = node->getChild(1); RETURN_IF_ERROR(mangle(sig, depth + 1)); Buffer << "WOj"; mangleIndex(node->getChild(2)->getIndex()); return ManglingError::Success; } } ManglingError Remangler::mangleOutlinedEnumTagStore(Node *node, unsigned depth) { if (node->getNumChildren() == 2) { auto ty = node->getChild(0); RETURN_IF_ERROR(mangle(ty, depth + 1)); Buffer << "WOi"; mangleIndex(node->getChild(1)->getIndex()); return ManglingError::Success; } else { auto ty = node->getChild(0); RETURN_IF_ERROR(mangle(ty, depth + 1)); auto sig = node->getChild(1); RETURN_IF_ERROR(mangle(sig, depth + 1)); Buffer << "WOi"; mangleIndex(node->getChild(2)->getIndex()); return ManglingError::Success; } } ManglingError Remangler::mangleOutlinedVariable(Node *node, unsigned depth) { Buffer << "Tv"; mangleIndex(node->getIndex()); return ManglingError::Success; } ManglingError Remangler::mangleOutlinedReadOnlyObject(Node *node, unsigned depth) { Buffer << "Tv"; mangleIndex(node->getIndex()); Buffer << 'r'; return ManglingError::Success; } ManglingError Remangler::mangleOutlinedBridgedMethod(Node *node, unsigned depth) { Buffer << "Te"; Buffer << node->getText(); Buffer << "_"; return ManglingError::Success; } ManglingError Remangler::mangleSILBoxTypeWithLayout(Node *node, unsigned depth) { DEMANGLER_ASSERT(node->getNumChildren() == 1 || node->getNumChildren() == 3, node); DEMANGLER_ASSERT(node->getChild(0)->getKind() == Node::Kind::SILBoxLayout, node); auto layout = node->getChild(0); auto layoutTypeList = Factory.createNode(Node::Kind::TypeList); for (unsigned i = 0, e = layout->getNumChildren(); i < e; ++i) { DEMANGLER_ASSERT( layout->getChild(i)->getKind() == Node::Kind::SILBoxImmutableField || layout->getChild(i)->getKind() == Node::Kind::SILBoxMutableField, layout->getChild(i)); auto field = layout->getChild(i); DEMANGLER_ASSERT(field->getNumChildren() == 1 && field->getChild(0)->getKind() == Node::Kind::Type, field); auto fieldType = field->getChild(0); // 'inout' mangling is used to represent mutable fields. if (field->getKind() == Node::Kind::SILBoxMutableField) { auto inout = Factory.createNode(Node::Kind::InOut); inout->addChild(fieldType->getChild(0), Factory); fieldType = Factory.createNode(Node::Kind::Type); fieldType->addChild(inout, Factory); } layoutTypeList->addChild(fieldType, Factory); } RETURN_IF_ERROR(mangleTypeList(layoutTypeList, depth + 1)); if (node->getNumChildren() == 3) { auto signature = node->getChild(1); auto genericArgs = node->getChild(2); DEMANGLER_ASSERT( signature->getKind() == Node::Kind::DependentGenericSignature, node); DEMANGLER_ASSERT(genericArgs->getKind() == Node::Kind::TypeList, node); RETURN_IF_ERROR(mangleTypeList(genericArgs, depth + 1)); RETURN_IF_ERROR(mangleDependentGenericSignature(signature, depth + 1)); Buffer << "XX"; } else { Buffer << "Xx"; } return ManglingError::Success; } ManglingError Remangler::mangleSILBoxLayout(Node *node, unsigned depth) { // should be part of SILBoxTypeWithLayout return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleSILBoxMutableField(Node *node, unsigned depth) { // should be part of SILBoxTypeWithLayout return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleSILBoxImmutableField(Node *node, unsigned depth) { // should be part of SILBoxTypeWithLayout return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleAssocTypePath(Node *node, unsigned depth) { bool FirstElem = true; for (NodePointer Child : *node) { RETURN_IF_ERROR(mangle(Child, depth + 1)); mangleListSeparator(FirstElem); } return ManglingError::Success; } ManglingError Remangler::mangleModuleDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1)); Buffer << "MXM"; return ManglingError::Success; } ManglingError Remangler::mangleExtensionDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1)); Buffer << "MXE"; return ManglingError::Success; } ManglingError Remangler::mangleAnonymousDescriptor(Node *node, unsigned depth) { RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1)); if (node->getNumChildren() == 1) { Buffer << "MXX"; } else { RETURN_IF_ERROR(mangleIdentifier(node->getChild(1), depth + 1)); Buffer << "MXY"; } return ManglingError::Success; } ManglingError Remangler::mangleAssociatedTypeGenericParamRef(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1)); RETURN_IF_ERROR(mangleAssocTypePath(node->getChild(1), depth + 1)); Buffer << "MXA"; return ManglingError::Success; } ManglingError Remangler::mangleTypeSymbolicReference(Node *node, unsigned depth) { return mangle( Resolver(SymbolicReferenceKind::Context, (const void *)node->getIndex()), depth + 1); } ManglingError Remangler::mangleObjectiveCProtocolSymbolicReference(Node *node, unsigned depth) { return mangle(Resolver(SymbolicReferenceKind::ObjectiveCProtocol, (const void *)node->getIndex()), depth + 1); } ManglingError Remangler::mangleProtocolSymbolicReference(Node *node, unsigned depth) { return mangle( Resolver(SymbolicReferenceKind::Context, (const void *)node->getIndex()), depth + 1); } ManglingError Remangler::mangleOpaqueTypeDescriptorSymbolicReference(Node *node, unsigned depth) { return mangle( Resolver(SymbolicReferenceKind::Context, (const void *)node->getIndex()), depth + 1); } ManglingError Remangler::mangleSugaredOptional(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1)); Buffer << "XSq"; return ManglingError::Success; } ManglingError Remangler::mangleSugaredArray(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1)); Buffer << "XSa"; return ManglingError::Success; } ManglingError Remangler::mangleSugaredDictionary(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1)); RETURN_IF_ERROR(mangleType(node->getChild(1), depth + 1)); Buffer << "XSD"; return ManglingError::Success; } ManglingError Remangler::mangleSugaredParen(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1)); Buffer << "XSp"; return ManglingError::Success; } ManglingError Remangler::mangleOpaqueReturnType(Node *node, unsigned depth) { if (node->hasChildren() && node->getFirstChild()->getKind() == Node::Kind::OpaqueReturnTypeIndex) { Buffer << "QR"; mangleIndex(node->getFirstChild()->getIndex()); return ManglingError::Success; } Buffer << "Qr"; return ManglingError::Success; } ManglingError Remangler::mangleOpaqueReturnTypeIndex(Node *node, unsigned depth) { // Cannot appear unparented to an OpaqueReturnType. return ManglingError::WrongNodeType; } ManglingError Remangler::mangleOpaqueReturnTypeParent(Node *node, unsigned depth) { // Cannot appear unparented to an OpaqueReturnType. return ManglingError::WrongNodeType; } ManglingError Remangler::mangleOpaqueReturnTypeOf(Node *node, unsigned depth) { RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1)); Buffer << "QO"; return ManglingError::Success; } ManglingError Remangler::mangleOpaqueType(Node *node, unsigned depth) { SubstitutionEntry entry; if (trySubstitution(node, entry)) return ManglingError::Success; DEMANGLER_ASSERT(node->getNumChildren() >= 3, node); RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1)); auto boundGenerics = node->getChild(2); for (unsigned i = 0; i < boundGenerics->getNumChildren(); ++i) { Buffer << (i == 0 ? 'y' : '_'); RETURN_IF_ERROR(mangleChildNodes(boundGenerics->getChild(i), depth + 1)); } if (node->getNumChildren() >= 4) { auto retroactiveConformances = node->getChild(3); for (unsigned i = 0; i < retroactiveConformances->getNumChildren(); ++i) { RETURN_IF_ERROR(mangle(retroactiveConformances->getChild(i), depth + 1)); } } Buffer << "Qo"; mangleIndex(node->getChild(1)->getIndex()); addSubstitution(entry); return ManglingError::Success; } ManglingError Remangler::mangleAccessorFunctionReference(Node *node, unsigned depth) { return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleCanonicalSpecializedGenericMetaclass(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "MM"; return ManglingError::Success; } ManglingError Remangler::mangleCanonicalSpecializedGenericTypeMetadataAccessFunction( Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mb"; return ManglingError::Success; } ManglingError Remangler::mangleMetadataInstantiationCache(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "MK"; return ManglingError::Success; } ManglingError Remangler::mangleNoncanonicalSpecializedGenericTypeMetadata(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "MN"; return ManglingError::Success; } ManglingError Remangler::mangleNoncanonicalSpecializedGenericTypeMetadataCache( Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "MJ"; return ManglingError::Success; } ManglingError Remangler::mangleCanonicalPrespecializedGenericTypeCachingOnceToken( Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Mz"; return ManglingError::Success; } ManglingError Remangler::mangleGlobalVariableOnceToken(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "Wz"; return ManglingError::Success; } ManglingError Remangler::mangleGlobalVariableOnceFunction(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); Buffer << "WZ"; return ManglingError::Success; } ManglingError Remangler::mangleGlobalVariableOnceDeclList(Node *node, unsigned depth) { for (unsigned i = 0, e = node->getNumChildren(); i < e; ++i) { RETURN_IF_ERROR(mangle(node->getChild(i), depth + 1)); Buffer << '_'; } return ManglingError::Success; } ManglingError Remangler::mangleAccessibleFunctionRecord(Node *node, unsigned depth) { Buffer << "HF"; return ManglingError::Success; } ManglingError Remangler::mangleBackDeploymentThunk(Node *node, unsigned depth) { Buffer << "Twb"; return ManglingError::Success; } ManglingError Remangler::mangleBackDeploymentFallback(Node *node, unsigned depth) { Buffer << "TwB"; return ManglingError::Success; } ManglingError Remangler::mangleUniquable(Node *node, unsigned depth) { RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1)); Buffer << "Mq"; return ManglingError::Success; } ManglingError Remangler::mangleExtendedExistentialTypeShape(Node *node, unsigned depth) { NodePointer genSig, type; if (node->getNumChildren() == 1) { genSig = nullptr; type = node->getChild(0); } else { genSig = node->getChild(0); type = node->getChild(1); } if (genSig) { RETURN_IF_ERROR(mangle(genSig, depth + 1)); } RETURN_IF_ERROR(mangle(type, depth + 1)); if (genSig) Buffer << "XG"; else Buffer << "Xg"; return ManglingError::Success; } ManglingError Remangler::mangleHasSymbolQuery(Node *node, unsigned depth) { Buffer << "TwS"; return ManglingError::Success; } ManglingError Remangler::mangleSymbolicExtendedExistentialType(Node *node, unsigned int depth) { RETURN_IF_ERROR(mangle(node->getChild(0), depth+1)); for (auto arg: *node->getChild(1)) RETURN_IF_ERROR(mangle(arg, depth+1)); if (node->getNumChildren() > 2) for (auto conf: *node->getChild(2)) RETURN_IF_ERROR(mangle(conf, depth+1)); return ManglingError::Success; } ManglingError Remangler:: mangleUniqueExtendedExistentialTypeShapeSymbolicReference(Node *node, unsigned int depth) { // We don't support absolute references in the mangling of these return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler:: mangleNonUniqueExtendedExistentialTypeShapeSymbolicReference(Node *node, unsigned int depth) { // We don't support absolute references in the mangling of these return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleInteger(Node *node, unsigned int depth) { Buffer << "$"; mangleIndex(node->getIndex()); return ManglingError::Success; } ManglingError Remangler::mangleNegativeInteger(Node *node, unsigned int depth) { Buffer << "$n"; mangleIndex(-node->getIndex()); return ManglingError::Success; } ManglingError Remangler::mangleDependentGenericParamValueMarker(Node *node, unsigned depth) { DEMANGLER_ASSERT(node->getNumChildren() == 2, node); DEMANGLER_ASSERT(node->getChild(0)->getChild(0)->getKind() == Node::Kind::DependentGenericParamType, node); DEMANGLER_ASSERT(node->getChild(1)->getKind() == Node::Kind::Type, node); RETURN_IF_ERROR(mangleType(node->getChild(1), depth + 1)); Buffer << "RV"; mangleDependentGenericParamIndex(node->getChild(0)->getChild(0)); return ManglingError::Success; } } // anonymous namespace /// The top-level interface to the remangler. ManglingErrorOr Demangle::mangleNode(NodePointer node, ManglingFlavor Flavor) { return mangleNode(node, [](SymbolicReferenceKind, const void *) -> NodePointer { return nullptr; }, Flavor); // unreachable("should not try to mangle a symbolic reference; " // "resolve it to a non-symbolic demangling tree instead"); } ManglingErrorOr Demangle::mangleNode(NodePointer node, SymbolicResolver resolver, ManglingFlavor Flavor) { if (!node) return std::string(); NodeFactory Factory; Remangler remangler(resolver, Factory, Flavor); ManglingError err = remangler.mangle(node, 0); if (!err.isSuccess()) return err; return remangler.str(); } ManglingErrorOr Demangle::mangleNode(NodePointer node, SymbolicResolver resolver, NodeFactory &Factory, ManglingFlavor Flavor) { if (!node) return StringRef(); Remangler remangler(resolver, Factory, Flavor); ManglingError err = remangler.mangle(node, 0); if (!err.isSuccess()) return err; return remangler.getBufferStr(); } bool Demangle::isSpecialized(Node *node) { // We shouldn't get here with node being NULL; if we do, assert in debug, // or return false at runtime (which should at least help diagnose things // further if it happens). assert(node); if (!node) return false; switch (node->getKind()) { case Node::Kind::BoundGenericStructure: case Node::Kind::BoundGenericEnum: case Node::Kind::BoundGenericClass: case Node::Kind::BoundGenericOtherNominalType: case Node::Kind::BoundGenericTypeAlias: case Node::Kind::BoundGenericProtocol: case Node::Kind::BoundGenericFunction: case Node::Kind::ConstrainedExistential: return true; case Node::Kind::Structure: case Node::Kind::Enum: case Node::Kind::Class: case Node::Kind::TypeAlias: case Node::Kind::OtherNominalType: case Node::Kind::Protocol: case Node::Kind::Function: case Node::Kind::Allocator: case Node::Kind::Constructor: case Node::Kind::Destructor: case Node::Kind::Variable: case Node::Kind::Subscript: case Node::Kind::ExplicitClosure: case Node::Kind::ImplicitClosure: case Node::Kind::Initializer: case Node::Kind::PropertyWrapperBackingInitializer: case Node::Kind::PropertyWrapperInitFromProjectedValue: case Node::Kind::DefaultArgumentInitializer: case Node::Kind::Getter: case Node::Kind::Setter: case Node::Kind::WillSet: case Node::Kind::DidSet: case Node::Kind::ReadAccessor: case Node::Kind::ModifyAccessor: case Node::Kind::UnsafeAddressor: case Node::Kind::UnsafeMutableAddressor: case Node::Kind::Static: assert(node->getNumChildren() > 0); return node->getNumChildren() > 0 && isSpecialized(node->getChild(0)); case Node::Kind::Extension: assert(node->getNumChildren() > 1); return node->getNumChildren() > 1 && isSpecialized(node->getChild(1)); default: return false; } } ManglingErrorOr Demangle::getUnspecialized(Node *node, NodeFactory &Factory) { unsigned NumToCopy = 2; switch (node->getKind()) { case Node::Kind::Function: case Node::Kind::Getter: case Node::Kind::Setter: case Node::Kind::WillSet: case Node::Kind::DidSet: case Node::Kind::ReadAccessor: case Node::Kind::ModifyAccessor: case Node::Kind::UnsafeAddressor: case Node::Kind::UnsafeMutableAddressor: case Node::Kind::Allocator: case Node::Kind::Constructor: case Node::Kind::Destructor: case Node::Kind::Variable: case Node::Kind::Subscript: case Node::Kind::ExplicitClosure: case Node::Kind::ImplicitClosure: case Node::Kind::Initializer: case Node::Kind::PropertyWrapperBackingInitializer: case Node::Kind::PropertyWrapperInitFromProjectedValue: case Node::Kind::DefaultArgumentInitializer: case Node::Kind::Static: NumToCopy = node->getNumChildren(); LLVM_FALLTHROUGH; case Node::Kind::Structure: case Node::Kind::Enum: case Node::Kind::Class: case Node::Kind::TypeAlias: case Node::Kind::OtherNominalType: { NodePointer result = Factory.createNode(node->getKind()); DEMANGLER_ASSERT(node->hasChildren(), node); NodePointer parentOrModule = node->getChild(0); if (isSpecialized(parentOrModule)) { auto unspec = getUnspecialized(parentOrModule, Factory); if (!unspec.isSuccess()) return unspec; parentOrModule = unspec.result(); } result->addChild(parentOrModule, Factory); for (unsigned Idx = 1; Idx < NumToCopy; ++Idx) { result->addChild(node->getChild(Idx), Factory); } return result; } case Node::Kind::BoundGenericStructure: case Node::Kind::BoundGenericEnum: case Node::Kind::BoundGenericClass: case Node::Kind::BoundGenericProtocol: case Node::Kind::BoundGenericOtherNominalType: case Node::Kind::BoundGenericTypeAlias: { DEMANGLER_ASSERT(node->hasChildren(), node); NodePointer unboundType = node->getChild(0); DEMANGLER_ASSERT(unboundType->getKind() == Node::Kind::Type, unboundType); DEMANGLER_ASSERT(unboundType->hasChildren(), unboundType); NodePointer nominalType = unboundType->getChild(0); if (isSpecialized(nominalType)) return getUnspecialized(nominalType, Factory); return nominalType; } case Node::Kind::ConstrainedExistential: { DEMANGLER_ASSERT(node->hasChildren(), node); NodePointer unboundType = node->getChild(0); DEMANGLER_ASSERT(unboundType->getKind() == Node::Kind::Type, unboundType); return unboundType; } case Node::Kind::BoundGenericFunction: { DEMANGLER_ASSERT(node->hasChildren(), node); NodePointer unboundFunction = node->getChild(0); DEMANGLER_ASSERT(unboundFunction->getKind() == Node::Kind::Function || unboundFunction->getKind() == Node::Kind::Constructor, unboundFunction); if (isSpecialized(unboundFunction)) return getUnspecialized(unboundFunction, Factory); return unboundFunction; } case Node::Kind::Extension: { DEMANGLER_ASSERT(node->getNumChildren() >= 2, node); NodePointer parent = node->getChild(1); if (!isSpecialized(parent)) return node; auto unspec = getUnspecialized(parent, Factory); if (!unspec.isSuccess()) return unspec.error(); NodePointer result = Factory.createNode(Node::Kind::Extension); result->addChild(node->getFirstChild(), Factory); result->addChild(unspec.result(), Factory); if (node->getNumChildren() == 3) { // Add the generic signature of the extension. result->addChild(node->getChild(2), Factory); } return result; } default: return MANGLING_ERROR(ManglingError::BadNominalTypeKind, node); } }