mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
4367 lines
148 KiB
C++
4367 lines
148 KiB
C++
//===--- 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 <cstdio>
|
|
#include <cstdlib>
|
|
|
|
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 <typename Mangler>
|
|
friend void Mangle::mangleIdentifier(Mangler &M, StringRef ident);
|
|
friend class Mangle::SubstitutionMerging;
|
|
|
|
const ManglingFlavor Flavor = ManglingFlavor::Default;
|
|
const bool UsePunycode = true;
|
|
|
|
Vector<SubstitutionWord> Words;
|
|
Vector<WordReplacement> 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 <typename Mangler>
|
|
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<std::pair<int, Node *>> 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<std::pair<int, Node *>>
|
|
Remangler::mangleConstrainedType(Node *node, unsigned depth) {
|
|
if (node->getKind() == Node::Kind::Type)
|
|
node = getChildOfType(node);
|
|
|
|
SubstitutionEntry entry;
|
|
if (trySubstitution(node, entry))
|
|
return std::pair<int, Node *>{-1, nullptr};
|
|
|
|
Vector<Node *> 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<int, Node *>{-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, Node *>{(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::PropertyWrappedFieldInitAccessor:
|
|
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::mangleCoroutine(Node *node,
|
|
unsigned depth) {
|
|
RETURN_IF_ERROR(
|
|
mangleChildNodesReversed(node, depth + 1)); // argument tuple, result type
|
|
Buffer << "Xy";
|
|
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_IMPLICITACTOR) {
|
|
Buffer << 'A';
|
|
} else 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::mangleCoroFunctionPointer(Node *node, unsigned depth) {
|
|
Buffer << "Twc";
|
|
return ManglingError::Success;
|
|
}
|
|
|
|
ManglingError Remangler::mangleDefaultOverride(Node *node, unsigned depth) {
|
|
Buffer << "Twd";
|
|
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)
|
|
continue;
|
|
|
|
for (NodePointer paramChild : *Param) {
|
|
if (paramChild->getKind() == Node::Kind::FunctionSignatureSpecializationParamKind ||
|
|
paramChild->getKind() == Node::Kind::FunctionSignatureSpecializationParamPayload) {
|
|
continue;
|
|
}
|
|
RETURN_IF_ERROR(mangle(paramChild, depth + 1));
|
|
}
|
|
}
|
|
|
|
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.
|
|
const char *constPropPrefix = "p";
|
|
|
|
size_t idx = 0, end = node->getNumChildren();
|
|
while (idx < end) {
|
|
Node *kindNd = node->getChild(idx++);
|
|
if (kindNd->getKind() != Node::Kind::FunctionSignatureSpecializationParamKind)
|
|
continue;
|
|
|
|
unsigned kindValue = kindNd->getIndex();
|
|
|
|
switch (FunctionSigSpecializationParamKind(kindValue)) {
|
|
case FunctionSigSpecializationParamKind::ConstantPropFunction:
|
|
Buffer << constPropPrefix << "f";
|
|
constPropPrefix = "";
|
|
break;
|
|
case FunctionSigSpecializationParamKind::ConstantPropGlobal:
|
|
Buffer << constPropPrefix << "g";
|
|
constPropPrefix = "";
|
|
break;
|
|
case FunctionSigSpecializationParamKind::ConstantPropInteger:
|
|
Buffer << constPropPrefix << "i" << node->getChild(idx++)->getText();
|
|
constPropPrefix = "";
|
|
break;
|
|
case FunctionSigSpecializationParamKind::ConstantPropFloat:
|
|
Buffer << constPropPrefix << "d" << node->getChild(idx++)->getText();
|
|
constPropPrefix = "";
|
|
break;
|
|
case FunctionSigSpecializationParamKind::ConstantPropString: {
|
|
Buffer << constPropPrefix << "s";
|
|
constPropPrefix = "";
|
|
StringRef encodingStr = node->getChild(idx++)->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 << constPropPrefix << "k";
|
|
constPropPrefix = "";
|
|
break;
|
|
case FunctionSigSpecializationParamKind::ConstantPropStruct:
|
|
Buffer << constPropPrefix << "S";
|
|
constPropPrefix = "";
|
|
break;
|
|
case FunctionSigSpecializationParamKind::ClosureProp:
|
|
Buffer << 'c';
|
|
break;
|
|
case FunctionSigSpecializationParamKind::ClosurePropPreviousArg:
|
|
Buffer << 'C' << node->getChild(idx++)->getIndex();
|
|
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:
|
|
case Node::Kind::CoroFunctionPointer:
|
|
case Node::Kind::DefaultOverride:
|
|
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<char>(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<char>(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<char>(node->getText()).Case("sending", 'T').Default(0);
|
|
if (!diffChar)
|
|
return MANGLING_ERROR(ManglingError::InvalidImplParameterAttr, node);
|
|
Buffer << diffChar;
|
|
|
|
return ManglingError::Success;
|
|
}
|
|
|
|
ManglingError Remangler::mangleImplParameterIsolated(Node *node,
|
|
unsigned depth) {
|
|
DEMANGLER_ASSERT(node->hasText(), node);
|
|
char diffChar =
|
|
llvm::StringSwitch<char>(node->getText()).Case("isolated", 'I').Default(0);
|
|
if (!diffChar)
|
|
return MANGLING_ERROR(ManglingError::InvalidImplParameterAttr, node);
|
|
Buffer << diffChar;
|
|
|
|
return ManglingError::Success;
|
|
}
|
|
|
|
ManglingError Remangler::mangleImplParameterImplicitLeading(Node *node,
|
|
unsigned depth) {
|
|
DEMANGLER_ASSERT(node->hasText(), node);
|
|
char diffChar =
|
|
llvm::StringSwitch<char>(node->getText()).Case("sil_implicit_leading_param", 'L').Default(0);
|
|
if (!diffChar)
|
|
return MANGLING_ERROR(ManglingError::InvalidImplParameterAttr, 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<char>(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);
|
|
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<char>(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<char>(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<char>(Child->getText())
|
|
.Case("@Sendable", 'h')
|
|
.Case("@async", 'H')
|
|
.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<char>(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;
|
|
|
|
for (unsigned i = 1; i < Child->getNumChildren() - 1; ++i) {
|
|
auto *Grandchild = Child->getChild(i);
|
|
switch (Grandchild->getKind()) {
|
|
case Node::Kind::ImplParameterResultDifferentiability:
|
|
RETURN_IF_ERROR(mangleImplParameterResultDifferentiability(
|
|
Grandchild, depth + 1));
|
|
break;
|
|
case Node::Kind::ImplParameterSending:
|
|
RETURN_IF_ERROR(mangleImplParameterSending(
|
|
Grandchild, depth + 1));
|
|
break;
|
|
case Node::Kind::ImplParameterIsolated:
|
|
RETURN_IF_ERROR(mangleImplParameterIsolated(
|
|
Grandchild, depth + 1));
|
|
break;
|
|
case Node::Kind::ImplParameterImplicitLeading:
|
|
RETURN_IF_ERROR(mangleImplParameterImplicitLeading(
|
|
Grandchild, depth + 1));
|
|
break;
|
|
default:
|
|
Child->dump();
|
|
abort();
|
|
return MANGLING_ERROR(ManglingError::InvalidImplParameterAttr,
|
|
Grandchild);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case Node::Kind::ImplErrorResult:
|
|
Buffer << 'z';
|
|
LLVM_FALLTHROUGH;
|
|
case Node::Kind::ImplResult: {
|
|
char ConvCh =
|
|
llvm::StringSwitch<char>(Child->getFirstChild()->getText())
|
|
.Case("@out", 'r')
|
|
.Case("@owned", 'o')
|
|
.Case("@unowned", 'd')
|
|
.Case("@unowned_inner_pointer", 'u')
|
|
.Case("@autoreleased", 'a')
|
|
.Case("@pack_out", 'k')
|
|
.Case("@guaranteed_address", 'l')
|
|
.Case("@guaranteed", 'g')
|
|
.Case("@inout", 'm')
|
|
.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::mangleCompileTimeLiteral(Node *node, unsigned depth) {
|
|
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1));
|
|
Buffer << "Yt";
|
|
return ManglingError::Success;
|
|
}
|
|
|
|
ManglingError Remangler::mangleConstValue(Node *node, unsigned depth) {
|
|
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1));
|
|
Buffer << "Yg";
|
|
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::mangleYieldResult(Node *node, unsigned depth) {
|
|
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1));
|
|
Buffer << "Yy";
|
|
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::manglePropertyWrappedFieldInitAccessor(Node *node, unsigned depth) {
|
|
RETURN_IF_ERROR(mangleChildNodes(node, depth + 1));
|
|
Buffer << "fF";
|
|
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::mangleDependentProtocolConformanceOpaque(Node *node,
|
|
unsigned depth) {
|
|
DEMANGLER_ASSERT(node->getKind() == Node::Kind::DependentProtocolConformanceOpaque,
|
|
node);
|
|
RETURN_IF_ERROR(mangleAnyProtocolConformance(node->getChild(0), depth + 1));
|
|
RETURN_IF_ERROR(mangleType(node->getChild(1), depth + 1));
|
|
Buffer << "HO";
|
|
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);
|
|
case Node::Kind::DependentProtocolConformanceOpaque:
|
|
return mangleDependentProtocolConformanceOpaque(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::mangleKeyPathUnappliedMethodThunkHelper(Node *node, unsigned depth) {
|
|
return mangleKeyPathThunkHelper(node, "Tkmu", depth + 1);
|
|
}
|
|
|
|
ManglingError Remangler::mangleKeyPathAppliedMethodThunkHelper(Node *node,
|
|
unsigned depth) {
|
|
return mangleKeyPathThunkHelper(node, "TkMA", 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::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::mangleNonIsolatedCallerFunctionType(Node *node,
|
|
unsigned depth) {
|
|
Buffer << "YC";
|
|
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::mangleOutlinedInitializeWithTakeNoValueWitness(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::mangleSugaredInlineArray(Node *node, unsigned int depth) {
|
|
RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1));
|
|
RETURN_IF_ERROR(mangleType(node->getChild(1), 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;
|
|
}
|
|
|
|
ManglingError Remangler::mangleBorrowAccessor(Node *node, unsigned depth) {
|
|
return mangleAbstractStorage(node->getFirstChild(), "b", depth + 1);
|
|
}
|
|
|
|
ManglingError Remangler::mangleMutateAccessor(Node *node, unsigned depth) {
|
|
return mangleAbstractStorage(node->getFirstChild(), "z", depth + 1);
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
/// The top-level interface to the remangler.
|
|
ManglingErrorOr<std::string> 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<std::string> 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<llvm::StringRef> 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::PropertyWrappedFieldInitAccessor:
|
|
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<NodePointer> 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::PropertyWrappedFieldInitAccessor:
|
|
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);
|
|
}
|
|
}
|