Skip to content

Commit 4ca9852

Browse files
committed
Allow for passing a custom Archetype naming schema to the demangler.
LLDB would like to substitute the original Archetype names from the source code when demangling symbols instead of the confusing generic 'A', 'B', ... <rdar://problem/48259889>
1 parent 8278c06 commit 4ca9852

File tree

3 files changed

+28
-15
lines changed

3 files changed

+28
-15
lines changed

include/swift/Demangling/Demangle.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -35,6 +35,11 @@ namespace Demangle {
3535

3636
enum class SymbolicReferenceKind : uint8_t;
3737

38+
/// A simple default implementation that assigns letters to archetypes in
39+
/// alphabetic order.
40+
std::string archetypeName(uint64_t index, uint64_t depth);
41+
42+
/// Display style options for the demangler.
3843
struct DemangleOptions {
3944
bool SynthesizeSugarOnTypes = false;
4045
bool DisplayDebuggerGeneratedModule = true;
@@ -52,6 +57,7 @@ struct DemangleOptions {
5257
bool ShortenArchetype = false;
5358
bool ShowPrivateDiscriminators = true;
5459
bool ShowFunctionArgumentTypes = true;
60+
std::function<std::string(uint64_t, uint64_t)> ArchetypeName = archetypeName;
5561

5662
DemangleOptions() {}
5763

@@ -346,17 +352,19 @@ class Context {
346352
/// prefix: _T, _T0, $S, _$S.
347353
///
348354
/// \returns The demangled string.
349-
std::string demangleSymbolAsString(llvm::StringRef MangledName,
350-
const DemangleOptions &Options = DemangleOptions());
355+
std::string demangleSymbolAsString(
356+
llvm::StringRef MangledName,
357+
const DemangleOptions &Options = DemangleOptions());
351358

352359
/// Demangle the given type and return the readable name.
353360
///
354361
/// \param MangledName The mangled type string, which does _not_ start with
355362
/// a mangling prefix.
356363
///
357364
/// \returns The demangled string.
358-
std::string demangleTypeAsString(llvm::StringRef MangledName,
359-
const DemangleOptions &Options = DemangleOptions());
365+
std::string
366+
demangleTypeAsString(llvm::StringRef MangledName,
367+
const DemangleOptions &Options = DemangleOptions());
360368

361369
/// Returns true if the mangledName refers to a thunk function.
362370
///
@@ -571,7 +579,6 @@ bool nodeConsumesGenericArgs(Node *node);
571579
bool isSpecialized(Node *node);
572580

573581
NodePointer getUnspecialized(Node *node, NodeFactory &Factory);
574-
std::string archetypeName(Node::IndexType index, Node::IndexType depth);
575582

576583
/// Form a StringRef around the mangled name starting at base, if the name may
577584
/// contain symbolic references.

lib/Demangling/NodePrinter.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@ DemanglerPrinter &DemanglerPrinter::operator<<(long long n) & {
5050
return *this;
5151
}
5252

53-
std::string Demangle::archetypeName(Node::IndexType index,
54-
Node::IndexType depth) {
53+
std::string Demangle::archetypeName(uint64_t index, uint64_t depth) {
5554
DemanglerPrinter name;
5655
do {
5756
name << (char)('A' + (index % 26));
@@ -1959,7 +1958,7 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
19591958
}
19601959
// FIXME: Depth won't match when a generic signature applies to a
19611960
// method in generic type context.
1962-
Printer << archetypeName(index, depth);
1961+
Printer << Options.ArchetypeName(index, depth);
19631962
}
19641963
}
19651964

@@ -2036,13 +2035,8 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
20362035
}
20372036
case Node::Kind::DependentGenericParamType: {
20382037
unsigned index = Node->getChild(1)->getIndex();
2039-
do {
2040-
Printer << (char)('A' + (index % 26));
2041-
index /= 26;
2042-
} while (index);
20432038
unsigned depth = Node->getChild(0)->getIndex();
2044-
if (depth != 0)
2045-
Printer << depth;
2039+
Printer << Options.ArchetypeName(index, depth);
20462040
return nullptr;
20472041
}
20482042
case Node::Kind::DependentGenericType: {

unittests/Basic/DemangleTest.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,15 @@ TEST(Demangle, IsObjCSymbol) {
3131
isObjCSymbol(llvm::StringRef("_$s3pat7inlinedSo8NSNumberCvp")));
3232
EXPECT_EQ(true, isObjCSymbol(llvm::StringRef("_$sSC3fooyS2d_SdtFTO")));
3333
}
34+
35+
TEST(Demangle, CustomArchetypes) {
36+
std::string SymbolName = "_$s1a1gyq_q__xt_tr0_lF";
37+
std::string DemangledName = "a.g<Q, U>((U, Q)) -> U";
38+
39+
DemangleOptions Options;
40+
Options.ArchetypeName = [](uint64_t index, uint64_t depth) {
41+
return index ? "U" : "Q";
42+
};
43+
std::string Result = demangleSymbolAsString(SymbolName, Options);
44+
EXPECT_STREQ(DemangledName.c_str(), Result.c_str());
45+
}

0 commit comments

Comments
 (0)