in lib/Demangling/NodePrinter.cpp [1161:2939]
NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
bool asPrefixContext) {
if (depth > NodePrinter::MaxDepth) {
Printer << "<<too complex>>";
return nullptr;
}
if (!Node) {
Printer << "<null node pointer>";
return nullptr;
}
switch (auto kind = Node->getKind()) {
case Node::Kind::Static:
Printer << "static ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::CurryThunk:
Printer << "curry thunk of ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::DispatchThunk:
Printer << "dispatch thunk of ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::MethodDescriptor:
Printer << "method descriptor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::MethodLookupFunction:
Printer << "method lookup function for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ObjCMetadataUpdateFunction:
Printer << "ObjC metadata update function for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ObjCResilientClassStub:
Printer << "ObjC resilient class stub for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::FullObjCResilientClassStub:
Printer << "full ObjC resilient class stub for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OutlinedBridgedMethod:
Printer << "outlined bridged method (" << Node->getText() << ") of ";
return nullptr;
case Node::Kind::OutlinedCopy:
Printer << "outlined copy of ";
print(Node->getChild(0), depth + 1);
if (Node->getNumChildren() > 1)
print(Node->getChild(1), depth + 1);
return nullptr;
case Node::Kind::OutlinedConsume:
Printer << "outlined consume of ";
print(Node->getChild(0), depth + 1);
if (Node->getNumChildren() > 1)
print(Node->getChild(1), depth + 1);
return nullptr;
case Node::Kind::OutlinedRetain:
Printer << "outlined retain of ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OutlinedRelease:
Printer << "outlined release of ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OutlinedInitializeWithTake:
Printer << "outlined init with take of ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OutlinedInitializeWithCopy:
Printer << "outlined init with copy of ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OutlinedAssignWithTake:
Printer << "outlined assign with take of ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OutlinedAssignWithCopy:
Printer << "outlined assign with copy of ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OutlinedDestroy:
Printer << "outlined destroy of ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OutlinedVariable:
Printer << "outlined variable #" << Node->getIndex() << " of ";
return nullptr;
case Node::Kind::Directness:
Printer << toString(Directness(Node->getIndex())) << " ";
return nullptr;
case Node::Kind::AnonymousContext:
if (Options.QualifyEntities && Options.DisplayExtensionContexts) {
print(Node->getChild(1), depth + 1);
Printer << ".(unknown context at ";
print(Node->getChild(0), depth + 1);
Printer << ")";
if (Node->getNumChildren() >= 3 &&
Node->getChild(2)->getNumChildren() > 0) {
Printer << '<';
print(Node->getChild(2), depth + 1);
Printer << '>';
}
}
return nullptr;
case Node::Kind::Extension:
assert((Node->getNumChildren() == 2 || Node->getNumChildren() == 3)
&& "Extension expects 2 or 3 children.");
if (Options.QualifyEntities && Options.DisplayExtensionContexts) {
Printer << "(extension in ";
// Print the module where extension is defined.
print(Node->getChild(0), depth + 1, true);
Printer << "):";
}
print(Node->getChild(1), depth + 1);
if (Node->getNumChildren() == 3) {
// Currently the runtime does not mangle the generic signature.
// This is an open to-do in swift::_buildDemanglingForContext().
if (!Options.PrintForTypeName)
print(Node->getChild(2), depth + 1);
}
return nullptr;
case Node::Kind::Variable:
return printEntity(Node, depth, asPrefixContext, TypePrinting::WithColon,
/*hasName*/ true);
case Node::Kind::Function:
case Node::Kind::BoundGenericFunction:
return printEntity(Node, depth, asPrefixContext,
TypePrinting::FunctionStyle,
/*hasName*/ true);
case Node::Kind::Subscript:
return printEntity(
Node, depth, asPrefixContext, TypePrinting::FunctionStyle,
/*hasName*/ false, /*ExtraName*/ "", /*ExtraIndex*/ -1, "subscript");
case Node::Kind::GenericTypeParamDecl:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/ true);
case Node::Kind::ExplicitClosure:
return printEntity(
Node, depth, asPrefixContext,
Options.ShowFunctionArgumentTypes ? TypePrinting::FunctionStyle
: TypePrinting::NoType,
/*hasName*/ false, "closure #", (int)Node->getChild(1)->getIndex() + 1);
case Node::Kind::ImplicitClosure:
return printEntity(Node, depth, asPrefixContext,
Options.ShowFunctionArgumentTypes
? TypePrinting::FunctionStyle
: TypePrinting::NoType,
/*hasName*/ false, "implicit closure #",
(int)Node->getChild(1)->getIndex() + 1);
case Node::Kind::Global:
printChildren(Node, depth);
return nullptr;
case Node::Kind::Suffix:
if (Options.DisplayUnmangledSuffix) {
Printer << " with unmangled suffix "
<< QuotedString(Node->getText().str());
}
return nullptr;
case Node::Kind::Initializer:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/ false, "variable initialization expression");
case Node::Kind::PropertyWrapperBackingInitializer:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/ false,
"property wrapper backing initializer");
case Node::Kind::PropertyWrapperInitFromProjectedValue:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/ false,
"property wrapper init from projected value");
case Node::Kind::DefaultArgumentInitializer:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/ false, "default argument ",
(int)Node->getChild(1)->getIndex());
case Node::Kind::DeclContext:
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::Type:
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::TypeMangling:
if (Node->getChild(0)->getKind() == Node::Kind::LabelList) {
printFunctionType(Node->getChild(0), Node->getChild(1)->getFirstChild(),
depth);
} else {
print(Node->getChild(0), depth + 1);
}
return nullptr;
case Node::Kind::Class:
case Node::Kind::Structure:
case Node::Kind::Enum:
case Node::Kind::Protocol:
case Node::Kind::TypeAlias:
case Node::Kind::OtherNominalType:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/ true);
case Node::Kind::LocalDeclName:
print(Node->getChild(1), depth + 1);
if (Options.DisplayLocalNameContexts)
Printer << " #" << (Node->getChild(0)->getIndex() + 1);
return nullptr;
case Node::Kind::PrivateDeclName:
if (Node->getNumChildren() > 1) {
if (Options.ShowPrivateDiscriminators)
Printer << '(';
print(Node->getChild(1), depth + 1);
if (Options.ShowPrivateDiscriminators)
Printer << " in " << Node->getChild(0)->getText() << ')';
} else {
if (Options.ShowPrivateDiscriminators) {
Printer << "(in " << Node->getChild(0)->getText() << ')';
}
}
return nullptr;
case Node::Kind::RelatedEntityDeclName:
Printer << "related decl '" << Node->getFirstChild()->getText() << "' for ";
print(Node->getChild(1), depth + 1);
return nullptr;
case Node::Kind::Module:
if (Options.DisplayModuleNames)
Printer << Node->getText();
return nullptr;
case Node::Kind::Identifier:
Printer << Node->getText();
return nullptr;
case Node::Kind::Index:
Printer << Node->getIndex();
return nullptr;
case Node::Kind::UnknownIndex:
Printer << "unknown index";
return nullptr;
case Node::Kind::FunctionType:
case Node::Kind::UncurriedFunctionType:
case Node::Kind::NoEscapeFunctionType:
case Node::Kind::AutoClosureType:
case Node::Kind::EscapingAutoClosureType:
case Node::Kind::ThinFunctionType:
case Node::Kind::CFunctionPointer:
case Node::Kind::ObjCBlock:
case Node::Kind::EscapingObjCBlock:
printFunctionType(nullptr, Node, depth);
return nullptr;
case Node::Kind::ClangType:
Printer << Node->getText();
return nullptr;
case Node::Kind::ArgumentTuple:
printFunctionParameters(nullptr, Node, depth,
Options.ShowFunctionArgumentTypes);
return nullptr;
case Node::Kind::Tuple: {
Printer << "(";
printChildren(Node, depth, ", ");
Printer << ")";
return nullptr;
}
case Node::Kind::TupleElement: {
if (auto Label = getChildIf(Node, Node::Kind::TupleElementName))
Printer << Label->getText() << ": ";
auto Type = getChildIf(Node, Node::Kind::Type);
assert(Type && "malformed Node::Kind::TupleElement");
print(Type, depth + 1);
if (getChildIf(Node, Node::Kind::VariadicMarker))
Printer << "...";
return nullptr;
}
case Node::Kind::TupleElementName:
Printer << Node->getText() << ": ";
return nullptr;
case Node::Kind::ReturnType:
if (Node->getNumChildren() == 0)
Printer << " -> " << Node->getText();
else {
Printer << " -> ";
printChildren(Node, depth);
}
return nullptr;
case Node::Kind::RetroactiveConformance:
if (Node->getNumChildren() != 2)
return nullptr;
Printer << "retroactive @ ";
print(Node->getChild(0), depth + 1);
print(Node->getChild(1), depth + 1);
return nullptr;
#define REF_STORAGE(Name, ...) \
case Node::Kind::Name: \
Printer << keywordOf(ReferenceOwnership::Name) << " "; \
print(Node->getChild(0), depth + 1); \
return nullptr;
#include "swift/AST/ReferenceStorage.def"
case Node::Kind::InOut:
Printer << "inout ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::Isolated:
Printer << "isolated ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::CompileTimeConst:
Printer << "_const ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::Shared:
Printer << "__shared ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::Owned:
Printer << "__owned ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::NoDerivative:
Printer << "@noDerivative ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::NonObjCAttribute:
Printer << "@nonobjc ";
return nullptr;
case Node::Kind::ObjCAttribute:
Printer << "@objc ";
return nullptr;
case Node::Kind::DirectMethodReferenceAttribute:
Printer << "super ";
return nullptr;
case Node::Kind::DynamicAttribute:
Printer << "dynamic ";
return nullptr;
case Node::Kind::VTableAttribute:
Printer << "override ";
return nullptr;
case Node::Kind::FunctionSignatureSpecialization:
printSpecializationPrefix(Node, "function signature specialization", depth);
return nullptr;
case Node::Kind::GenericPartialSpecialization:
printSpecializationPrefix(Node, "generic partial specialization", depth,
"Signature = ");
return nullptr;
case Node::Kind::GenericPartialSpecializationNotReAbstracted:
printSpecializationPrefix(Node,
"generic not-reabstracted partial specialization",
depth, "Signature = ");
return nullptr;
case Node::Kind::GenericSpecialization:
case Node::Kind::GenericSpecializationInResilienceDomain:
printSpecializationPrefix(Node, "generic specialization", depth);
return nullptr;
case Node::Kind::GenericSpecializationPrespecialized:
printSpecializationPrefix(Node, "generic pre-specialization", depth);
return nullptr;
case Node::Kind::GenericSpecializationNotReAbstracted:
printSpecializationPrefix(Node, "generic not re-abstracted specialization",
depth);
return nullptr;
case Node::Kind::InlinedGenericFunction:
printSpecializationPrefix(Node, "inlined generic function", depth);
return nullptr;
case Node::Kind::IsSerialized:
Printer << "serialized";
return nullptr;
case Node::Kind::GenericSpecializationParam:
print(Node->getChild(0), depth + 1);
for (unsigned i = 1, e = Node->getNumChildren(); i < e; ++i) {
if (i == 1)
Printer << " with ";
else
Printer << " and ";
print(Node->getChild(i), depth + 1);
}
return nullptr;
case Node::Kind::FunctionSignatureSpecializationReturn:
case Node::Kind::FunctionSignatureSpecializationParam:
printer_unreachable("should be handled in printSpecializationPrefix");
case Node::Kind::FunctionSignatureSpecializationParamPayload: {
std::string demangledName = demangleSymbolAsString(Node->getText());
if (demangledName.empty()) {
Printer << Node->getText();
} else {
Printer << demangledName;
}
return nullptr;
}
case Node::Kind::FunctionSignatureSpecializationParamKind: {
uint64_t raw = Node->getIndex();
bool printedOptionSet = false;
if (raw &
uint64_t(FunctionSigSpecializationParamKind::ExistentialToGeneric)) {
printedOptionSet = true;
Printer << "Existential To Protocol Constrained Generic";
}
if (raw & uint64_t(FunctionSigSpecializationParamKind::Dead)) {
if (printedOptionSet)
Printer << " and ";
printedOptionSet = true;
Printer << "Dead";
}
if (raw & uint64_t(FunctionSigSpecializationParamKind::OwnedToGuaranteed)) {
if (printedOptionSet)
Printer << " and ";
printedOptionSet = true;
Printer << "Owned To Guaranteed";
}
if (raw & uint64_t(FunctionSigSpecializationParamKind::GuaranteedToOwned)) {
if (printedOptionSet)
Printer << " and ";
printedOptionSet = true;
Printer << "Guaranteed To Owned";
}
if (raw & uint64_t(FunctionSigSpecializationParamKind::SROA)) {
if (printedOptionSet)
Printer << " and ";
Printer << "Exploded";
return nullptr;
}
if (printedOptionSet)
return nullptr;
switch (FunctionSigSpecializationParamKind(raw)) {
case FunctionSigSpecializationParamKind::BoxToValue:
Printer << "Value Promoted from Box";
return nullptr;
case FunctionSigSpecializationParamKind::BoxToStack:
Printer << "Stack Promoted from Box";
return nullptr;
case FunctionSigSpecializationParamKind::InOutToOut:
Printer << "InOut Converted to Out";
return nullptr;
case FunctionSigSpecializationParamKind::ConstantPropFunction:
Printer << "Constant Propagated Function";
return nullptr;
case FunctionSigSpecializationParamKind::ConstantPropGlobal:
Printer << "Constant Propagated Global";
return nullptr;
case FunctionSigSpecializationParamKind::ConstantPropInteger:
Printer << "Constant Propagated Integer";
return nullptr;
case FunctionSigSpecializationParamKind::ConstantPropFloat:
Printer << "Constant Propagated Float";
return nullptr;
case FunctionSigSpecializationParamKind::ConstantPropString:
Printer << "Constant Propagated String";
return nullptr;
case FunctionSigSpecializationParamKind::ClosureProp:
Printer << "Closure Propagated";
return nullptr;
case FunctionSigSpecializationParamKind::ExistentialToGeneric:
case FunctionSigSpecializationParamKind::Dead:
case FunctionSigSpecializationParamKind::OwnedToGuaranteed:
case FunctionSigSpecializationParamKind::GuaranteedToOwned:
case FunctionSigSpecializationParamKind::SROA:
printer_unreachable("option sets should have been handled earlier");
}
return nullptr;
}
case Node::Kind::SpecializationPassID:
Printer << Node->getIndex();
return nullptr;
case Node::Kind::BuiltinTypeName:
Printer << Node->getText();
return nullptr;
case Node::Kind::Number:
Printer << Node->getIndex();
return nullptr;
case Node::Kind::InfixOperator:
Printer << Node->getText() << " infix";
return nullptr;
case Node::Kind::PrefixOperator:
Printer << Node->getText() << " prefix";
return nullptr;
case Node::Kind::PostfixOperator:
Printer << Node->getText() << " postfix";
return nullptr;
case Node::Kind::LazyProtocolWitnessTableAccessor:
Printer << "lazy protocol witness table accessor for type ";
print(Node->getChild(0), depth + 1);
Printer << " and conformance ";
print(Node->getChild(1), depth + 1);
return nullptr;
case Node::Kind::LazyProtocolWitnessTableCacheVariable:
Printer << "lazy protocol witness table cache variable for type ";
print(Node->getChild(0), depth + 1);
Printer << " and conformance ";
print(Node->getChild(1), depth + 1);
return nullptr;
case Node::Kind::ProtocolSelfConformanceWitnessTable:
Printer << "protocol self-conformance witness table for ";
print(Node->getFirstChild(), depth + 1);
return nullptr;
case Node::Kind::ProtocolWitnessTableAccessor:
Printer << "protocol witness table accessor for ";
print(Node->getFirstChild(), depth + 1);
return nullptr;
case Node::Kind::ProtocolWitnessTable:
Printer << "protocol witness table for ";
print(Node->getFirstChild(), depth + 1);
return nullptr;
case Node::Kind::ProtocolWitnessTablePattern:
Printer << "protocol witness table pattern for ";
print(Node->getFirstChild(), depth + 1);
return nullptr;
case Node::Kind::GenericProtocolWitnessTable:
Printer << "generic protocol witness table for ";
print(Node->getFirstChild(), depth + 1);
return nullptr;
case Node::Kind::GenericProtocolWitnessTableInstantiationFunction:
Printer << "instantiation function for generic protocol witness table for ";
print(Node->getFirstChild(), depth + 1);
return nullptr;
case Node::Kind::ResilientProtocolWitnessTable:
Printer << "resilient protocol witness table for ";
print(Node->getFirstChild(), depth + 1);
return nullptr;
case Node::Kind::VTableThunk: {
Printer << "vtable thunk for ";
print(Node->getChild(1), depth + 1);
Printer << " dispatching to ";
print(Node->getChild(0), depth + 1);
return nullptr;
}
case Node::Kind::ProtocolSelfConformanceWitness: {
Printer << "protocol self-conformance witness for ";
print(Node->getChild(0), depth + 1);
return nullptr;
}
case Node::Kind::ProtocolWitness: {
Printer << "protocol witness for ";
print(Node->getChild(1), depth + 1);
Printer << " in conformance ";
print(Node->getChild(0), depth + 1);
return nullptr;
}
case Node::Kind::PartialApplyForwarder:
if (Options.ShortenPartialApply)
Printer << "partial apply";
else
Printer << "partial apply forwarder";
if (Node->hasChildren()) {
Printer << " for ";
printChildren(Node, depth);
}
return nullptr;
case Node::Kind::PartialApplyObjCForwarder:
if (Options.ShortenPartialApply)
Printer << "partial apply";
else
Printer << "partial apply ObjC forwarder";
if (Node->hasChildren()) {
Printer << " for ";
printChildren(Node, depth);
}
return nullptr;
case Node::Kind::KeyPathGetterThunkHelper:
case Node::Kind::KeyPathSetterThunkHelper:
if (Node->getKind() == Node::Kind::KeyPathGetterThunkHelper)
Printer << "key path getter for ";
else
Printer << "key path setter for ";
print(Node->getChild(0), depth + 1);
Printer << " : ";
for (unsigned index = 1; index < Node->getNumChildren(); ++index) {
auto Child = Node->getChild(index);
if (Child->getKind() == Node::Kind::IsSerialized)
Printer << ", ";
print(Child, depth + 1);
}
return nullptr;
case Node::Kind::KeyPathEqualsThunkHelper:
case Node::Kind::KeyPathHashThunkHelper: {
Printer << "key path index "
<< (Node->getKind() == Node::Kind::KeyPathEqualsThunkHelper
? "equality" : "hash")
<< " operator for ";
unsigned lastChildIndex = Node->getNumChildren();
auto lastChild = Node->getChild(lastChildIndex - 1);
if (lastChild->getKind() == Node::Kind::IsSerialized) {
--lastChildIndex;
lastChild = Node->getChild(lastChildIndex - 1);
}
if (lastChild->getKind() == Node::Kind::DependentGenericSignature) {
print(lastChild, depth + 1);
--lastChildIndex;
}
Printer << "(";
for (unsigned i = 0; i < lastChildIndex; ++i) {
if (i != 0)
Printer << ", ";
print(Node->getChild(i), depth + 1);
}
Printer << ")";
return nullptr;
}
case Node::Kind::FieldOffset: {
print(Node->getChild(0), depth + 1); // directness
Printer << "field offset for ";
auto entity = Node->getChild(1);
print(entity, depth + 1, /*asContext*/ false);
return nullptr;
}
case Node::Kind::EnumCase: {
Printer << "enum case for ";
auto entity = Node->getChild(0);
print(entity, depth + 1, /*asContext*/ false);
return nullptr;
}
case Node::Kind::ReabstractionThunk:
case Node::Kind::ReabstractionThunkHelper: {
if (Options.ShortenThunk) {
Printer << "thunk for ";
print(Node->getChild(Node->getNumChildren() - 1), depth + 1);
return nullptr;
}
Printer << "reabstraction thunk ";
if (Node->getKind() == Node::Kind::ReabstractionThunkHelper)
Printer << "helper ";
unsigned idx = 0;
if (Node->getNumChildren() == 3) {
auto generics = Node->getChild(0);
idx = 1;
print(generics, depth + 1);
Printer << " ";
}
Printer << "from ";
print(Node->getChild(idx + 1), depth + 1);
Printer << " to ";
print(Node->getChild(idx), depth + 1);
return nullptr;
}
case Node::Kind::ReabstractionThunkHelperWithGlobalActor: {
print(Node->getChild(0), depth + 1);
Printer << " with global actor constraint ";
print(Node->getChild(1), depth + 1);
return nullptr;
}
case Node::Kind::ReabstractionThunkHelperWithSelf: {
Printer << "reabstraction thunk ";
unsigned idx = 0;
if (Node->getNumChildren() == 4) {
auto generics = Node->getChild(0);
idx = 1;
print(generics, depth + 1);
Printer << " ";
}
Printer << "from ";
print(Node->getChild(idx + 2), depth + 1);
Printer << " to ";
print(Node->getChild(idx + 1), depth + 1);
Printer << " self ";
print(Node->getChild(idx), depth + 1);
return nullptr;
}
case Node::Kind::AutoDiffFunction:
case Node::Kind::AutoDiffDerivativeVTableThunk: {
unsigned prefixEndIndex = 0;
while (prefixEndIndex != Node->getNumChildren() &&
Node->getChild(prefixEndIndex)->getKind()
!= Node::Kind::AutoDiffFunctionKind)
++prefixEndIndex;
auto funcKind = Node->getChild(prefixEndIndex);
auto paramIndices = Node->getChild(prefixEndIndex + 1);
auto resultIndices = Node->getChild(prefixEndIndex + 2);
if (kind == Node::Kind::AutoDiffDerivativeVTableThunk)
Printer << "vtable thunk for ";
print(funcKind, depth + 1);
Printer << " of ";
NodePointer optionalGenSig = nullptr;
for (unsigned i = 0; i < prefixEndIndex; ++i) {
// The last node may be a generic signature. If so, print it later.
if (i == prefixEndIndex - 1 &&
Node->getChild(i)->getKind()
== Node::Kind::DependentGenericSignature) {
optionalGenSig = Node->getChild(i);
break;
}
print(Node->getChild(i), depth + 1);
}
if (Options.ShortenThunk)
return nullptr;
Printer << " with respect to parameters ";
print(paramIndices, depth + 1);
Printer << " and results ";
print(resultIndices, depth + 1);
if (optionalGenSig && Options.DisplayWhereClauses) {
Printer << " with ";
print(optionalGenSig, depth + 1);
}
return nullptr;
}
case Node::Kind::AutoDiffSelfReorderingReabstractionThunk: {
Printer << "autodiff self-reordering reabstraction thunk ";
auto childIt = Node->begin();
auto fromType = *childIt++;
auto toType = *childIt++;
if (Options.ShortenThunk) {
Printer << "for ";
print(fromType, depth + 1);
return nullptr;
}
NodePointer optionalGenSig =
(*childIt)->getKind() == Node::Kind::DependentGenericSignature
? *childIt++ : nullptr;
Printer << "for ";
print(*childIt++, depth + 1); // kind
if (optionalGenSig) {
print(optionalGenSig, depth + 1);
Printer << ' ';
}
Printer << " from ";
print(fromType, depth + 1);
Printer << " to ";
print(toType, depth + 1);
return nullptr;
}
case Node::Kind::AutoDiffSubsetParametersThunk: {
Printer << "autodiff subset parameters thunk for ";
auto currentIndex = Node->getNumChildren() - 1;
auto toParamIndices = Node->getChild(currentIndex--);
auto resultIndices = Node->getChild(currentIndex--);
auto paramIndices = Node->getChild(currentIndex--);
auto kind = Node->getChild(currentIndex--);
print(kind, depth + 1);
Printer << " from ";
// Print the "from" thing.
if (currentIndex == 0) {
print(Node->getFirstChild(), depth + 1); // the "from" type
} else {
for (unsigned i = 0; i < currentIndex; ++i) // the "from" global
print(Node->getChild(i), depth + 1);
}
if (Options.ShortenThunk)
return nullptr;
Printer << " with respect to parameters ";
print(paramIndices, depth + 1);
Printer << " and results ";
print(resultIndices, depth + 1);
Printer << " to parameters ";
print(toParamIndices, depth + 1);
if (currentIndex > 0) {
Printer << " of type ";
print(Node->getChild(currentIndex), depth + 1); // "to" type
}
return nullptr;
}
case Node::Kind::AutoDiffFunctionKind: {
auto kind = (AutoDiffFunctionKind)Node->getIndex();
switch (kind) {
case AutoDiffFunctionKind::JVP:
Printer << "forward-mode derivative";
break;
case AutoDiffFunctionKind::VJP:
Printer << "reverse-mode derivative";
break;
case AutoDiffFunctionKind::Differential:
Printer << "differential";
break;
case AutoDiffFunctionKind::Pullback:
Printer << "pullback";
break;
}
return nullptr;
}
case Node::Kind::DifferentiabilityWitness: {
auto kindNodeIndex = Node->getNumChildren() - (
Node->getLastChild()->getKind() == Node::Kind::DependentGenericSignature
? 4 : 3);
auto kind =
(MangledDifferentiabilityKind)Node->getChild(kindNodeIndex)->getIndex();
switch (kind) {
case MangledDifferentiabilityKind::Forward:
Printer << "forward-mode";
break;
case MangledDifferentiabilityKind::Reverse:
Printer << "reverse-mode";
break;
case MangledDifferentiabilityKind::Normal:
Printer << "normal";
break;
case MangledDifferentiabilityKind::Linear:
Printer << "linear";
break;
case MangledDifferentiabilityKind::NonDifferentiable:
assert(false && "Impossible case");
}
Printer << " differentiability witness for ";
unsigned idx = 0;
for (auto numChildren = Node->getNumChildren();
idx < numChildren &&
Node->getChild(idx)->getKind() != Node::Kind::Index; ++idx)
print(Node->getChild(idx), depth + 1);
++idx; // kind (handled earlier)
Printer << " with respect to parameters ";
print(Node->getChild(idx++), depth + 1); // parameter indices
Printer << " and results ";
print(Node->getChild(idx++), depth + 1);
if (idx < Node->getNumChildren()) {
auto *genSig = Node->getChild(idx);
assert(genSig->getKind() == Node::Kind::DependentGenericSignature);
Printer << " with ";
print(genSig, depth + 1);
}
return nullptr;
}
case Node::Kind::IndexSubset: {
Printer << '{';
auto text = Node->getText();
bool printedAnyIndex = false;
for (unsigned i = 0, n = text.size(); i < n; ++i) {
if (text[i] != 'S') {
assert(text[i] == 'U');
continue;
}
if (printedAnyIndex)
Printer << ", ";
Printer << i;
printedAnyIndex = true;
}
Printer << '}';
return nullptr;
}
case Node::Kind::MergedFunction:
if (!Options.ShortenThunk) {
Printer << "merged ";
}
return nullptr;
case Node::Kind::TypeSymbolicReference:
Printer << "type symbolic reference 0x";
Printer.writeHex(Node->getIndex());
return nullptr;
case Node::Kind::OpaqueTypeDescriptorSymbolicReference:
Printer << "opaque type symbolic reference 0x";
Printer.writeHex(Node->getIndex());
return nullptr;
case Node::Kind::DistributedThunk:
if (!Options.ShortenThunk) {
Printer << "distributed thunk for ";
}
return nullptr;
case Node::Kind::DistributedAccessor:
if (!Options.ShortenThunk) {
Printer << "distributed accessor for ";
}
return nullptr;
case Node::Kind::AccessibleFunctionRecord:
if (!Options.ShortenThunk) {
Printer << "accessible function runtime record for ";
}
return nullptr;
case Node::Kind::DynamicallyReplaceableFunctionKey:
if (!Options.ShortenThunk) {
Printer << "dynamically replaceable key for ";
}
return nullptr;
case Node::Kind::DynamicallyReplaceableFunctionImpl:
if (!Options.ShortenThunk) {
Printer << "dynamically replaceable thunk for ";
}
return nullptr;
case Node::Kind::DynamicallyReplaceableFunctionVar:
if (!Options.ShortenThunk) {
Printer << "dynamically replaceable variable for ";
}
return nullptr;
case Node::Kind::ProtocolSymbolicReference:
Printer << "protocol symbolic reference 0x";
Printer.writeHex(Node->getIndex());
return nullptr;
case Node::Kind::GenericTypeMetadataPattern:
Printer << "generic type metadata pattern for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::Metaclass:
Printer << "metaclass for ";
print(Node->getFirstChild(), depth + 1);
return nullptr;
case Node::Kind::ProtocolSelfConformanceDescriptor:
Printer << "protocol self-conformance descriptor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ProtocolConformanceDescriptor:
Printer << "protocol conformance descriptor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ProtocolConformanceDescriptorRecord:
Printer << "protocol conformance descriptor runtime record for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ProtocolDescriptor:
Printer << "protocol descriptor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ProtocolDescriptorRecord:
Printer << "protocol descriptor runtime record for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ProtocolRequirementsBaseDescriptor:
Printer << "protocol requirements base descriptor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::FullTypeMetadata:
Printer << "full type metadata for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::TypeMetadata:
Printer << "type metadata for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::TypeMetadataAccessFunction:
Printer << "type metadata accessor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::TypeMetadataInstantiationCache:
Printer << "type metadata instantiation cache for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::TypeMetadataInstantiationFunction:
Printer << "type metadata instantiation function for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::TypeMetadataSingletonInitializationCache:
Printer << "type metadata singleton initialization cache for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::TypeMetadataCompletionFunction:
Printer << "type metadata completion function for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::TypeMetadataDemanglingCache:
Printer << "demangling cache variable for type metadata for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::TypeMetadataLazyCache:
Printer << "lazy cache variable for type metadata for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::AssociatedConformanceDescriptor:
Printer << "associated conformance descriptor for ";
print(Node->getChild(0), depth + 1);
Printer << ".";
print(Node->getChild(1), depth + 1);
Printer << ": ";
print(Node->getChild(2), depth + 1);
return nullptr;
case Node::Kind::DefaultAssociatedConformanceAccessor:
Printer << "default associated conformance accessor for ";
print(Node->getChild(0), depth + 1);
Printer << ".";
print(Node->getChild(1), depth + 1);
Printer << ": ";
print(Node->getChild(2), depth + 1);
return nullptr;
case Node::Kind::AssociatedTypeDescriptor:
Printer << "associated type descriptor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::AssociatedTypeMetadataAccessor:
Printer << "associated type metadata accessor for ";
print(Node->getChild(1), depth + 1);
Printer << " in ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::BaseConformanceDescriptor:
Printer << "base conformance descriptor for ";
print(Node->getChild(0), depth + 1);
Printer << ": ";
print(Node->getChild(1), depth + 1);
return nullptr;
case Node::Kind::DefaultAssociatedTypeMetadataAccessor:
Printer << "default associated type metadata accessor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::AssociatedTypeWitnessTableAccessor:
Printer << "associated type witness table accessor for ";
print(Node->getChild(1), depth + 1);
Printer << " : ";
print(Node->getChild(2), depth + 1);
Printer << " in ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::BaseWitnessTableAccessor:
Printer << "base witness table accessor for ";
print(Node->getChild(1), depth + 1);
Printer << " in ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ClassMetadataBaseOffset:
Printer << "class metadata base offset for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::PropertyDescriptor:
Printer << "property descriptor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::NominalTypeDescriptor:
Printer << "nominal type descriptor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::NominalTypeDescriptorRecord:
Printer << "nominal type descriptor runtime record for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OpaqueTypeDescriptor:
Printer << "opaque type descriptor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OpaqueTypeDescriptorRecord:
Printer << "opaque type descriptor runtime record for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OpaqueTypeDescriptorAccessor:
Printer << "opaque type descriptor accessor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OpaqueTypeDescriptorAccessorImpl:
Printer << "opaque type descriptor accessor impl for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OpaqueTypeDescriptorAccessorKey:
Printer << "opaque type descriptor accessor key for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::OpaqueTypeDescriptorAccessorVar:
Printer << "opaque type descriptor accessor var for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::CoroutineContinuationPrototype:
Printer << "coroutine continuation prototype for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ValueWitness:
Printer << toString(ValueWitnessKind(Node->getFirstChild()->getIndex()));
if (Options.ShortenValueWitness) Printer << " for ";
else Printer << " value witness for ";
print(Node->getChild(1), depth + 1);
return nullptr;
case Node::Kind::ValueWitnessTable:
Printer << "value witness table for ";
print(Node->getFirstChild(), depth + 1);
return nullptr;
case Node::Kind::BoundGenericClass:
case Node::Kind::BoundGenericStructure:
case Node::Kind::BoundGenericEnum:
case Node::Kind::BoundGenericProtocol:
case Node::Kind::BoundGenericOtherNominalType:
case Node::Kind::BoundGenericTypeAlias:
printBoundGeneric(Node, depth);
return nullptr;
case Node::Kind::DynamicSelf:
Printer << "Self";
return nullptr;
case Node::Kind::SILBoxType: {
Printer << "@box ";
NodePointer type = Node->getChild(0);
print(type, depth + 1);
return nullptr;
}
case Node::Kind::Metatype: {
unsigned Idx = 0;
if (Node->getNumChildren() == 2) {
NodePointer repr = Node->getChild(Idx);
print(repr, depth + 1);
Printer << " ";
++Idx;
}
NodePointer type = Node->getChild(Idx)->getChild(0);
printWithParens(type, depth);
if (isExistentialType(type)) {
Printer << ".Protocol";
} else {
Printer << ".Type";
}
return nullptr;
}
case Node::Kind::ExistentialMetatype: {
unsigned Idx = 0;
if (Node->getNumChildren() == 2) {
NodePointer repr = Node->getChild(Idx);
print(repr, depth + 1);
Printer << " ";
++Idx;
}
NodePointer type = Node->getChild(Idx);
print(type, depth + 1);
Printer << ".Type";
return nullptr;
}
case Node::Kind::MetatypeRepresentation: {
Printer << Node->getText();
return nullptr;
}
case Node::Kind::AssociatedTypeRef:
print(Node->getChild(0), depth + 1);
Printer << '.' << Node->getChild(1)->getText();
return nullptr;
case Node::Kind::ProtocolList: {
NodePointer type_list = Node->getChild(0);
if (!type_list)
return nullptr;
if (type_list->getNumChildren() == 0)
Printer << "Any";
else
printChildren(type_list, depth, " & ");
return nullptr;
}
case Node::Kind::ProtocolListWithClass: {
if (Node->getNumChildren() < 2)
return nullptr;
NodePointer protocols = Node->getChild(0);
NodePointer superclass = Node->getChild(1);
print(superclass, depth + 1);
Printer << " & ";
if (protocols->getNumChildren() < 1)
return nullptr;
NodePointer type_list = protocols->getChild(0);
printChildren(type_list, depth, " & ");
return nullptr;
}
case Node::Kind::ProtocolListWithAnyObject: {
if (Node->getNumChildren() < 1)
return nullptr;
NodePointer protocols = Node->getChild(0);
if (protocols->getNumChildren() < 1)
return nullptr;
NodePointer type_list = protocols->getChild(0);
if (type_list->getNumChildren() > 0) {
printChildren(type_list, depth, " & ");
Printer << " & ";
}
if (Options.QualifyEntities && Options.DisplayStdlibModule)
Printer << swift::STDLIB_NAME << ".";
Printer << "AnyObject";
return nullptr;
}
case Node::Kind::AssociatedType:
// Don't print for now.
return nullptr;
case Node::Kind::OwningAddressor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"owningAddressor");
case Node::Kind::OwningMutableAddressor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"owningMutableAddressor");
case Node::Kind::NativeOwningAddressor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"nativeOwningAddressor");
case Node::Kind::NativeOwningMutableAddressor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"nativeOwningMutableAddressor");
case Node::Kind::NativePinningAddressor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"nativePinningAddressor");
case Node::Kind::NativePinningMutableAddressor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"nativePinningMutableAddressor");
case Node::Kind::UnsafeAddressor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"unsafeAddressor");
case Node::Kind::UnsafeMutableAddressor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"unsafeMutableAddressor");
case Node::Kind::GlobalGetter:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"getter");
case Node::Kind::Getter:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"getter");
case Node::Kind::Setter:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"setter");
case Node::Kind::MaterializeForSet:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"materializeForSet");
case Node::Kind::WillSet:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"willset");
case Node::Kind::DidSet:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"didset");
case Node::Kind::ReadAccessor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"read");
case Node::Kind::ModifyAccessor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"modify");
case Node::Kind::Allocator:
return printEntity(
Node, depth, asPrefixContext, TypePrinting::FunctionStyle,
/*hasName*/ false,
isClassType(Node->getChild(0)) ? "__allocating_init" : "init");
case Node::Kind::Constructor:
return printEntity(Node, depth, asPrefixContext,
TypePrinting::FunctionStyle,
/*hasName*/ Node->getNumChildren() > 2, "init");
case Node::Kind::Destructor:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/ false, "deinit");
case Node::Kind::Deallocator:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/ false,
isClassType(Node->getChild(0)) ? "__deallocating_deinit"
: "deinit");
case Node::Kind::IVarInitializer:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/ false, "__ivar_initializer");
case Node::Kind::IVarDestroyer:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/ false, "__ivar_destroyer");
case Node::Kind::ProtocolConformance: {
NodePointer child0 = Node->getChild(0);
NodePointer child1 = Node->getChild(1);
NodePointer child2 = Node->getChild(2);
if (Node->getNumChildren() == 4) {
// TODO: check if this is correct
Printer << "property behavior storage of ";
print(child2, depth + 1);
Printer << " in ";
print(child0, depth + 1);
Printer << " : ";
print(child1, depth + 1);
} else {
print(child0, depth + 1);
if (Options.DisplayProtocolConformances) {
Printer << " : ";
print(child1, depth + 1);
Printer << " in ";
print(child2, depth + 1);
}
}
return nullptr;
}
case Node::Kind::TypeList:
printChildren(Node, depth);
return nullptr;
case Node::Kind::LabelList:
return nullptr;
case Node::Kind::ImplDifferentiabilityKind:
Printer << "@differentiable";
switch ((MangledDifferentiabilityKind)Node->getIndex()) {
case MangledDifferentiabilityKind::Normal:
break;
case MangledDifferentiabilityKind::Linear:
Printer << "(_linear)";
break;
case MangledDifferentiabilityKind::Forward:
Printer << "(_forward)";
break;
case MangledDifferentiabilityKind::Reverse:
Printer << "(reverse)";
break;
case MangledDifferentiabilityKind::NonDifferentiable:
assert(false && "Impossible case 'NonDifferentiable'");
}
return nullptr;
case Node::Kind::ImplEscaping:
Printer << "@escaping";
return nullptr;
case Node::Kind::ImplConvention:
Printer << Node->getText();
return nullptr;
case Node::Kind::ImplParameterResultDifferentiability:
// Skip if text is empty.
if (Node->getText().empty())
return nullptr;
// Otherwise, print with trailing space.
Printer << Node->getText() << ' ';
return nullptr;
case Node::Kind::ImplFunctionAttribute:
Printer << Node->getText();
return nullptr;
case Node::Kind::ImplFunctionConvention:
Printer << "@convention(";
switch (Node->getNumChildren()) {
case 1:
Printer << Node->getChild(0)->getText();
break;
case 2:
Printer << Node->getChild(0)->getText() << ", mangledCType: \"";
print(Node->getChild(1), depth + 1);
Printer << '"';
break;
default:
assert(false && "Unexpected numChildren for ImplFunctionConvention");
}
Printer << ')';
return nullptr;
case Node::Kind::ImplFunctionConventionName:
assert(false && "Already handled in ImplFunctionConvention");
return nullptr;
case Node::Kind::ImplErrorResult:
Printer << "@error ";
printChildren(Node, depth, " ");
return nullptr;
case Node::Kind::ImplYield:
Printer << "@yields ";
printChildren(Node, depth, " ");
return nullptr;
case Node::Kind::ImplParameter:
case Node::Kind::ImplResult:
// Children: `convention, differentiability?, type`
// Print convention.
print(Node->getChild(0), depth + 1);
Printer << " ";
// Print differentiability, if it exists.
if (Node->getNumChildren() == 3)
print(Node->getChild(1), depth + 1);
// Print type.
print(Node->getLastChild(), depth + 1);
return nullptr;
case Node::Kind::ImplFunctionType:
printImplFunctionType(Node, depth);
return nullptr;
case Node::Kind::ImplInvocationSubstitutions:
Printer << "for <";
printChildren(Node->getChild(0), depth, ", ");
Printer << '>';
return nullptr;
case Node::Kind::ImplPatternSubstitutions:
Printer << "@substituted ";
print(Node->getChild(0), depth + 1);
Printer << " for <";
printChildren(Node->getChild(1), depth, ", ");
Printer << '>';
return nullptr;
case Node::Kind::ErrorType:
Printer << "<ERROR TYPE>";
return nullptr;
case Node::Kind::DependentPseudogenericSignature:
case Node::Kind::DependentGenericSignature: {
Printer << '<';
unsigned depth = 0;
unsigned numChildren = Node->getNumChildren();
for (;
depth < numChildren
&& Node->getChild(depth)->getKind()
== Node::Kind::DependentGenericParamCount;
++depth) {
if (depth != 0)
Printer << "><";
unsigned count = Node->getChild(depth)->getIndex();
for (unsigned index = 0; index < count; ++index) {
if (index != 0)
Printer << ", ";
// Limit the number of printed generic parameters. In practice this
// it will never be exceeded. The limit is only imporant for malformed
// symbols where count can be really huge.
if (index >= 128) {
Printer << "...";
break;
}
// FIXME: Depth won't match when a generic signature applies to a
// method in generic type context.
Printer << Options.GenericParameterName(depth, index);
}
}
if (depth != numChildren) {
if (Options.DisplayWhereClauses) {
Printer << " where ";
for (unsigned i = depth; i < numChildren; ++i) {
if (i > depth)
Printer << ", ";
print(Node->getChild(i), depth + 1);
}
}
}
Printer << '>';
return nullptr;
}
case Node::Kind::DependentGenericParamCount:
printer_unreachable("should be printed as a child of a "
"DependentGenericSignature");
case Node::Kind::DependentGenericConformanceRequirement: {
NodePointer type = Node->getChild(0);
NodePointer reqt = Node->getChild(1);
print(type, depth + 1);
Printer << ": ";
print(reqt, depth + 1);
return nullptr;
}
case Node::Kind::DependentGenericLayoutRequirement: {
NodePointer type = Node->getChild(0);
NodePointer layout = Node->getChild(1);
print(type, depth + 1);
Printer << ": ";
assert(layout->getKind() == Node::Kind::Identifier);
assert(layout->getText().size() == 1);
char c = layout->getText()[0];
StringRef name;
if (c == 'U') {
name = "_UnknownLayout";
} else if (c == 'R') {
name = "_RefCountedObject";
} else if (c == 'N') {
name = "_NativeRefCountedObject";
} else if (c == 'C') {
name = "AnyObject";
} else if (c == 'D') {
name = "_NativeClass";
} else if (c == 'T') {
name = "_Trivial";
} else if (c == 'E' || c == 'e') {
name = "_Trivial";
} else if (c == 'M' || c == 'm') {
name = "_TrivialAtMost";
}
Printer << name;
if (Node->getNumChildren() > 2) {
Printer << "(";
print(Node->getChild(2), depth + 1);
if (Node->getNumChildren() > 3) {
Printer << ", ";
print(Node->getChild(3), depth + 1);
}
Printer << ")";
}
return nullptr;
}
case Node::Kind::DependentGenericSameTypeRequirement: {
NodePointer fst = Node->getChild(0);
NodePointer snd = Node->getChild(1);
print(fst, depth + 1);
Printer << " == ";
print(snd, depth + 1);
return nullptr;
}
case Node::Kind::DependentGenericParamType: {
unsigned index = Node->getChild(1)->getIndex();
unsigned depth = Node->getChild(0)->getIndex();
Printer << Options.GenericParameterName(depth, index);
return nullptr;
}
case Node::Kind::DependentGenericType: {
NodePointer sig = Node->getChild(0);
NodePointer depTy = Node->getChild(1);
print(sig, depth + 1);
if (needSpaceBeforeType(depTy))
Printer << ' ';
print(depTy, depth + 1);
return nullptr;
}
case Node::Kind::DependentMemberType: {
NodePointer base = Node->getChild(0);
print(base, depth + 1);
Printer << '.';
NodePointer assocTy = Node->getChild(1);
print(assocTy, depth + 1);
return nullptr;
}
case Node::Kind::DependentAssociatedTypeRef: {
if (Node->getNumChildren() > 1) {
print(Node->getChild(1), depth + 1);
Printer << '.';
}
print(Node->getChild(0), depth + 1);
return nullptr;
}
case Node::Kind::ReflectionMetadataBuiltinDescriptor:
Printer << "reflection metadata builtin descriptor ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ReflectionMetadataFieldDescriptor:
Printer << "reflection metadata field descriptor ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ReflectionMetadataAssocTypeDescriptor:
Printer << "reflection metadata associated type descriptor ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ReflectionMetadataSuperclassDescriptor:
Printer << "reflection metadata superclass descriptor ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ConcurrentFunctionType:
Printer << "@Sendable ";
return nullptr;
case Node::Kind::DifferentiableFunctionType: {
Printer << "@differentiable";
auto kind = (MangledDifferentiabilityKind)Node->getIndex();
switch (kind) {
case MangledDifferentiabilityKind::Forward:
Printer << "(_forward)";
break;
case MangledDifferentiabilityKind::Reverse:
Printer << "(reverse)";
break;
case MangledDifferentiabilityKind::Linear:
Printer << "(_linear)";
break;
case MangledDifferentiabilityKind::Normal:
break;
case MangledDifferentiabilityKind::NonDifferentiable:
assert(false && "Unexpected case NonDifferentiable");
}
Printer << ' ';
return nullptr;
}
case Node::Kind::GlobalActorFunctionType: {
if (Node->getNumChildren() > 0) {
Printer << '@';
print(Node->getChild(0), depth + 1);
Printer << ' ';
}
return nullptr;
}
case Node::Kind::AsyncAnnotation:
Printer << " async ";
return nullptr;
case Node::Kind::ThrowsAnnotation:
Printer << " throws ";
return nullptr;
case Node::Kind::EmptyList:
Printer << " empty-list ";
return nullptr;
case Node::Kind::FirstElementMarker:
Printer << " first-element-marker ";
return nullptr;
case Node::Kind::VariadicMarker:
Printer << " variadic-marker ";
return nullptr;
case Node::Kind::SILBoxTypeWithLayout: {
assert(Node->getNumChildren() == 1 || Node->getNumChildren() == 3);
NodePointer layout = Node->getChild(0);
assert(layout->getKind() == Node::Kind::SILBoxLayout);
NodePointer signature, genericArgs = nullptr;
if (Node->getNumChildren() == 3) {
signature = Node->getChild(1);
assert(signature->getKind() == Node::Kind::DependentGenericSignature);
genericArgs = Node->getChild(2);
assert(genericArgs->getKind() == Node::Kind::TypeList);
print(signature, depth + 1);
Printer << ' ';
}
print(layout, depth + 1);
if (genericArgs) {
Printer << " <";
for (unsigned i = 0, e = genericArgs->getNumChildren(); i < e; ++i) {
if (i > 0)
Printer << ", ";
print(genericArgs->getChild(i), depth + 1);
}
Printer << '>';
}
return nullptr;
}
case Node::Kind::SILBoxLayout:
Printer << '{';
for (unsigned i = 0; i < Node->getNumChildren(); ++i) {
if (i > 0)
Printer << ',';
Printer << ' ';
print(Node->getChild(i), depth + 1);
}
Printer << " }";
return nullptr;
case Node::Kind::SILBoxImmutableField:
case Node::Kind::SILBoxMutableField:
Printer << (Node->getKind() == Node::Kind::SILBoxImmutableField
? "let "
: "var ");
assert(Node->getNumChildren() == 1
&& Node->getChild(0)->getKind() == Node::Kind::Type);
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::AssocTypePath:
printChildren(Node->begin(), Node->end(), depth, ".");
return nullptr;
case Node::Kind::ModuleDescriptor:
Printer << "module descriptor ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::AnonymousDescriptor:
Printer << "anonymous descriptor ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::ExtensionDescriptor:
Printer << "extension descriptor ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::AssociatedTypeGenericParamRef:
Printer << "generic parameter reference for associated type ";
printChildren(Node, depth);
return nullptr;
case Node::Kind::AnyProtocolConformanceList:
printChildren(Node, depth);
return nullptr;
case Node::Kind::ConcreteProtocolConformance:
Printer << "concrete protocol conformance ";
if (Node->hasIndex())
Printer << "#" << Node->getIndex() << " ";
printChildren(Node, depth);
return nullptr;
case Node::Kind::DependentAssociatedConformance:
Printer << "dependent associated conformance ";
printChildren(Node, depth);
return nullptr;
case Node::Kind::DependentProtocolConformanceAssociated:
Printer << "dependent associated protocol conformance ";
printOptionalIndex(Node->getChild(2));
print(Node->getChild(0), depth + 1);
print(Node->getChild(1), depth + 1);
return nullptr;
case Node::Kind::DependentProtocolConformanceInherited:
Printer << "dependent inherited protocol conformance ";
printOptionalIndex(Node->getChild(2));
print(Node->getChild(0), depth + 1);
print(Node->getChild(1), depth + 1);
return nullptr;
case Node::Kind::DependentProtocolConformanceRoot:
Printer << "dependent root protocol conformance ";
printOptionalIndex(Node->getChild(2));
print(Node->getChild(0), depth + 1);
print(Node->getChild(1), depth + 1);
return nullptr;
case Node::Kind::ProtocolConformanceRefInTypeModule:
Printer << "protocol conformance ref (type's module) ";
printChildren(Node, depth);
return nullptr;
case Node::Kind::ProtocolConformanceRefInProtocolModule:
Printer << "protocol conformance ref (protocol's module) ";
printChildren(Node, depth);
return nullptr;
case Node::Kind::ProtocolConformanceRefInOtherModule:
Printer << "protocol conformance ref (retroactive) ";
printChildren(Node, depth);
return nullptr;
case Node::Kind::SugaredOptional:
printWithParens(Node->getChild(0), depth);
Printer << "?";
return nullptr;
case Node::Kind::SugaredArray:
Printer << "[";
print(Node->getChild(0), depth + 1);
Printer << "]";
return nullptr;
case Node::Kind::SugaredDictionary:
Printer << "[";
print(Node->getChild(0), depth + 1);
Printer << " : ";
print(Node->getChild(1), depth + 1);
Printer << "]";
return nullptr;
case Node::Kind::SugaredParen:
Printer << "(";
print(Node->getChild(0), depth + 1);
Printer << ")";
return nullptr;
case Node::Kind::OpaqueReturnType:
case Node::Kind::OpaqueReturnTypeIndexed:
Printer << "some";
return nullptr;
case Node::Kind::OpaqueReturnTypeOf:
Printer << "<<opaque return type of ";
printChildren(Node, depth);
Printer << ">>";
return nullptr;
case Node::Kind::OpaqueType:
print(Node->getChild(0), depth + 1);
Printer << '.';
print(Node->getChild(1), depth + 1);
return nullptr;
case Node::Kind::AccessorFunctionReference:
Printer << "accessor function at " << Node->getIndex();
return nullptr;
case Node::Kind::CanonicalSpecializedGenericMetaclass:
Printer << "specialized generic metaclass for ";
print(Node->getFirstChild(), depth + 1);
return nullptr;
case Node::Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction:
Printer << "canonical specialized generic type metadata accessor for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::MetadataInstantiationCache:
Printer << "metadata instantiation cache for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::NoncanonicalSpecializedGenericTypeMetadata:
Printer << "noncanonical specialized generic type metadata for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::NoncanonicalSpecializedGenericTypeMetadataCache:
Printer << "cache variable for noncanonical specialized generic type metadata for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::GlobalVariableOnceToken:
case Node::Kind::GlobalVariableOnceFunction:
Printer << (kind == Node::Kind::GlobalVariableOnceToken
? "one-time initialization token for "
: "one-time initialization function for ");
printContext(Node->getChild(0));
print(Node->getChild(1), depth + 1);
return nullptr;
case Node::Kind::GlobalVariableOnceDeclList:
if (Node->getNumChildren() == 1) {
print(Node->getChild(0), depth + 1);
} else {
Printer << '(';
for (unsigned i = 0, e = Node->getNumChildren(); i < e; ++i) {
if (i != 0) {
Printer << ", ";
}
print(Node->getChild(i), depth + 1);
}
Printer << ')';
}
return nullptr;
case Node::Kind::PredefinedObjCAsyncCompletionHandlerImpl:
Printer << "predefined ";
LLVM_FALLTHROUGH;
case Node::Kind::ObjCAsyncCompletionHandlerImpl:
Printer << "@objc completion handler block implementation for ";
if (Node->getNumChildren() >= 4)
print(Node->getChild(3), depth + 1);
print(Node->getChild(0), depth + 1);
Printer << " with result type ";
print(Node->getChild(1), depth + 1);
switch (Node->getChild(2)->getIndex()) {
case 0:
break;
case 1:
Printer << " nonzero on error";
break;
case 2:
Printer << " zero on error";
break;
default:
Printer << " <invalid error flag>";
break;
}
return nullptr;
case Node::Kind::CanonicalPrespecializedGenericTypeCachingOnceToken:
Printer << "flag for loading of canonical specialized generic type "
"metadata for ";
print(Node->getChild(0), depth + 1);
return nullptr;
case Node::Kind::AsyncFunctionPointer:
Printer << "async function pointer to ";
return nullptr;
case Node::Kind::AsyncAwaitResumePartialFunction:
if (Options.ShowAsyncResumePartial) {
Printer << "(";
print(Node->getChild(0), depth + 1);
Printer << ")";
Printer << " await resume partial function for ";
}
return nullptr;
case Node::Kind::AsyncSuspendResumePartialFunction:
if (Options.ShowAsyncResumePartial) {
Printer << "(";
print(Node->getChild(0), depth + 1);
Printer << ")";
Printer << " suspend resume partial function for ";
}
return nullptr;
}
printer_unreachable("bad node kind!");
}