diff --git a/CHANGELOG.md b/CHANGELOG.md
index f2b56647c..c9ac1b4cf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## Unreleased
+
+**Features**
+
+- Updated libswift demangle to v6.1.0. ([#913](https://github.com/getsentry/symbolic/pull/913))
+
## 12.15.3
**Features**
diff --git a/symbolic-demangle/tests/test_swift.rs b/symbolic-demangle/tests/test_swift.rs
index 0e58568f8..47709a0ee 100644
--- a/symbolic-demangle/tests/test_swift.rs
+++ b/symbolic-demangle/tests/test_swift.rs
@@ -295,5 +295,8 @@ fn test_demangle_swift_no_args() {
// Swift 6.0.3
"$ss27withTaskCancellationHandler9operation8onCancel9isolationxxyYaKXE_yyYbXEScA_pSgYitYaKlFTwb" => "withTaskCancellationHandler",
"$s11Supercharge2AXO7ElementPAAE8elements33_35EDDAA799FBB5B74D2F426690B0D99DLL3for2asSayqd__GSo28NSAccessibilityAttributeNamea_qd__mtSo7AXErrorVYKAcDRd__lFAC3AppC_AC6WindowCTgm5" => "specialized AX.Element.elements",
+
+ // Swift 6.1.0
+ "$sTB" => "$sTB",
});
}
diff --git a/symbolic-demangle/vendor/swift/1-arguments.patch b/symbolic-demangle/vendor/swift/1-arguments.patch
index 2d5340b27..b5b3df924 100644
--- a/symbolic-demangle/vendor/swift/1-arguments.patch
+++ b/symbolic-demangle/vendor/swift/1-arguments.patch
@@ -1,11 +1,11 @@
-commit 80e772078494a73f2fbb5e385de2092e6057d913
-Author: David Herberth
-Date: Thu Jan 9 10:54:28 2025 +0100
+commit 688c78af45dc197ce0ef8a0ea520d77592905394
+Author: Sebastian Zivota
+Date: Wed Apr 16 18:43:43 2025 +0200
- apply patch
+ Apply patch
diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h
-index f66dd7fd..940c3652 100644
+index 3e029a9b..da18a09a 100644
--- a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h
+++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h
@@ -58,6 +58,7 @@ struct DemangleOptions {
@@ -25,10 +25,10 @@ index f66dd7fd..940c3652 100644
return Opt;
};
diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp
-index 6c309bbf..5b251e8d 100644
+index d9098192..5e8ae258 100644
--- a/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp
+++ b/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp
-@@ -955,10 +955,11 @@ private:
+@@ -966,10 +966,11 @@ private:
if (isSendable)
Printer << "@Sendable ";
diff --git a/symbolic-demangle/vendor/swift/README.md b/symbolic-demangle/vendor/swift/README.md
index 4bd7fddaf..e536fc9e2 100644
--- a/symbolic-demangle/vendor/swift/README.md
+++ b/symbolic-demangle/vendor/swift/README.md
@@ -3,7 +3,7 @@
This folder contains a vendored subset of the [Swift Programming Language]. The Swift library is
reduced to the demangler only to reduce the size of this package.
-The current version is **Swift 5.5.1**.
+The current version is **Swift 6.1.0**.
## Sentry Modifications
@@ -28,7 +28,7 @@ patch is maintained in `1-arguments.patch`.
4. Check out the release branch of the latest release:
```
$ cd swift
- $ git checkout swift-5.5.1-RELEASE
+ $ git checkout swift-x.x.x-RELEASE
```
5. Build the complete swift project (be very patient, this may take long):
```
@@ -40,14 +40,16 @@ patch is maintained in `1-arguments.patch`.
$ ./update.py swift-source
```
2. Check for modifications.
- 3. Commit _"feat(demangle): Import libswift demangle x.x.x"_ before proceeding.
+ 3. **BUG**: If the file `./include/swift/ABI/InvertibleProtocols.def` is not automatically
+ copied, copy it manually from `swift-source/swift/include/swift/ABI/InvertibleProtocols.def`.
+ 4. Commit _"feat(demangle): Import libswift demangle x.x.x"_ before proceeding.
3. **Apply the patch:**
1. Apply `1-arguments.patch`.
2. Build the Rust library and ensure tests work.
3. Commit the changes.
4. **Add tests for new mangling schemes:**
1. Identify new mangling schemes. Skip if there are no known changes.
- 2. Add test cases to `tests/swift.rs`
+ 2. Add test cases to `tests/test_swift.rs`
5. **Update Repository metadata**:
1. Bump the Swift version number in this README.
2. Check for changes in the license and update the files.
diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h
index 940c36520..da18a09a2 100644
--- a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h
+++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h
@@ -138,7 +138,11 @@ enum class MangledDifferentiabilityKind : char {
Linear = 'l',
};
-enum class MangledLifetimeDependenceKind : char { Inherit = 'i', Scope = 's' };
+enum class MangledSILThunkKind : char {
+ Invalid = 0,
+ Identity = 'I',
+ HopToMainActorIfNeeded = 'H',
+};
/// The pass that caused the specialization to occur. We use this to make sure
/// that two passes that generate similar changes do not yield the same
@@ -247,6 +251,25 @@ class Node {
}
}
+ static bool deepEquals(const Node *lhs, const Node *rhs) {
+ if (lhs == rhs)
+ return true;
+ if ((!lhs && rhs) || (lhs && !rhs))
+ return false;
+ if (!lhs->isSimilarTo(rhs))
+ return false;
+ for (auto li = lhs->begin(), ri = rhs->begin(), le = lhs->end(); li != le;
+ ++li, ++ri) {
+ if (!deepEquals(*li, *ri))
+ return false;
+ }
+ return true;
+ }
+
+ bool isDeepEqualTo(const Node *other) const {
+ return deepEquals(this, other);
+ }
+
bool hasText() const { return NodePayloadKind == PayloadKind::Text; }
llvm::StringRef getText() const {
assert(hasText());
@@ -601,6 +624,7 @@ struct [[nodiscard]] ManglingError {
UnknownEncoding,
InvalidImplCalleeConvention,
InvalidImplDifferentiability,
+ InvalidImplCoroutineKind,
InvalidImplFunctionAttribute,
InvalidImplParameterConvention,
InvalidImplParameterSending,
diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/DemangleNodes.def b/symbolic-demangle/vendor/swift/include/swift/Demangling/DemangleNodes.def
index c872f1be9..201b770b0 100644
--- a/symbolic-demangle/vendor/swift/include/swift/Demangling/DemangleNodes.def
+++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/DemangleNodes.def
@@ -46,6 +46,7 @@ NODE(BoundGenericTypeAlias)
NODE(BoundGenericFunction)
NODE(BuiltinTypeName)
NODE(BuiltinTupleType)
+NODE(BuiltinFixedArray)
NODE(CFunctionPointer)
NODE(ClangType)
CONTEXT_NODE(Class)
@@ -140,6 +141,7 @@ NODE(ImplFunctionAttribute)
NODE(ImplFunctionConvention)
NODE(ImplFunctionConventionName)
NODE(ImplFunctionType)
+NODE(ImplCoroutineKind)
NODE(ImplInvocationSubstitutions)
CONTEXT_NODE(ImplicitClosure)
NODE(ImplParameter)
@@ -152,6 +154,7 @@ NODE(InfixOperator)
CONTEXT_NODE(Initializer)
CONTEXT_NODE(InitAccessor)
NODE(Isolated)
+CONTEXT_NODE(IsolatedDeallocator)
NODE(Sending)
NODE(IsolatedAnyFunctionType)
NODE(SendingResultFunctionType)
@@ -177,6 +180,7 @@ NODE(ObjCMetadataUpdateFunction)
NODE(ObjCResilientClassStub)
NODE(FullObjCResilientClassStub)
CONTEXT_NODE(ModifyAccessor)
+CONTEXT_NODE(Modify2Accessor)
CONTEXT_NODE(Module)
CONTEXT_NODE(NativeOwningAddressor)
CONTEXT_NODE(NativeOwningMutableAddressor)
@@ -229,6 +233,7 @@ NODE(ReabstractionThunkHelper)
NODE(ReabstractionThunkHelperWithSelf)
NODE(ReabstractionThunkHelperWithGlobalActor)
CONTEXT_NODE(ReadAccessor)
+CONTEXT_NODE(Read2Accessor)
NODE(RelatedEntityDeclName)
NODE(RetroactiveConformance)
NODE(ReturnType)
@@ -287,6 +292,8 @@ NODE(ReflectionMetadataAssocTypeDescriptor)
NODE(ReflectionMetadataSuperclassDescriptor)
NODE(GenericTypeParamDecl)
NODE(CurryThunk)
+NODE(SILThunkIdentity)
+NODE(SILThunkHopToMainActorIfNeeded)
NODE(DispatchThunk)
NODE(MethodDescriptor)
NODE(ProtocolRequirementsBaseDescriptor)
@@ -321,7 +328,7 @@ NODE(AssociatedTypeGenericParamRef)
NODE(SugaredOptional)
NODE(SugaredArray)
NODE(SugaredDictionary)
-NODE(SugaredParen)
+NODE(SugaredParen) // Removed in Swift 6.TBD
// Added in Swift 5.1
NODE(AccessorFunctionReference)
@@ -374,7 +381,7 @@ NODE(NonUniqueExtendedExistentialTypeShapeSymbolicReference)
NODE(SymbolicExtendedExistentialType)
// Added in Swift 5.8
-NODE(MetatypeParamsRemoved)
+NODE(DroppedArgument)
NODE(HasSymbolQuery)
NODE(OpaqueReturnTypeIndex)
NODE(OpaqueReturnTypeParent)
@@ -388,8 +395,6 @@ NODE(AsyncRemoved)
// Added in Swift 5.TBD
NODE(ObjectiveCProtocolSymbolicReference)
-NODE(ParamLifetimeDependence)
-NODE(SelfLifetimeDependence)
NODE(OutlinedInitializeWithCopyNoValueWitness)
NODE(OutlinedAssignWithTakeNoValueWitness)
@@ -398,5 +403,10 @@ NODE(OutlinedDestroyNoValueWitness)
NODE(DependentGenericInverseConformanceRequirement)
+// Added in Swift 6.TBD
+NODE(Integer)
+NODE(NegativeInteger)
+NODE(DependentGenericParamValueMarker)
+
#undef CONTEXT_NODE
#undef NODE
diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangler.h b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangler.h
index a3b62f2c0..e6d76bccf 100644
--- a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangler.h
+++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangler.h
@@ -44,14 +44,14 @@ class NodeFactory {
/// The end of the current slab.
char *End = nullptr;
- struct Slab {
+ struct AllocatedSlab {
// The previously allocated slab.
- Slab *Previous;
+ AllocatedSlab *Previous;
// Tail allocated memory starts here.
};
/// The head of the single-linked slab list.
- Slab *CurrentSlab = nullptr;
+ AllocatedSlab *CurrentSlab = nullptr;
/// The size of the previously allocated slab. This may NOT be the size of
/// CurrentSlab, in the case where a checkpoint has been popped.
@@ -66,7 +66,7 @@ class NodeFactory {
& ~((uintptr_t)Alignment - 1));
}
- static void freeSlabs(Slab *slab);
+ static void freeSlabs(AllocatedSlab *slab);
/// If not null, the NodeFactory from which this factory borrowed free memory.
NodeFactory *BorrowedFrom = nullptr;
@@ -149,8 +149,8 @@ class NodeFactory {
// No. We have to malloc a new slab.
// We double the slab size for each allocated slab.
SlabSize = std::max(SlabSize * 2, ObjectSize + alignof(T));
- size_t AllocSize = sizeof(Slab) + SlabSize;
- Slab *newSlab = (Slab *)malloc(AllocSize);
+ size_t AllocSize = sizeof(AllocatedSlab) + SlabSize;
+ AllocatedSlab *newSlab = (AllocatedSlab *)malloc(AllocSize);
// Insert the new slab in the single-linked list of slabs.
newSlab->Previous = CurrentSlab;
@@ -225,7 +225,7 @@ class NodeFactory {
/// A checkpoint which captures the allocator's state at any given time. A
/// checkpoint can be popped to free all allocations made since it was made.
struct Checkpoint {
- Slab *Slab;
+ AllocatedSlab *Slab;
char *CurPtr;
char *End;
};
@@ -594,7 +594,9 @@ class Demangler : public NodeFactory {
NodePointer popDependentAssociatedConformance();
NodePointer demangleDependentProtocolConformanceAssociated();
NodePointer demangleThunkOrSpecialization();
- NodePointer demangleGenericSpecialization(Node::Kind SpecKind);
+ NodePointer demangleGenericSpecialization(Node::Kind SpecKind,
+ NodePointer droppedArguments);
+ NodePointer demangleGenericSpecializationWithDroppedArguments();
NodePointer demangleFunctionSpecialization();
NodePointer demangleFuncSpecParam(Node::Kind Kind);
NodePointer addFuncSpecParamNumber(NodePointer Param,
@@ -635,7 +637,7 @@ class Demangler : public NodeFactory {
bool demangleBoundGenerics(Vector &TypeListList,
NodePointer &RetroactiveConformances);
- NodePointer demangleLifetimeDependenceKind(bool isSelfDependence);
+ NodePointer demangleIntegerType();
void dump();
diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingMacros.h b/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingMacros.h
index 5cf386314..c93f4508e 100644
--- a/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingMacros.h
+++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingMacros.h
@@ -17,12 +17,12 @@
#define MANGLE_AS_STRING(M) STRINGIFY_MANGLING(M)
/// The mangling prefix for the new mangling.
-#if !defined(_MSC_VER) || _MSC_VER-0 >= 1926
+#if defined(__clang__)
_Pragma("clang diagnostic push")
_Pragma("clang diagnostic ignored \"-Wdollar-in-identifier-extension\"")
#endif
#define MANGLING_PREFIX $s
-#if !defined(_MSC_VER) || _MSC_VER-0 >= 1926
+#if defined(__clang__)
_Pragma("clang diagnostic pop")
#endif
diff --git a/symbolic-demangle/vendor/swift/include/swift/Strings.h b/symbolic-demangle/vendor/swift/include/swift/Strings.h
index 8538e6931..be4791f9a 100644
--- a/symbolic-demangle/vendor/swift/include/swift/Strings.h
+++ b/symbolic-demangle/vendor/swift/include/swift/Strings.h
@@ -85,6 +85,10 @@ constexpr static const StringLiteral CLANG_MODULE_DEFAULT_SPI_GROUP_NAME =
constexpr static const StringLiteral SPI_AVAILABLE_ATTRNAME =
"_spi_available";
+/// The attribute name for @_unavailableInEmbedded
+constexpr static const StringLiteral UNAVAILABLE_IN_EMBEDDED_ATTRNAME =
+ "_unavailableInEmbedded";
+
/// A composition class containing a StringLiteral for the names of
/// Swift builtins. The reason we use this is to ensure that we when
/// necessary slice off the "Builtin." prefix from these names in a
@@ -172,6 +176,8 @@ constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_UNKNOWNOBJECT = {
/// The name of the Builtin type for Vector
constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_VEC = {
"Builtin.Vec"};
+constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_FIXEDARRAY = {
+ "Builtin.FixedArray"};
/// The name of the Builtin type for SILToken
constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_SILTOKEN = {
"Builtin.SILToken"};
diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/Context.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/Context.cpp
index 69f366140..c762ea193 100644
--- a/symbolic-demangle/vendor/swift/lib/Demangling/Context.cpp
+++ b/symbolic-demangle/vendor/swift/lib/Demangling/Context.cpp
@@ -70,7 +70,7 @@ std::string Context::demangleTypeAsString(llvm::StringRef MangledName,
const DemangleOptions &Options) {
NodePointer root = demangleTypeAsNode(MangledName);
if (!root) return MangledName.str();
-
+
std::string demangling = nodeToString(root, Options);
if (demangling.empty())
return MangledName.str();
diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp
index 704fbcadb..d2b5d4682 100644
--- a/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp
+++ b/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp
@@ -80,6 +80,7 @@ static bool isEntity(Node::Kind kind) {
static bool isRequirement(Node::Kind kind) {
switch (kind) {
case Node::Kind::DependentGenericParamPackMarker:
+ case Node::Kind::DependentGenericParamValueMarker:
case Node::Kind::DependentGenericSameTypeRequirement:
case Node::Kind::DependentGenericSameShapeRequirement:
case Node::Kind::DependentGenericLayoutRequirement:
@@ -223,6 +224,8 @@ llvm::StringRef swift::Demangle::dropSwiftManglingPrefix(StringRef mangledName){
}
static bool isAliasNode(Demangle::NodePointer Node) {
+ if (!Node)
+ return false;
switch (Node->getKind()) {
case Demangle::Node::Kind::Type:
return isAliasNode(Node->getChild(0));
@@ -240,6 +243,8 @@ bool swift::Demangle::isAlias(llvm::StringRef mangledName) {
}
static bool isClassNode(Demangle::NodePointer Node) {
+ if (!Node)
+ return false;
switch (Node->getKind()) {
case Demangle::Node::Kind::Type:
return isClassNode(Node->getChild(0));
@@ -258,6 +263,8 @@ bool swift::Demangle::isClass(llvm::StringRef mangledName) {
}
static bool isEnumNode(Demangle::NodePointer Node) {
+ if (!Node)
+ return false;
switch (Node->getKind()) {
case Demangle::Node::Kind::Type:
return isEnumNode(Node->getChild(0));
@@ -276,6 +283,8 @@ bool swift::Demangle::isEnum(llvm::StringRef mangledName) {
}
static bool isProtocolNode(Demangle::NodePointer Node) {
+ if (!Node)
+ return false;
switch (Node->getKind()) {
case Demangle::Node::Kind::Type:
return isProtocolNode(Node->getChild(0));
@@ -295,6 +304,8 @@ bool swift::Demangle::isProtocol(llvm::StringRef mangledName) {
}
static bool isStructNode(Demangle::NodePointer Node) {
+ if (!Node)
+ return false;
switch (Node->getKind()) {
case Demangle::Node::Kind::Type:
return isStructNode(Node->getChild(0));
@@ -470,9 +481,9 @@ Node* Node::findByKind(Node::Kind kind, int maxDepth) {
// NodeFactory member functions //
//////////////////////////////////
-void NodeFactory::freeSlabs(Slab *slab) {
+void NodeFactory::freeSlabs(AllocatedSlab *slab) {
while (slab) {
- Slab *prev = slab->Previous;
+ AllocatedSlab *prev = slab->Previous;
free(slab);
slab = prev;
}
@@ -532,7 +543,7 @@ void NodeFactory::popCheckpoint(NodeFactory::Checkpoint checkpoint) {
// checkpoint's slab is less than 1/16th of the current slab's space. We
// won't repeatedly allocate and deallocate the current slab. The size
// doubles each time so we'll quickly pass the threshold.
- Slab *savedSlab = nullptr;
+ AllocatedSlab *savedSlab = nullptr;
if (CurrentSlab) {
size_t checkpointSlabFreeSpace = checkpoint.End - checkpoint.CurPtr;
size_t currentSlabSize = End - (char *)(CurrentSlab + 1);
@@ -746,6 +757,8 @@ NodePointer Demangler::demangleSymbol(StringRef MangledName,
NodePointer topLevel = createNode(Node::Kind::Global);
+ NodePointer suffix = popNode(Node::Kind::Suffix);
+
NodePointer Parent = topLevel;
while (NodePointer FuncAttr = popNode(isFunctionAttr)) {
Parent->addChild(FuncAttr, *this);
@@ -763,6 +776,9 @@ NodePointer Demangler::demangleSymbol(StringRef MangledName,
break;
}
}
+ if (suffix)
+ topLevel->addChild(suffix, *this);
+
if (topLevel->getNumChildren() == 0)
return nullptr;
@@ -773,17 +789,27 @@ NodePointer Demangler::demangleType(StringRef MangledName,
std::function Resolver) {
DemangleInitRAII state(*this, MangledName, std::move(Resolver));
- parseAndPushNodes();
+ if (!parseAndPushNodes())
+ return nullptr;
- if (NodePointer Result = popNode())
- return Result;
+ NodePointer Result = popNode();
- return createNode(Node::Kind::Suffix, Text);
+ // The result is only valid if it was the only node on the stack.
+ if (popNode())
+ return nullptr;
+
+ return Result;
}
bool Demangler::parseAndPushNodes() {
const auto textSize = Text.size();
while (Pos < textSize) {
+ // Programs may look up a type by NUL-terminated name with an excessive
+ // length. Keep them working by returning success if we encounter a NUL in
+ // the middle of the string where an operator is expected.
+ if (peekChar() == '\0')
+ return true;
+
NodePointer Node = demangleOperator();
if (!Node)
return false;
@@ -947,7 +973,7 @@ NodePointer Demangler::demangleSymbolicReference(unsigned char rawKind) {
}
NodePointer Demangler::demangleTypeAnnotation() {
- switch (char c2 = nextChar()) {
+ switch (nextChar()) {
case 'a':
return createNode(Node::Kind::AsyncAnnotation);
case 'A':
@@ -975,10 +1001,6 @@ NodePointer Demangler::demangleTypeAnnotation() {
case 'u':
return createType(
createWithChild(Node::Kind::Sending, popTypeAndGetChild()));
- case 'l':
- return demangleLifetimeDependenceKind(/*isSelfDependence*/ false);
- case 'L':
- return demangleLifetimeDependenceKind(/*isSelfDependence*/ true);
default:
return nullptr;
}
@@ -1003,7 +1025,7 @@ NodePointer Demangler::demangleOperator() {
case 'F': return demanglePlainFunction();
case 'G': return demangleBoundGenericType();
case 'H':
- switch (char c2 = nextChar()) {
+ switch (nextChar()) {
case 'A': return demangleDependentProtocolConformanceAssociated();
case 'C': return demangleConcreteProtocolConformance();
case 'D': return demangleDependentProtocolConformanceRoot();
@@ -1085,6 +1107,7 @@ NodePointer Demangler::demangleOperator() {
// outlined copy functions. We treat such a suffix as "unmangled suffix".
pushBack();
return createNode(Node::Kind::Suffix, consumeAll());
+ case '$': return demangleIntegerType();
default:
pushBack();
return demangleIdentifier();
@@ -1184,7 +1207,7 @@ NodePointer Demangler::createSwiftType(Node::Kind typeKind, const char *name) {
}
NodePointer Demangler::demangleStandardSubstitution() {
- switch (char c = nextChar()) {
+ switch (nextChar()) {
case 'o':
return createNode(Node::Kind::Module, MANGLING_MODULE_OBJC);
case 'C':
@@ -1452,6 +1475,18 @@ NodePointer Demangler::demangleBuiltinType() {
Ty = createNode(Node::Kind::BuiltinTypeName, name);
break;
}
+ case 'V': {
+ NodePointer element = popNode(Node::Kind::Type);
+ if (!element)
+ return nullptr;
+ NodePointer size = popNode(Node::Kind::Type);
+ if (!size)
+ return nullptr;
+ Ty = createNode(Node::Kind::BuiltinFixedArray);
+ Ty->addChild(size, *this);
+ Ty->addChild(element, *this);
+ break;
+ }
case 'O':
Ty = createNode(Node::Kind::BuiltinTypeName,
BUILTIN_TYPE_NAME_UNKNOWNOBJECT);
@@ -1520,34 +1555,53 @@ NodePointer Demangler::demangleExtensionContext() {
/// Associate any \c OpaqueReturnType nodes with the declaration whose opaque
/// return type they refer back to.
-static Node *setParentForOpaqueReturnTypeNodes(Demangler &D,
- Node *parent,
- Node *visitedNode) {
- if (!parent || !visitedNode)
- return nullptr;
- if (visitedNode->getKind() == Node::Kind::OpaqueReturnType) {
+/// Implementation for \c setParentForOpaqueReturnTypeNodes. Don't invoke
+/// directly.
+static void setParentForOpaqueReturnTypeNodesImpl(
+ Demangler &D, Node &visitedNode,
+ llvm::function_ref getParentID) {
+ if (visitedNode.getKind() == Node::Kind::OpaqueReturnType) {
// If this node is not already parented, parent it.
- if (visitedNode->hasChildren()
- && visitedNode->getLastChild()->getKind() == Node::Kind::OpaqueReturnTypeParent) {
- return parent;
+ if (visitedNode.hasChildren() && visitedNode.getLastChild()->getKind() ==
+ Node::Kind::OpaqueReturnTypeParent) {
+ return;
}
- visitedNode->addChild(D.createNode(Node::Kind::OpaqueReturnTypeParent,
- (Node::IndexType)parent), D);
- return parent;
+ visitedNode.addChild(D.createNode(Node::Kind::OpaqueReturnTypeParent,
+ StringRef(getParentID())),
+ D);
+ return;
}
-
+
// If this node is one that may in turn define its own opaque return type,
// stop recursion, since any opaque return type nodes underneath would refer
// to the nested declaration rather than the one we're looking at.
- if (visitedNode->getKind() == Node::Kind::Function
- || visitedNode->getKind() == Node::Kind::Variable
- || visitedNode->getKind() == Node::Kind::Subscript) {
- return parent;
+ if (visitedNode.getKind() == Node::Kind::Function ||
+ visitedNode.getKind() == Node::Kind::Variable ||
+ visitedNode.getKind() == Node::Kind::Subscript) {
+ return;
}
-
- for (size_t i = 0, e = visitedNode->getNumChildren(); i < e; ++i) {
- setParentForOpaqueReturnTypeNodes(D, parent, visitedNode->getChild(i));
+
+ for (Node *child : visitedNode) {
+ assert(child);
+ setParentForOpaqueReturnTypeNodesImpl(D, *child, getParentID);
}
+}
+
+/// Associate any \c OpaqueReturnType nodes with the declaration whose opaque
+/// return type they refer back to.
+static Node *setParentForOpaqueReturnTypeNodes(Demangler &D, Node *parent,
+ Node *visitedNode) {
+ if (!parent || !visitedNode)
+ return nullptr;
+ std::string parentID;
+ setParentForOpaqueReturnTypeNodesImpl(D, *visitedNode, [&] {
+ if (!parentID.empty())
+ return StringRef(parentID);
+ const auto mangleResult = mangleNode(parent);
+ assert(mangleResult.isSuccess());
+ parentID = mangleResult.result();
+ return StringRef(parentID);
+ });
return parent;
}
@@ -1574,25 +1628,51 @@ NodePointer Demangler::demanglePlainFunction() {
NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) {
NodePointer FuncType = createNode(kind);
+
+ // Demangle a C function type if the function node kind says that
+ // one follows.
NodePointer ClangType = nullptr;
if (hasClangType) {
ClangType = demangleClangType();
}
addChild(FuncType, ClangType);
- addChild(FuncType, popNode(Node::Kind::SelfLifetimeDependence));
- addChild(FuncType, popNode(Node::Kind::GlobalActorFunctionType));
- addChild(FuncType, popNode(Node::Kind::IsolatedAnyFunctionType));
+
+ // The components of function-signature. Note that these need to be
+ // popped in the reverse of the order they're mangled. If you add a
+ // new component, be sure to add a demangling test case for combinations
+ // of specifiers.
+
+ // sending-result?
addChild(FuncType, popNode(Node::Kind::SendingResultFunctionType));
+
+ // function-isolation?
+ auto isFunctionIsolation = [](Node::Kind kind) {
+ return kind == Node::Kind::GlobalActorFunctionType ||
+ kind == Node::Kind::IsolatedAnyFunctionType;
+ };
+ addChild(FuncType, popNode(isFunctionIsolation));
+
+ // differentiable?
addChild(FuncType, popNode(Node::Kind::DifferentiableFunctionType));
+
+ // throws?
addChild(FuncType, popNode([](Node::Kind kind) {
return kind == Node::Kind::ThrowsAnnotation ||
kind == Node::Kind::TypedThrowsAnnotation;
}));
+
+ // sendable?
addChild(FuncType, popNode(Node::Kind::ConcurrentFunctionType));
+
+ // async?
addChild(FuncType, popNode(Node::Kind::AsyncAnnotation));
+ // params-type
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ArgumentTuple));
+
+ // result-type
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ReturnType));
+
return createType(FuncType);
}
@@ -1623,7 +1703,7 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
unsigned FirstChildIdx = 0;
if (FuncType->getChild(FirstChildIdx)->getKind() ==
- Node::Kind::SelfLifetimeDependence)
+ Node::Kind::SendingResultFunctionType)
++FirstChildIdx;
if (FuncType->getChild(FirstChildIdx)->getKind()
== Node::Kind::GlobalActorFunctionType)
@@ -1631,9 +1711,6 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
if (FuncType->getChild(FirstChildIdx)->getKind()
== Node::Kind::IsolatedAnyFunctionType)
++FirstChildIdx;
- if (FuncType->getChild(FirstChildIdx)->getKind() ==
- Node::Kind::SendingResultFunctionType)
- ++FirstChildIdx;
if (FuncType->getChild(FirstChildIdx)->getKind()
== Node::Kind::DifferentiableFunctionType)
++FirstChildIdx;
@@ -1648,9 +1725,6 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
if (FuncType->getChild(FirstChildIdx)->getKind()
== Node::Kind::AsyncAnnotation)
++FirstChildIdx;
- if (FuncType->getChild(FirstChildIdx)->getKind() ==
- Node::Kind::ParamLifetimeDependence)
- ++FirstChildIdx;
auto ParameterType = FuncType->getChild(FirstChildIdx);
assert(ParameterType->getKind() == Node::Kind::ArgumentTuple);
@@ -2160,6 +2234,7 @@ NodePointer Demangler::demangleImplParamConvention(Node::Kind ConvKind) {
case 'l': attr = "@inout"; break;
case 'b': attr = "@inout_aliasable"; break;
case 'n': attr = "@in_guaranteed"; break;
+ case 'X': attr = "@in_cxx"; break;
case 'x': attr = "@owned"; break;
case 'g': attr = "@guaranteed"; break;
case 'e': attr = "@deallocating"; break;
@@ -2319,11 +2394,13 @@ NodePointer Demangler::demangleImplFunctionType() {
const char *CoroAttr = nullptr;
if (nextIf('A'))
- CoroAttr = "@yield_once";
+ CoroAttr = "yield_once";
+ else if (nextIf('I'))
+ CoroAttr = "yield_once_2";
else if (nextIf('G'))
- CoroAttr = "@yield_many";
+ CoroAttr = "yield_many";
if (CoroAttr)
- type->addChild(createNode(Node::Kind::ImplFunctionAttribute, CoroAttr), *this);
+ type->addChild(createNode(Node::Kind::ImplCoroutineKind, CoroAttr), *this);
if (nextIf('h')) {
type->addChild(createNode(Node::Kind::ImplFunctionAttribute, "@Sendable"),
@@ -2335,6 +2412,10 @@ NodePointer Demangler::demangleImplFunctionType() {
*this);
}
+ if (nextIf('T')) {
+ type->addChild(createNode(Node::Kind::ImplSendingResult), *this);
+ }
+
addChild(type, GenSig);
int NumTypesToAdd = 0;
@@ -2348,10 +2429,6 @@ NodePointer Demangler::demangleImplFunctionType() {
++NumTypesToAdd;
}
- if (nextIf('T')) {
- type->addChild(createNode(Node::Kind::ImplSendingResult), *this);
- }
-
while (NodePointer Result = demangleImplResultConvention(
Node::Kind::ImplResult)) {
type = addChild(type, Result);
@@ -2384,7 +2461,7 @@ NodePointer Demangler::demangleImplFunctionType() {
return nullptr;
type->getChild(type->getNumChildren() - Idx - 1)->addChild(ConvTy, *this);
}
-
+
return createType(type);
}
@@ -2764,6 +2841,18 @@ NodePointer Demangler::popProtocolConformance() {
NodePointer Demangler::demangleThunkOrSpecialization() {
switch (char c = nextChar()) {
+ // Thunks that are from a thunk inst. We take the TT namespace.
+ case 'T': {
+ switch (nextChar()) {
+ case 'I':
+ return createWithChild(Node::Kind::SILThunkIdentity, popNode(isEntity));
+ case 'H':
+ return createWithChild(Node::Kind::SILThunkHopToMainActorIfNeeded,
+ popNode(isEntity));
+ default:
+ return nullptr;
+ }
+ }
case 'c': return createWithChild(Node::Kind::CurryThunk, popNode(isEntity));
case 'j': return createWithChild(Node::Kind::DispatchThunk, popNode(isEntity));
case 'q': return createWithChild(Node::Kind::MethodDescriptor, popNode(isEntity));
@@ -2835,18 +2924,20 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
return Thunk;
}
case 'g':
- return demangleGenericSpecialization(Node::Kind::GenericSpecialization);
+ return demangleGenericSpecialization(Node::Kind::GenericSpecialization, nullptr);
case 'G':
return demangleGenericSpecialization(Node::Kind::
- GenericSpecializationNotReAbstracted);
+ GenericSpecializationNotReAbstracted, nullptr);
case 'B':
return demangleGenericSpecialization(Node::Kind::
- GenericSpecializationInResilienceDomain);
+ GenericSpecializationInResilienceDomain, nullptr);
+ case 't':
+ return demangleGenericSpecializationWithDroppedArguments();
case 's':
return demangleGenericSpecialization(
- Node::Kind::GenericSpecializationPrespecialized);
+ Node::Kind::GenericSpecializationPrespecialized, nullptr);
case 'i':
- return demangleGenericSpecialization(Node::Kind::InlinedGenericFunction);
+ return demangleGenericSpecialization(Node::Kind::InlinedGenericFunction, nullptr);
case 'p': {
NodePointer Spec = demangleSpecAttributes(Node::Kind::
GenericPartialSpecialization);
@@ -3102,7 +3193,7 @@ NodePointer Demangler::demangleDifferentiabilityWitness() {
result = addChild(result, node);
result->reverseChildren();
MangledDifferentiabilityKind kind;
- switch (auto c = nextChar()) {
+ switch (nextChar()) {
case 'f': kind = MangledDifferentiabilityKind::Forward; break;
case 'r': kind = MangledDifferentiabilityKind::Reverse; break;
case 'd': kind = MangledDifferentiabilityKind::Normal; break;
@@ -3134,7 +3225,7 @@ NodePointer Demangler::demangleIndexSubset() {
NodePointer Demangler::demangleDifferentiableFunctionType() {
MangledDifferentiabilityKind kind;
- switch (auto c = nextChar()) {
+ switch (nextChar()) {
case 'f': kind = MangledDifferentiabilityKind::Forward; break;
case 'r': kind = MangledDifferentiabilityKind::Reverse; break;
case 'd': kind = MangledDifferentiabilityKind::Normal; break;
@@ -3145,28 +3236,6 @@ NodePointer Demangler::demangleDifferentiableFunctionType() {
Node::Kind::DifferentiableFunctionType, (Node::IndexType)kind);
}
-NodePointer Demangler::demangleLifetimeDependenceKind(bool isSelfDependence) {
- MangledLifetimeDependenceKind kind;
- switch (auto c = nextChar()) {
- case 's':
- kind = MangledLifetimeDependenceKind::Scope;
- break;
- case 'i':
- kind = MangledLifetimeDependenceKind::Inherit;
- break;
- default:
- return nullptr;
- }
- if (isSelfDependence) {
- return createNode(Node::Kind::SelfLifetimeDependence,
- (Node::IndexType)kind);
- }
- auto node = createWithChildren(Node::Kind::ParamLifetimeDependence,
- createNode(Node::Kind::Index, unsigned(kind)),
- popTypeAndGetChild());
- return createType(node);
-}
-
std::string Demangler::demangleBridgedMethodParams() {
if (nextIf('_'))
return std::string();
@@ -3190,10 +3259,18 @@ std::string Demangler::demangleBridgedMethodParams() {
return Str;
}
-NodePointer Demangler::demangleGenericSpecialization(Node::Kind SpecKind) {
+NodePointer Demangler::demangleGenericSpecialization(Node::Kind SpecKind,
+ NodePointer droppedArguments) {
NodePointer Spec = demangleSpecAttributes(SpecKind);
if (!Spec)
return nullptr;
+
+ if (droppedArguments) {
+ for (NodePointer a : *droppedArguments) {
+ Spec->addChild(a, *this);
+ }
+ }
+
NodePointer TyList = popTypeList();
if (!TyList)
return nullptr;
@@ -3204,6 +3281,24 @@ NodePointer Demangler::demangleGenericSpecialization(Node::Kind SpecKind) {
return Spec;
}
+NodePointer Demangler::demangleGenericSpecializationWithDroppedArguments() {
+ pushBack();
+ NodePointer tmp = createNode(Node::Kind::GenericSpecialization);
+ while (nextIf('t')) {
+ int n = demangleNatural();
+ addChild(tmp, createNode(Node::Kind::DroppedArgument, n < 0 ? 0 : n + 1));
+ }
+ Node::Kind specKind;
+ switch (nextChar()) {
+ case 'g': specKind = Node::Kind::GenericSpecialization; break;
+ case 'G': specKind = Node::Kind::GenericSpecializationNotReAbstracted; break;
+ case 'B': specKind = Node::Kind::GenericSpecializationInResilienceDomain; break;
+ default:
+ return nullptr;
+ }
+ return demangleGenericSpecialization(specKind, tmp);
+}
+
NodePointer Demangler::demangleFunctionSpecialization() {
NodePointer Spec = demangleSpecAttributes(
Node::Kind::FunctionSignatureSpecialization);
@@ -3417,21 +3512,16 @@ NodePointer Demangler::addFuncSpecParamNumber(NodePointer Param,
}
NodePointer Demangler::demangleSpecAttributes(Node::Kind SpecKind) {
- bool metatypeParamsRemoved = nextIf('m');
bool isSerialized = nextIf('q');
bool asyncRemoved = nextIf('a');
int PassID = (int)nextChar() - '0';
if (PassID < 0 || PassID >= MAX_SPECIALIZATION_PASS) {
- assert(false && "unexpected pass id");
return nullptr;
}
NodePointer SpecNd = createNode(SpecKind);
- if (metatypeParamsRemoved)
- SpecNd->addChild(createNode(Node::Kind::MetatypeParamsRemoved), *this);
-
if (isSerialized)
SpecNd->addChild(createNode(Node::Kind::IsSerialized),
*this);
@@ -3647,7 +3737,7 @@ NodePointer Demangler::demangleWitness() {
case 'z': {
auto declList = createNode(Node::Kind::GlobalVariableOnceDeclList);
std::vector vars;
- while (auto sig = popNode(Node::Kind::FirstElementMarker)) {
+ while (popNode(Node::Kind::FirstElementMarker)) {
auto identifier = popNode(isDeclName);
if (!identifier)
return nullptr;
@@ -3698,7 +3788,7 @@ NodePointer Demangler::demangleSpecialType() {
case 'j':
return demangleSymbolicExtendedExistentialType();
case 'z':
- switch (auto cchar = nextChar()) {
+ switch (nextChar()) {
case 'B':
return popFunctionType(Node::Kind::ObjCBlock, true);
case 'C':
@@ -3906,7 +3996,9 @@ NodePointer Demangler::demangleAccessor(NodePointer ChildNode) {
case 'w': Kind = Node::Kind::WillSet; break;
case 'W': Kind = Node::Kind::DidSet; break;
case 'r': Kind = Node::Kind::ReadAccessor; break;
+ case 'y': Kind = Node::Kind::Read2Accessor; break;
case 'M': Kind = Node::Kind::ModifyAccessor; break;
+ case 'x': Kind = Node::Kind::Modify2Accessor; break;
case 'i': Kind = Node::Kind::InitAccessor; break;
case 'a':
switch (nextChar()) {
@@ -3947,6 +4039,10 @@ NodePointer Demangler::demangleFunctionEntity() {
switch (nextChar()) {
case 'D': Args = None; Kind = Node::Kind::Deallocator; break;
case 'd': Args = None; Kind = Node::Kind::Destructor; break;
+ case 'Z':
+ Args = None;
+ Kind = Node::Kind::IsolatedDeallocator;
+ break;
case 'E': Args = None; Kind = Node::Kind::IVarDestroyer; break;
case 'e': Args = None; Kind = Node::Kind::IVarInitializer; break;
case 'i': Args = None; Kind = Node::Kind::Initializer; break;
@@ -4118,10 +4214,21 @@ NodePointer Demangler::demangleGenericSignature(bool hasParamCounts) {
NodePointer Demangler::demangleGenericRequirement() {
enum { Generic, Assoc, CompoundAssoc, Substitution } TypeKind;
- enum { Protocol, BaseClass, SameType, SameShape, Layout, PackMarker, Inverse } ConstraintKind;
+
+ enum {
+ Protocol,
+ BaseClass,
+ SameType,
+ SameShape,
+ Layout,
+ PackMarker,
+ Inverse,
+ ValueMarker
+ } ConstraintKind;
NodePointer inverseKind = nullptr;
switch (nextChar()) {
+ case 'V': ConstraintKind = ValueMarker; TypeKind = Generic; break;
case 'v': ConstraintKind = PackMarker; TypeKind = Generic; break;
case 'c': ConstraintKind = BaseClass; TypeKind = Assoc; break;
case 'C': ConstraintKind = BaseClass; TypeKind = CompoundAssoc; break;
@@ -4176,6 +4283,10 @@ NodePointer Demangler::demangleGenericRequirement() {
}
switch (ConstraintKind) {
+ case ValueMarker:
+ return createWithChildren(
+ Node::Kind::DependentGenericParamValueMarker, ConstrTy,
+ popNode(Node::Kind::Type));
case PackMarker:
return createWithChild(
Node::Kind::DependentGenericParamPackMarker, ConstrTy);
@@ -4365,3 +4476,20 @@ NodePointer Demangler::demangleMacroExpansion() {
result->addChild(privateDiscriminator, *this);
return result;
}
+
+NodePointer Demangler::demangleIntegerType() {
+ NodePointer integer = nullptr;
+
+ switch (peekChar()) {
+ case 'n':
+ nextChar();
+ integer = createNode(Node::Kind::NegativeInteger, -demangleIndex());
+ break;
+
+ default:
+ integer = createNode(Node::Kind::Integer, demangleIndex());
+ break;
+ }
+
+ return createType(integer);
+}
diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp
index 5b251e8da..5e8ae2587 100644
--- a/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp
+++ b/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp
@@ -296,6 +296,7 @@ class NodePrinter {
case Node::Kind::BoundGenericFunction:
case Node::Kind::BuiltinTypeName:
case Node::Kind::BuiltinTupleType:
+ case Node::Kind::BuiltinFixedArray:
case Node::Kind::Class:
case Node::Kind::DependentGenericType:
case Node::Kind::DependentMemberType:
@@ -329,6 +330,8 @@ class NodePrinter {
case Node::Kind::SugaredArray:
case Node::Kind::SugaredDictionary:
case Node::Kind::SugaredParen:
+ case Node::Kind::Integer:
+ case Node::Kind::NegativeInteger:
return true;
case Node::Kind::Type:
@@ -365,8 +368,11 @@ class NodePrinter {
case Node::Kind::Constructor:
case Node::Kind::CoroutineContinuationPrototype:
case Node::Kind::CurryThunk:
+ case Node::Kind::SILThunkIdentity:
+ case Node::Kind::SILThunkHopToMainActorIfNeeded:
case Node::Kind::DispatchThunk:
case Node::Kind::Deallocator:
+ case Node::Kind::IsolatedDeallocator:
case Node::Kind::DeclContext:
case Node::Kind::DefaultArgumentInitializer:
case Node::Kind::DefaultAssociatedTypeMetadataAccessor:
@@ -433,6 +439,7 @@ class NodePrinter {
case Node::Kind::ImplFunctionConvention:
case Node::Kind::ImplFunctionConventionName:
case Node::Kind::ImplFunctionType:
+ case Node::Kind::ImplCoroutineKind:
case Node::Kind::ImplInvocationSubstitutions:
case Node::Kind::ImplPatternSubstitutions:
case Node::Kind::ImplicitClosure:
@@ -466,6 +473,7 @@ class NodePrinter {
case Node::Kind::MethodDescriptor:
case Node::Kind::MethodLookupFunction:
case Node::Kind::ModifyAccessor:
+ case Node::Kind::Modify2Accessor:
case Node::Kind::NativeOwningAddressor:
case Node::Kind::NativeOwningMutableAddressor:
case Node::Kind::NativePinningAddressor:
@@ -516,6 +524,7 @@ class NodePrinter {
case Node::Kind::ReabstractionThunkHelperWithSelf:
case Node::Kind::ReabstractionThunkHelperWithGlobalActor:
case Node::Kind::ReadAccessor:
+ case Node::Kind::Read2Accessor:
case Node::Kind::RelatedEntityDeclName:
case Node::Kind::RetroactiveConformance:
case Node::Kind::Setter:
@@ -524,7 +533,7 @@ class NodePrinter {
case Node::Kind::SILBoxMutableField:
case Node::Kind::SILBoxImmutableField:
case Node::Kind::IsSerialized:
- case Node::Kind::MetatypeParamsRemoved:
+ case Node::Kind::DroppedArgument:
case Node::Kind::SpecializationPassID:
case Node::Kind::Static:
case Node::Kind::Subscript:
@@ -645,9 +654,8 @@ class NodePrinter {
case Node::Kind::SymbolicExtendedExistentialType:
case Node::Kind::HasSymbolQuery:
case Node::Kind::ObjectiveCProtocolSymbolicReference:
- case Node::Kind::ParamLifetimeDependence:
- case Node::Kind::SelfLifetimeDependence:
case Node::Kind::DependentGenericInverseConformanceRequirement:
+ case Node::Kind::DependentGenericParamValueMarker:
return false;
}
printer_unreachable("bad node kind");
@@ -890,6 +898,18 @@ class NodePrinter {
// handled earlier
++startIndex;
}
+
+ // Be sure to check for function signature components in the same
+ // order that they're added by the demangler, which is the reverse
+ // of the order that they appear in the mangling grammar.
+
+ if (node->getChild(startIndex)->getKind() ==
+ Node::Kind::SendingResultFunctionType) {
+ ++startIndex;
+ hasSendingResult = true;
+ }
+
+ // function-isolation; note that these can't actually both appear.
if (node->getChild(startIndex)->getKind()
== Node::Kind::IsolatedAnyFunctionType) {
print(node->getChild(startIndex), depth + 1);
@@ -900,17 +920,13 @@ class NodePrinter {
print(node->getChild(startIndex), depth + 1);
++startIndex;
}
+
if (node->getChild(startIndex)->getKind() ==
Node::Kind::DifferentiableFunctionType) {
diffKind =
(MangledDifferentiabilityKind)node->getChild(startIndex)->getIndex();
++startIndex;
}
- if (node->getChild(startIndex)->getKind() ==
- Node::Kind::SelfLifetimeDependence) {
- print(node->getChild(startIndex), depth + 1);
- ++startIndex;
- }
Node *thrownErrorNode = nullptr;
if (node->getChild(startIndex)->getKind() == Node::Kind::ThrowsAnnotation ||
@@ -929,11 +945,6 @@ class NodePrinter {
++startIndex;
isAsync = true;
}
- if (node->getChild(startIndex)->getKind() ==
- Node::Kind::SendingResultFunctionType) {
- ++startIndex;
- hasSendingResult = true;
- }
switch (diffKind) {
case MangledDifferentiabilityKind::Forward:
@@ -1064,7 +1075,8 @@ class NodePrinter {
auto child = Node->getChild(firstRequirement);
if (child->getKind() == Node::Kind::Type)
child = child->getChild(0);
- if (child->getKind() != Node::Kind::DependentGenericParamPackMarker) {
+ if (child->getKind() != Node::Kind::DependentGenericParamPackMarker &&
+ child->getKind() != Node::Kind::DependentGenericParamValueMarker) {
break;
}
}
@@ -1092,6 +1104,30 @@ class NodePrinter {
return false;
};
+ auto isGenericParamValue = [&](unsigned depth, unsigned index) {
+ for (unsigned i = numGenericParams; i < firstRequirement; ++i) {
+ auto child = Node->getChild(i);
+ if (child->getKind() != Node::Kind::DependentGenericParamValueMarker)
+ continue;
+ child = child->getChild(0);
+
+ if (child->getKind() != Node::Kind::Type)
+ continue;
+
+ auto param = child->getChild(0);
+ auto type = child->getChild(1);
+ if (param->getKind() != Node::Kind::DependentGenericParamType)
+ continue;
+
+ if (index == param->getChild(0)->getIndex() &&
+ depth == param->getChild(1)->getIndex()) {
+ return std::make_pair(true, type);
+ }
+ }
+
+ return std::make_pair(false, NodePointer());
+ };
+
unsigned gpDepth = 0;
for (; gpDepth < numGenericParams; ++gpDepth) {
if (gpDepth != 0)
@@ -1113,9 +1149,19 @@ class NodePrinter {
if (isGenericParamPack(gpDepth, index))
Printer << "each ";
+ auto value = isGenericParamValue(gpDepth, index);
+
+ if (value.first)
+ Printer << "let ";
+
// FIXME: Depth won't match when a generic signature applies to a
// method in generic type context.
Printer << Options.GenericParameterName(gpDepth, index);
+
+ if (value.second) {
+ Printer << ": ";
+ print(value.second, depth + 1);
+ }
}
}
@@ -1296,7 +1342,7 @@ void NodePrinter::printSpecializationPrefix(NodePointer node,
for (NodePointer child : *node) {
switch (child->getKind()) {
case Node::Kind::SpecializationPassID:
- case Node::Kind::MetatypeParamsRemoved:
+ case Node::Kind::DroppedArgument:
// We skip those nodes since it does not contain any
// information that is useful to our users.
break;
@@ -1356,11 +1402,11 @@ static bool shouldShowEntityType(Node::Kind EntityKind,
switch (EntityKind) {
case Node::Kind::ExplicitClosure:
case Node::Kind::ImplicitClosure:
- // The signature of a closure (its `Type` node) can optionally be omitted.
- // Unlike functions which can have overloads, the signature of a closure is
- // not needed to be uniquely identified. A closure is uniquely identified by
- // its index and parent. Omitting the signature improves the readability
- // when long type names are in use.
+ /// The signature of a closure (its `Type` node) can optionally be omitted.
+ /// Unlike functions which can have overloads, the signature of a closure is
+ /// not needed to be uniquely identified. A closure is uniquely identified
+ /// by its index and parent. Omitting the signature improves the readability
+ /// when long type names are in use.
return Options.ShowClosureSignature;
default:
return true;
@@ -1392,6 +1438,14 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
Printer << "curry thunk of ";
print(Node->getChild(0), depth + 1);
return nullptr;
+ case Node::Kind::SILThunkIdentity:
+ Printer << "identity thunk of ";
+ print(Node->getChild(0), depth + 1);
+ return nullptr;
+ case Node::Kind::SILThunkHopToMainActorIfNeeded:
+ Printer << "hop to main actor thunk of ";
+ print(Node->getChild(0), depth + 1);
+ return nullptr;
case Node::Kind::DispatchThunk:
Printer << "dispatch thunk of ";
print(Node->getChild(0), depth + 1);
@@ -1783,33 +1837,6 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
Printer << "@noDerivative ";
print(Node->getChild(0), depth + 1);
return nullptr;
- case Node::Kind::ParamLifetimeDependence: {
- Printer << "lifetime dependence: ";
- auto kind = (MangledLifetimeDependenceKind)Node->getChild(0)->getIndex();
- switch (kind) {
- case MangledLifetimeDependenceKind::Inherit:
- Printer << "inherit ";
- break;
- case MangledLifetimeDependenceKind::Scope:
- Printer << "scope ";
- break;
- }
- print(Node->getChild(1), depth + 1);
- return nullptr;
- }
- case Node::Kind::SelfLifetimeDependence: {
- Printer << "(self lifetime dependence: ";
- auto kind = (MangledLifetimeDependenceKind)Node->getIndex();
- switch (kind) {
- case MangledLifetimeDependenceKind::Inherit:
- Printer << "inherit) ";
- break;
- case MangledLifetimeDependenceKind::Scope:
- Printer << "scope) ";
- break;
- }
- return nullptr;
- }
case Node::Kind::NonObjCAttribute:
Printer << "@nonobjc ";
return nullptr;
@@ -1854,8 +1881,8 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
case Node::Kind::IsSerialized:
Printer << "serialized";
return nullptr;
- case Node::Kind::MetatypeParamsRemoved:
- Printer << "metatypes-removed";
+ case Node::Kind::DroppedArgument:
+ Printer << "param" << Node->getIndex() << "-removed";
return nullptr;
case Node::Kind::GenericSpecializationParam:
print(Node->getChild(0), depth + 1);
@@ -1968,6 +1995,13 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
case Node::Kind::BuiltinTupleType:
Printer << "Builtin.TheTupleType";
return nullptr;
+ case Node::Kind::BuiltinFixedArray:
+ Printer << "Builtin.FixedArray<";
+ print(Node->getChild(0), depth + 1);
+ Printer << ", ";
+ print(Node->getChild(1), depth + 1);
+ Printer << ">";
+ return nullptr;
case Node::Kind::Number:
Printer << Node->getIndex();
return nullptr;
@@ -2717,9 +2751,15 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
case Node::Kind::ReadAccessor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"read");
+ case Node::Kind::Read2Accessor:
+ return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
+ "read2");
case Node::Kind::ModifyAccessor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"modify");
+ case Node::Kind::Modify2Accessor:
+ return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
+ "modify2");
case Node::Kind::InitAccessor:
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
"init");
@@ -2740,6 +2780,12 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
/*hasName*/ false,
isClassType(Node->getChild(0)) ? "__deallocating_deinit"
: "deinit");
+ case Node::Kind::IsolatedDeallocator:
+ return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
+ /*hasName*/ false,
+ isClassType(Node->getChild(0))
+ ? "__isolated_deallocating_deinit"
+ : "deinit");
case Node::Kind::IVarInitializer:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/ false, "__ivar_initializer");
@@ -2797,6 +2843,13 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
return nullptr;
case Node::Kind::ImplErasedIsolation:
Printer << "@isolated(any)";
+ return nullptr;
+ case Node::Kind::ImplCoroutineKind:
+ // Skip if text is empty.
+ if (Node->getText().empty())
+ return nullptr;
+ // Otherwise, print with leading @.
+ Printer << '@' << Node->getText();
return nullptr;
case Node::Kind::ImplSendingResult:
Printer << "sending";
@@ -2891,6 +2944,7 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
}
case Node::Kind::DependentGenericParamCount:
case Node::Kind::DependentGenericParamPackMarker:
+ case Node::Kind::DependentGenericParamValueMarker:
printer_unreachable("should be printed as a child of a "
"DependentGenericSignature");
case Node::Kind::DependentGenericConformanceRequirement: {
@@ -3401,6 +3455,15 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
case Node::Kind::OpaqueReturnTypeIndex:
case Node::Kind::OpaqueReturnTypeParent:
return nullptr;
+ case Node::Kind::Integer:
+ Printer << Node->getIndex();
+ return nullptr;
+ case Node::Kind::NegativeInteger: {
+ intptr_t signedValue = Node->getIndex();
+
+ Printer << signedValue;
+ return nullptr;
+ }
}
printer_unreachable("bad node kind!");
diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/OldDemangler.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/OldDemangler.cpp
new file mode 100644
index 000000000..2a4b5f659
--- /dev/null
+++ b/symbolic-demangle/vendor/swift/lib/Demangling/OldDemangler.cpp
@@ -0,0 +1,2408 @@
+//===--- OldDemangler.cpp - Old Swift Demangling --------------------------===//
+//
+// 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 Swift symbol demangling with the old scheme.
+//
+//===----------------------------------------------------------------------===//
+
+#include "swift/Demangling/Demangle.h"
+#include "swift/Demangling/Demangler.h"
+#include "swift/Demangling/ManglingMacros.h"
+#include "swift/Demangling/ManglingUtils.h"
+#include "swift/Demangling/Punycode.h"
+#include "swift/Strings.h"
+#include
+#include
+#include
+#include
+#include
+
+using namespace swift;
+using namespace Demangle;
+
+namespace {
+ struct FindPtr {
+ FindPtr(Node *v) : Target(v) {}
+ bool operator()(NodePointer sp) const {
+ return sp == Target;
+ }
+ private:
+ Node *Target;
+ };
+} // end anonymous namespace
+
+static bool isStartOfIdentifier(char c) {
+ if (c >= '0' && c <= '9')
+ return true;
+ return c == 'o';
+}
+
+static bool isStartOfNominalType(char c) {
+ switch (c) {
+ case 'C':
+ case 'V':
+ case 'O':
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool isStartOfEntity(char c) {
+ switch (c) {
+ case 'F':
+ case 'I':
+ case 'v':
+ case 'P':
+ case 's':
+ case 'Z':
+ return true;
+ default:
+ return isStartOfNominalType(c);
+ }
+}
+
+static Node::Kind nominalTypeMarkerToNodeKind(char c) {
+ if (c == 'C')
+ return Node::Kind::Class;
+ if (c == 'V')
+ return Node::Kind::Structure;
+ if (c == 'O')
+ return Node::Kind::Enum;
+ return Node::Kind::Identifier;
+}
+
+namespace {
+
+/// A convenient class for parsing characters out of a string.
+class NameSource {
+ StringRef Text;
+public:
+ NameSource(StringRef text) : Text(text) {}
+
+ /// Return whether there are at least len characters remaining.
+ bool hasAtLeast(size_t len) { return (len <= Text.size()); }
+
+ bool isEmpty() { return Text.empty(); }
+ explicit operator bool() { return !isEmpty(); }
+
+ /// Return the next character without claiming it. Asserts that
+ /// there is at least one remaining character.
+ char peek() {
+ if (isEmpty()) {
+ // Return an otherwise unused character to prevent crashes for malformed
+ // symbols.
+ return '.';
+ }
+ return Text.front();
+ }
+
+ /// Claim and return the next character. Asserts that there is at
+ /// least one remaining character.
+ char next() {
+ char c = peek();
+ if (!isEmpty())
+ advanceOffset(1);
+ return c;
+ }
+
+ /// Claim the next character if it exists and equals the given
+ /// character.
+ bool nextIf(char c) {
+ if (isEmpty() || peek() != c) return false;
+ advanceOffset(1);
+ return true;
+ }
+
+ /// Claim the next few characters if they exactly match the given string.
+ bool nextIf(StringRef str) {
+ if (!Text.starts_with(str)) return false;
+ advanceOffset(str.size());
+ return true;
+ }
+
+ /// Return the next len characters without claiming them. Asserts
+ /// that there are at least so many characters.
+ StringRef slice(size_t len) { return Text.substr(0, len); }
+
+ /// Return the current string ref without claiming any characters.
+ StringRef str() { return Text; }
+
+ /// Claim the next len characters.
+ void advanceOffset(size_t len) {
+ Text = Text.substr(len);
+ }
+
+ /// Claim and return all the rest of the characters.
+ StringRef getString() {
+ auto result = Text;
+ advanceOffset(Text.size());
+ return result;
+ }
+
+ bool readUntil(char c, std::string &result) {
+ std::optional c2;
+ while (!isEmpty() && (c2 = peek()).value() != c) {
+ result.push_back(c2.value());
+ advanceOffset(1);
+ }
+ return c2.has_value() && c2.value() == c;
+ }
+};
+
+/// The main class for parsing a demangling tree out of a mangled string.
+class OldDemangler {
+ std::vector Substitutions;
+ NameSource Mangled;
+ NodeFactory &Factory;
+
+ static const unsigned MaxDepth = 1024;
+
+public:
+ OldDemangler(llvm::StringRef mangled, NodeFactory &Factory)
+ : Mangled(mangled), Factory(Factory) {}
+
+/// Try to demangle a child node of the given kind. If that fails,
+/// return; otherwise add it to the parent.
+#define DEMANGLE_CHILD_OR_RETURN(PARENT, CHILD_KIND, DEPTH) \
+ do { \
+ auto _node = demangle##CHILD_KIND(DEPTH); \
+ if (!_node) \
+ return nullptr; \
+ addChild(PARENT, _node); \
+ } while (false)
+
+/// Try to demangle a child node of the given kind. If that fails,
+/// return; otherwise add it to the parent.
+#define DEMANGLE_CHILD_AS_NODE_OR_RETURN(PARENT, CHILD_KIND, DEPTH) \
+ do { \
+ auto _kind = demangle##CHILD_KIND(DEPTH); \
+ if (!_kind.has_value()) \
+ return nullptr; \
+ addChild(PARENT, \
+ Factory.createNode(Node::Kind::CHILD_KIND, unsigned(*_kind))); \
+ } while (false)
+
+ /// Attempt to demangle the source string. The root node will
+ /// always be a Global. Extra characters at the end will be
+ /// tolerated (and included as a Suffix node as a child of the
+ /// Global).
+ ///
+ /// \return true if the mangling succeeded
+ NodePointer demangleTopLevel() {
+ if (!Mangled.nextIf("_T"))
+ return nullptr;
+
+ NodePointer topLevel = Factory.createNode(Node::Kind::Global);
+
+ // First demangle any specialization prefixes.
+ if (Mangled.nextIf("TS")) {
+ do {
+ DEMANGLE_CHILD_OR_RETURN(topLevel, SpecializedAttribute, 0);
+
+ // The Substitution header does not share state with the rest
+ // of the mangling.
+ Substitutions.clear();
+ } while (Mangled.nextIf("_TTS"));
+
+ // Then check that we have a global.
+ if (!Mangled.nextIf("_T"))
+ return nullptr;
+
+ } else if (Mangled.nextIf("To")) {
+ addChild(topLevel, Factory.createNode(Node::Kind::ObjCAttribute));
+ } else if (Mangled.nextIf("TO")) {
+ addChild(topLevel, Factory.createNode(Node::Kind::NonObjCAttribute));
+ } else if (Mangled.nextIf("TD")) {
+ addChild(topLevel, Factory.createNode(Node::Kind::DynamicAttribute));
+ } else if (Mangled.nextIf("Td")) {
+ addChild(topLevel, Factory.createNode(
+ Node::Kind::DirectMethodReferenceAttribute));
+ } else if (Mangled.nextIf("TV")) {
+ addChild(topLevel, Factory.createNode(Node::Kind::VTableAttribute));
+ }
+
+ DEMANGLE_CHILD_OR_RETURN(topLevel, Global, 0);
+
+ // Add a suffix node if there's anything left unmangled.
+ if (!Mangled.isEmpty()) {
+ addChild(topLevel, Factory.createNode(Node::Kind::Suffix,
+ Mangled.getString()));
+ }
+
+ return topLevel;
+ }
+
+ NodePointer demangleTypeName(unsigned depth) { return demangleType(depth); }
+
+private:
+ enum class IsVariadic {
+ yes = true, no = false
+ };
+
+ void addChild(NodePointer Parent, NodePointer Child) {
+ Parent->addChild(Child, Factory);
+ }
+
+ std::optional demangleDirectness(unsigned depth) {
+ if (Mangled.nextIf('d'))
+ return Directness::Direct;
+ if (Mangled.nextIf('i'))
+ return Directness::Indirect;
+ return std::nullopt;
+ }
+
+ bool demangleNatural(Node::IndexType &num, unsigned depth) {
+ if (!Mangled)
+ return false;
+ char c = Mangled.next();
+ if (c < '0' || c > '9')
+ return false;
+ num = (c - '0');
+ while (true) {
+ if (!Mangled) {
+ return true;
+ }
+ c = Mangled.peek();
+ if (c < '0' || c > '9') {
+ return true;
+ } else {
+ num = (10 * num) + (c - '0');
+ }
+ Mangled.next();
+ }
+ }
+
+ bool demangleBuiltinSize(Node::IndexType &num, unsigned depth) {
+ if (!demangleNatural(num, depth + 1))
+ return false;
+ if (Mangled.nextIf('_'))
+ return true;
+ return false;
+ }
+
+ std::optional demangleValueWitnessKind(unsigned depth) {
+ char Code[2];
+ if (!Mangled)
+ return std::nullopt;
+ Code[0] = Mangled.next();
+ if (!Mangled)
+ return std::nullopt;
+ Code[1] = Mangled.next();
+
+ StringRef CodeStr(Code, 2);
+#define VALUE_WITNESS(MANGLING, NAME) \
+ if (CodeStr == #MANGLING) return ValueWitnessKind::NAME;
+#include "swift/Demangling/ValueWitnessMangling.def"
+
+ return std::nullopt;
+ }
+
+ NodePointer demangleGlobal(unsigned depth) {
+ if (depth > OldDemangler::MaxDepth || !Mangled)
+ return nullptr;
+
+ // Type metadata.
+ if (Mangled.nextIf('M')) {
+ if (Mangled.nextIf('P')) {
+ auto pattern =
+ Factory.createNode(Node::Kind::GenericTypeMetadataPattern);
+ DEMANGLE_CHILD_OR_RETURN(pattern, Type, depth + 1);
+ return pattern;
+ }
+ if (Mangled.nextIf('a')) {
+ auto accessor =
+ Factory.createNode(Node::Kind::TypeMetadataAccessFunction);
+ DEMANGLE_CHILD_OR_RETURN(accessor, Type, depth + 1);
+ return accessor;
+ }
+ if (Mangled.nextIf('L')) {
+ auto cache = Factory.createNode(Node::Kind::TypeMetadataLazyCache);
+ DEMANGLE_CHILD_OR_RETURN(cache, Type, depth + 1);
+ return cache;
+ }
+ if (Mangled.nextIf('m')) {
+ auto metaclass = Factory.createNode(Node::Kind::Metaclass);
+ DEMANGLE_CHILD_OR_RETURN(metaclass, Type, depth + 1);
+ return metaclass;
+ }
+ if (Mangled.nextIf('n')) {
+ auto nominalType =
+ Factory.createNode(Node::Kind::NominalTypeDescriptor);
+ DEMANGLE_CHILD_OR_RETURN(nominalType, Type, depth + 1);
+ return nominalType;
+ }
+ if (Mangled.nextIf('f')) {
+ auto metadata = Factory.createNode(Node::Kind::FullTypeMetadata);
+ DEMANGLE_CHILD_OR_RETURN(metadata, Type, depth + 1);
+ return metadata;
+ }
+ if (Mangled.nextIf('p')) {
+ auto metadata = Factory.createNode(Node::Kind::ProtocolDescriptor);
+ DEMANGLE_CHILD_OR_RETURN(metadata, ProtocolName, depth + 1);
+ return metadata;
+ }
+ auto metadata = Factory.createNode(Node::Kind::TypeMetadata);
+ DEMANGLE_CHILD_OR_RETURN(metadata, Type, depth + 1);
+ return metadata;
+ }
+
+ // Partial application thunks.
+ if (Mangled.nextIf("PA")) {
+ Node::Kind kind = Node::Kind::PartialApplyForwarder;
+ if (Mangled.nextIf('o'))
+ kind = Node::Kind::PartialApplyObjCForwarder;
+ auto forwarder = Factory.createNode(kind);
+ if (Mangled.nextIf("__T"))
+ DEMANGLE_CHILD_OR_RETURN(forwarder, Global, depth + 1);
+ return forwarder;
+ }
+
+ // Top-level types, for various consumers.
+ if (Mangled.nextIf('t')) {
+ auto type = Factory.createNode(Node::Kind::TypeMangling);
+ DEMANGLE_CHILD_OR_RETURN(type, Type, depth + 1);
+ return type;
+ }
+
+ // Value witnesses.
+ if (Mangled.nextIf('w')) {
+ std::optional w = demangleValueWitnessKind(depth + 1);
+ if (!w.has_value())
+ return nullptr;
+ auto witness =
+ Factory.createNode(Node::Kind::ValueWitness);
+ NodePointer Idx = Factory.createNode(Node::Kind::Index,
+ unsigned(w.value()));
+ witness->addChild(Idx, Factory);
+ DEMANGLE_CHILD_OR_RETURN(witness, Type, depth + 1);
+ return witness;
+ }
+
+ // Offsets, value witness tables, and protocol witnesses.
+ if (Mangled.nextIf('W')) {
+ if (Mangled.nextIf('V')) {
+ auto witnessTable = Factory.createNode(Node::Kind::ValueWitnessTable);
+ DEMANGLE_CHILD_OR_RETURN(witnessTable, Type, depth + 1);
+ return witnessTable;
+ }
+ if (Mangled.nextIf('v')) {
+ auto fieldOffset = Factory.createNode(Node::Kind::FieldOffset);
+ DEMANGLE_CHILD_AS_NODE_OR_RETURN(fieldOffset, Directness, depth + 1);
+ DEMANGLE_CHILD_OR_RETURN(fieldOffset, Entity, depth + 1);
+ return fieldOffset;
+ }
+ if (Mangled.nextIf('P')) {
+ auto witnessTable =
+ Factory.createNode(Node::Kind::ProtocolWitnessTable);
+ DEMANGLE_CHILD_OR_RETURN(witnessTable, ProtocolConformance, depth + 1);
+ return witnessTable;
+ }
+ if (Mangled.nextIf('G')) {
+ auto witnessTable =
+ Factory.createNode(Node::Kind::GenericProtocolWitnessTable);
+ DEMANGLE_CHILD_OR_RETURN(witnessTable, ProtocolConformance, depth + 1);
+ return witnessTable;
+ }
+ if (Mangled.nextIf('I')) {
+ auto witnessTable = Factory.createNode(
+ Node::Kind::GenericProtocolWitnessTableInstantiationFunction);
+ DEMANGLE_CHILD_OR_RETURN(witnessTable, ProtocolConformance, depth + 1);
+ return witnessTable;
+ }
+ if (Mangled.nextIf('l')) {
+ auto accessor =
+ Factory.createNode(Node::Kind::LazyProtocolWitnessTableAccessor);
+ DEMANGLE_CHILD_OR_RETURN(accessor, Type, depth + 1);
+ DEMANGLE_CHILD_OR_RETURN(accessor, ProtocolConformance, depth + 1);
+ return accessor;
+ }
+ if (Mangled.nextIf('L')) {
+ auto accessor =
+ Factory.createNode(Node::Kind::LazyProtocolWitnessTableCacheVariable);
+ DEMANGLE_CHILD_OR_RETURN(accessor, Type, depth + 1);
+ DEMANGLE_CHILD_OR_RETURN(accessor, ProtocolConformance, depth + 1);
+ return accessor;
+ }
+ if (Mangled.nextIf('a')) {
+ auto tableTemplate =
+ Factory.createNode(Node::Kind::ProtocolWitnessTableAccessor);
+ DEMANGLE_CHILD_OR_RETURN(tableTemplate, ProtocolConformance, depth + 1);
+ return tableTemplate;
+ }
+ if (Mangled.nextIf('t')) {
+ auto accessor = Factory.createNode(
+ Node::Kind::AssociatedTypeMetadataAccessor);
+ DEMANGLE_CHILD_OR_RETURN(accessor, ProtocolConformance, depth + 1);
+ DEMANGLE_CHILD_OR_RETURN(accessor, DeclName, depth + 1);
+ return accessor;
+ }
+ if (Mangled.nextIf('T')) {
+ auto accessor = Factory.createNode(
+ Node::Kind::AssociatedTypeWitnessTableAccessor);
+ DEMANGLE_CHILD_OR_RETURN(accessor, ProtocolConformance, depth + 1);
+ DEMANGLE_CHILD_OR_RETURN(accessor, DeclName, depth + 1);
+ DEMANGLE_CHILD_OR_RETURN(accessor, ProtocolName, depth + 1);
+ return accessor;
+ }
+ return nullptr;
+ }
+
+ // Other thunks.
+ if (Mangled.nextIf('T')) {
+ if (Mangled.nextIf('R')) {
+ auto thunk = Factory.createNode(Node::Kind::ReabstractionThunkHelper);
+ if (!demangleReabstractSignature(thunk, depth + 1))
+ return nullptr;
+ return thunk;
+ }
+ if (Mangled.nextIf('r')) {
+ auto thunk = Factory.createNode(Node::Kind::ReabstractionThunk);
+ if (!demangleReabstractSignature(thunk, depth + 1))
+ return nullptr;
+ return thunk;
+ }
+ if (Mangled.nextIf('W')) {
+ NodePointer thunk = Factory.createNode(Node::Kind::ProtocolWitness);
+ DEMANGLE_CHILD_OR_RETURN(thunk, ProtocolConformance, depth + 1);
+ // The entity is mangled in its own generic context.
+ DEMANGLE_CHILD_OR_RETURN(thunk, Entity, depth + 1);
+ return thunk;
+ }
+ return nullptr;
+ }
+
+ // Everything else is just an entity.
+ return demangleEntity(depth + 1);
+ }
+
+ NodePointer demangleGenericSpecialization(NodePointer specialization,
+ unsigned depth) {
+ if (depth > OldDemangler::MaxDepth)
+ return nullptr;
+
+ while (!Mangled.nextIf('_')) {
+ // Otherwise, we have another parameter. Demangle the type.
+ NodePointer param = Factory.createNode(Node::Kind::GenericSpecializationParam);
+ DEMANGLE_CHILD_OR_RETURN(param, Type, depth + 1);
+
+ // Then parse any conformances until we find an underscore. Pop off the
+ // underscore since it serves as the end of our mangling list.
+ while (!Mangled.nextIf('_')) {
+ DEMANGLE_CHILD_OR_RETURN(param, ProtocolConformance, depth + 1);
+ }
+
+ // Add the parameter to our specialization list.
+ specialization->addChild(param, Factory);
+ }
+
+ return specialization;
+ }
+
+/// TODO: This is an atrocity. Come up with a shorter name.
+#define FUNCSIGSPEC_CREATE_PARAM_KIND(kind) \
+ Factory.createNode( \
+ Node::Kind::FunctionSignatureSpecializationParamKind, \
+ Node::IndexType(FunctionSigSpecializationParamKind::kind))
+
+#define FUNCSIGSPEC_CREATE_PARAM_PAYLOAD(payload) \
+ Factory.createNode(Node::Kind::FunctionSignatureSpecializationParamPayload, \
+ payload)
+
+ bool demangleFuncSigSpecializationConstantProp(NodePointer parent,
+ unsigned depth) {
+ // Then figure out what was actually constant propagated. First check if
+ // we have a function.
+ if (Mangled.nextIf("fr")) {
+ // Demangle the identifier
+ NodePointer name = demangleIdentifier(depth + 1);
+ if (!name || !Mangled.nextIf('_'))
+ return false;
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_KIND(ConstantPropFunction), Factory);
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_PAYLOAD(name->getText()), Factory);
+ return true;
+ }
+
+ if (Mangled.nextIf('g')) {
+ NodePointer name = demangleIdentifier(depth + 1);
+ if (!name || !Mangled.nextIf('_'))
+ return false;
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_KIND(ConstantPropGlobal), Factory);
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_PAYLOAD(name->getText()), Factory);
+ return true;
+ }
+
+ if (Mangled.nextIf('i')) {
+ std::string Str;
+ if (!Mangled.readUntil('_', Str) || !Mangled.nextIf('_'))
+ return false;
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_KIND(ConstantPropInteger), Factory);
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_PAYLOAD(Str), Factory);
+ return true;
+ }
+
+ if (Mangled.nextIf("fl")) {
+ std::string Str;
+ if (!Mangled.readUntil('_', Str) || !Mangled.nextIf('_'))
+ return false;
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_KIND(ConstantPropFloat), Factory);
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_PAYLOAD(Str), Factory);
+ return true;
+ }
+
+ if (Mangled.nextIf("s")) {
+ // Skip: 'e' encoding 'v' str. encoding is a 0 or 1 and str is a string of
+ // length less than or equal to 32. We do not specialize strings with a
+ // length greater than 32.
+ if (!Mangled.nextIf('e'))
+ return false;
+ char encoding = Mangled.peek();
+ if (encoding != '0' && encoding != '1')
+ return false;
+ std::string encodingStr;
+ if (encoding == '0')
+ encodingStr += "u8";
+ else
+ encodingStr += "u16";
+ Mangled.advanceOffset(1);
+
+ if (!Mangled.nextIf('v'))
+ return false;
+ NodePointer str = demangleIdentifier(depth + 1);
+ if (!str || !Mangled.nextIf('_'))
+ return false;
+
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_KIND(ConstantPropString), Factory);
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_PAYLOAD(encodingStr), Factory);
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_PAYLOAD(str->getText()), Factory);
+ return true;
+ }
+
+ // Unknown constant prop specialization
+ return false;
+ }
+
+ bool demangleFuncSigSpecializationClosureProp(NodePointer parent,
+ unsigned depth) {
+ // We don't actually demangle the function or types for now. But we do want
+ // to signal that we specialized a closure.
+
+ NodePointer name = demangleIdentifier(depth + 1);
+ if (!name) {
+ return false;
+ }
+
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_KIND(ClosureProp), Factory);
+ parent->addChild(FUNCSIGSPEC_CREATE_PARAM_PAYLOAD(name->getText()), Factory);
+
+ // Then demangle types until we fail.
+ NodePointer type = nullptr;
+ while (Mangled.peek() != '_' && (type = demangleType(depth + 1))) {
+ parent->addChild(type, Factory);
+ }
+
+ // Eat last '_'
+ if (!Mangled.nextIf('_'))
+ return false;
+
+ return true;
+ }
+
+ NodePointer
+ demangleFunctionSignatureSpecialization(NodePointer specialization,
+ unsigned depth) {
+ // Until we hit the last '_' in our specialization info...
+ while (!Mangled.nextIf('_')) {
+ // Create the parameter.
+ NodePointer param =
+ Factory.createNode(Node::Kind::FunctionSignatureSpecializationParam);
+
+ // First handle options.
+ if (Mangled.nextIf("n_")) {
+ // Leave the parameter empty.
+ } else if (Mangled.nextIf("cp")) {
+ if (!demangleFuncSigSpecializationConstantProp(param, depth + 1))
+ return nullptr;
+ } else if (Mangled.nextIf("cl")) {
+ if (!demangleFuncSigSpecializationClosureProp(param, depth + 1))
+ return nullptr;
+ } else if (Mangled.nextIf("i_")) {
+ auto result = FUNCSIGSPEC_CREATE_PARAM_KIND(BoxToValue);
+ if (!result)
+ return nullptr;
+ param->addChild(result, Factory);
+ } else if (Mangled.nextIf("k_")) {
+ auto result = FUNCSIGSPEC_CREATE_PARAM_KIND(BoxToStack);
+ if (!result)
+ return nullptr;
+ param->addChild(result, Factory);
+ } else if (Mangled.nextIf("r_")) {
+ auto result = FUNCSIGSPEC_CREATE_PARAM_KIND(InOutToOut);
+ if (!result)
+ return nullptr;
+ param->addChild(result, Factory);
+ } else {
+ // Otherwise handle option sets.
+ unsigned Value = 0;
+ if (Mangled.nextIf('d')) {
+ Value |=
+ unsigned(FunctionSigSpecializationParamKind::Dead);
+ }
+
+ if (Mangled.nextIf('g')) {
+ Value |=
+ unsigned(FunctionSigSpecializationParamKind::OwnedToGuaranteed);
+ }
+
+ if (Mangled.nextIf('o')) {
+ Value |=
+ unsigned(FunctionSigSpecializationParamKind::GuaranteedToOwned);
+ }
+
+ if (Mangled.nextIf('s')) {
+ Value |= unsigned(FunctionSigSpecializationParamKind::SROA);
+ }
+
+ if (!Mangled.nextIf('_'))
+ return nullptr;
+
+ if (!Value)
+ return nullptr;
+
+ auto result = Factory.createNode(
+ Node::Kind::FunctionSignatureSpecializationParamKind, Value);
+ if (!result)
+ return nullptr;
+ param->addChild(result, Factory);
+ }
+
+ specialization->addChild(param, Factory);
+ }
+
+ return specialization;
+ }
+
+#undef FUNCSIGSPEC_CREATE_PARAM_KIND
+#undef FUNCSIGSPEC_CREATE_PARAM_PAYLOAD
+
+ NodePointer demangleSpecializedAttribute(unsigned depth) {
+ bool isNotReAbstracted = false;
+ if (Mangled.nextIf("g") || (isNotReAbstracted = Mangled.nextIf("r"))) {
+ auto spec = Factory.createNode(isNotReAbstracted ?
+ Node::Kind::GenericSpecializationNotReAbstracted :
+ Node::Kind::GenericSpecialization);
+
+ // Create a node if the specialization is serialized.
+ if (Mangled.nextIf("q")) {
+ auto kind = Node::Kind::IsSerialized;
+ spec->addChild(Factory.createNode(kind), Factory);
+ }
+
+ // Create a node for the pass id.
+ spec->addChild(Factory.createNode(Node::Kind::SpecializationPassID,
+ unsigned(Mangled.next() - 48)), Factory);
+
+ // And then mangle the generic specialization.
+ return demangleGenericSpecialization(spec, depth + 1);
+ }
+ if (Mangled.nextIf("f")) {
+ auto spec =
+ Factory.createNode(Node::Kind::FunctionSignatureSpecialization);
+
+ // Create a node if the specialization is serialized.
+ if (Mangled.nextIf("q")) {
+ auto kind = Node::Kind::IsSerialized;
+ spec->addChild(Factory.createNode(kind), Factory);
+ }
+
+ // Add the pass id.
+ spec->addChild(Factory.createNode(Node::Kind::SpecializationPassID,
+ unsigned(Mangled.next() - 48)), Factory);
+
+ // Then perform the function signature specialization.
+ return demangleFunctionSignatureSpecialization(spec, depth + 1);
+ }
+
+ // We don't know how to handle this specialization.
+ return nullptr;
+ }
+
+ NodePointer demangleDeclName(unsigned depth) {
+ // decl-name ::= local-decl-name
+ // local-decl-name ::= 'L' index identifier
+ if (Mangled.nextIf('L')) {
+ NodePointer discriminator = demangleIndexAsNode(depth + 1);
+ if (!discriminator) return nullptr;
+
+ NodePointer name = demangleIdentifier(depth + 1);
+ if (!name) return nullptr;
+
+ NodePointer localName = Factory.createNode(Node::Kind::LocalDeclName);
+ localName->addChild(discriminator, Factory);
+ localName->addChild(name, Factory);
+ return localName;
+
+ } else if (Mangled.nextIf('P')) {
+ NodePointer discriminator = demangleIdentifier(depth + 1);
+ if (!discriminator) return nullptr;
+
+ NodePointer name = demangleIdentifier(depth + 1);
+ if (!name) return nullptr;
+
+ auto privateName = Factory.createNode(Node::Kind::PrivateDeclName);
+ privateName->addChild(discriminator, Factory);
+ privateName->addChild(name, Factory);
+ return privateName;
+ }
+
+ // decl-name ::= identifier
+ return demangleIdentifier(depth + 1);
+ }
+
+ NodePointer
+ demangleIdentifier(unsigned depth,
+ std::optional kind = std::nullopt) {
+ if (!Mangled)
+ return nullptr;
+
+ bool isPunycoded = Mangled.nextIf('X');
+ std::string decodeBuffer;
+
+ auto decode = [&](StringRef s) -> StringRef {
+ if (!isPunycoded)
+ return s;
+ if (!Punycode::decodePunycodeUTF8(s, decodeBuffer))
+ return {};
+ return decodeBuffer;
+ };
+
+ bool isOperator = false;
+ if (Mangled.nextIf('o')) {
+ isOperator = true;
+ // Operator identifiers aren't valid in the contexts that are
+ // building more specific identifiers.
+ if (kind.has_value()) return nullptr;
+
+ char op_mode = Mangled.next();
+ switch (op_mode) {
+ case 'p':
+ kind = Node::Kind::PrefixOperator;
+ break;
+ case 'P':
+ kind = Node::Kind::PostfixOperator;
+ break;
+ case 'i':
+ kind = Node::Kind::InfixOperator;
+ break;
+ default:
+ return nullptr;
+ }
+ }
+
+ if (!kind.has_value()) kind = Node::Kind::Identifier;
+
+ Node::IndexType length;
+ if (!demangleNatural(length, depth + 1))
+ return nullptr;
+ if (!Mangled.hasAtLeast(length))
+ return nullptr;
+
+ StringRef identifier = Mangled.slice(length);
+ Mangled.advanceOffset(length);
+
+ // Decode Unicode identifiers.
+ identifier = decode(identifier);
+ if (identifier.empty())
+ return nullptr;
+
+ // Decode operator names.
+ std::string opDecodeBuffer;
+ if (isOperator) {
+ // abcdefghijklmnopqrstuvwxyz
+ static const char op_char_table[] = "& @/= > <*!|+?%-~ ^ .";
+
+ opDecodeBuffer.reserve(identifier.size());
+ for (signed char c : identifier) {
+ if (c < 0) {
+ // Pass through Unicode characters.
+ opDecodeBuffer.push_back(c);
+ continue;
+ }
+ if (c < 'a' || c > 'z')
+ return nullptr;
+ char o = op_char_table[c - 'a'];
+ if (o == ' ')
+ return nullptr;
+ opDecodeBuffer.push_back(o);
+ }
+ identifier = opDecodeBuffer;
+ }
+
+ return Factory.createNode(*kind, identifier);
+ }
+
+ bool demangleIndex(Node::IndexType &natural, unsigned depth) {
+ if (Mangled.nextIf('_')) {
+ natural = 0;
+ return true;
+ }
+ if (demangleNatural(natural, depth + 1)) {
+ if (!Mangled.nextIf('_'))
+ return false;
+ ++natural;
+ return true;
+ }
+ return false;
+ }
+
+ /// Demangle an and package it as a node of some kind.
+ NodePointer demangleIndexAsNode(unsigned depth,
+ Node::Kind kind = Node::Kind::Number) {
+ Node::IndexType index;
+ if (!demangleIndex(index, depth))
+ return nullptr;
+ return Factory.createNode(kind, index);
+ }
+
+ NodePointer createSwiftType(Node::Kind typeKind, StringRef name) {
+ NodePointer type = Factory.createNode(typeKind);
+ type->addChild(Factory.createNode(Node::Kind::Module, STDLIB_NAME), Factory);
+ type->addChild(Factory.createNode(Node::Kind::Identifier, name), Factory);
+ return type;
+ }
+
+ /// Demangle a , given that we've already consumed the 'S'.
+ NodePointer demangleSubstitutionIndex(unsigned depth) {
+ if (!Mangled)
+ return nullptr;
+ if (Mangled.nextIf('o'))
+ return Factory.createNode(Node::Kind::Module, MANGLING_MODULE_OBJC);
+ if (Mangled.nextIf('C'))
+ return Factory.createNode(Node::Kind::Module,
+ MANGLING_MODULE_CLANG_IMPORTER);
+ if (Mangled.nextIf('a'))
+ return createSwiftType(Node::Kind::Structure, "Array");
+ if (Mangled.nextIf('b'))
+ return createSwiftType(Node::Kind::Structure, "Bool");
+ if (Mangled.nextIf('c'))
+ return createSwiftType(Node::Kind::Structure, "UnicodeScalar");
+ if (Mangled.nextIf('d'))
+ return createSwiftType(Node::Kind::Structure, "Double");
+ if (Mangled.nextIf('f'))
+ return createSwiftType(Node::Kind::Structure, "Float");
+ if (Mangled.nextIf('i'))
+ return createSwiftType(Node::Kind::Structure, "Int");
+ if (Mangled.nextIf('V'))
+ return createSwiftType(Node::Kind::Structure, "UnsafeRawPointer");
+ if (Mangled.nextIf('v'))
+ return createSwiftType(Node::Kind::Structure, "UnsafeMutableRawPointer");
+ if (Mangled.nextIf('P'))
+ return createSwiftType(Node::Kind::Structure, "UnsafePointer");
+ if (Mangled.nextIf('p'))
+ return createSwiftType(Node::Kind::Structure, "UnsafeMutablePointer");
+ if (Mangled.nextIf('q'))
+ return createSwiftType(Node::Kind::Enum, "Optional");
+ if (Mangled.nextIf('Q'))
+ return createSwiftType(Node::Kind::Enum, "ImplicitlyUnwrappedOptional");
+ if (Mangled.nextIf('R'))
+ return createSwiftType(Node::Kind::Structure, "UnsafeBufferPointer");
+ if (Mangled.nextIf('r'))
+ return createSwiftType(Node::Kind::Structure, "UnsafeMutableBufferPointer");
+ if (Mangled.nextIf('S'))
+ return createSwiftType(Node::Kind::Structure, "String");
+ if (Mangled.nextIf('u'))
+ return createSwiftType(Node::Kind::Structure, "UInt");
+ Node::IndexType index_sub;
+ if (!demangleIndex(index_sub, depth))
+ return nullptr;
+ if (index_sub >= Substitutions.size())
+ return nullptr;
+ return Substitutions[index_sub];
+ }
+
+ NodePointer demangleModule(unsigned depth) {
+ if (Mangled.nextIf('s')) {
+ return Factory.createNode(Node::Kind::Module, STDLIB_NAME);
+ }
+ if (Mangled.nextIf('S')) {
+ NodePointer module = demangleSubstitutionIndex(depth + 1);
+ if (!module)
+ return nullptr;
+ if (module->getKind() != Node::Kind::Module)
+ return nullptr;
+ return module;
+ }
+
+ NodePointer module = demangleIdentifier(depth + 1, Node::Kind::Module);
+ if (!module) return nullptr;
+ Substitutions.push_back(module);
+ return module;
+ }
+
+ NodePointer demangleDeclarationName(Node::Kind kind, unsigned depth) {
+ NodePointer context = demangleContext(depth + 1);
+ if (!context) return nullptr;
+
+ auto name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+
+ auto decl = Factory.createNode(kind);
+ decl->addChild(context, Factory);
+ decl->addChild(name, Factory);
+ Substitutions.push_back(decl);
+ return decl;
+ }
+
+ NodePointer demangleProtocolName(unsigned depth) {
+ NodePointer proto = demangleProtocolNameImpl(depth);
+ if (!proto) return nullptr;
+
+ NodePointer type = Factory.createNode(Node::Kind::Type);
+ type->addChild(proto, Factory);
+ return type;
+ }
+
+ NodePointer demangleProtocolNameGivenContext(NodePointer context,
+ unsigned depth) {
+ NodePointer name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+
+ auto proto = Factory.createNode(Node::Kind::Protocol);
+ proto->addChild(context, Factory);
+ proto->addChild(name, Factory);
+ Substitutions.push_back(proto);
+ return proto;
+ }
+
+ NodePointer demangleProtocolNameImpl(unsigned depth) {
+ if (depth > OldDemangler::MaxDepth)
+ return nullptr;
+
+ // There's an ambiguity in between a substitution of
+ // the protocol and a substitution of the protocol's context, so
+ // we have to duplicate some of the logic from
+ // demangleDeclarationName.
+ if (Mangled.nextIf('S')) {
+ NodePointer sub = demangleSubstitutionIndex(depth + 1);
+ if (!sub) return nullptr;
+ if (sub->getKind() == Node::Kind::Protocol)
+ return sub;
+
+ if (sub->getKind() != Node::Kind::Module)
+ return nullptr;
+
+ return demangleProtocolNameGivenContext(sub, depth + 1);
+ }
+
+ if (Mangled.nextIf('s')) {
+ NodePointer stdlib = Factory.createNode(Node::Kind::Module, STDLIB_NAME);
+
+ return demangleProtocolNameGivenContext(stdlib, depth + 1);
+ }
+
+ return demangleDeclarationName(Node::Kind::Protocol, depth + 1);
+ }
+
+ NodePointer demangleNominalType(unsigned depth) {
+ if (Mangled.nextIf('S'))
+ return demangleSubstitutionIndex(depth + 1);
+ if (Mangled.nextIf('V'))
+ return demangleDeclarationName(Node::Kind::Structure, depth + 1);
+ if (Mangled.nextIf('O'))
+ return demangleDeclarationName(Node::Kind::Enum, depth + 1);
+ if (Mangled.nextIf('C'))
+ return demangleDeclarationName(Node::Kind::Class, depth + 1);
+ if (Mangled.nextIf('P'))
+ return demangleDeclarationName(Node::Kind::Protocol, depth + 1);
+ return nullptr;
+ }
+
+ NodePointer demangleBoundGenericArgs(NodePointer nominalType,
+ unsigned depth) {
+ if (nominalType->getNumChildren() == 0)
+ return nullptr;
+
+ // Generic arguments for the outermost type come first.
+ NodePointer parentOrModule = nominalType->getChild(0);
+
+ if (parentOrModule->getKind() != Node::Kind::Module &&
+ parentOrModule->getKind() != Node::Kind::Function &&
+ parentOrModule->getKind() != Node::Kind::Extension) {
+ parentOrModule = demangleBoundGenericArgs(parentOrModule, depth + 1);
+ if (!parentOrModule)
+ return nullptr;
+
+ // Rebuild this type with the new parent type, which may have
+ // had its generic arguments applied.
+ NodePointer result = Factory.createNode(nominalType->getKind());
+ result->addChild(parentOrModule, Factory);
+ for (unsigned ndx = 1; ndx < nominalType->getNumChildren(); ++ndx)
+ result->addChild(nominalType->getChild(ndx), Factory);
+
+ nominalType = result;
+ }
+
+ NodePointer args = Factory.createNode(Node::Kind::TypeList);
+ while (!Mangled.nextIf('_')) {
+ NodePointer type = demangleType(depth + 1);
+ if (!type)
+ return nullptr;
+ args->addChild(type, Factory);
+ if (Mangled.isEmpty())
+ return nullptr;
+ }
+
+ // If there were no arguments at this level there is nothing left
+ // to do.
+ if (args->getNumChildren() == 0)
+ return nominalType;
+
+ // Otherwise, build a bound generic type node from the unbound
+ // type and arguments.
+ NodePointer unboundType = Factory.createNode(Node::Kind::Type);
+ unboundType->addChild(nominalType, Factory);
+
+ Node::Kind kind;
+ switch (nominalType->getKind()) { // look through Type node
+ case Node::Kind::Class:
+ kind = Node::Kind::BoundGenericClass;
+ break;
+ case Node::Kind::Structure:
+ kind = Node::Kind::BoundGenericStructure;
+ break;
+ case Node::Kind::Enum:
+ kind = Node::Kind::BoundGenericEnum;
+ break;
+ default:
+ return nullptr;
+ }
+ NodePointer result = Factory.createNode(kind);
+ result->addChild(unboundType, Factory);
+ result->addChild(args, Factory);
+ return result;
+ }
+
+ NodePointer demangleBoundGenericType(unsigned depth) {
+ // bound-generic-type ::= 'G' nominal-type (args+ '_')+
+ //
+ // Each level of nominal type nesting has its own list of arguments.
+
+ NodePointer nominalType = demangleNominalType(depth + 1);
+ if (!nominalType)
+ return nullptr;
+
+ return demangleBoundGenericArgs(nominalType, depth + 1);
+ }
+
+ NodePointer demangleContext(unsigned depth) {
+ // context ::= module
+ // context ::= entity
+ // context ::= 'E' module context (extension defined in a different module)
+ // context ::= 'e' module context generic-signature (constrained extension)
+ if (!Mangled) return nullptr;
+ if (Mangled.nextIf('E')) {
+ NodePointer ext = Factory.createNode(Node::Kind::Extension);
+ NodePointer def_module = demangleModule(depth + 1);
+ if (!def_module) return nullptr;
+ NodePointer type = demangleContext(depth + 1);
+ if (!type) return nullptr;
+ ext->addChild(def_module, Factory);
+ ext->addChild(type, Factory);
+ return ext;
+ }
+ if (Mangled.nextIf('e')) {
+ NodePointer ext = Factory.createNode(Node::Kind::Extension);
+ NodePointer def_module = demangleModule(depth + 1);
+ if (!def_module) return nullptr;
+ NodePointer sig = demangleGenericSignature(depth + 1);
+ // The generic context is currently re-specified by the type mangling.
+ // If we ever remove 'self' from manglings, we should stop resetting the
+ // context here.
+ if (!sig) return nullptr;
+ NodePointer type = demangleContext(depth + 1);
+ if (!type) return nullptr;
+
+ ext->addChild(def_module, Factory);
+ ext->addChild(type, Factory);
+ ext->addChild(sig, Factory);
+ return ext;
+ }
+ if (Mangled.nextIf('S'))
+ return demangleSubstitutionIndex(depth + 1);
+ if (Mangled.nextIf('s'))
+ return Factory.createNode(Node::Kind::Module, STDLIB_NAME);
+ if (Mangled.nextIf('G'))
+ return demangleBoundGenericType(depth + 1);
+ if (isStartOfEntity(Mangled.peek()))
+ return demangleEntity(depth + 1);
+ return demangleModule(depth + 1);
+ }
+
+ NodePointer demangleProtocolList(unsigned depth) {
+ NodePointer proto_list = Factory.createNode(Node::Kind::ProtocolList);
+ NodePointer type_list = Factory.createNode(Node::Kind::TypeList);
+ proto_list->addChild(type_list, Factory);
+ while (!Mangled.nextIf('_')) {
+ NodePointer proto = demangleProtocolName(depth + 1);
+ if (!proto)
+ return nullptr;
+ type_list->addChild(proto, Factory);
+ }
+ return proto_list;
+ }
+
+ NodePointer demangleProtocolConformance(unsigned depth) {
+ NodePointer type = demangleType(depth + 1);
+ if (!type)
+ return nullptr;
+ NodePointer protocol = demangleProtocolName(depth + 1);
+ if (!protocol)
+ return nullptr;
+ NodePointer context = demangleContext(depth + 1);
+ if (!context)
+ return nullptr;
+ NodePointer proto_conformance =
+ Factory.createNode(Node::Kind::ProtocolConformance);
+ proto_conformance->addChild(type, Factory);
+ proto_conformance->addChild(protocol, Factory);
+ proto_conformance->addChild(context, Factory);
+ return proto_conformance;
+ }
+
+ // entity ::= entity-kind context entity-name
+ // entity ::= nominal-type
+ NodePointer demangleEntity(unsigned depth) {
+ if (depth > OldDemangler::MaxDepth)
+ return nullptr;
+
+ // static?
+ bool isStatic = Mangled.nextIf('Z');
+
+ // entity-kind
+ Node::Kind entityBasicKind;
+ if (Mangled.nextIf('F')) {
+ entityBasicKind = Node::Kind::Function;
+ } else if (Mangled.nextIf('v')) {
+ entityBasicKind = Node::Kind::Variable;
+ } else if (Mangled.nextIf('I')) {
+ entityBasicKind = Node::Kind::Initializer;
+ } else if (Mangled.nextIf('i')) {
+ entityBasicKind = Node::Kind::Subscript;
+ } else {
+ return demangleNominalType(depth + 1);
+ }
+
+ NodePointer context = demangleContext(depth + 1);
+ if (!context) return nullptr;
+
+ // entity-name
+ Node::Kind entityKind;
+ bool hasType = true;
+ // Wrap the enclosed entity in a variable or subscript node
+ bool wrapEntity = false;
+ NodePointer name = nullptr;
+ if (Mangled.nextIf('D')) {
+ entityKind = Node::Kind::Deallocator;
+ hasType = false;
+ } else if (Mangled.nextIf('Z')) {
+ entityKind = Node::Kind::IsolatedDeallocator;
+ hasType = false;
+ } else if (Mangled.nextIf('d')) {
+ entityKind = Node::Kind::Destructor;
+ hasType = false;
+ } else if (Mangled.nextIf('e')) {
+ entityKind = Node::Kind::IVarInitializer;
+ hasType = false;
+ } else if (Mangled.nextIf('E')) {
+ entityKind = Node::Kind::IVarDestroyer;
+ hasType = false;
+ } else if (Mangled.nextIf('C')) {
+ entityKind = Node::Kind::Allocator;
+ } else if (Mangled.nextIf('c')) {
+ entityKind = Node::Kind::Constructor;
+ } else if (Mangled.nextIf('a')) {
+ wrapEntity = true;
+ if (Mangled.nextIf('O')) {
+ entityKind = Node::Kind::OwningMutableAddressor;
+ } else if (Mangled.nextIf('o')) {
+ entityKind = Node::Kind::NativeOwningMutableAddressor;
+ } else if (Mangled.nextIf('p')) {
+ entityKind = Node::Kind::NativePinningMutableAddressor;
+ } else if (Mangled.nextIf('u')) {
+ entityKind = Node::Kind::UnsafeMutableAddressor;
+ } else {
+ return nullptr;
+ }
+ name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+ } else if (Mangled.nextIf('l')) {
+ wrapEntity = true;
+ if (Mangled.nextIf('O')) {
+ entityKind = Node::Kind::OwningAddressor;
+ } else if (Mangled.nextIf('o')) {
+ entityKind = Node::Kind::NativeOwningAddressor;
+ } else if (Mangled.nextIf('p')) {
+ entityKind = Node::Kind::NativePinningAddressor;
+ } else if (Mangled.nextIf('u')) {
+ entityKind = Node::Kind::UnsafeAddressor;
+ } else {
+ return nullptr;
+ }
+ name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+ } else if (Mangled.nextIf('g')) {
+ wrapEntity = true;
+ entityKind = Node::Kind::Getter;
+ name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+ } else if (Mangled.nextIf('G')) {
+ wrapEntity = true;
+ entityKind = Node::Kind::GlobalGetter;
+ name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+ } else if (Mangled.nextIf('s')) {
+ wrapEntity = true;
+ entityKind = Node::Kind::Setter;
+ name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+ } else if (Mangled.nextIf('m')) {
+ wrapEntity = true;
+ entityKind = Node::Kind::MaterializeForSet;
+ name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+ } else if (Mangled.nextIf('w')) {
+ wrapEntity = true;
+ entityKind = Node::Kind::WillSet;
+ name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+ } else if (Mangled.nextIf('W')) {
+ wrapEntity = true;
+ entityKind = Node::Kind::DidSet;
+ name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+ } else if (Mangled.nextIf('r')) {
+ wrapEntity = true;
+ entityKind = Node::Kind::ReadAccessor;
+ name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+ } else if (Mangled.nextIf('M')) {
+ wrapEntity = true;
+ entityKind = Node::Kind::ModifyAccessor;
+ name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+ } else if (Mangled.nextIf('U')) {
+ entityKind = Node::Kind::ExplicitClosure;
+ name = demangleIndexAsNode(depth + 1);
+ if (!name) return nullptr;
+ } else if (Mangled.nextIf('u')) {
+ entityKind = Node::Kind::ImplicitClosure;
+ name = demangleIndexAsNode(depth + 1);
+ if (!name) return nullptr;
+ } else if (entityBasicKind == Node::Kind::Initializer) {
+ // entity-name ::= 'A' index
+ if (Mangled.nextIf('A')) {
+ entityKind = Node::Kind::DefaultArgumentInitializer;
+ name = demangleIndexAsNode(depth + 1);
+ if (!name) return nullptr;
+ // entity-name ::= 'i'
+ } else if (Mangled.nextIf('i')) {
+ entityKind = Node::Kind::Initializer;
+ } else {
+ return nullptr;
+ }
+ hasType = false;
+ } else {
+ entityKind = entityBasicKind;
+ name = demangleDeclName(depth + 1);
+ if (!name) return nullptr;
+ }
+
+ NodePointer entity = Factory.createNode(entityKind);
+ if (wrapEntity) {
+ // Create a subscript or variable node and make it the accessor's child
+ NodePointer wrappedEntity;
+ bool isSubscript = false;
+
+ // Rewrite the subscript's name to match the new mangling scheme
+ switch (name->getKind()) {
+ case Node::Kind::Identifier:
+ if (name->getText() == "subscript") {
+ isSubscript = true;
+ // Subscripts have no 'subscript' identifier name
+ name = nullptr;
+ }
+ break;
+ case Node::Kind::PrivateDeclName: // identifier file-discriminator?
+ if (name->getNumChildren() > 1 &&
+ name->getChild(1)->getText() == "subscript") {
+ isSubscript = true;
+
+ auto discriminator = name->getChild(0);
+
+ // Create new PrivateDeclName with no 'subscript' identifier child
+ name = Factory.createNode(Node::Kind::PrivateDeclName);
+ name->addChild(discriminator, Factory);
+ }
+ break;
+ default:
+ break;
+ }
+
+ // Create wrapped entity node
+ if (isSubscript) {
+ wrappedEntity = Factory.createNode(Node::Kind::Subscript);
+ } else {
+ wrappedEntity = Factory.createNode(Node::Kind::Variable);
+ }
+ wrappedEntity->addChild(context, Factory);
+
+ // Variables mangle their name before their type
+ if (!isSubscript)
+ wrappedEntity->addChild(name, Factory);
+
+ if (hasType) {
+ auto type = demangleType(depth + 1);
+ if (!type) return nullptr;
+ wrappedEntity->addChild(type, Factory);
+ }
+
+ // Subscripts mangle their file-discriminator after the type
+ if (isSubscript && name)
+ wrappedEntity->addChild(name, Factory);
+
+ entity->addChild(wrappedEntity, Factory);
+ } else {
+ entity->addChild(context, Factory);
+
+ if (name) entity->addChild(name, Factory);
+
+ if (hasType) {
+ auto type = demangleType(depth + 1);
+ if (!type) return nullptr;
+ entity->addChild(type, Factory);
+ }
+ }
+
+ if (isStatic) {
+ auto staticNode = Factory.createNode(Node::Kind::Static);
+ staticNode->addChild(entity, Factory);
+ return staticNode;
+ }
+
+ return entity;
+ }
+
+ NodePointer getDependentGenericParamType(unsigned depth, unsigned index) {
+ DemanglerPrinter PrintName;
+ PrintName << genericParameterName(depth, index);
+
+ auto paramTy = Factory.createNode(Node::Kind::DependentGenericParamType);
+ paramTy->addChild(Factory.createNode(Node::Kind::Index, depth), Factory);
+ paramTy->addChild(Factory.createNode(Node::Kind::Index, index), Factory);
+
+ return paramTy;
+ }
+
+ NodePointer demangleGenericParamIndex(unsigned depth) {
+ Node::IndexType paramDepth, index;
+
+ if (Mangled.nextIf('d')) {
+ if (!demangleIndex(paramDepth, depth + 1))
+ return nullptr;
+ paramDepth += 1;
+ if (!demangleIndex(index, depth + 1))
+ return nullptr;
+ } else if (Mangled.nextIf('x')) {
+ paramDepth = 0;
+ index = 0;
+ } else {
+ if (!demangleIndex(index, depth + 1))
+ return nullptr;
+ paramDepth = 0;
+ index += 1;
+ }
+ return getDependentGenericParamType(paramDepth, index);
+ }
+
+ NodePointer demangleDependentMemberTypeName(NodePointer base,
+ unsigned depth) {
+ assert(base->getKind() == Node::Kind::Type
+ && "base should be a type");
+ NodePointer assocTy = nullptr;
+
+ if (Mangled.nextIf('S')) {
+ assocTy = demangleSubstitutionIndex(depth + 1);
+ if (!assocTy)
+ return nullptr;
+ if (assocTy->getKind() != Node::Kind::DependentAssociatedTypeRef)
+ return nullptr;
+ } else {
+ NodePointer protocol = nullptr;
+ if (Mangled.nextIf('P')) {
+ protocol = demangleProtocolName(depth + 1);
+ if (!protocol) return nullptr;
+ }
+
+ // TODO: If the protocol name was elided from the assoc type mangling,
+ // we could try to fish it out of the generic signature constraints on the
+ // base.
+ NodePointer ID = demangleIdentifier(depth + 1);
+ if (!ID) return nullptr;
+ assocTy = Factory.createNode(Node::Kind::DependentAssociatedTypeRef);
+ if (!assocTy) return nullptr;
+ assocTy->addChild(ID, Factory);
+ if (protocol)
+ assocTy->addChild(protocol, Factory);
+
+ Substitutions.push_back(assocTy);
+ }
+
+ NodePointer depTy = Factory.createNode(Node::Kind::DependentMemberType);
+ depTy->addChild(base, Factory);
+ depTy->addChild(assocTy, Factory);
+ return depTy;
+ }
+
+ NodePointer demangleAssociatedTypeSimple(unsigned depth) {
+ // Demangle the base type.
+ auto base = demangleGenericParamIndex(depth + 1);
+ if (!base)
+ return nullptr;
+
+ NodePointer nodeType = Factory.createNode(Node::Kind::Type);
+ nodeType->addChild(base, Factory);
+
+ // Demangle the associated type name.
+ return demangleDependentMemberTypeName(nodeType, depth + 1);
+ }
+
+ NodePointer demangleAssociatedTypeCompound(unsigned depth) {
+ // Demangle the base type.
+ auto base = demangleGenericParamIndex(depth + 1);
+ if (!base)
+ return nullptr;
+
+ // Demangle the associated type chain.
+ while (!Mangled.nextIf('_')) {
+ NodePointer nodeType = Factory.createNode(Node::Kind::Type);
+ nodeType->addChild(base, Factory);
+
+ base = demangleDependentMemberTypeName(nodeType, depth + 1);
+ if (!base)
+ return nullptr;
+ }
+
+ return base;
+ }
+
+ NodePointer demangleDependentType(unsigned depth) {
+ if (!Mangled)
+ return nullptr;
+
+ // A dependent member type begins with a non-index, non-'d' character.
+ auto c = Mangled.peek();
+ if (c != 'd' && c != '_' && !Mangle::isDigit(c)) {
+ NodePointer baseType = demangleType(depth + 1);
+ if (!baseType) return nullptr;
+ return demangleDependentMemberTypeName(baseType, depth + 1);
+ }
+
+ // Otherwise, we have a generic parameter.
+ return demangleGenericParamIndex(depth + 1);
+ }
+
+ NodePointer demangleConstrainedTypeImpl(unsigned depth) {
+ // The constrained type can only be a generic parameter or an associated
+ // type thereof. The 'q' introducer is thus left off of generic params.
+ if (Mangled.nextIf('w')) {
+ return demangleAssociatedTypeSimple(depth + 1);
+ }
+ if (Mangled.nextIf('W')) {
+ return demangleAssociatedTypeCompound(depth + 1);
+ }
+ return demangleGenericParamIndex(depth + 1);
+ }
+
+ NodePointer demangleConstrainedType(unsigned depth) {
+ auto type = demangleConstrainedTypeImpl(depth);
+ if (!type)
+ return nullptr;
+
+ NodePointer nodeType = Factory.createNode(Node::Kind::Type);
+ nodeType->addChild(type, Factory);
+ return nodeType;
+ }
+
+ NodePointer demangleGenericSignature(unsigned depth,
+ bool isPseudogeneric = false) {
+ auto sig =
+ Factory.createNode(isPseudogeneric
+ ? Node::Kind::DependentPseudogenericSignature
+ : Node::Kind::DependentGenericSignature);
+ // First read in the parameter counts at each depth.
+ Node::IndexType count = ~(Node::IndexType)0;
+
+ auto addCount = [&]{
+ auto countNode =
+ Factory.createNode(Node::Kind::DependentGenericParamCount, count);
+ sig->addChild(countNode, Factory);
+ };
+
+ while (Mangled.peek() != 'R' && Mangled.peek() != 'r') {
+ if (Mangled.nextIf('z')) {
+ count = 0;
+ } else if (demangleIndex(count, depth + 1)) {
+ count += 1;
+ } else {
+ return nullptr;
+ }
+ addCount();
+ }
+
+ // No mangled parameters means we have exactly one.
+ if (count == ~(Node::IndexType)0) {
+ count = 1;
+ addCount();
+ }
+
+ // Next read in the generic requirements, if any.
+ if (Mangled.nextIf('r'))
+ return sig;
+
+ if (!Mangled.nextIf('R'))
+ return nullptr;
+
+ while (!Mangled.nextIf('r')) {
+ NodePointer reqt = demangleGenericRequirement(depth + 1);
+ if (!reqt) return nullptr;
+ sig->addChild(reqt, Factory);
+ }
+
+ return sig;
+ }
+
+ NodePointer demangleMetatypeRepresentation(unsigned depth) {
+ if (Mangled.nextIf('t'))
+ return Factory.createNode(Node::Kind::MetatypeRepresentation, "@thin");
+
+ if (Mangled.nextIf('T'))
+ return Factory.createNode(Node::Kind::MetatypeRepresentation, "@thick");
+
+ if (Mangled.nextIf('o'))
+ return Factory.createNode(Node::Kind::MetatypeRepresentation,
+ "@objc_metatype");
+
+ // Unknown metatype representation
+ return nullptr;
+ }
+
+ NodePointer demangleGenericRequirement(unsigned depth) {
+ NodePointer constrainedType = demangleConstrainedType(depth + 1);
+ if (!constrainedType)
+ return nullptr;
+ if (Mangled.nextIf('z')) {
+ NodePointer second = demangleType(depth + 1);
+ if (!second) return nullptr;
+ auto reqt = Factory.createNode(
+ Node::Kind::DependentGenericSameTypeRequirement);
+ reqt->addChild(constrainedType, Factory);
+ reqt->addChild(second, Factory);
+ return reqt;
+ }
+
+ if (Mangled.nextIf('l')) {
+ StringRef name;
+ Node::Kind kind;
+ Node::IndexType size = SIZE_MAX;
+ Node::IndexType alignment = SIZE_MAX;
+ if (Mangled.nextIf('U')) {
+ kind = Node::Kind::Identifier;
+ name = "U";
+ } else if (Mangled.nextIf('R')) {
+ kind = Node::Kind::Identifier;
+ name = "R";
+ } else if (Mangled.nextIf('N')) {
+ kind = Node::Kind::Identifier;
+ name = "N";
+ } else if (Mangled.nextIf('T')) {
+ kind = Node::Kind::Identifier;
+ name = "T";
+ } else if (Mangled.nextIf('B')) {
+ kind = Node::Kind::Identifier;
+ name = "B";
+ } else if (Mangled.nextIf('E')) {
+ kind = Node::Kind::Identifier;
+ if (!demangleNatural(size, depth + 1))
+ return nullptr;
+ if (!Mangled.nextIf('_'))
+ return nullptr;
+ if (!demangleNatural(alignment, depth + 1))
+ return nullptr;
+ name = "E";
+ } else if (Mangled.nextIf('e')) {
+ kind = Node::Kind::Identifier;
+ if (!demangleNatural(size, depth + 1))
+ return nullptr;
+ name = "e";
+ } else if (Mangled.nextIf('M')) {
+ kind = Node::Kind::Identifier;
+ if (!demangleNatural(size, depth + 1))
+ return nullptr;
+ if (!Mangled.nextIf('_'))
+ return nullptr;
+ if (!demangleNatural(alignment, depth + 1))
+ return nullptr;
+ name = "M";
+ } else if (Mangled.nextIf('m')) {
+ kind = Node::Kind::Identifier;
+ if (!demangleNatural(size, depth + 1))
+ return nullptr;
+ name = "m";
+ } else if (Mangled.nextIf('S')) {
+ kind = Node::Kind::Identifier;
+ if (!demangleNatural(size, depth + 1))
+ return nullptr;
+ name = "S";
+ } else {
+ return nullptr;
+ }
+
+ NodePointer second = Factory.createNode(kind, name);
+ if (!second) return nullptr;
+ auto reqt = Factory.createNode(
+ Node::Kind::DependentGenericLayoutRequirement);
+ reqt->addChild(constrainedType, Factory);
+ reqt->addChild(second, Factory);
+ if (size != SIZE_MAX) {
+ reqt->addChild(Factory.createNode(Node::Kind::Number, size), Factory);
+ if (alignment != SIZE_MAX)
+ reqt->addChild(Factory.createNode(Node::Kind::Number, alignment), Factory);
+ }
+ return reqt;
+ }
+
+ // Base class constraints are introduced by a class type mangling, which
+ // will begin with either 'C' or 'S'.
+ if (!Mangled)
+ return nullptr;
+ NodePointer constraint = nullptr;
+
+ auto next = Mangled.peek();
+
+ if (next == 'C') {
+ constraint = demangleType(depth + 1);
+ if (!constraint) return nullptr;
+ } else if (next == 'S') {
+ // A substitution may be either the module name of a protocol or a full
+ // type name.
+ NodePointer typeName = nullptr;
+ Mangled.next();
+ NodePointer sub = demangleSubstitutionIndex(depth + 1);
+ if (!sub) return nullptr;
+ if (sub->getKind() == Node::Kind::Protocol
+ || sub->getKind() == Node::Kind::Class) {
+ typeName = sub;
+ } else if (sub->getKind() == Node::Kind::Module) {
+ typeName = demangleProtocolNameGivenContext(sub, depth + 1);
+ if (!typeName)
+ return nullptr;
+ } else {
+ return nullptr;
+ }
+ constraint = Factory.createNode(Node::Kind::Type);
+ constraint->addChild(typeName, Factory);
+ } else {
+ constraint = demangleProtocolName(depth + 1);
+ if (!constraint)
+ return nullptr;
+ }
+ auto reqt = Factory.createNode(
+ Node::Kind::DependentGenericConformanceRequirement);
+ reqt->addChild(constrainedType, Factory);
+ reqt->addChild(constraint, Factory);
+ return reqt;
+ }
+
+ NodePointer demangleArchetypeType(unsigned depth) {
+ auto makeAssociatedType = [&](NodePointer root) -> NodePointer {
+ NodePointer name = demangleIdentifier(depth + 1);
+ if (!name)
+ return nullptr;
+ auto assocType = Factory.createNode(Node::Kind::AssociatedTypeRef);
+ assocType->addChild(root, Factory);
+ assocType->addChild(name, Factory);
+ Substitutions.push_back(assocType);
+ return assocType;
+ };
+
+ if (Mangled.nextIf('Q')) {
+ NodePointer root = demangleArchetypeType(depth + 1);
+ if (!root) return nullptr;
+ return makeAssociatedType(root);
+ }
+ if (Mangled.nextIf('S')) {
+ NodePointer sub = demangleSubstitutionIndex(depth + 1);
+ if (!sub) return nullptr;
+ return makeAssociatedType(sub);
+ }
+ if (Mangled.nextIf('s')) {
+ NodePointer stdlib = Factory.createNode(Node::Kind::Module, STDLIB_NAME);
+ return makeAssociatedType(stdlib);
+ }
+ return nullptr;
+ }
+
+ NodePointer demangleTuple(IsVariadic isV, unsigned depth) {
+ NodePointer tuple = Factory.createNode(Node::Kind::Tuple);
+ NodePointer elt = nullptr;
+ while (!Mangled.nextIf('_')) {
+ if (!Mangled)
+ return nullptr;
+ elt = Factory.createNode(Node::Kind::TupleElement);
+
+ if (isStartOfIdentifier(Mangled.peek())) {
+ NodePointer label =
+ demangleIdentifier(depth + 1, Node::Kind::TupleElementName);
+ if (!label)
+ return nullptr;
+ elt->addChild(label, Factory);
+ }
+
+ NodePointer type = demangleType(depth + 1);
+ if (!type)
+ return nullptr;
+ elt->addChild(type, Factory);
+
+ tuple->addChild(elt, Factory);
+ }
+ if (isV == IsVariadic::yes && elt) {
+ elt->reverseChildren();
+ NodePointer marker = Factory.createNode(Node::Kind::VariadicMarker);
+ elt->addChild(marker, Factory);
+ elt->reverseChildren();
+ }
+ return tuple;
+ }
+
+ NodePointer postProcessReturnTypeNode (NodePointer out_args) {
+ NodePointer out_node = Factory.createNode(Node::Kind::ReturnType);
+ out_node->addChild(out_args, Factory);
+ return out_node;
+ }
+
+ NodePointer demangleType(unsigned depth) {
+ NodePointer type = demangleTypeImpl(depth);
+ if (!type)
+ return nullptr;
+ NodePointer nodeType = Factory.createNode(Node::Kind::Type);
+ nodeType->addChild(type, Factory);
+ return nodeType;
+ }
+
+ NodePointer demangleFunctionType(Node::Kind kind, unsigned depth) {
+ bool throws = false, concurrent = false, async = false;
+ auto diffKind = MangledDifferentiabilityKind::NonDifferentiable;
+ NodePointer globalActorType = nullptr;
+ if (Mangled) {
+ throws = Mangled.nextIf('z');
+ concurrent = Mangled.nextIf('y');
+ async = Mangled.nextIf('Z');
+ if (Mangled.nextIf('D')) {
+ switch (auto kind = (MangledDifferentiabilityKind)Mangled.next()) {
+ case MangledDifferentiabilityKind::Forward:
+ case MangledDifferentiabilityKind::Reverse:
+ case MangledDifferentiabilityKind::Normal:
+ case MangledDifferentiabilityKind::Linear:
+ diffKind = kind;
+ break;
+ case MangledDifferentiabilityKind::NonDifferentiable:
+ assert(false && "Impossible case 'NonDifferentiable'");
+ }
+ }
+ if (Mangled.nextIf('Y')) {
+ globalActorType = demangleType(depth + 1);
+ if (!globalActorType)
+ return nullptr;
+ }
+ }
+ NodePointer in_args = demangleType(depth + 1);
+ if (!in_args)
+ return nullptr;
+ NodePointer out_args = demangleType(depth + 1);
+ if (!out_args)
+ return nullptr;
+ NodePointer block = Factory.createNode(kind);
+
+ if (throws) {
+ block->addChild(Factory.createNode(Node::Kind::ThrowsAnnotation), Factory);
+ }
+ if (async) {
+ block->addChild(Factory.createNode(Node::Kind::AsyncAnnotation), Factory);
+ }
+ if (concurrent) {
+ block->addChild(
+ Factory.createNode(Node::Kind::ConcurrentFunctionType), Factory);
+ }
+ if (diffKind != MangledDifferentiabilityKind::NonDifferentiable) {
+ block->addChild(
+ Factory.createNode(
+ Node::Kind::DifferentiableFunctionType, (char)diffKind), Factory);
+ }
+ if (globalActorType) {
+ auto globalActorNode =
+ Factory.createNode(Node::Kind::GlobalActorFunctionType);
+ globalActorNode->addChild(globalActorType, Factory);
+ block->addChild(globalActorNode, Factory);
+ }
+ // Is there any need to handle isolated(any) function types here?
+
+ NodePointer in_node = Factory.createNode(Node::Kind::ArgumentTuple);
+ block->addChild(in_node, Factory);
+ in_node->addChild(in_args, Factory);
+ block->addChild(postProcessReturnTypeNode(out_args), Factory);
+ return block;
+ }
+
+ NodePointer demangleTypeImpl(unsigned depth) {
+ if (depth > OldDemangler::MaxDepth || !Mangled)
+ return nullptr;
+ char c = Mangled.next();
+ if (c == 'B') {
+ if (!Mangled)
+ return nullptr;
+ c = Mangled.next();
+ if (c == 'b')
+ return Factory.createNode(Node::Kind::BuiltinTypeName,
+ "Builtin.BridgeObject");
+ if (c == 'B')
+ return Factory.createNode(Node::Kind::BuiltinTypeName,
+ "Builtin.UnsafeValueBuffer");
+ if (c == 'f') {
+ Node::IndexType size;
+ if (demangleBuiltinSize(size, depth + 1)) {
+ return Factory.createNode(
+ Node::Kind::BuiltinTypeName,
+ std::move(DemanglerPrinter() << "Builtin.FPIEEE" << size).str());
+ }
+ }
+ if (c == 'i') {
+ Node::IndexType size;
+ if (demangleBuiltinSize(size, depth + 1)) {
+ return Factory.createNode(
+ Node::Kind::BuiltinTypeName,
+ (DemanglerPrinter() << "Builtin.Int" << size).str());
+ }
+ }
+ if (c == 'v') {
+ Node::IndexType elts;
+ if (demangleNatural(elts, depth + 1)) {
+ if (!Mangled.nextIf('B'))
+ return nullptr;
+ if (Mangled.nextIf('i')) {
+ Node::IndexType size;
+ if (!demangleBuiltinSize(size, depth + 1))
+ return nullptr;
+ return Factory.createNode(
+ Node::Kind::BuiltinTypeName,
+ (DemanglerPrinter() << "Builtin.Vec" << elts << "xInt" << size)
+ .str());
+ }
+ if (Mangled.nextIf('f')) {
+ Node::IndexType size;
+ if (!demangleBuiltinSize(size, depth + 1))
+ return nullptr;
+ return Factory.createNode(
+ Node::Kind::BuiltinTypeName,
+ (DemanglerPrinter() << "Builtin.Vec" << elts << "xFPIEEE"
+ << size).str());
+ }
+ if (Mangled.nextIf('p'))
+ return Factory.createNode(
+ Node::Kind::BuiltinTypeName,
+ (DemanglerPrinter() << "Builtin.Vec" << elts << "xRawPointer")
+ .str());
+ }
+ }
+ if (c == 'O')
+ return Factory.createNode(Node::Kind::BuiltinTypeName,
+ "Builtin.UnknownObject");
+ if (c == 'o')
+ return Factory.createNode(Node::Kind::BuiltinTypeName,
+ "Builtin.NativeObject");
+ if (c == 'p')
+ return Factory.createNode(Node::Kind::BuiltinTypeName,
+ "Builtin.RawPointer");
+ if (c == 't')
+ return Factory.createNode(Node::Kind::BuiltinTypeName,
+ "Builtin.SILToken");
+ if (c == 'w')
+ return Factory.createNode(Node::Kind::BuiltinTypeName,
+ "Builtin.Word");
+ return nullptr;
+ }
+ if (c == 'a')
+ return demangleDeclarationName(Node::Kind::TypeAlias, depth + 1);
+
+ if (c == 'b') {
+ return demangleFunctionType(Node::Kind::ObjCBlock, depth + 1);
+ }
+ if (c == 'c') {
+ return demangleFunctionType(Node::Kind::CFunctionPointer, depth + 1);
+ }
+ if (c == 'D') {
+ NodePointer type = demangleType(depth + 1);
+ if (!type)
+ return nullptr;
+
+ NodePointer dynamicSelf = Factory.createNode(Node::Kind::DynamicSelf);
+ dynamicSelf->addChild(type, Factory);
+ return dynamicSelf;
+ }
+ if (c == 'E') {
+ if (!Mangled.nextIf('R'))
+ return nullptr;
+ if (!Mangled.nextIf('R'))
+ return nullptr;
+ return Factory.createNode(Node::Kind::ErrorType, std::string());
+ }
+ if (c == 'F') {
+ return demangleFunctionType(Node::Kind::FunctionType, depth + 1);
+ }
+ if (c == 'f') {
+ return demangleFunctionType(Node::Kind::UncurriedFunctionType, depth + 1);
+ }
+ if (c == 'G') {
+ return demangleBoundGenericType(depth + 1);
+ }
+ if (c == 'X') {
+ if (Mangled.nextIf('b')) {
+ NodePointer type = demangleType(depth + 1);
+ if (!type)
+ return nullptr;
+ NodePointer boxType = Factory.createNode(Node::Kind::SILBoxType);
+ boxType->addChild(type, Factory);
+ return boxType;
+ }
+ if (Mangled.nextIf('B')) {
+ NodePointer signature = nullptr;
+ if (Mangled.nextIf('G')) {
+ signature = demangleGenericSignature(depth, /*pseudogeneric*/ false);
+ if (!signature)
+ return nullptr;
+ }
+ NodePointer layout = Factory.createNode(Node::Kind::SILBoxLayout);
+ while (!Mangled.nextIf('_')) {
+ Node::Kind kind;
+ if (Mangled.nextIf('m'))
+ kind = Node::Kind::SILBoxMutableField;
+ else if (Mangled.nextIf('i'))
+ kind = Node::Kind::SILBoxImmutableField;
+ else
+ return nullptr;
+
+ auto type = demangleType(depth + 1);
+ if (!type)
+ return nullptr;
+ auto field = Factory.createNode(kind);
+ field->addChild(type, Factory);
+ layout->addChild(field, Factory);
+ }
+ NodePointer genericArgs = nullptr;
+ if (signature) {
+ genericArgs = Factory.createNode(Node::Kind::TypeList);
+ while (!Mangled.nextIf('_')) {
+ auto type = demangleType(depth + 1);
+ if (!type)
+ return nullptr;
+ genericArgs->addChild(type, Factory);
+ }
+ }
+ NodePointer boxType =
+ Factory.createNode(Node::Kind::SILBoxTypeWithLayout);
+ boxType->addChild(layout, Factory);
+ if (signature) {
+ boxType->addChild(signature, Factory);
+ assert(genericArgs);
+ boxType->addChild(genericArgs, Factory);
+ }
+ return boxType;
+ }
+ }
+ if (c == 'K') {
+ return demangleFunctionType(Node::Kind::AutoClosureType, depth + 1);
+ }
+ if (c == 'M') {
+ NodePointer type = demangleType(depth + 1);
+ if (!type)
+ return nullptr;
+ NodePointer metatype = Factory.createNode(Node::Kind::Metatype);
+ metatype->addChild(type, Factory);
+ return metatype;
+ }
+ if (c == 'X') {
+ if (Mangled.nextIf('M')) {
+ NodePointer metatypeRepr = demangleMetatypeRepresentation(depth + 1);
+ if (!metatypeRepr) return nullptr;
+
+ NodePointer type = demangleType(depth + 1);
+ if (!type)
+ return nullptr;
+ NodePointer metatype = Factory.createNode(Node::Kind::Metatype);
+ metatype->addChild(metatypeRepr, Factory);
+ metatype->addChild(type, Factory);
+ return metatype;
+ }
+ }
+ if (c == 'P') {
+ if (Mangled.nextIf('M')) {
+ NodePointer type = demangleType(depth + 1);
+ if (!type) return nullptr;
+ auto metatype = Factory.createNode(Node::Kind::ExistentialMetatype);
+ metatype->addChild(type, Factory);
+ return metatype;
+ }
+
+ return demangleProtocolList(depth + 1);
+ }
+
+ if (c == 'X') {
+ if (Mangled.nextIf('P')) {
+ if (Mangled.nextIf('M')) {
+ NodePointer metatypeRepr = demangleMetatypeRepresentation(depth + 1);
+ if (!metatypeRepr) return nullptr;
+
+ NodePointer type = demangleType(depth + 1);
+ if (!type) return nullptr;
+
+ auto metatype = Factory.createNode(Node::Kind::ExistentialMetatype);
+ metatype->addChild(metatypeRepr, Factory);
+ metatype->addChild(type, Factory);
+ return metatype;
+ }
+
+ return demangleProtocolList(depth + 1);
+ }
+ }
+ if (c == 'Q') {
+ if (Mangled.nextIf('u')) {
+ // Special mangling for opaque return type.
+ return Factory.createNode(Node::Kind::OpaqueReturnType);
+ }
+ if (Mangled.nextIf('U')) {
+ // Special mangling for opaque return type.
+ Node::IndexType ordinal;
+ if (!demangleIndex(ordinal, depth))
+ return nullptr;
+ auto result = Factory.createNode(Node::Kind::OpaqueReturnType);
+ result->addChild(
+ Factory.createNode(Node::Kind::OpaqueReturnTypeIndex, ordinal), Factory);
+ return result;
+ }
+ return demangleArchetypeType(depth + 1);
+ }
+ if (c == 'q') {
+ return demangleDependentType(depth + 1);
+ }
+ if (c == 'x') {
+ // Special mangling for the first generic param.
+ return getDependentGenericParamType(0, 0);
+ }
+ if (c == 'w') {
+ return demangleAssociatedTypeSimple(depth + 1);
+ }
+ if (c == 'W') {
+ return demangleAssociatedTypeCompound(depth + 1);
+ }
+ if (c == 'R') {
+ NodePointer inout = Factory.createNode(Node::Kind::InOut);
+ NodePointer type = demangleTypeImpl(depth + 1);
+ if (!type)
+ return nullptr;
+ inout->addChild(type, Factory);
+ return inout;
+ }
+ if (c == 'k') {
+ auto noDerivative = Factory.createNode(Node::Kind::NoDerivative);
+ auto type = demangleTypeImpl(depth + 1);
+ if (!type)
+ return nullptr;
+ noDerivative->addChild(type, Factory);
+ return noDerivative;
+ }
+ if (c == 'S') {
+ return demangleSubstitutionIndex(depth + 1);
+ }
+ if (c == 'T') {
+ return demangleTuple(IsVariadic::no, depth + 1);
+ }
+ if (c == 't') {
+ return demangleTuple(IsVariadic::yes, depth + 1);
+ }
+ if (c == 'u') {
+ NodePointer sig = demangleGenericSignature(depth + 1);
+ if (!sig) return nullptr;
+ NodePointer sub = demangleType(depth + 1);
+ if (!sub) return nullptr;
+ NodePointer dependentGenericType
+ = Factory.createNode(Node::Kind::DependentGenericType);
+ dependentGenericType->addChild(sig, Factory);
+ dependentGenericType->addChild(sub, Factory);
+ return dependentGenericType;
+ }
+ if (c == 'X') {
+ if (Mangled.nextIf('f')) {
+ return demangleFunctionType(Node::Kind::ThinFunctionType, depth + 1);
+ }
+ if (Mangled.nextIf('o')) {
+ NodePointer type = demangleType(depth + 1);
+ if (!type)
+ return nullptr;
+ NodePointer unowned = Factory.createNode(Node::Kind::Unowned);
+ unowned->addChild(type, Factory);
+ return unowned;
+ }
+ if (Mangled.nextIf('u')) {
+ NodePointer type = demangleType(depth + 1);
+ if (!type)
+ return nullptr;
+ NodePointer unowned = Factory.createNode(Node::Kind::Unmanaged);
+ unowned->addChild(type, Factory);
+ return unowned;
+ }
+ if (Mangled.nextIf('w')) {
+ NodePointer type = demangleType(depth + 1);
+ if (!type)
+ return nullptr;
+ NodePointer weak = Factory.createNode(Node::Kind::Weak);
+ weak->addChild(type, Factory);
+ return weak;
+ }
+
+ // type ::= 'XF' impl-function-type
+ if (Mangled.nextIf('F')) {
+ return demangleImplFunctionType(depth + 1);
+ }
+
+ return nullptr;
+ }
+ if (isStartOfNominalType(c))
+ return demangleDeclarationName(nominalTypeMarkerToNodeKind(c), depth + 1);
+ return nullptr;
+ }
+
+ bool demangleReabstractSignature(NodePointer signature, unsigned depth) {
+ if (Mangled.nextIf('G')) {
+ NodePointer generics = demangleGenericSignature(depth + 1);
+ if (!generics) return false;
+ signature->addChild(generics, Factory);
+ }
+
+ NodePointer srcType = demangleType(depth + 1);
+ if (!srcType) return false;
+ signature->addChild(srcType, Factory);
+
+ NodePointer destType = demangleType(depth + 1);
+ if (!destType) return false;
+ signature->addChild(destType, Factory);
+
+ return true;
+ }
+
+ // impl-function-type ::= impl-callee-convention impl-function-attribute*
+ // generics? '_' impl-parameter* '_' impl-result* '_'
+ // impl-function-attribute ::= 'Cb' // compatible with C block invocation function
+ // impl-function-attribute ::= 'Cc' // compatible with C global function
+ // impl-function-attribute ::= 'Cm' // compatible with Swift method
+ // impl-function-attribute ::= 'CO' // compatible with ObjC method
+ // impl-function-attribute ::= 'Cw' // compatible with protocol witness
+ // impl-function-attribute ::= 'G' // generic
+ NodePointer demangleImplFunctionType(unsigned depth) {
+ NodePointer type = Factory.createNode(Node::Kind::ImplFunctionType);
+
+ if (!demangleImplCalleeConvention(type, depth + 1))
+ return nullptr;
+
+ if (Mangled.nextIf('C')) {
+ if (Mangled.nextIf('b'))
+ addImplFunctionConvention(type, "block");
+ else if (Mangled.nextIf('c'))
+ addImplFunctionConvention(type, "c");
+ else if (Mangled.nextIf('m'))
+ addImplFunctionConvention(type, "method");
+ else if (Mangled.nextIf('O'))
+ addImplFunctionConvention(type, "objc_method");
+ else if (Mangled.nextIf('w'))
+ addImplFunctionConvention(type, "witness_method");
+ else
+ return nullptr;
+ }
+
+ if (Mangled.nextIf('h'))
+ addImplFunctionAttribute(type, "@Sendable");
+
+ if (Mangled.nextIf('H'))
+ addImplFunctionAttribute(type, "@async");
+
+ // Enter a new generic context if this type is generic.
+ // FIXME: replace with std::optional, when we have it.
+ bool isPseudogeneric = false;
+ if (Mangled.nextIf('G') ||
+ (isPseudogeneric = Mangled.nextIf('g'))) {
+ NodePointer generics =
+ demangleGenericSignature(depth + 1, isPseudogeneric);
+ if (!generics)
+ return nullptr;
+ type->addChild(generics, Factory);
+ }
+
+ // Expect the attribute terminator.
+ if (!Mangled.nextIf('_'))
+ return nullptr;
+
+ // Demangle the parameters.
+ if (!demangleImplParameters(type, depth + 1))
+ return nullptr;
+
+ // Demangle the result type.
+ if (!demangleImplResults(type, depth + 1))
+ return nullptr;
+
+ return type;
+ }
+
+ enum class ImplConventionContext { Callee, Parameter, Result };
+
+ /// impl-convention ::= 'a' // direct, autoreleased
+ /// impl-convention ::= 'd' // direct, no ownership transfer
+ /// impl-convention ::= 'D' // direct, no ownership transfer,
+ /// // dependent on self
+ /// impl-convention ::= 'g' // direct, guaranteed
+ /// impl-convention ::= 'e' // direct, deallocating
+ /// impl-convention ::= 'i' // indirect, ownership transfer
+ /// impl-convention ::= 'l' // indirect, inout
+ /// impl-convention ::= 'o' // direct, ownership transfer
+ ///
+ /// Returns an empty string otherwise.
+ StringRef demangleImplConvention(ImplConventionContext ctxt, unsigned depth) {
+#define CASE(CHAR, FOR_CALLEE, FOR_PARAMETER, FOR_RESULT) \
+ if (Mangled.nextIf(CHAR)) { \
+ switch (ctxt) { \
+ case ImplConventionContext::Callee: return (FOR_CALLEE); \
+ case ImplConventionContext::Parameter: return (FOR_PARAMETER); \
+ case ImplConventionContext::Result: return (FOR_RESULT); \
+ } \
+ return StringRef(); \
+ }
+ auto Nothing = StringRef();
+ CASE('a', Nothing, Nothing, "@autoreleased")
+ CASE('d', "@callee_unowned", "@unowned", "@unowned")
+ CASE('D', Nothing, Nothing, "@unowned_inner_pointer")
+ CASE('g', "@callee_guaranteed", "@guaranteed", Nothing)
+ CASE('e', Nothing, "@deallocating", Nothing)
+ CASE('i', Nothing, "@in", "@out")
+ CASE('l', Nothing, "@inout", Nothing)
+ CASE('o', "@callee_owned", "@owned", "@owned")
+ return Nothing;
+#undef CASE
+ }
+
+ // impl-callee-convention ::= 't'
+ // impl-callee-convention ::= impl-convention
+ bool demangleImplCalleeConvention(NodePointer type, unsigned depth) {
+ StringRef attr;
+ if (Mangled.nextIf('t')) {
+ attr = "@convention(thin)";
+ } else {
+ attr = demangleImplConvention(ImplConventionContext::Callee, depth + 1);
+ }
+ if (attr.empty()) {
+ return false;
+ }
+ type->addChild(Factory.createNode(Node::Kind::ImplConvention, attr), Factory);
+ return true;
+ }
+
+ void addImplFunctionAttribute(NodePointer parent, StringRef attr,
+ Node::Kind kind = Node::Kind::ImplFunctionAttribute) {
+ parent->addChild(Factory.createNode(kind, attr), Factory);
+ }
+
+ void addImplFunctionConvention(NodePointer parent, StringRef attr) {
+ auto attrNode = Factory.createNode(Node::Kind::ImplFunctionConvention);
+ attrNode->addChild(
+ Factory.createNode(Node::Kind::ImplFunctionConventionName, attr),
+ Factory);
+ parent->addChild(attrNode, Factory);
+ }
+
+ // impl-parameter ::= impl-convention type
+ bool demangleImplParameters(NodePointer parent, unsigned depth) {
+ while (!Mangled.nextIf('_')) {
+ auto input =
+ demangleImplParameterOrResult(Node::Kind::ImplParameter, depth + 1);
+ if (!input) return false;
+ parent->addChild(input, Factory);
+ }
+ return true;
+ }
+
+ // impl-result ::= impl-convention type
+ bool demangleImplResults(NodePointer parent, unsigned depth) {
+ while (!Mangled.nextIf('_')) {
+ auto res =
+ demangleImplParameterOrResult(Node::Kind::ImplResult, depth + 1);
+ if (!res) return false;
+ parent->addChild(res, Factory);
+ }
+ return true;
+ }
+
+ NodePointer demangleImplParameterOrResult(Node::Kind kind, unsigned depth) {
+ if (Mangled.nextIf('z')) {
+ // Only valid for a result.
+ if (kind != Node::Kind::ImplResult)
+ return nullptr;
+ kind = Node::Kind::ImplErrorResult;
+ }
+
+ ImplConventionContext ConvCtx;
+ if (kind == Node::Kind::ImplParameter) {
+ ConvCtx = ImplConventionContext::Parameter;
+ } else if (kind == Node::Kind::ImplResult
+ || kind == Node::Kind::ImplErrorResult) {
+ ConvCtx = ImplConventionContext::Result;
+ } else {
+ return nullptr;
+ }
+
+ auto convention = demangleImplConvention(ConvCtx, depth + 1);
+ if (convention.empty()) return nullptr;
+ auto type = demangleType(depth + 1);
+ if (!type) return nullptr;
+
+ NodePointer node = Factory.createNode(kind);
+ node->addChild(Factory.createNode(Node::Kind::ImplConvention, convention),
+ Factory);
+ node->addChild(type, Factory);
+
+ return node;
+ }
+};
+} // end anonymous namespace
+
+NodePointer
+swift::Demangle::demangleOldSymbolAsNode(StringRef MangledName,
+ NodeFactory &Factory) {
+ OldDemangler demangler(MangledName, Factory);
+ return demangler.demangleTopLevel();
+}
+
diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/OldRemangler.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/OldRemangler.cpp
new file mode 100644
index 000000000..86d8d1f7f
--- /dev/null
+++ b/symbolic-demangle/vendor/swift/lib/Demangling/OldRemangler.cpp
@@ -0,0 +1,3099 @@
+//===--- 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
+#include
+
+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::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 << "";
+ 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::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 << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleAssociatedConformanceDescriptor(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError
+Remangler::mangleDefaultAssociatedConformanceAccessor(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleBaseConformanceDescriptor(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ 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 << "";
+ 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 << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleReabstractionThunkHelper(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError
+Remangler::mangleReabstractionThunkHelperWithSelf(Node *node, unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleReabstractionThunk(Node *node, unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError
+Remangler::mangleReabstractionThunkHelperWithGlobalActor(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleAutoDiffFunction(Node *node, EntityContext &ctx,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleAutoDiffDerivativeVTableThunk(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError
+Remangler::mangleAutoDiffSelfReorderingReabstractionThunk(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleAutoDiffSubsetParametersThunk(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleAutoDiffFunctionKind(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleDifferentiabilityWitness(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleIndexSubset(Node *node, unsigned depth) {
+ Buffer << "";
+ 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::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
+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 << "";
+ 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::InvalidImplParameterSending, node);
+}
+
+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::mangleCompileTimeConst(Node *node, unsigned depth) {
+ Buffer << "Yt";
+ 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 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 << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleSILThunkIdentity(Node *node, unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleSILThunkHopToMainActorIfNeeded(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleDispatchThunk(Node *node, unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleMethodDescriptor(Node *node, unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleMethodLookupFunction(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleObjCMetadataUpdateFunction(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleObjCResilientClassStub(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleFullObjCResilientClassStub(Node *node,
+ unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleEmptyList(Node *node, unsigned depth) {
+ Buffer << "";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleFirstElementMarker(Node *node, unsigned depth) {
+ Buffer << "";
+ 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::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::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::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
+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
+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
+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);
+}
diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/Remangler.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/Remangler.cpp
index be1bca1d7..ab51452a5 100644
--- a/symbolic-demangle/vendor/swift/lib/Demangling/Remangler.cpp
+++ b/symbolic-demangle/vendor/swift/lib/Demangling/Remangler.cpp
@@ -359,7 +359,7 @@ class Remangler : public RemanglerBase {
}
ManglingError mangleGenericSpecializationNode(Node *node,
- const char *operatorStr,
+ char specKind,
unsigned depth);
ManglingError mangleAnyNominalType(Node *node, unsigned depth);
ManglingError mangleAnyGenericType(Node *node, StringRef TypeOp,
@@ -374,6 +374,9 @@ class Remangler : public RemanglerBase {
ManglingError mangleKeyPathThunkHelper(Node *node, StringRef op,
unsigned depth);
+ ManglingError mangleSILThunkIdentity(Node *node, StringRef op,
+ unsigned depth);
+
ManglingError mangleAutoDiffFunctionOrSimpleThunk(Node *node, StringRef op,
unsigned depth);
@@ -720,7 +723,7 @@ ManglingError Remangler::mangleAllocator(Node *node, unsigned depth) {
}
ManglingError Remangler::mangleArgumentTuple(Node *node, unsigned depth) {
- Node *Child = skipType(getSingleChild(node));
+ Node *Child = skipType(node->getChild(0));
if (Child->getKind() == Node::Kind::Tuple &&
Child->getNumChildren() == 0) {
Buffer << 'y';
@@ -894,6 +897,12 @@ ManglingError Remangler::mangleBoundGenericFunction(Node *node,
return ManglingError::Success;
}
+ManglingError Remangler::mangleBuiltinFixedArray(Node *node, unsigned depth) {
+ RETURN_IF_ERROR(mangleChildNodes(node, depth + 1));
+ Buffer << "BV";
+ return ManglingError::Success;
+}
+
ManglingError Remangler::mangleBuiltinTypeName(Node *node, unsigned depth) {
Buffer << 'B';
StringRef text = node->getText();
@@ -1017,6 +1026,12 @@ ManglingError Remangler::mangleDeallocator(Node *node, unsigned depth) {
return ManglingError::Success;
}
+ManglingError Remangler::mangleIsolatedDeallocator(Node *node, unsigned depth) {
+ RETURN_IF_ERROR(mangleChildNodes(node, depth + 1));
+ Buffer << "fZ";
+ return ManglingError::Success;
+}
+
ManglingError Remangler::mangleDeclContext(Node *node, unsigned depth) {
return mangleSingleChildNode(node, depth + 1);
}
@@ -1693,7 +1708,7 @@ Remangler::mangleGenericPartialSpecializationNotReAbstracted(Node *node,
}
ManglingError
-Remangler::mangleGenericSpecializationNode(Node *node, const char *operatorStr,
+Remangler::mangleGenericSpecializationNode(Node *node, char specKind,
unsigned depth) {
bool FirstParam = true;
for (NodePointer Child : *node) {
@@ -1705,11 +1720,21 @@ Remangler::mangleGenericSpecializationNode(Node *node, const char *operatorStr,
DEMANGLER_ASSERT(
!FirstParam && "generic specialization with no substitutions", node);
- Buffer << operatorStr;
+ Buffer << 'T';
for (NodePointer Child : *node) {
- if (Child->getKind() != Node::Kind::GenericSpecializationParam)
+ if (Child->getKind() == Node::Kind::DroppedArgument)
+ RETURN_IF_ERROR(mangle(Child, depth + 1));
+ }
+
+
+ Buffer << specKind;
+
+ for (NodePointer Child : *node) {
+ if (Child->getKind() != Node::Kind::GenericSpecializationParam &&
+ Child->getKind() != Node::Kind::DroppedArgument) {
RETURN_IF_ERROR(mangle(Child, depth + 1));
+ }
}
return ManglingError::Success;
@@ -1717,30 +1742,30 @@ Remangler::mangleGenericSpecializationNode(Node *node, const char *operatorStr,
ManglingError Remangler::mangleGenericSpecialization(Node *node,
unsigned depth) {
- return mangleGenericSpecializationNode(node, "Tg", depth + 1);
+ return mangleGenericSpecializationNode(node, 'g', depth + 1);
}
ManglingError
Remangler::mangleGenericSpecializationPrespecialized(Node *node,
unsigned depth) {
- return mangleGenericSpecializationNode(node, "Ts", depth + 1);
+ return mangleGenericSpecializationNode(node, 's', depth + 1);
}
ManglingError
Remangler::mangleGenericSpecializationNotReAbstracted(Node *node,
unsigned depth) {
- return mangleGenericSpecializationNode(node, "TG", depth + 1);
+ return mangleGenericSpecializationNode(node, 'G', depth + 1);
}
ManglingError
Remangler::mangleGenericSpecializationInResilienceDomain(Node *node,
unsigned depth) {
- return mangleGenericSpecializationNode(node, "TB", depth + 1);
+ return mangleGenericSpecializationNode(node, 'B', depth + 1);
}
ManglingError Remangler::mangleInlinedGenericFunction(Node *node,
unsigned depth) {
- return mangleGenericSpecializationNode(node, "Ti", depth + 1);
+ return mangleGenericSpecializationNode(node, 'i', depth + 1);
}
ManglingError Remangler::mangleGenericSpecializationParam(Node *node,
@@ -1966,13 +1991,19 @@ ManglingError Remangler::mangleImplPatternSubstitutions(Node *node,
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
+ManglingError Remangler::mangleImplCoroutineKind(Node *node,
+ unsigned depth) {
+ // handled inline
+ return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
+}
+
ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
const char *PseudoGeneric = "";
Node *GenSig = nullptr;
Node *PatternSubs = nullptr;
Node *InvocationSubs = nullptr;
for (NodePointer Child : *node) {
- switch (auto kind = Child->getKind()) {
+ switch (Child->getKind()) {
case Node::Kind::ImplParameter:
case Node::Kind::ImplResult:
case Node::Kind::ImplYield:
@@ -2064,13 +2095,25 @@ ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
RETURN_IF_ERROR(mangleImplFunctionConvention(Child, depth + 1));
break;
}
+ case Node::Kind::ImplCoroutineKind: {
+ char CoroAttr = llvm::StringSwitch(Child->getText())
+ .Case("yield_once", 'A')
+ .Case("yield_once_2", 'I')
+ .Case("yield_many", 'G')
+ .Default(0);
+
+ if (!CoroAttr) {
+ return MANGLING_ERROR(ManglingError::InvalidImplCoroutineKind,
+ Child);
+ }
+ Buffer << CoroAttr;
+ break;
+ }
case Node::Kind::ImplFunctionAttribute: {
char FuncAttr = llvm::StringSwitch(Child->getText())
- .Case("@yield_once", 'A')
- .Case("@yield_many", 'G')
- .Case("@Sendable", 'h')
- .Case("@async", 'H')
- .Default(0);
+ .Case("@Sendable", 'h')
+ .Case("@async", 'H')
+ .Default(0);
if (!FuncAttr) {
return MANGLING_ERROR(ManglingError::InvalidImplFunctionAttribute,
Child);
@@ -2089,6 +2132,7 @@ ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
.Case("@inout", 'l')
.Case("@inout_aliasable", 'b')
.Case("@in_guaranteed", 'n')
+ .Case("@in_cxx", 'X')
.Case("@in_constant", 'c')
.Case("@owned", 'x')
.Case("@guaranteed", 'g')
@@ -2222,19 +2266,6 @@ ManglingError Remangler::mangleNoDerivative(Node *node, unsigned depth) {
return ManglingError::Success;
}
-ManglingError Remangler::mangleParamLifetimeDependence(Node *node,
- unsigned depth) {
- RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1));
- Buffer << "Yl" << (char)node->getFirstChild()->getIndex();
- return ManglingError::Success;
-}
-
-ManglingError Remangler::mangleSelfLifetimeDependence(Node *node,
- unsigned depth) {
- Buffer << "YL" << (char)node->getIndex();
- return ManglingError::Success;
-}
-
ManglingError Remangler::mangleInfixOperator(Node *node, unsigned depth) {
mangleIdentifierImpl(node, /*isOperator*/ true);
Buffer << "oi";
@@ -2328,6 +2359,10 @@ ManglingError Remangler::mangleModifyAccessor(Node *node, unsigned depth) {
return mangleAbstractStorage(node->getFirstChild(), "M", depth + 1);
}
+ManglingError Remangler::mangleModify2Accessor(Node *node, unsigned depth) {
+ return mangleAbstractStorage(node->getFirstChild(), "x", depth + 1);
+}
+
ManglingError Remangler::mangleModule(Node *node, unsigned depth) {
auto text = node->getText();
if (text == STDLIB_NAME) {
@@ -2980,6 +3015,10 @@ ManglingError Remangler::mangleReadAccessor(Node *node, unsigned depth) {
return mangleAbstractStorage(node->getFirstChild(), "r", depth + 1);
}
+ManglingError Remangler::mangleRead2Accessor(Node *node, unsigned depth) {
+ return mangleAbstractStorage(node->getFirstChild(), "y", depth + 1);
+}
+
ManglingError Remangler::mangleKeyPathThunkHelper(Node *node, StringRef op,
unsigned depth) {
for (NodePointer Child : *node)
@@ -3052,8 +3091,11 @@ ManglingError Remangler::mangleAsyncRemoved(Node *node, unsigned depth) {
return ManglingError::Success;
}
-ManglingError Remangler::mangleMetatypeParamsRemoved(Node *node, unsigned depth) {
- Buffer << 'm';
+ManglingError Remangler::mangleDroppedArgument(Node *node, unsigned depth) {
+ Buffer << "t";
+ int n = node->getIndex();
+ if (n > 0)
+ Buffer << (n-1);
return ManglingError::Success;
}
@@ -3338,6 +3380,22 @@ ManglingError Remangler::mangleCurryThunk(Node *node, unsigned depth) {
return ManglingError::Success;
}
+ManglingError Remangler::mangleSILThunkIdentity(Node *node, unsigned depth) {
+ RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); // type
+ // TT is for a thunk that is for a thunk inst... I is for identity.
+ Buffer << "TT"
+ << "I";
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleSILThunkHopToMainActorIfNeeded(Node *node,
+ unsigned depth) {
+ RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); // type
+ Buffer << "TT"
+ << "H";
+ return ManglingError::Success;
+}
+
ManglingError Remangler::mangleDispatchThunk(Node *node, unsigned depth) {
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1));
Buffer << "Tj";
@@ -3936,6 +3994,32 @@ mangleNonUniqueExtendedExistentialTypeShapeSymbolicReference(Node *node,
// We don't support absolute references in the mangling of these
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
}
+
+ManglingError Remangler::mangleInteger(Node *node, unsigned int depth) {
+ Buffer << "$";
+ mangleIndex(node->getIndex());
+
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleNegativeInteger(Node *node, unsigned int depth) {
+ Buffer << "$n";
+ mangleIndex(-node->getIndex());
+
+ return ManglingError::Success;
+}
+
+ManglingError Remangler::mangleDependentGenericParamValueMarker(Node *node,
+ unsigned depth) {
+ DEMANGLER_ASSERT(node->getNumChildren() == 2, node);
+ DEMANGLER_ASSERT(node->getChild(0)->getChild(0)->getKind() == Node::Kind::DependentGenericParamType, node);
+ DEMANGLER_ASSERT(node->getChild(1)->getKind() == Node::Kind::Type, node);
+ RETURN_IF_ERROR(mangleType(node->getChild(1), depth + 1));
+ Buffer << "RV";
+ mangleDependentGenericParamIndex(node->getChild(0)->getChild(0));
+ return ManglingError::Success;
+}
+
} // anonymous namespace
/// The top-level interface to the remangler.