Files
swift-mirror/lib/Demangling/OldRemangler.cpp
Slava Pestov 7ed5d2bfc2 ASTDemangler: Round-trip @isolated @sil_implicit_leading_param parameter attributes
We sometimes mangle SILFunctionTypes when generating debug info
for reabstraction thunks, and these can have various exotic
parameter and result attributes. Two recent additions were
never plumbed through the mangler, causing assertion failures
when emitting debug info.

Fixes rdar://153730847.
2025-06-26 15:00:44 -04:00

3155 lines
112 KiB
C++

//===--- OldRemangler.cpp - Old Swift Re-mangler --------------------------===//
//
// 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/ManglingUtils.h"
#include "swift/Demangling/Punycode.h"
#include "swift/Strings.h"
#include <cstdio>
#include <cstdlib>
using namespace swift;
using namespace Demangle;
namespace {
class Remangler : public RemanglerBase {
static const unsigned MaxDepth = 1024;
public:
Remangler(NodeFactory &Factory) : RemanglerBase(Factory) { }
class EntityContext {
bool AsContext = false;
std::string AnonymousContextDiscriminator;
public:
bool isAsContext() const {
return AsContext;
}
void setAnonymousContextDiscriminator(StringRef discriminator) {
AnonymousContextDiscriminator = discriminator.str();
}
std::string takeAnonymousContextDiscriminator() {
auto r = std::move(AnonymousContextDiscriminator);
AnonymousContextDiscriminator.clear();
return r;
}
class ManglingContextRAII {
EntityContext &Ctx;
bool SavedValue;
public:
ManglingContextRAII(EntityContext &ctx)
: Ctx(ctx), SavedValue(ctx.AsContext) {
ctx.AsContext = true;
}
~ManglingContextRAII() {
Ctx.AsContext = SavedValue;
}
};
};
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);
}
ManglingError mangleGenericArgs(Node *node, EntityContext &ctx,
unsigned depth);
ManglingError mangleAnyNominalType(Node *node, EntityContext &ctx,
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, EntityContext &ctx, unsigned depth);
#include "swift/Demangling/DemangleNodes.def"
void mangleIndex(Node::IndexType index);
ManglingError mangleIdentifier(StringRef name, OperatorKind operatorKind);
ManglingError mangleAccessor(Node *storageNode, StringRef accessorCode,
EntityContext &ctx, unsigned depth);
ManglingError mangleChildNodes(Node *node, unsigned depth) {
return mangleNodes(node->begin(), node->end(), depth);
}
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) {
DEMANGLER_ASSERT(index < node->getNumChildren(), node);
return mangle(node->begin()[index], depth);
}
ManglingError mangleSimpleEntity(Node *node, char basicKind,
StringRef entityKind, EntityContext &ctx,
unsigned depth);
ManglingError
mangleNamedEntity(Node *node, char basicKind, StringRef entityKind,
EntityContext &ctx, unsigned depth,
StringRef ArtificialPrivateDiscriminator = {});
ManglingError mangleTypedEntity(Node *node, char basicKind,
StringRef entityKind, EntityContext &ctx,
unsigned depth);
ManglingError mangleNamedAndTypedEntity(Node *node, char basicKind,
StringRef entityKind,
EntityContext &ctx, unsigned depth);
ManglingError
mangleNominalType(Node *node, char basicKind, EntityContext &ctx,
unsigned depth,
StringRef ArtificialPrivateDiscriminator = {});
ManglingError mangleProtocolWithoutPrefix(Node *node, unsigned depth);
ManglingError
mangleProtocolListWithoutPrefix(Node *node, unsigned depth,
Node *additionalProto = nullptr);
ManglingError mangleEntityContext(Node *node, EntityContext &ctx,
unsigned depth);
ManglingError mangleEntityType(Node *node, EntityContext &ctx,
unsigned depth);
ManglingError mangleEntityGenericType(Node *node, EntityContext &ctx);
bool trySubstitution(Node *node, SubstitutionEntry &entry);
bool mangleStandardSubstitution(Node *node);
ManglingError mangleDependentGenericParamIndex(Node *node, unsigned depth);
ManglingError mangleConstrainedType(Node *node, unsigned depth);
};
} // end anonymous namespace
#define NODE(ID)
#define CONTEXT_NODE(ID) \
ManglingError Remangler::mangle##ID(Node *node, unsigned depth) { \
EntityContext ctx; \
return mangle##ID(node, ctx, depth); \
}
#include "swift/Demangling/DemangleNodes.def"
/// Re-apply labels from the function to its parameter type
/// to preserve old mangling style.
///
/// \param LabelList The list of labels to apply.
/// \param OrigType The function parameter type to apply labels to.
/// \param Factory The node factory to use to allocate new nodes.
static NodePointer applyParamLabels(NodePointer LabelList, NodePointer OrigType,
NodeFactory &Factory) {
if (LabelList->getNumChildren() == 0)
return OrigType;
auto applyParamLabels = [&](NodePointer ArgTuple) -> NodePointer {
assert(ArgTuple->getKind() == Node::Kind::ArgumentTuple);
auto ParamsType = Factory.createNode(Node::Kind::ArgumentTuple);
auto Tuple = Factory.createNode(Node::Kind::Tuple);
auto processParameter = [&](NodePointer Label, NodePointer Param) {
if (Label->getKind() == Node::Kind::FirstElementMarker) {
Tuple->addChild(Param, Factory);
return;
}
auto NewParam = Factory.createNode(Node::Kind::TupleElement);
NewParam->addChild(Factory.createNodeWithAllocatedText(
Node::Kind::TupleElementName, Label->getText()),
Factory);
for (auto &Child : *Param)
NewParam->addChild(Child, Factory);
Tuple->addChild(NewParam, Factory);
};
auto OrigTuple = ArgTuple->getFirstChild()->getFirstChild();
if (OrigTuple->getKind() != Node::Kind::Tuple) {
processParameter(LabelList->getChild(0), OrigTuple);
} else {
for (unsigned i = 0, n = OrigTuple->getNumChildren(); i != n; ++i) {
processParameter(LabelList->getChild(i), OrigTuple->getChild(i));
}
}
auto Type = Factory.createNode(Node::Kind::Type);
Type->addChild(Tuple, Factory);
ParamsType->addChild(Type, Factory);
return ParamsType;
};
auto visitTypeChild = [&](NodePointer Child) -> NodePointer {
if (Child->getKind() != Node::Kind::FunctionType &&
Child->getKind() != Node::Kind::NoEscapeFunctionType)
return Child;
auto FuncType = Factory.createNode(Node::Kind::FunctionType);
for (unsigned i = 0, n = Child->getNumChildren(); i != n; ++i) {
NodePointer FuncChild = Child->getChild(i);
if (FuncChild->getKind() == Node::Kind::ArgumentTuple)
FuncChild = applyParamLabels(FuncChild);
FuncType->addChild(FuncChild, Factory);
}
return FuncType;
};
auto Type = Factory.createNode(OrigType->getKind());
for (auto &Child : *OrigType)
Type->addChild(visitTypeChild(Child), Factory);
return Type;
}
bool Remangler::trySubstitution(Node *node, SubstitutionEntry &entry) {
if (mangleStandardSubstitution(node))
return true;
// Go ahead and initialize the substitution entry.
entry = entryForNode(node);
int Idx = findSubstitution(entry);
if (Idx < 0)
return false;
Buffer << 'S';
mangleIndex(Idx);
return true;
}
static bool isInSwiftModule(Node *node) {
Node *context = node->getFirstChild();
return (context->getKind() == Node::Kind::Module &&
context->getText() == STDLIB_NAME &&
// Check for private declarations in Swift
node->getChild(1)->getKind() == Node::Kind::Identifier);
}
bool Remangler::mangleStandardSubstitution(Node *node) {
// Look for known substitutions.
switch (node->getKind()) {
#define SUCCESS_IF_IS(VALUE, EXPECTED, SUBSTITUTION) \
do { \
if ((VALUE) == (EXPECTED)) { \
Buffer << SUBSTITUTION; \
return true; \
} \
} while (0)
#define SUCCESS_IF_TEXT_IS(EXPECTED, SUBSTITUTION) \
SUCCESS_IF_IS(node->getText(), EXPECTED, SUBSTITUTION)
#define SUCCESS_IF_DECLNAME_IS(EXPECTED, SUBSTITUTION) \
SUCCESS_IF_IS(node->getChild(1)->getText(), EXPECTED, SUBSTITUTION)
case Node::Kind::Module:
SUCCESS_IF_TEXT_IS(STDLIB_NAME, "s");
SUCCESS_IF_TEXT_IS(MANGLING_MODULE_OBJC, "So");
SUCCESS_IF_TEXT_IS(MANGLING_MODULE_CLANG_IMPORTER, "SC");
break;
case Node::Kind::Structure:
if (isInSwiftModule(node)) {
SUCCESS_IF_DECLNAME_IS("Array", "Sa");
SUCCESS_IF_DECLNAME_IS("Bool", "Sb");
SUCCESS_IF_DECLNAME_IS("UnicodeScalar", "Sc");
SUCCESS_IF_DECLNAME_IS("Double", "Sd");
SUCCESS_IF_DECLNAME_IS("Float", "Sf");
SUCCESS_IF_DECLNAME_IS("Int", "Si");
SUCCESS_IF_DECLNAME_IS("UnsafeRawPointer", "SV");
SUCCESS_IF_DECLNAME_IS("UnsafeMutableRawPointer", "Sv");
SUCCESS_IF_DECLNAME_IS("UnsafePointer", "SP");
SUCCESS_IF_DECLNAME_IS("UnsafeMutablePointer", "Sp");
SUCCESS_IF_DECLNAME_IS("UnsafeBufferPointer", "SR");
SUCCESS_IF_DECLNAME_IS("UnsafeMutableBufferPointer", "Sr");
SUCCESS_IF_DECLNAME_IS("String", "SS");
SUCCESS_IF_DECLNAME_IS("UInt", "Su");
}
break;
case Node::Kind::Enum:
if (isInSwiftModule(node)) {
SUCCESS_IF_DECLNAME_IS("Optional", "Sq");
SUCCESS_IF_DECLNAME_IS("ImplicitlyUnwrappedOptional", "SQ");
}
break;
default:
break;
#undef SUCCESS_IF_DECLNAME_IS
#undef SUCCESS_IF_TEXT_IS
#undef SUCCESS_IF_IS
}
return false;
}
ManglingError Remangler::mangleIdentifier(Node *node, unsigned depth) {
return mangleIdentifier(node->getText(), OperatorKind::NotOperator);
}
ManglingError Remangler::manglePrefixOperator(Node *node, unsigned depth) {
return mangleIdentifier(node->getText(), OperatorKind::Prefix);
}
ManglingError Remangler::manglePostfixOperator(Node *node, unsigned depth) {
return mangleIdentifier(node->getText(), OperatorKind::Postfix);
}
ManglingError Remangler::mangleInfixOperator(Node *node, unsigned depth) {
return mangleIdentifier(node->getText(), OperatorKind::Infix);
}
ManglingError Remangler::mangleIdentifier(StringRef ident,
OperatorKind operatorKind) {
// Mangle normal identifiers as
// count identifier-char+
// where the count is the number of characters in the identifier,
// and where individual identifier characters represent themselves.
// Mangle operator identifiers as
// operator ::= 'o' operator-fixity count operator-char+
// operator-fixity ::= 'p' // prefix
// operator-fixity ::= 'P' // postfix
// operator-fixity ::= 'i' // infix
// where the count is the number of characters in the operator,
// and where the individual operator characters are translated.
switch (operatorKind) {
case OperatorKind::NotOperator:
Buffer << ident.size() << ident;
return ManglingError::Success;
case OperatorKind::Infix:
Buffer << "oi";
break;
case OperatorKind::Prefix:
Buffer << "op";
break;
case OperatorKind::Postfix:
Buffer << "oP";
break;
}
// Mangle ASCII operators directly.
Buffer << ident.size();
for (char ch : ident) {
Buffer << Mangle::translateOperatorChar(ch);
}
return ManglingError::Success;
}
ManglingError Remangler::mangleNumber(Node *node, unsigned depth) {
mangleIndex(node->getIndex());
return ManglingError::Success;
}
void Remangler::mangleIndex(Node::IndexType value) {
if (value == 0) {
Buffer << '_';
} else {
Buffer << (value - 1) << '_';
}
}
ManglingError Remangler::mangleGlobal(Node *node, unsigned depth) {
Buffer << "_T";
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleSuffix(Node *node, unsigned depth) {
// Just add the suffix back on.
Buffer << node->getText();
return ManglingError::Success;
}
ManglingError Remangler::mangleGenericSpecialization(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleGenericSpecializationPrespecialized(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleGenericSpecializationNotReAbstracted(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleGenericSpecializationInResilienceDomain(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleInlinedGenericFunction(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleGenericPartialSpecialization(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleGenericPartialSpecializationNotReAbstracted(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleGenericSpecializationParam(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleFunctionSignatureSpecialization(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleSpecializationPassID(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
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" << node->getIndex();
return ManglingError::Success;
}
ManglingError
Remangler::mangleFunctionSignatureSpecializationReturn(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleFunctionSignatureSpecializationParam(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleFunctionSignatureSpecializationParamPayload(Node *node,
unsigned depth) {
// This should never be called since mangling parameter payloads require
// knowing what the parameter kind is.
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleFunctionSignatureSpecializationParamKind(Node *node,
unsigned depth) {
// This should never be called since mangling parameter kinds have influence
// on the payloads.
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleRetroactiveConformance(Node *node,
unsigned depth) {
// Retroactive conformances aren't in the old mangling
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleProtocolConformanceRefInTypeModule(Node *node,
unsigned depth) {
// Protocol conformance references aren't in the old mangling
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleProtocolConformanceRefInProtocolModule(Node *node,
unsigned depth) {
// Protocol conformance references aren't in the old mangling
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleProtocolConformanceRefInOtherModule(Node *node,
unsigned depth) {
// Protocol conformance references aren't in the old mangling
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleConcreteProtocolConformance(Node *node,
unsigned depth) {
// Concrete conformances aren't in the old mangling
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::manglePackProtocolConformance(Node *node,
unsigned depth) {
// Pack conformances aren't in the old mangling
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleAnyProtocolConformanceList(Node *node,
unsigned depth) {
// Conformance lists aren't in the old mangling
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleDependentAssociatedConformance(Node *node,
unsigned depth) {
// Dependent associated conformances aren't in the old mangling
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleDependentProtocolConformanceRoot(Node *node, unsigned depth) {
// Dependent conformances aren't in the old mangling
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleDependentProtocolConformanceInherited(Node *node,
unsigned depth) {
// Dependent conformances aren't in the old mangling
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleDependentProtocolConformanceAssociated(Node *node,
unsigned depth) {
// Dependent conformances aren't in the old mangling
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleDependentProtocolConformanceOpaque(Node *node,
unsigned depth) {
// Dependent conformances aren't in the old mangling
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleProtocolConformance(Node *node, unsigned depth) {
// type, protocol name, context
DEMANGLER_ASSERT(node->getNumChildren() == 3, node);
RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1));
RETURN_IF_ERROR(mangleProtocolWithoutPrefix(node->begin()[1], depth + 1));
return mangleChildNode(node, 2, depth + 1);
}
ManglingError Remangler::mangleObjCAttribute(Node *node, unsigned depth) {
Buffer << "To";
return ManglingError::Success;
}
ManglingError Remangler::mangleNonObjCAttribute(Node *node, unsigned depth) {
Buffer << "TO";
return ManglingError::Success;
}
ManglingError Remangler::mangleDirectMethodReferenceAttribute(Node *node,
unsigned depth) {
Buffer << "Td";
return ManglingError::Success;
}
ManglingError Remangler::mangleDynamicAttribute(Node *node, unsigned depth) {
Buffer << "TD";
return ManglingError::Success;
}
ManglingError Remangler::mangleVTableAttribute(Node *node, unsigned depth) {
Buffer << "TV";
return ManglingError::Success;
}
ManglingError Remangler::mangleGenericTypeMetadataPattern(Node *node,
unsigned depth) {
Buffer << "MP";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleTypeMetadataAccessFunction(Node *node,
unsigned depth) {
Buffer << "Ma";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleTypeMetadataInstantiationCache(Node *node,
unsigned depth) {
Buffer << "MI";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError
Remangler::mangleTypeMetadataInstantiationFunction(Node *node, unsigned depth) {
Buffer << "Mi";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError
Remangler::mangleTypeMetadataSingletonInitializationCache(Node *node,
unsigned depth) {
Buffer << "Ml";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleTypeMetadataCompletionFunction(Node *node,
unsigned depth) {
Buffer << "Mr";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleTypeMetadataDemanglingCache(Node *node,
unsigned depth) {
// not supported
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleTypeMetadataLazyCache(Node *node,
unsigned depth) {
Buffer << "ML";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleMetaclass(Node *node, unsigned depth) {
Buffer << "Mm";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleClassMetadataBaseOffset(Node *node,
unsigned depth) {
Buffer << "Mo";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleNominalTypeDescriptor(Node *node,
unsigned depth) {
Buffer << "Mn";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleNominalTypeDescriptorRecord(Node *node,
unsigned depth) {
Buffer << "Hn";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::manglePropertyDescriptor(Node *node, unsigned depth) {
// not supported
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleTypeMetadata(Node *node, unsigned depth) {
Buffer << "M";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleFullTypeMetadata(Node *node, unsigned depth) {
Buffer << "Mf";
return mangleChildNodes(node, depth + 1); // type
}
ManglingError Remangler::mangleProtocolDescriptor(Node *node, unsigned depth) {
Buffer << "Mp";
return mangleProtocolWithoutPrefix(node->begin()[0], depth + 1);
}
ManglingError Remangler::mangleProtocolDescriptorRecord(Node *node,
unsigned depth) {
Buffer << "Hr";
return mangleProtocolWithoutPrefix(node->begin()[0], depth + 1);
}
ManglingError
Remangler::mangleProtocolRequirementsBaseDescriptor(Node *node,
unsigned depth) {
// ###TODO: Is this an error?
Buffer << "<protocol-requirements-base-descriptor>";
return ManglingError::Success;
}
ManglingError Remangler::mangleProtocolWitnessTablePattern(Node *node,
unsigned depth) {
// todo
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleProtocolConformanceDescriptor(Node *node,
unsigned depth) {
Buffer << "Mc";
return mangleProtocolConformance(node->begin()[0], depth + 1);
}
ManglingError
Remangler::mangleProtocolConformanceDescriptorRecord(Node *node,
unsigned depth) {
Buffer << "Hc";
return mangleProtocolConformance(node->begin()[0], depth + 1);
}
ManglingError
Remangler::mangleProtocolSelfConformanceDescriptor(Node *node, unsigned depth) {
Buffer << "MS";
return mangleProtocol(node->begin()[0], depth + 1);
}
ManglingError Remangler::manglePartialApplyForwarder(Node *node,
unsigned depth) {
Buffer << "PA";
if (node->getNumChildren() == 1) {
Buffer << "__T";
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); // global
}
return ManglingError::Success;
}
ManglingError Remangler::manglePartialApplyObjCForwarder(Node *node,
unsigned depth) {
Buffer << "PAo";
if (node->getNumChildren() == 1) {
Buffer << "__T";
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); // global
}
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) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleAsyncSuspendResumePartialFunction(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleDirectness(Node *node, unsigned depth) {
switch (node->getIndex()) {
case uint64_t(Directness::Direct):
Buffer << 'd';
break;
case uint64_t(Directness::Indirect):
Buffer << 'i';
break;
default:
return MANGLING_ERROR(ManglingError::BadDirectness, node);
}
return ManglingError::Success;
}
ManglingError Remangler::mangleValueWitness(Node *node, unsigned depth) {
const char *Code = nullptr;
switch (node->getFirstChild()->getIndex()) {
#define VALUE_WITNESS(MANGLING, NAME) \
case uint64_t(ValueWitnessKind::NAME): \
Code = #MANGLING; \
break;
#include "swift/Demangling/ValueWitnessMangling.def"
default:
return MANGLING_ERROR(ManglingError::BadValueWitnessKind, node);
}
Buffer << 'w' << Code;
return mangleChildNode(node, 1, depth + 1); // type
}
ManglingError Remangler::mangleValueWitnessTable(Node *node, unsigned depth) {
Buffer << "WV";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleConcurrentFunctionType(Node *node,
unsigned depth) {
Buffer << "y";
return ManglingError::Success;
}
ManglingError Remangler::mangleAsyncAnnotation(Node *node, unsigned depth) {
Buffer << "Z";
return ManglingError::Success;
}
ManglingError Remangler::mangleThrowsAnnotation(Node *node, unsigned depth) {
Buffer << "z";
return ManglingError::Success;
}
ManglingError Remangler::mangleTypedThrowsAnnotation(Node *node, unsigned depth) {
Buffer << "z";
return ManglingError::Success;
}
ManglingError Remangler::mangleDifferentiableFunctionType(Node *node,
unsigned depth) {
Buffer << "D";
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleGlobalActorFunctionType(Node *node,
unsigned depth) {
Buffer << "Y" << (char)node->getIndex(); // differentiability kind
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::mangleFieldOffset(Node *node, unsigned depth) {
Buffer << "Wv";
return mangleChildNodes(node, depth + 1); // directness, entity
}
ManglingError Remangler::mangleEnumCase(Node *node, unsigned depth) {
Buffer << "WC";
return mangleSingleChildNode(node, depth + 1); // enum case
}
ManglingError
Remangler::mangleProtocolSelfConformanceWitnessTable(Node *node,
unsigned depth) {
Buffer << "WS";
return mangleSingleChildNode(node, depth + 1); // protocol
}
ManglingError Remangler::mangleProtocolWitnessTable(Node *node,
unsigned depth) {
Buffer << "WP";
return mangleSingleChildNode(node, depth + 1); // protocol conformance
}
ManglingError Remangler::mangleGenericProtocolWitnessTable(Node *node,
unsigned depth) {
Buffer << "WG";
return mangleSingleChildNode(node, depth + 1); // protocol conformance
}
ManglingError Remangler::mangleResilientProtocolWitnessTable(Node *node,
unsigned depth) {
// todo
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleGenericProtocolWitnessTableInstantiationFunction(
Node *node, unsigned depth) {
Buffer << "WI";
return mangleSingleChildNode(node, depth + 1); // protocol conformance
}
ManglingError Remangler::mangleProtocolWitnessTableAccessor(Node *node,
unsigned depth) {
Buffer << "Wa";
return mangleSingleChildNode(node, depth + 1); // protocol conformance
}
ManglingError
Remangler::mangleLazyProtocolWitnessTableAccessor(Node *node, unsigned depth) {
Buffer << "Wl";
return mangleChildNodes(node, depth + 1); // type, protocol conformance
}
ManglingError
Remangler::mangleLazyProtocolWitnessTableCacheVariable(Node *node,
unsigned depth) {
Buffer << "WL";
return mangleChildNodes(node, depth + 1); // type, protocol conformance
}
ManglingError Remangler::mangleAssociatedTypeDescriptor(Node *node,
unsigned depth) {
// ###TODO: Check this (and similar ones below). Should this be a failure?
Buffer << "<associated-type-descriptor>";
return ManglingError::Success;
}
ManglingError Remangler::mangleAssociatedConformanceDescriptor(Node *node,
unsigned depth) {
Buffer << "<associated-conformance-descriptor>";
return ManglingError::Success;
}
ManglingError
Remangler::mangleDefaultAssociatedConformanceAccessor(Node *node,
unsigned depth) {
Buffer << "<default-associated-conformance-descriptor>";
return ManglingError::Success;
}
ManglingError Remangler::mangleBaseConformanceDescriptor(Node *node,
unsigned depth) {
Buffer << "<base-conformance-descriptor>";
return ManglingError::Success;
}
ManglingError Remangler::mangleAssociatedTypeMetadataAccessor(Node *node,
unsigned depth) {
Buffer << "Wt";
return mangleChildNodes(node, depth + 1); // protocol conformance, identifier
}
ManglingError
Remangler::mangleDefaultAssociatedTypeMetadataAccessor(Node *node,
unsigned depth) {
Buffer << "<default-associated-type-metadata-accessor>";
return ManglingError::Success;
}
ManglingError
Remangler::mangleAssociatedTypeWitnessTableAccessor(Node *node,
unsigned depth) {
Buffer << "WT";
DEMANGLER_ASSERT(node->getNumChildren() == 3, node);
RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); // protocol conformance
RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); // type
return mangleProtocolWithoutPrefix(node->begin()[2], depth + 1); // type
}
ManglingError Remangler::mangleBaseWitnessTableAccessor(Node *node,
unsigned depth) {
Buffer << "<base-witness-table-accessor>";
return ManglingError::Success;
}
ManglingError Remangler::mangleReabstractionThunkHelper(Node *node,
unsigned depth) {
Buffer << "<reabstraction-thunk-helper>";
return ManglingError::Success;
}
ManglingError
Remangler::mangleReabstractionThunkHelperWithSelf(Node *node, unsigned depth) {
Buffer << "<reabstraction-thunk-helper-with-self>";
return ManglingError::Success;
}
ManglingError Remangler::mangleReabstractionThunk(Node *node, unsigned depth) {
Buffer << "<reabstraction-thunk>";
return ManglingError::Success;
}
ManglingError
Remangler::mangleReabstractionThunkHelperWithGlobalActor(Node *node,
unsigned depth) {
Buffer << "<reabstraction-thunk-helper-with-global-actor>";
return ManglingError::Success;
}
ManglingError Remangler::mangleAutoDiffFunction(Node *node, EntityContext &ctx,
unsigned depth) {
Buffer << "<autodiff-function>";
return ManglingError::Success;
}
ManglingError Remangler::mangleAutoDiffDerivativeVTableThunk(Node *node,
unsigned depth) {
Buffer << "<autodiff-derivative-vtable-thunk>";
return ManglingError::Success;
}
ManglingError
Remangler::mangleAutoDiffSelfReorderingReabstractionThunk(Node *node,
unsigned depth) {
Buffer << "<autodiff-self-reordering-reabstraction-thunk>";
return ManglingError::Success;
}
ManglingError Remangler::mangleAutoDiffSubsetParametersThunk(Node *node,
unsigned depth) {
Buffer << "<autodiff-subset-parameters-thunk>";
return ManglingError::Success;
}
ManglingError Remangler::mangleAutoDiffFunctionKind(Node *node,
unsigned depth) {
Buffer << "<autodiff-function-kind>";
return ManglingError::Success;
}
ManglingError Remangler::mangleDifferentiabilityWitness(Node *node,
unsigned depth) {
Buffer << "<differentiability-witness>";
return ManglingError::Success;
}
ManglingError Remangler::mangleIndexSubset(Node *node, unsigned depth) {
Buffer << "<index-subset>";
return ManglingError::Success;
}
ManglingError Remangler::mangleProtocolSelfConformanceWitness(Node *node,
unsigned depth) {
Buffer << "TS";
return mangleSingleChildNode(node, depth + 1); // entity
}
ManglingError Remangler::mangleProtocolWitness(Node *node, unsigned depth) {
Buffer << "TW";
return mangleChildNodes(node, depth + 1); // protocol conformance, entity
}
ManglingError Remangler::mangleFunction(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleNamedAndTypedEntity(node, 'F', "", ctx, depth + 1);
}
ManglingError Remangler::mangleVariable(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleNamedAndTypedEntity(node, 'v', "", ctx, depth + 1);
}
ManglingError Remangler::mangleSubscript(Node *node, EntityContext &ctx,
unsigned depth) {
DEMANGLER_ASSERT(node->getNumChildren() >= 2, node);
Buffer << 'i';
RETURN_IF_ERROR(mangleEntityContext(node->begin()[0], ctx, depth + 1));
if (node->getLastChild()->getKind() == Node::Kind::PrivateDeclName)
RETURN_IF_ERROR(mangle(node->getLastChild(), depth + 1));
if (node->getNumChildren() >= 3
&& node->begin()[1]->getKind() == Node::Kind::LabelList) {
auto LabelList = node->begin()[1];
auto Type = node->begin()[2];
RETURN_IF_ERROR(mangleEntityType(applyParamLabels(LabelList, Type, Factory),
ctx, depth + 1));
} else {
RETURN_IF_ERROR(mangleEntityType(node->begin()[1], ctx, depth + 1));
}
return ManglingError::Success;
}
ManglingError Remangler::mangleMacro(Node *node, unsigned depth) {
Buffer << "fm";
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleFreestandingMacroExpansion(
Node *node, unsigned depth) {
Buffer << "fMf";
RETURN_IF_ERROR(mangleIndex(node, depth + 1));
return mangleChildNodes(node, depth + 1);
}
#define FREESTANDING_MACRO_ROLE(Name, Description)
#define ATTACHED_MACRO_ROLE(Name, Description, MangledChar) \
ManglingError Remangler::mangle##Name##AttachedMacroExpansion( \
Node *node, unsigned depth) { \
Buffer << "fM" MangledChar; \
RETURN_IF_ERROR(mangleIndex(node, depth + 1)); \
return mangleChildNodes(node, depth + 1); \
}
#include "swift/Basic/MacroRoles.def"
ManglingError Remangler::mangleMacroExpansionUniqueName(
Node *node, unsigned depth) {
Buffer << "fMu";
RETURN_IF_ERROR(mangleIndex(node, depth + 1));
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleMacroExpansionLoc(
Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleAccessor(Node *storageNode,
StringRef accessorCode,
EntityContext &ctx, unsigned depth) {
Buffer << 'F';
RETURN_IF_ERROR(
mangleEntityContext(storageNode->getChild(0), ctx, depth + 1));
Buffer << accessorCode;
auto mangleAccessorType = [&](unsigned TypeIndex) {
auto LabelList = storageNode->getChild(TypeIndex);
if (LabelList->getKind() == Node::Kind::LabelList) {
auto Type = storageNode->getChild(TypeIndex + 1);
return mangleEntityType(applyParamLabels(LabelList, Type, Factory), ctx,
depth + 1);
} else {
return mangleEntityType(storageNode->getChild(TypeIndex), ctx, depth + 1);
}
};
switch (storageNode->getKind()) {
case Demangle::Node::Kind::Variable: {
RETURN_IF_ERROR(mangleChildNode(storageNode, 1, depth + 1));
RETURN_IF_ERROR(mangleAccessorType(2));
break;
}
case Demangle::Node::Kind::Subscript: {
auto NumChildren = storageNode->getNumChildren();
DEMANGLER_ASSERT(NumChildren <= 4, storageNode);
auto PrivateName = storageNode->getChild(NumChildren - 1);
if (PrivateName->getKind() == Node::Kind::PrivateDeclName)
RETURN_IF_ERROR(mangle(PrivateName, depth + 1));
RETURN_IF_ERROR(mangleIdentifier("subscript", OperatorKind::NotOperator));
RETURN_IF_ERROR(mangleAccessorType(1));
break;
}
default:
return MANGLING_ERROR(ManglingError::NotAStorageNode, storageNode);
}
return ManglingError::Success;
}
ManglingError Remangler::mangleInitializer(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleSimpleEntity(node, 'I', "i", ctx, depth + 1);
}
ManglingError Remangler::manglePropertyWrapperBackingInitializer(
Node *node, EntityContext &ctx, unsigned depth) {
return mangleSimpleEntity(node, 'I', "P", ctx, depth + 1);
}
ManglingError Remangler::manglePropertyWrapperInitFromProjectedValue(
Node *node, EntityContext &ctx, unsigned depth) {
return mangleSimpleEntity(node, 'I', "W", ctx, depth + 1);
}
ManglingError Remangler::mangleDefaultArgumentInitializer(Node *node,
EntityContext &ctx,
unsigned depth) {
return mangleNamedEntity(node, 'I', "A", ctx, 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::mangleDeallocator(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleSimpleEntity(node, 'F', "D", ctx, depth + 1);
}
ManglingError Remangler::mangleIsolatedDeallocator(Node *node,
EntityContext &ctx,
unsigned depth) {
return mangleSimpleEntity(node, 'F', "Z", ctx, depth + 1);
}
ManglingError Remangler::mangleDestructor(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleSimpleEntity(node, 'F', "d", ctx, depth + 1);
}
ManglingError Remangler::mangleAllocator(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleTypedEntity(node, 'F', "C", ctx, depth + 1);
}
ManglingError Remangler::mangleConstructor(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleTypedEntity(node, 'F', "c", ctx, depth + 1);
}
ManglingError Remangler::mangleIVarInitializer(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleSimpleEntity(node, 'F', "e", ctx, depth + 1);
}
ManglingError Remangler::mangleIVarDestroyer(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleSimpleEntity(node, 'F', "E", ctx, depth + 1);
}
ManglingError Remangler::mangleGetter(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "g", ctx, depth + 1);
}
ManglingError Remangler::mangleGlobalGetter(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "G", ctx, depth + 1);
}
ManglingError Remangler::mangleSetter(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "s", ctx, depth + 1);
}
ManglingError Remangler::mangleMaterializeForSet(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "m", ctx, depth + 1);
}
ManglingError Remangler::mangleWillSet(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "w", ctx, depth + 1);
}
ManglingError Remangler::mangleDidSet(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "W", ctx, depth + 1);
}
ManglingError Remangler::mangleInitAccessor(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "i", ctx, depth + 1);
}
ManglingError Remangler::mangleOwningMutableAddressor(Node *node,
EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "aO", ctx, depth + 1);
}
ManglingError Remangler::mangleNativeOwningMutableAddressor(Node *node,
EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "ao", ctx, depth + 1);
}
ManglingError Remangler::mangleNativePinningMutableAddressor(Node *node,
EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "ap", ctx, depth + 1);
}
ManglingError Remangler::mangleUnsafeMutableAddressor(Node *node,
EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "au", ctx, depth + 1);
}
ManglingError Remangler::mangleOwningAddressor(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "lO", ctx, depth + 1);
}
ManglingError Remangler::mangleNativeOwningAddressor(Node *node,
EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "lo", ctx, depth + 1);
}
ManglingError Remangler::mangleNativePinningAddressor(Node *node,
EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "lp", ctx, depth + 1);
}
ManglingError Remangler::mangleUnsafeAddressor(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "lu", ctx, depth + 1);
}
ManglingError Remangler::mangleReadAccessor(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "r", ctx, depth + 1);
}
ManglingError Remangler::mangleRead2Accessor(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "y", ctx, depth + 1);
}
ManglingError Remangler::mangleModifyAccessor(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "M", ctx, depth + 1);
}
ManglingError Remangler::mangleModify2Accessor(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAccessor(node->getFirstChild(), "x", ctx, depth + 1);
}
ManglingError Remangler::mangleExplicitClosure(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleNamedAndTypedEntity(node, 'F', "U", ctx,
depth + 1); // name is index
}
ManglingError Remangler::mangleImplicitClosure(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleNamedAndTypedEntity(node, 'F', "u", ctx,
depth + 1); // name is index
}
ManglingError Remangler::mangleStatic(Node *node, EntityContext &ctx,
unsigned depth) {
Buffer << 'Z';
return mangleEntityContext(node->getChild(0), ctx, depth + 1);
}
ManglingError Remangler::mangleSimpleEntity(Node *node, char basicKind,
StringRef entityKind,
EntityContext &ctx,
unsigned depth) {
DEMANGLER_ASSERT(node->getNumChildren() == 1, node);
Buffer << basicKind;
RETURN_IF_ERROR(mangleEntityContext(node->begin()[0], ctx, depth + 1));
Buffer << entityKind;
return ManglingError::Success;
}
ManglingError
Remangler::mangleNamedEntity(Node *node, char basicKind, StringRef entityKind,
EntityContext &ctx, unsigned depth,
StringRef artificialPrivateDiscriminator) {
DEMANGLER_ASSERT(node->getNumChildren() == 2, node);
if (basicKind != '\0') Buffer << basicKind;
RETURN_IF_ERROR(mangleEntityContext(node->begin()[0], ctx, depth + 1));
Buffer << entityKind;
auto privateDiscriminator = ctx.takeAnonymousContextDiscriminator();
if (!privateDiscriminator.empty() &&
swift::Mangle::isDigit(privateDiscriminator[0]))
privateDiscriminator = "_" + privateDiscriminator;
if (!artificialPrivateDiscriminator.empty())
privateDiscriminator.append(artificialPrivateDiscriminator.data(),
artificialPrivateDiscriminator.size());
// Include the artificial private discriminator if one was given.
auto name = node->getChild(1);
if (!privateDiscriminator.empty()
&& name->getKind() == Node::Kind::Identifier) {
Buffer << 'P';
RETURN_IF_ERROR(
mangleIdentifier(privateDiscriminator, OperatorKind::NotOperator));
}
return mangle(name, depth + 1);
}
ManglingError Remangler::mangleTypedEntity(Node *node, char basicKind,
StringRef entityKind,
EntityContext &ctx, unsigned depth) {
DEMANGLER_ASSERT(node->getNumChildren() == 2 || node->getNumChildren() == 3,
node);
Buffer << basicKind;
RETURN_IF_ERROR(mangleEntityContext(node->begin()[0], ctx, depth + 1));
Buffer << entityKind;
if (node->begin()[1]->getKind() == Node::Kind::LabelList) {
auto LabelList = node->begin()[1];
auto Type = node->begin()[2];
RETURN_IF_ERROR(mangleEntityType(applyParamLabels(LabelList, Type, Factory),
ctx, depth + 1));
} else {
RETURN_IF_ERROR(mangleEntityType(node->begin()[1], ctx, depth + 1));
}
return ManglingError::Success;
}
ManglingError Remangler::mangleNamedAndTypedEntity(Node *node, char basicKind,
StringRef entityKind,
EntityContext &ctx,
unsigned depth) {
DEMANGLER_ASSERT(node->getNumChildren() == 3 || node->getNumChildren() == 4,
node);
Buffer << basicKind;
RETURN_IF_ERROR(mangleEntityContext(node->begin()[0], ctx, depth + 1));
Buffer << entityKind;
RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); // decl name / index
if (node->begin()[2]->getKind() == Node::Kind::LabelList) {
auto LabelList = node->begin()[2];
auto Type = node->begin()[3];
RETURN_IF_ERROR(mangleEntityType(applyParamLabels(LabelList, Type, Factory),
ctx, depth + 1));
} else {
RETURN_IF_ERROR(mangleEntityType(node->begin()[2], ctx, depth + 1));
}
return ManglingError::Success;
}
ManglingError Remangler::mangleEntityContext(Node *node, EntityContext &ctx,
unsigned depth) {
// Remember that we're mangling a context.
EntityContext::ManglingContextRAII raii(ctx);
// Deal with bound generic types.
switch (node->getKind()) {
case Node::Kind::BoundGenericStructure:
case Node::Kind::BoundGenericEnum:
case Node::Kind::BoundGenericClass:
case Node::Kind::BoundGenericOtherNominalType:
case Node::Kind::BoundGenericTypeAlias:
return mangleAnyNominalType(node, ctx, depth + 1);
default:
break;
}
switch (node->getKind()) {
#define NODE(ID) \
case Node::Kind::ID:
#define CONTEXT_NODE(ID)
#include "swift/Demangling/DemangleNodes.def"
return MANGLING_ERROR(ManglingError::NotAContextNode, node);
#define NODE(ID)
#define CONTEXT_NODE(ID) \
case Node::Kind::ID: \
return mangle##ID(node, ctx, depth + 1);
#include "swift/Demangling/DemangleNodes.def"
}
return MANGLING_ERROR(ManglingError::BadNodeKind, node);
}
ManglingError Remangler::mangleEntityType(Node *node, EntityContext &ctx,
unsigned depth) {
DEMANGLER_ASSERT(node->getKind() == Node::Kind::Type, node);
DEMANGLER_ASSERT(node->getNumChildren() == 1, node);
node = node->begin()[0];
// Expand certain kinds of type within the entity context.
switch (node->getKind()) {
case Node::Kind::NoEscapeFunctionType:
case Node::Kind::FunctionType:
case Node::Kind::UncurriedFunctionType: {
Buffer << ((node->getKind() == Node::Kind::FunctionType ||
node->getKind() == Node::Kind::NoEscapeFunctionType)
? 'F'
: 'f');
DEMANGLER_ASSERT(node->getNumChildren() >= 2, node);
unsigned inputIndex = node->getNumChildren() - 2;
for (unsigned i = 0; i <= inputIndex; ++i)
RETURN_IF_ERROR(mangle(node->begin()[i], depth + 1));
auto returnType = node->begin()[inputIndex+1];
DEMANGLER_ASSERT(returnType->getKind() == Node::Kind::ReturnType,
returnType);
DEMANGLER_ASSERT(returnType->getNumChildren() == 1, returnType);
return mangleEntityType(returnType->begin()[0], ctx, depth + 1);
}
default:
return mangle(node, depth + 1);
}
}
ManglingError Remangler::mangleLocalDeclName(Node *node, unsigned depth) {
Buffer << 'L';
return mangleChildNodes(node, depth + 1); // index, identifier
}
ManglingError Remangler::manglePrivateDeclName(Node *node, unsigned depth) {
Buffer << 'P';
return mangleChildNodes(node, depth + 1); // identifier, identifier
}
ManglingError Remangler::mangleRelatedEntityDeclName(Node *node,
unsigned depth) {
// Non-round-trip mangling: pretend we have a private discriminator "$A" for a
// related entity "A".
NodePointer kindNode = node->getFirstChild();
Buffer << 'P' << (kindNode->getText().size() + 1) << '$' << kindNode->getText();
return mangleChildNode(node, 1, depth + 1);
}
ManglingError Remangler::mangleTypeMangling(Node *node, unsigned depth) {
Buffer << 't';
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleType(Node *node, unsigned depth) {
return mangleSingleChildNode(node, depth + 1);
}
template <size_t N>
static bool stripPrefix(StringRef &string, const char (&data)[N]) {
constexpr size_t prefixLength = N - 1;
if (!string.starts_with(StringRef(data, prefixLength)))
return false;
string = string.drop_front(prefixLength);
return true;
}
ManglingError Remangler::mangleBuiltinFixedArray(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnexpectedBuiltinType, node);
}
ManglingError Remangler::mangleBuiltinTypeName(Node *node, unsigned depth) {
Buffer << 'B';
StringRef text = node->getText();
if (text == "Builtin.BridgeObject") {
Buffer << 'b';
} else if (text == "Builtin.UnsafeValueBuffer") {
Buffer << 'B';
} else if (text == "Builtin.UnknownObject") {
Buffer << 'O';
} else if (text == "Builtin.NativeObject") {
Buffer << 'o';
} else if (text == "Builtin.RawPointer") {
Buffer << 'p';
} else if (text == "Builtin.Word") {
Buffer << 'w';
} else if (stripPrefix(text, "Builtin.Int")) {
Buffer << 'i' << text << '_';
} else if (stripPrefix(text, "Builtin.FPIEEE")) {
Buffer << 'f' << text << '_';
} else if (stripPrefix(text, "Builtin.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');
Buffer << 'v' << text.substr(0, splitIdx) << 'B';
auto element = text.substr(splitIdx).substr(1);
if (element == "RawPointer") {
Buffer << 'p';
} else if (stripPrefix(element, "FPIEEE")) {
Buffer << 'f' << element << '_';
} else if (stripPrefix(element, "Int")) {
Buffer << 'i' << element << '_';
} else {
return MANGLING_ERROR(ManglingError::UnexpectedBuiltinVectorType, node);
}
} else {
return MANGLING_ERROR(ManglingError::UnexpectedBuiltinType, node);
}
return ManglingError::Success;
}
ManglingError Remangler::mangleBuiltinTupleType(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnexpectedBuiltinType, node);
}
ManglingError Remangler::mangleTypeAlias(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAnyNominalType(node, ctx, depth + 1);
}
ManglingError Remangler::mangleFunctionType(Node *node, unsigned depth) {
Buffer << 'F';
return mangleChildNodes(node, depth + 1); // argument tuple, result type
}
ManglingError Remangler::mangleUncurriedFunctionType(Node *node,
unsigned depth) {
Buffer << 'f';
return mangleChildNodes(node, depth + 1); // argument tuple, result type
}
ManglingError Remangler::mangleObjCBlock(Node *node, unsigned depth) {
Buffer << 'b';
return mangleChildNodes(node, depth + 1); // argument tuple, result type
}
ManglingError Remangler::mangleEscapingObjCBlock(Node *node, unsigned depth) {
// ###TODO: Is this right? Should this be an error?
// We shouldn't ever be remangling anything with a DWARF-only mangling.
Buffer << "<escaping block type>";
return ManglingError::Success;
}
ManglingError Remangler::mangleCFunctionPointer(Node *node, unsigned depth) {
Buffer << 'c';
return mangleChildNodes(node, depth + 1); // argument tuple, result type
}
ManglingError Remangler::mangleAutoClosureType(Node *node, unsigned depth) {
Buffer << 'K';
return mangleChildNodes(node, depth + 1); // argument tuple, result type
}
ManglingError Remangler::mangleNoEscapeFunctionType(Node *node,
unsigned depth) {
Buffer << 'F';
return mangleChildNodes(node, depth + 1); // argument tuple, result type
}
ManglingError Remangler::mangleEscapingAutoClosureType(Node *node,
unsigned depth) {
Buffer << 'K';
return mangleChildNodes(node, depth + 1); // argument tuple, result type
}
ManglingError Remangler::mangleThinFunctionType(Node *node, unsigned depth) {
Buffer << "Xf";
return mangleChildNodes(node, depth + 1); // argument tuple, result type
}
ManglingError Remangler::mangleArgumentTuple(Node *node, unsigned depth) {
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleReturnType(Node *node, unsigned depth) {
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
Buffer << "XF";
auto i = node->begin(), e = node->end();
if (i != e && (*i)->getKind() == Node::Kind::ImplConvention) {
StringRef text = (*i)->getText();
++i;
if (text == "@callee_unowned") {
Buffer << 'd';
} else if (text == "@callee_guaranteed") {
Buffer << 'g';
} else if (text == "@callee_owned") {
Buffer << 'o';
} else {
return MANGLING_ERROR(ManglingError::InvalidImplCalleeConvention, *i);
}
} else {
Buffer << 't';
}
for (; i != e &&
(*i)->getKind() == Node::Kind::ImplFunctionAttribute; ++i) {
RETURN_IF_ERROR(mangle(*i, depth + 1)); // impl function attribute
}
if (i != e &&
((*i)->getKind() == Node::Kind::DependentGenericSignature ||
(*i)->getKind() == Node::Kind::DependentPseudogenericSignature)) {
Buffer << ((*i)->getKind() == Node::Kind::DependentGenericSignature
? 'G' : 'g');
RETURN_IF_ERROR(mangleDependentGenericSignature((*i), depth + 1));
++i;
}
Buffer << '_';
for (; i != e && (*i)->getKind() == Node::Kind::ImplParameter; ++i) {
RETURN_IF_ERROR(mangleImplParameter(*i, depth + 1));
}
Buffer << '_';
RETURN_IF_ERROR(mangleNodes(i, e, depth + 1)); // impl results
Buffer << '_';
return ManglingError::Success;
}
ManglingError Remangler::mangleImplCoroutineKind(Node *node,
unsigned depth) {
StringRef text = node->getText();
if (text == "yield_once") {
Buffer << "A";
} else if (text == "yield_once_2") {
Buffer << "I";
} else if (text == "yield_many") {
Buffer << "G";
} else {
return MANGLING_ERROR(ManglingError::InvalidImplCoroutineKind, node);
}
return ManglingError::Success;
}
ManglingError Remangler::mangleImplFunctionAttribute(Node *node,
unsigned depth) {
StringRef text = node->getText();
if (text == "@Sendable") {
Buffer << "h";
} else if (text == "@async") {
Buffer << "H";
} else {
return MANGLING_ERROR(ManglingError::InvalidImplFunctionAttribute, node);
}
return ManglingError::Success;
}
ManglingError Remangler::mangleImplFunctionConvention(Node *node,
unsigned depth) {
return mangle(node->getChild(0), depth + 1);
}
ManglingError Remangler::mangleImplFunctionConventionName(Node *node,
unsigned depth) {
StringRef text = node->getText();
if (text == "block") {
Buffer << "Cb";
} else if (text == "c") {
Buffer << "Cc";
} else if (text == "method") {
Buffer << "Cm";
} else if (text == "objc_method") {
Buffer << "CO";
} else if (text == "witness_method") {
Buffer << "Cw";
} else {
return MANGLING_ERROR(ManglingError::InvalidImplCalleeConvention, node);
}
return ManglingError::Success;
}
ManglingError Remangler::mangleClangType(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleImplParameter(Node *node, unsigned depth) {
DEMANGLER_ASSERT(node->getNumChildren() == 2, node);
return mangleChildNodes(node, depth + 1); // impl convention, type
}
ManglingError Remangler::mangleImplErrorResult(Node *node, unsigned depth) {
DEMANGLER_ASSERT(node->getNumChildren() == 2, node);
Buffer << 'z';
return mangleChildNodes(node, depth + 1); // impl convention, type
}
ManglingError Remangler::mangleImplResult(Node *node, unsigned depth) {
DEMANGLER_ASSERT(node->getNumChildren() == 2, node);
return mangleChildNodes(node, depth + 1); // impl convention, type
}
ManglingError Remangler::mangleImplYield(Node *node, unsigned depth) {
DEMANGLER_ASSERT(node->getNumChildren() == 2, node);
Buffer << 'Y';
return mangleChildNodes(node, depth + 1); // impl convention, type
}
ManglingError Remangler::mangleImplDifferentiabilityKind(Node *node,
unsigned depth) {
// TODO(TF-750): Check if this code path actually triggers and add a test.
Buffer << (char)node->getIndex();
return ManglingError::Success;
}
ManglingError Remangler::mangleImplEscaping(Node *node, unsigned depth) {
// The old mangler does not encode escaping.
return ManglingError::Success;
}
ManglingError Remangler::mangleImplErasedIsolation(Node *node, unsigned depth) {
// The old mangler does not encode @isolated(any).
return ManglingError::Success;
}
ManglingError Remangler::mangleImplSendingResult(Node *node, unsigned depth) {
// The old mangler does not encode sending result
return ManglingError::Success;
}
ManglingError Remangler::mangleImplPatternSubstitutions(Node *node,
unsigned depth) {
// The old mangler does not encode substituted function types.
return ManglingError::Success;
}
ManglingError Remangler::mangleImplInvocationSubstitutions(Node *node,
unsigned depth) {
// The old mangler does not encode substituted function types.
return ManglingError::Success;
}
ManglingError Remangler::mangleImplConvention(Node *node, unsigned depth) {
DEMANGLER_ASSERT(node->getKind() == Node::Kind::ImplConvention, node);
StringRef text = node->getText();
if (text == "@autoreleased") {
Buffer << 'a';
} else if (text == "@unowned") {
Buffer << 'd';
} else if (text == "@unowned_inner_pointer") {
Buffer << 'D'; // only in results
} else if (text == "@guaranteed") {
Buffer << 'g';
} else if (text == "@deallocating") {
Buffer << 'e';
} else if (text == "@in") {
Buffer << 'i'; // only in parameters
} else if (text == "@out") {
Buffer << 'i'; // only in results
} else if (text == "@inout") {
Buffer << 'l';
} else if (text == "@owned") {
Buffer << 'o';
} else {
return MANGLING_ERROR(ManglingError::InvalidImplParameterConvention, node);
}
return ManglingError::Success;
}
ManglingError
Remangler::mangleImplParameterResultDifferentiability(Node *node,
unsigned depth) {
DEMANGLER_ASSERT(node->getKind() == Node::Kind::ImplDifferentiabilityKind,
node);
StringRef text = node->getText();
// Empty string represents default differentiability.
if (text.empty())
return ManglingError::Success;
if (text == "@noDerivative") {
Buffer << 'w';
return ManglingError::Success;
}
return MANGLING_ERROR(ManglingError::InvalidImplDifferentiability, node);
}
ManglingError Remangler::mangleImplParameterSending(Node *node,
unsigned depth) {
StringRef text = node->getText();
if (text == "sending") {
Buffer << 'T';
return ManglingError::Success;
}
return MANGLING_ERROR(ManglingError::InvalidImplParameterAttr, node);
}
ManglingError Remangler::mangleImplParameterIsolated(Node *node,
unsigned depth) {
return ManglingError::Success;
}
ManglingError Remangler::mangleImplParameterImplicitLeading(Node *node,
unsigned depth) {
return ManglingError::Success;
}
ManglingError Remangler::mangleDynamicSelf(Node *node, unsigned depth) {
Buffer << 'D';
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleErrorType(Node *node, unsigned depth) {
Buffer << "ERR";
return ManglingError::Success;
}
ManglingError Remangler::mangleSILBoxType(Node *node, unsigned depth) {
Buffer << 'X' << 'b';
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleMetatype(Node *node, unsigned depth) {
if (node->getNumChildren() == 1) {
Buffer << 'M';
return mangleSingleChildNode(node, depth + 1); // type
} else {
DEMANGLER_ASSERT(node->getNumChildren() == 2, node);
Buffer << "XM";
return mangleChildNodes(node, depth + 1); // metatype representation, type
}
}
ManglingError Remangler::mangleExistentialMetatype(Node *node, unsigned depth) {
if (node->getNumChildren() == 1) {
Buffer << "PM";
return mangleSingleChildNode(node, depth + 1); // type
} else {
DEMANGLER_ASSERT(node->getNumChildren() == 2, node);
Buffer << "XPM";
return mangleChildNodes(node, depth + 1); // metatype representation, type
}
}
ManglingError Remangler::mangleMetatypeRepresentation(Node *node,
unsigned depth) {
StringRef 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::mangleProtocolList(Node *node, unsigned depth) {
// In its usual use as a type, this gets a prefix 'P'.
Buffer << 'P';
return mangleProtocolListWithoutPrefix(node, depth + 1);
}
ManglingError
Remangler::mangleProtocolListWithoutPrefix(Node *node, unsigned depth,
Node *additionalProto) {
DEMANGLER_ASSERT(node->getKind() == Node::Kind::ProtocolList, node);
DEMANGLER_ASSERT(node->getNumChildren() == 1, node);
auto typeList = node->begin()[0];
DEMANGLER_ASSERT(typeList->getKind() == Node::Kind::TypeList, typeList);
for (auto &child : *typeList) {
RETURN_IF_ERROR(mangleProtocolWithoutPrefix(child, depth + 1));
}
if (additionalProto) {
RETURN_IF_ERROR(mangleProtocolWithoutPrefix(additionalProto, depth + 1));
}
Buffer << '_';
return ManglingError::Success;
}
#define REF_STORAGE(Name, ...) \
ManglingError Remangler::mangle##Name(Node *node, unsigned depth) { \
Buffer << manglingOf(ReferenceOwnership::Name); \
return mangleSingleChildNode(node, depth + 1); /* type */ \
}
#include "swift/AST/ReferenceStorage.def"
ManglingError Remangler::mangleShared(Node *node, unsigned depth) {
Buffer << 'h';
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleOwned(Node *node, unsigned depth) {
Buffer << 'n';
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleInOut(Node *node, unsigned depth) {
Buffer << 'R';
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleIsolated(Node *node, unsigned depth) {
Buffer << "Yi";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleSending(Node *node, unsigned depth) {
Buffer << "Yu";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleCompileTimeLiteral(Node *node, unsigned depth) {
Buffer << "Yt";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleConstValue(Node *node, unsigned depth) {
Buffer << "Yg";
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleNoDerivative(Node *node, unsigned depth) {
Buffer << 'k';
return mangleSingleChildNode(node, depth + 1); // type
}
ManglingError Remangler::mangleTuple(Node *node, unsigned depth) {
size_t NumElems = node->getNumChildren();
if (NumElems > 0 &&
node->getChild(NumElems - 1)->getFirstChild()->getKind() ==
Node::Kind::VariadicMarker) {
Buffer << 't';
} else {
Buffer << 'T';
}
RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); // tuple elements
Buffer << '_';
return ManglingError::Success;
}
ManglingError Remangler::mangleTupleElement(Node *node, unsigned depth) {
return mangleChildNodes(node, depth + 1); // tuple element name?, type
}
ManglingError Remangler::mangleTupleElementName(Node *node, unsigned depth) {
return mangleIdentifier(node->getText(), OperatorKind::NotOperator);
}
ManglingError Remangler::manglePack(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleSILPackDirect(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleSILPackIndirect(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::manglePackExpansion(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::manglePackElement(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::manglePackElementLevel(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleDependentGenericType(Node *node,
unsigned depth) {
Buffer << 'u';
return mangleChildNodes(node, depth + 1); // generic signature, type
}
ManglingError Remangler::mangleDependentPseudogenericSignature(Node *node,
unsigned depth) {
return mangleDependentGenericSignature(node, depth + 1);
}
ManglingError Remangler::mangleDependentGenericParamPackMarker(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleDependentGenericSignature(Node *node,
unsigned depth) {
auto i = node->begin(), e = node->end();
// If there's only one generic param, mangle nothing.
if (node->getNumChildren() >= 1
&& node->getChild(0)->getKind() == Node::Kind::DependentGenericParamCount
&& node->getChild(0)->getIndex() == 1
&& (node->getNumChildren() == 1
|| node->getChild(1)->getKind() != Node::Kind::DependentGenericParamCount))
{
++i;
goto mangle_requirements;
}
// Remangle generic params.
for (; i != e &&
(*i)->getKind() == Node::Kind::DependentGenericParamCount; ++i) {
auto count = *i;
if (count->getIndex() > 0)
mangleIndex(count->getIndex() - 1);
else
Buffer << 'z';
}
mangle_requirements:
if (i == e) { // no generic requirements
Buffer << 'r';
return ManglingError::Success;
}
Buffer << 'R';
RETURN_IF_ERROR(mangleNodes(i, e, depth + 1)); // generic requirements
Buffer << 'r';
return ManglingError::Success;
}
ManglingError Remangler::mangleDependentGenericParamCount(Node *node,
unsigned depth) {
// handled inline in DependentGenericSignature
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleDependentGenericConformanceRequirement(Node *node,
unsigned depth) {
RETURN_IF_ERROR(mangleConstrainedType(node->getChild(0), depth + 1));
// If the constraint represents a protocol, use the shorter mangling.
if (node->getNumChildren() == 2
&& node->getChild(1)->getKind() == Node::Kind::Type
&& node->getChild(1)->getNumChildren() == 1
&& node->getChild(1)->getChild(0)->getKind() == Node::Kind::Protocol) {
return mangleProtocolWithoutPrefix(node->getChild(1)->getChild(0),
depth + 1);
}
return mangle(node->getChild(1), depth + 1);
}
ManglingError
Remangler::mangleDependentGenericSameTypeRequirement(Node *node,
unsigned depth) {
RETURN_IF_ERROR(mangleConstrainedType(node->getChild(0), depth + 1));
Buffer << 'z';
return mangle(node->getChild(1), depth + 1);
}
ManglingError
Remangler::mangleDependentGenericSameShapeRequirement(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleDependentGenericLayoutRequirement(Node *node, unsigned depth) {
RETURN_IF_ERROR(mangleConstrainedType(node->getChild(0), depth + 1));
Buffer << 'l';
auto id = node->getChild(1)->getText();
auto size = -1;
if (node->getNumChildren() > 2) {
size = node->getChild(2)->getIndex();
}
int alignment = -1;
if (node->getNumChildren() > 3) {
alignment = node->getChild(3)->getIndex();
}
Buffer << id;
if (size >= 0)
Buffer << size;
if (alignment >= 0) {
Buffer << "_" << alignment;
}
return ManglingError::Success;
}
ManglingError Remangler::mangleConstrainedType(Node *node, unsigned depth) {
if (node->getFirstChild()->getKind()
== Node::Kind::DependentGenericParamType) {
// Can be mangled without an introducer.
return mangleDependentGenericParamIndex(node->getFirstChild(), depth + 1);
} else {
return mangle(node, depth + 1);
}
}
ManglingError Remangler::mangleAssociatedType(Node *node, unsigned depth) {
if (node->hasChildren()) {
DEMANGLER_ASSERT(node->getNumChildren() == 1, node);
return mangleProtocolListWithoutPrefix(*node->begin(), depth + 1);
} else {
Buffer << '_';
return ManglingError::Success;
}
}
ManglingError Remangler::mangleDeclContext(Node *node, unsigned depth) {
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleExtension(Node *node, EntityContext &ctx,
unsigned depth) {
DEMANGLER_ASSERT(node->getNumChildren() == 2 || node->getNumChildren() == 3,
node);
if (node->getNumChildren() == 3) {
Buffer << 'e';
} else {
Buffer << 'E';
}
// module
RETURN_IF_ERROR(mangleEntityContext(node->begin()[0], ctx, depth + 1));
if (node->getNumChildren() == 3) {
// generic sig
RETURN_IF_ERROR(
mangleDependentGenericSignature(node->begin()[2], depth + 1));
}
// context
return mangleEntityContext(node->begin()[1], ctx, depth + 1);
}
ManglingError Remangler::mangleAnonymousContext(Node *node, EntityContext &ctx,
unsigned depth) {
RETURN_IF_ERROR(mangleEntityContext(node->getChild(1), ctx, depth + 1));
// Since we can't change the old mangling, mangle an anonymous context by
// introducing a private discriminator onto its child contexts.
ctx.setAnonymousContextDiscriminator(node->getChild(0)->getText());
return ManglingError::Success;
}
ManglingError Remangler::mangleModule(Node *node, EntityContext &ctx,
unsigned depth) {
SubstitutionEntry entry;
if (trySubstitution(node, entry))
return ManglingError::Success;
// Module types get an M prefix, but module contexts don't.
if (!ctx.isAsContext()) Buffer << 'M';
RETURN_IF_ERROR(mangleIdentifier(node->getText(), OperatorKind::NotOperator));
addSubstitution(entry);
return ManglingError::Success;
}
ManglingError Remangler::mangleAssociatedTypeRef(Node *node, unsigned depth) {
SubstitutionEntry entry;
if (trySubstitution(node, entry))
return ManglingError::Success;
Buffer << "Q";
RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); // type, identifier
addSubstitution(entry);
return ManglingError::Success;
}
ManglingError Remangler::mangleDependentMemberType(Node *node, unsigned depth) {
Vector<Node *> members;
Node *base = node;
do {
members.push_back(base, Factory);
base = base->getFirstChild()->getFirstChild();
} while (base->getKind() == Node::Kind::DependentMemberType);
DEMANGLER_ASSERT(base->getKind() == Node::Kind::DependentGenericParamType &&
"dependent members not based on a generic param are "
"non-canonical and shouldn't need remangling",
base);
DEMANGLER_ASSERT(members.size() >= 1, node);
if (members.size() == 1) {
Buffer << 'w';
RETURN_IF_ERROR(mangleDependentGenericParamIndex(base, depth + 1));
RETURN_IF_ERROR(mangle(members[0]->getChild(1), depth + 1));
} else {
Buffer << 'W';
RETURN_IF_ERROR(mangleDependentGenericParamIndex(base, depth + 1));
for (unsigned i = 1, n = members.size(); i <= n; ++i) {
Node *member = members[n - i];
RETURN_IF_ERROR(mangle(member->getChild(1), depth + 1));
}
Buffer << '_';
}
return ManglingError::Success;
}
ManglingError Remangler::mangleDependentAssociatedTypeRef(Node *node,
unsigned depth) {
SubstitutionEntry entry;
if (trySubstitution(node, entry))
return ManglingError::Success;
if (node->getNumChildren() > 1) {
Buffer << 'P';
RETURN_IF_ERROR(mangleProtocolWithoutPrefix(node->getChild(1), depth + 1));
}
RETURN_IF_ERROR(mangleIdentifier(node->getFirstChild(), depth + 1));
addSubstitution(entry);
return ManglingError::Success;
}
ManglingError Remangler::mangleDependentGenericParamIndex(Node *node,
unsigned depth) {
auto paramDepth = node->getChild(0)->getIndex();
auto index = node->getChild(1)->getIndex();
if (paramDepth != 0) {
Buffer << 'd';
mangleIndex(paramDepth - 1);
mangleIndex(index);
return ManglingError::Success;
}
if (index != 0) {
mangleIndex(index - 1);
return ManglingError::Success;
}
// paramDepth == index == 0
Buffer << 'x';
return ManglingError::Success;
}
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';
return mangleDependentGenericParamIndex(node, depth + 1);
}
ManglingError Remangler::mangleIndex(Node *node, unsigned depth) {
mangleIndex(node->getIndex());
return ManglingError::Success;
}
ManglingError Remangler::mangleUnknownIndex(Node *node, unsigned depth) {
// should not be reached in an arbitrary context
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleProtocol(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleNominalType(node, 'P', ctx, depth + 1);
}
ManglingError Remangler::mangleProtocolWithoutPrefix(Node *node,
unsigned depth) {
if (mangleStandardSubstitution(node))
return ManglingError::Success;
if (node->getKind() == Node::Kind::Type) {
DEMANGLER_ASSERT(node->getNumChildren() == 1, node);
node = node->begin()[0];
}
DEMANGLER_ASSERT(node->getKind() == Node::Kind::Protocol, node);
EntityContext ctx;
return mangleNominalType(node, '\0', ctx, depth + 1);
}
ManglingError Remangler::mangleGenericArgs(Node *node, EntityContext &ctx,
unsigned depth) {
switch (node->getKind()) {
case Node::Kind::Structure:
case Node::Kind::Enum:
case Node::Kind::Class: {
NodePointer parentOrModule = node->getChild(0);
RETURN_IF_ERROR(mangleGenericArgs(parentOrModule, ctx, depth + 1));
// No generic arguments at this level
Buffer << '_';
break;
}
case Node::Kind::BoundGenericStructure:
case Node::Kind::BoundGenericEnum:
case Node::Kind::BoundGenericClass: {
NodePointer unboundType = node->getChild(0);
DEMANGLER_ASSERT(unboundType->getKind() == Node::Kind::Type, unboundType);
NodePointer nominalType = unboundType->getChild(0);
NodePointer parentOrModule = nominalType->getChild(0);
RETURN_IF_ERROR(mangleGenericArgs(parentOrModule, ctx, depth + 1));
RETURN_IF_ERROR(mangleTypeList(node->getChild(1), depth + 1));
break;
}
case Node::Kind::AnonymousContext:
case Node::Kind::Extension: {
RETURN_IF_ERROR(mangleGenericArgs(node->getChild(1), ctx, depth + 1));
break;
}
default:
break;
}
return ManglingError::Success;
}
ManglingError Remangler::mangleAnyNominalType(Node *node, EntityContext &ctx,
unsigned depth) {
if (depth > Remangler::MaxDepth)
return MANGLING_ERROR(ManglingError::TooComplex, node);
if (isSpecialized(node)) {
Buffer << 'G';
auto unspec = getUnspecialized(node, Factory);
if (!unspec.isSuccess())
return unspec.error();
NodePointer unboundType = unspec.result();
RETURN_IF_ERROR(mangleAnyNominalType(unboundType, ctx, depth + 1));
return mangleGenericArgs(node, ctx, depth + 1);
}
switch (node->getKind()) {
case Node::Kind::Type:
RETURN_IF_ERROR(mangleAnyNominalType(node->getChild(0), ctx, depth + 1));
break;
case Node::Kind::OtherNominalType:
// Mangle unknown type kinds as structures since we can't change the old
// mangling. Give the mangling an artificial "private discriminator" so that
// clients who understand the old mangling know this is an unstable
// mangled name.
RETURN_IF_ERROR(
mangleNominalType(node, 'V', ctx, depth + 1, "_UnknownTypeKind"));
break;
case Node::Kind::Structure:
RETURN_IF_ERROR(mangleNominalType(node, 'V', ctx, depth + 1));
break;
case Node::Kind::Enum:
RETURN_IF_ERROR(mangleNominalType(node, 'O', ctx, depth + 1));
break;
case Node::Kind::Class:
RETURN_IF_ERROR(mangleNominalType(node, 'C', ctx, depth + 1));
break;
case Node::Kind::TypeAlias:
RETURN_IF_ERROR(mangleNominalType(node, 'a', ctx, depth + 1));
break;
default:
return MANGLING_ERROR(ManglingError::BadNominalTypeKind, node);
}
return ManglingError::Success;
}
ManglingError Remangler::mangleStructure(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAnyNominalType(node, ctx, depth + 1);
}
ManglingError Remangler::mangleEnum(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAnyNominalType(node, ctx, depth + 1);
}
ManglingError Remangler::mangleClass(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAnyNominalType(node, ctx, depth + 1);
}
ManglingError Remangler::mangleOtherNominalType(Node *node, EntityContext &ctx,
unsigned depth) {
return mangleAnyNominalType(node, ctx, depth + 1);
}
ManglingError
Remangler::mangleNominalType(Node *node, char kind, EntityContext &ctx,
unsigned depth,
StringRef artificialPrivateDiscriminator) {
SubstitutionEntry entry;
if (node->getKind() == Node::Kind::Type) {
node = node->getChild(0);
}
if (trySubstitution(node, entry))
return ManglingError::Success;
RETURN_IF_ERROR(mangleNamedEntity(node, kind, "", ctx, depth + 1,
artificialPrivateDiscriminator));
addSubstitution(entry);
return ManglingError::Success;
}
ManglingError Remangler::mangleBoundGenericClass(Node *node, unsigned depth) {
EntityContext ctx;
return mangleAnyNominalType(node, ctx, depth + 1);
}
ManglingError Remangler::mangleBoundGenericStructure(Node *node,
unsigned depth) {
EntityContext ctx;
return mangleAnyNominalType(node, ctx, depth + 1);
}
ManglingError Remangler::mangleBoundGenericEnum(Node *node, unsigned depth) {
EntityContext ctx;
return mangleAnyNominalType(node, ctx, depth + 1);
}
ManglingError Remangler::mangleBoundGenericOtherNominalType(Node *node,
unsigned depth) {
EntityContext ctx;
return mangleAnyNominalType(node, ctx, depth + 1);
}
ManglingError Remangler::mangleBoundGenericProtocol(Node *node,
unsigned depth) {
EntityContext ctx;
return mangleAnyNominalType(node, ctx, depth + 1);
}
ManglingError Remangler::mangleBoundGenericTypeAlias(Node *node,
unsigned depth) {
EntityContext ctx;
return mangleAnyNominalType(node, ctx, depth + 1);
}
ManglingError Remangler::mangleBoundGenericFunction(Node *node,
unsigned depth) {
EntityContext ctx;
// Not really a nominal type, but it works for functions, too.
return mangleAnyNominalType(node, ctx, depth + 1);
}
ManglingError Remangler::mangleTypeList(Node *node, unsigned depth) {
RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); // all types
Buffer << '_';
return ManglingError::Success;
}
ManglingError Remangler::mangleLabelList(Node *node, unsigned depth) {
if (node->getNumChildren() == 0) {
Buffer << 'y';
return ManglingError::Success;
} else {
return mangleChildNodes(node, depth + 1);
}
}
ManglingError
Remangler::mangleReflectionMetadataBuiltinDescriptor(Node *node,
unsigned depth) {
Buffer << "MRb";
return ManglingError::Success;
}
ManglingError
Remangler::mangleReflectionMetadataFieldDescriptor(Node *node, unsigned depth) {
Buffer << "MRf";
return ManglingError::Success;
}
ManglingError
Remangler::mangleReflectionMetadataAssocTypeDescriptor(Node *node,
unsigned depth) {
Buffer << "MRa";
return ManglingError::Success;
}
ManglingError
Remangler::mangleReflectionMetadataSuperclassDescriptor(Node *node,
unsigned depth) {
Buffer << "MRc";
return ManglingError::Success;
}
ManglingError Remangler::mangleGenericTypeParamDecl(Node *node,
unsigned depth) {
// todo
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleCurryThunk(Node *node, unsigned depth) {
// ###TODO: Are these errors?!
Buffer << "<curry-thunk>";
return ManglingError::Success;
}
ManglingError Remangler::mangleSILThunkIdentity(Node *node, unsigned depth) {
Buffer << "<sil-identity-thunk>";
return ManglingError::Success;
}
ManglingError Remangler::mangleDispatchThunk(Node *node, unsigned depth) {
Buffer << "<dispatch-thunk>";
return ManglingError::Success;
}
ManglingError Remangler::mangleMethodDescriptor(Node *node, unsigned depth) {
Buffer << "<method-descriptor>";
return ManglingError::Success;
}
ManglingError Remangler::mangleMethodLookupFunction(Node *node,
unsigned depth) {
Buffer << "<method-lookup-function>";
return ManglingError::Success;
}
ManglingError Remangler::mangleObjCMetadataUpdateFunction(Node *node,
unsigned depth) {
Buffer << "<objc-metadata-update-function>";
return ManglingError::Success;
}
ManglingError Remangler::mangleObjCResilientClassStub(Node *node,
unsigned depth) {
Buffer << "<objc-resilient-class-stub>";
return ManglingError::Success;
}
ManglingError Remangler::mangleFullObjCResilientClassStub(Node *node,
unsigned depth) {
Buffer << "<full-objc-resilient-class-stub>";
return ManglingError::Success;
}
ManglingError Remangler::mangleEmptyList(Node *node, unsigned depth) {
Buffer << "<empty>";
return ManglingError::Success;
}
ManglingError Remangler::mangleFirstElementMarker(Node *node, unsigned depth) {
Buffer << "<first>";
return ManglingError::Success;
}
ManglingError Remangler::mangleVariadicMarker(Node *node, unsigned depth) {
// Handled in mangleTuple
// ###TODO: Is this an error?
return ManglingError::Success;
}
ManglingError Remangler::mangleOutlinedCopy(Node *node, unsigned depth) {
Buffer << "Wy";
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedConsume(Node *node, unsigned depth) {
Buffer << "We";
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedRetain(Node *node, unsigned depth) {
Buffer << "Wr";
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedRelease(Node *node, unsigned depth) {
Buffer << "Ws";
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedInitializeWithTake(Node *node,
unsigned depth) {
Buffer << "Wb";
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedInitializeWithCopy(Node *node,
unsigned depth) {
Buffer << "Wc";
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedAssignWithTake(Node *node,
unsigned depth) {
Buffer << "Wd";
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedAssignWithCopy(Node *node,
unsigned depth) {
Buffer << "Wf";
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedDestroy(Node *node, unsigned depth) {
Buffer << "Wh";
return mangleSingleChildNode(node, depth + 1);
}
ManglingError
Remangler::mangleOutlinedInitializeWithTakeNoValueWitness(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleOutlinedInitializeWithCopyNoValueWitness(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleOutlinedAssignWithTakeNoValueWitness(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleOutlinedAssignWithCopyNoValueWitness(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleOutlinedDestroyNoValueWitness(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleOutlinedEnumTagStore(Node *node, unsigned depth) {
Buffer << "Wi";
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedEnumGetTag(Node *node, unsigned depth) {
Buffer << "Wg";
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedEnumProjectDataForLoad(Node *node, unsigned depth) {
Buffer << "Wj";
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedVariable(Node *node, unsigned depth) {
Buffer << "Tv" << node->getIndex();
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedReadOnlyObject(Node *node, unsigned depth) {
Buffer << "Tv" << node->getIndex() << 'r';
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleOutlinedBridgedMethod(Node *node,
unsigned depth) {
Buffer << "Te" << node->getText();
return mangleSingleChildNode(node, depth + 1);
}
ManglingError Remangler::mangleCoroutineContinuationPrototype(Node *node,
unsigned depth) {
Buffer << "TC";
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleKeyPathGetterThunkHelper(Node *node,
unsigned depth) {
Buffer << "TK";
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleKeyPathSetterThunkHelper(Node *node,
unsigned depth) {
Buffer << "Tk";
return mangleChildNodes(node, depth + 1);
}
ManglingError
Remangler::mangleKeyPathUnappliedMethodThunkHelper(Node *node, unsigned depth) {
Buffer << "Tkmu";
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleKeyPathAppliedMethodThunkHelper(Node *node,
unsigned depth) {
Buffer << "TkMA";
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleKeyPathEqualsThunkHelper(Node *node,
unsigned depth) {
Buffer << "TH";
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleKeyPathHashThunkHelper(Node *node,
unsigned depth) {
Buffer << "Th";
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleProtocolListWithClass(Node *node,
unsigned depth) {
Buffer << "Xc";
RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1));
return mangleProtocolListWithoutPrefix(node->getChild(0), depth + 1);
}
ManglingError Remangler::mangleProtocolListWithAnyObject(Node *node,
unsigned depth) {
Node *P = Factory.createNode(Node::Kind::Protocol);
P->addChild(Factory.createNode(Node::Kind::Module, "Swift"), Factory);
P->addChild(Factory.createNode(Node::Kind::Identifier, "AnyObject"), Factory);
Buffer << "P";
return mangleProtocolListWithoutPrefix(node->getChild(0), depth + 1,
/*additionalProto*/ P);
}
ManglingError Remangler::mangleVTableThunk(Node *node, unsigned depth) {
Buffer << "TV";
return mangleChildNodes(node, depth + 1);
}
ManglingError Remangler::mangleSILBoxTypeWithLayout(Node *node,
unsigned depth) {
DEMANGLER_ASSERT(node->getKind() == Node::Kind::SILBoxTypeWithLayout, node);
DEMANGLER_ASSERT(node->getNumChildren() == 1 || node->getNumChildren() == 3,
node);
Buffer << "XB";
auto layout = node->getChild(0);
DEMANGLER_ASSERT(layout->getKind() == Node::Kind::SILBoxLayout, layout);
NodePointer genericArgs = nullptr;
if (node->getNumChildren() == 3) {
NodePointer signature = node->getChild(1);
DEMANGLER_ASSERT(signature->getKind() ==
Node::Kind::DependentGenericSignature,
signature);
genericArgs = node->getChild(2);
DEMANGLER_ASSERT(genericArgs->getKind() == Node::Kind::TypeList,
genericArgs);
Buffer << 'G';
RETURN_IF_ERROR(mangleDependentGenericSignature(signature, depth + 1));
}
RETURN_IF_ERROR(mangleSILBoxLayout(layout, depth + 1));
if (genericArgs) {
for (unsigned i = 0; i < genericArgs->getNumChildren(); ++i) {
auto type = genericArgs->getChild(i);
DEMANGLER_ASSERT(genericArgs->getKind() == Node::Kind::Type, genericArgs);
RETURN_IF_ERROR(mangleType(type, depth + 1));
}
Buffer << '_';
}
return ManglingError::Success;
}
ManglingError Remangler::mangleSILBoxLayout(Node *node, unsigned depth) {
DEMANGLER_ASSERT(node->getKind() == Node::Kind::SILBoxLayout, node);
for (unsigned i = 0; i < node->getNumChildren(); ++i) {
DEMANGLER_ASSERT(node->getKind() == Node::Kind::SILBoxImmutableField ||
node->getKind() == Node::Kind::SILBoxMutableField,
node);
RETURN_IF_ERROR(mangle(node->getChild(i), depth + 1));
}
Buffer << '_';
return ManglingError::Success;
}
ManglingError Remangler::mangleSILBoxMutableField(Node *node, unsigned depth) {
Buffer << 'm';
DEMANGLER_ASSERT(node->getNumChildren() == 1 &&
node->getChild(0)->getKind() == Node::Kind::Type,
node);
return mangleType(node->getChild(0), depth + 1);
}
ManglingError Remangler::mangleSILBoxImmutableField(Node *node,
unsigned depth) {
Buffer << 'i';
DEMANGLER_ASSERT(node->getNumChildren() == 1 &&
node->getChild(0)->getKind() == Node::Kind::Type,
node);
return mangleType(node->getChild(0), depth + 1);
}
ManglingError Remangler::mangleAssocTypePath(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleModuleDescriptor(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleExtensionDescriptor(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleAnonymousDescriptor(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleAssociatedTypeGenericParamRef(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleTypeSymbolicReference(Node *node,
EntityContext &,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleProtocolSymbolicReference(Node *node,
EntityContext &,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleOpaqueTypeDescriptorSymbolicReference(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleSugaredOptional(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleSugaredArray(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleSugaredInlineArray(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleSugaredDictionary(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleSugaredParen(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleOpaqueReturnType(Node *node, unsigned depth) {
if (node->hasChildren()
&& node->getFirstChild()->getKind() == Node::Kind::OpaqueReturnTypeIndex){
Buffer << "QU";
mangleIndex(node->getFirstChild()->getIndex());
return ManglingError::Success;
}
Buffer << "Qu";
return ManglingError::Success;
}
ManglingError Remangler::mangleOpaqueReturnTypeIndex(Node *node, unsigned depth) {
return ManglingError::WrongNodeType;
}
ManglingError Remangler::mangleOpaqueReturnTypeParent(Node *node, unsigned depth) {
return ManglingError::WrongNodeType;
}
ManglingError Remangler::mangleOpaqueReturnTypeOf(Node *node,
EntityContext &ctx,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleOpaqueType(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleOpaqueTypeDescriptor(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleOpaqueTypeDescriptorRecord(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleOpaqueTypeDescriptorAccessor(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleOpaqueTypeDescriptorAccessorImpl(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleOpaqueTypeDescriptorAccessorKey(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleOpaqueTypeDescriptorAccessorVar(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleAccessorFunctionReference(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleMetadataInstantiationCache(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleGlobalVariableOnceToken(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleGlobalVariableOnceFunction(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleGlobalVariableOnceDeclList(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::manglePredefinedObjCAsyncCompletionHandlerImpl(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleObjCAsyncCompletionHandlerImpl(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleConstrainedExistential(Node *node,
unsigned int depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleConstrainedExistentialRequirementList(Node *node,
unsigned int depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleConstrainedExistentialSelf(Node *node,
unsigned int depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleUniquable(Node *node, unsigned int depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleExtendedExistentialTypeShape(Node *node,
unsigned int depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleSymbolicExtendedExistentialType(Node *node,
unsigned int depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::
mangleUniqueExtendedExistentialTypeShapeSymbolicReference(Node *node,
unsigned int depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::
mangleNonUniqueExtendedExistentialTypeShapeSymbolicReference(Node *node,
unsigned int depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleObjectiveCProtocolSymbolicReference(Node *node,
unsigned int depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError
Remangler::mangleCanonicalSpecializedGenericMetaclass(Node *node,
unsigned depth) {
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); // type
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::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;
}
/// The top-level interface to the remangler.
ManglingErrorOr<std::string>
Demangle::mangleNodeOld(NodePointer node) {
if (!node) return std::string();
NodeFactory Factory;
Remangler remangler(Factory);
ManglingError err = remangler.mangle(node, 0);
if (!err.isSuccess())
return err;
return remangler.str();
}
ManglingErrorOr<llvm::StringRef>
Demangle::mangleNodeOld(NodePointer node, NodeFactory &Factory) {
if (!node) return llvm::StringRef();
Remangler remangler(Factory);
ManglingError err = remangler.mangle(node, 0);
if (!err.isSuccess())
return err;
return remangler.getBufferStr();
}
ManglingErrorOr<const char *>
Demangle::mangleNodeAsObjcCString(NodePointer node,
NodeFactory &Factory) {
DEMANGLER_ASSERT(node, node);
Remangler remangler(Factory);
remangler.append("_Tt");
ManglingError err = remangler.mangle(node, 0);
if (!err.isSuccess())
return err;
remangler.append(StringRef("_", 2)); // Include the trailing 0 char.
return remangler.getBufferStr().data();
}
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::mangleHasSymbolQuery(Node *node, unsigned depth) {
Buffer << "TwS";
return ManglingError::Success;
}
ManglingError
Remangler::mangleDependentGenericInverseConformanceRequirement(Node *node,
unsigned depth) {
DEMANGLER_ASSERT(node->getNumChildren() == 2, node);
RETURN_IF_ERROR(mangleConstrainedType(node->getChild(0), depth + 1));
return mangle(node->getChild(1), depth + 1);
}
ManglingError Remangler::mangleInteger(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleNegativeInteger(Node *node, unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
ManglingError Remangler::mangleDependentGenericParamValueMarker(Node *node,
unsigned depth) {
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}