Skip to content

Commit df26c47

Browse files
authored
Merge pull request #10588 from eeckstein/mangling-prefix
demangler: Support the future final mangling prefix $S
2 parents 59af91a + 79c522a commit df26c47

File tree

6 files changed

+68
-52
lines changed

6 files changed

+68
-52
lines changed

include/swift/Demangling/Demangle.h

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,21 @@ class Node {
216216
void dump();
217217
};
218218

219+
/// Returns the length of the swift mangling prefix of the \p SymbolName.
220+
///
221+
/// Returns 0 if \p SymbolName is not a mangled swift (>= swift 4.x) name.
222+
int getManglingPrefixLength(const char *mangledName);
223+
224+
/// Returns true if \p SymbolName is a mangled swift name.
225+
///
226+
/// This does not include the old (<= swift 3.x) mangling prefix "_T".
227+
inline bool isMangledName(llvm::StringRef MangledName) {
228+
return getManglingPrefixLength(MangledName.data()) != 0;
229+
}
230+
219231
/// Returns true if the mangledName starts with the swift mangling prefix.
220232
///
233+
/// This includes the old (<= swift 3.x) mangling prefix "_T".
221234
/// \param mangledName A null-terminated string containing a mangled name.
222235
bool isSwiftSymbol(const char *mangledName);
223236

@@ -252,8 +265,8 @@ class Context {
252265

253266
/// Demangle the given symbol and return the parse tree.
254267
///
255-
/// \param MangledName The mangled symbol string, which start with the
256-
/// mangling prefix _T.
268+
/// \param MangledName The mangled symbol string, which start a mangling
269+
/// prefix: _T, _T0, $S, _$S.
257270
///
258271
/// \returns A parse tree for the demangled string - or a null pointer
259272
/// on failure.
@@ -263,8 +276,8 @@ class Context {
263276

264277
/// Demangle the given type and return the parse tree.
265278
///
266-
/// \param MangledName The mangled type string, which does _not_ start with
267-
/// the mangling prefix _T.
279+
/// \param MangledName The mangled symbol string, which start a mangling
280+
/// prefix: _T, _T0, $S, _$S.
268281
///
269282
/// \returns A parse tree for the demangled string - or a null pointer
270283
/// on failure.
@@ -274,8 +287,8 @@ class Context {
274287

275288
/// Demangle the given symbol and return the readable name.
276289
///
277-
/// \param MangledName The mangled symbol string, which start with the
278-
/// mangling prefix _T.
290+
/// \param MangledName The mangled symbol string, which start a mangling
291+
/// prefix: _T, _T0, $S, _$S.
279292
///
280293
/// \returns The demangled string.
281294
std::string demangleSymbolAsString(llvm::StringRef MangledName,
@@ -284,7 +297,7 @@ class Context {
284297
/// Demangle the given type and return the readable name.
285298
///
286299
/// \param MangledName The mangled type string, which does _not_ start with
287-
/// the mangling prefix _T.
300+
/// a mangling prefix.
288301
///
289302
/// \returns The demangled string.
290303
std::string demangleTypeAsString(llvm::StringRef MangledName,

lib/Demangling/Context.cpp

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,9 @@ void Context::clear() {
3636
}
3737

3838
NodePointer Context::demangleSymbolAsNode(llvm::StringRef MangledName) {
39-
#ifndef NO_NEW_DEMANGLING
40-
if (MangledName.startswith(MANGLING_PREFIX_STR)
41-
// Also accept the future mangling prefix.
42-
// TODO: remove this line as soon as MANGLING_PREFIX_STR gets "_S".
43-
|| MangledName.startswith("_S")) {
39+
if (isMangledName(MangledName.data())) {
4440
return D->demangleSymbol(MangledName);
4541
}
46-
#endif
4742
return demangleOldSymbolAsNode(MangledName, *D);
4843
}
4944

@@ -74,10 +69,7 @@ std::string Context::demangleTypeAsString(llvm::StringRef MangledName,
7469
}
7570

7671
bool Context::isThunkSymbol(llvm::StringRef MangledName) {
77-
if (MangledName.startswith(MANGLING_PREFIX_STR)
78-
// Also accept the future mangling prefix.
79-
// TODO: remove this line as soon as MANGLING_PREFIX_STR gets "_S".
80-
|| MangledName.startswith("_S")) {
72+
if (isMangledName(MangledName)) {
8173
// First do a quick check
8274
if (MangledName.endswith("TA") || // partial application forwarder
8375
MangledName.endswith("Ta") || // ObjC partial application forwarder
@@ -126,11 +118,7 @@ std::string Context::getThunkTarget(llvm::StringRef MangledName) {
126118
if (!isThunkSymbol(MangledName))
127119
return std::string();
128120

129-
if (MangledName.startswith(MANGLING_PREFIX_STR)
130-
// Also accept the future mangling prefix.
131-
// TODO: remove this line as soon as MANGLING_PREFIX_STR gets "_S".
132-
|| MangledName.startswith("_S")) {
133-
121+
if (isMangledName(MangledName)) {
134122
// The targets of those thunks not derivable from the mangling.
135123
if (MangledName.endswith("TR") ||
136124
MangledName.endswith("Tr") ||

lib/Demangling/Demangler.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,31 @@ static bool isFunctionAttr(Node::Kind kind) {
112112
namespace swift {
113113
namespace Demangle {
114114

115+
//////////////////////////////////
116+
// Public utility functions //
117+
//////////////////////////////////
118+
119+
int getManglingPrefixLength(const char *mangledName) {
120+
// Check for the swift-4 prefix
121+
if (mangledName[0] == '_' && mangledName[1] == 'T' && mangledName[2] == '0')
122+
return 3;
123+
124+
// Check for the swift > 4 prefix
125+
unsigned Offset = (mangledName[0] == '_' ? 1 : 0);
126+
if (mangledName[Offset] == '$' && mangledName[Offset + 1] == 'S')
127+
return Offset + 2;
128+
129+
return 0;
130+
}
131+
132+
bool isSwiftSymbol(const char *mangledName) {
133+
// The old mangling.
134+
if (mangledName[0] == '_' && mangledName[1] == 'T')
135+
return true;
136+
137+
return getManglingPrefixLength(mangledName) != 0;
138+
}
139+
115140
//////////////////////////////////
116141
// Node member functions //
117142
//////////////////////////////////
@@ -226,12 +251,12 @@ NodePointer Demangler::demangleSymbol(StringRef MangledName) {
226251
if (nextIf("_Tt"))
227252
return demangleObjCTypeName();
228253

229-
if (!nextIf(MANGLING_PREFIX_STR)
230-
// Also accept the future mangling prefix.
231-
// TODO: remove this line as soon as MANGLING_PREFIX_STR gets "_S".
232-
&& !nextIf("_S"))
254+
unsigned PrefixLength = getManglingPrefixLength(MangledName.data());
255+
if (PrefixLength == 0)
233256
return nullptr;
234257

258+
Pos += PrefixLength;
259+
235260
// If any other prefixes are accepted, please update Mangler::verify.
236261

237262
if (!parseAndPushNodes())

lib/Demangling/OldDemangler.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,23 +2199,6 @@ class OldDemangler {
21992199
};
22002200
} // end anonymous namespace
22012201

2202-
2203-
bool
2204-
swift::Demangle::isSwiftSymbol(const char *mangledName) {
2205-
// The old mangling.
2206-
if (mangledName[0] == '_'
2207-
// Also accept the future mangling prefix.
2208-
&& (mangledName[1] == 'T' || mangledName[1] == 'S'))
2209-
return true;
2210-
2211-
// The new mangling.
2212-
for (unsigned i = 0; i < sizeof(MANGLING_PREFIX_STR) - 1; i++) {
2213-
if (mangledName[i] != MANGLING_PREFIX_STR[i])
2214-
return false;
2215-
}
2216-
return true;
2217-
}
2218-
22192202
NodePointer
22202203
swift::Demangle::demangleOldSymbolAsNode(StringRef MangledName,
22212204
NodeFactory &Factory) {

test/Demangle/Inputs/manglings.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,12 @@ _TToFC3foo3bar3basfT3zimCS_3zim_T_ ---> {T:_TFC3foo3bar3basfT3zimCS_3zim_T_,C} @
8181
_TTOFSC3fooFTSdSd_Sd ---> {T:_TFSC3fooFTSdSd_Sd} @nonobjc __C.foo(Swift.Double, Swift.Double) -> Swift.Double
8282
_T03foo3barC3basyAA3zimCAE_tFTo ---> {T:_T03foo3barC3basyAA3zimCAE_tF,C} @objc foo.bar.bas(zim: foo.zim) -> ()
8383
_T0SC3fooS2d_SdtFTO ---> {T:_T0SC3fooS2d_SdtF} @nonobjc __C.foo(Swift.Double, Swift.Double) -> Swift.Double
84-
_S3foo3barC3basyAA3zimCAE_tFTo ---> {T:_S3foo3barC3basyAA3zimCAE_tF,C} @objc foo.bar.bas(zim: foo.zim) -> ()
85-
_SSC3fooS2d_SdtFTO ---> {T:_SSC3fooS2d_SdtF} @nonobjc __C.foo(Swift.Double, Swift.Double) -> Swift.Double
84+
__$S3foo3barC3basyAA3zimCAE_tFTo ---> {T:_$S3foo3barC3basyAA3zimCAE_tF,C} @objc foo.bar.bas(zim: foo.zim) -> ()
85+
__$SSC3fooS2d_SdtFTO ---> {T:_$SSC3fooS2d_SdtF} @nonobjc __C.foo(Swift.Double, Swift.Double) -> Swift.Double
86+
_$S3foo3barC3basyAA3zimCAE_tFTo ---> {T:_$S3foo3barC3basyAA3zimCAE_tF,C} @objc foo.bar.bas(zim: foo.zim) -> ()
87+
_$SSC3fooS2d_SdtFTO ---> {T:_$SSC3fooS2d_SdtF} @nonobjc __C.foo(Swift.Double, Swift.Double) -> Swift.Double
88+
$S3foo3barC3basyAA3zimCAE_tFTo ---> {T:$S3foo3barC3basyAA3zimCAE_tF,C} @objc foo.bar.bas(zim: foo.zim) -> ()
89+
$SSC3fooS2d_SdtFTO ---> {T:$SSC3fooS2d_SdtF} @nonobjc __C.foo(Swift.Double, Swift.Double) -> Swift.Double
8690
_TTDFC3foo3bar3basfT3zimCS_3zim_T_ ---> dynamic foo.bar.bas(zim: foo.zim) -> ()
8791
_TFC3foo3bar3basfT3zimCS_3zim_T_ ---> foo.bar.bas(zim: foo.zim) -> ()
8892
_TF3foooi1pFTCS_3barVS_3bas_OS_3zim ---> foo.+ infix(foo.bar, foo.bas) -> foo.zim

tools/swift-demangle/swift-demangle.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,15 @@ static void demangle(llvm::raw_ostream &os, llvm::StringRef name,
102102
remangled = name;
103103
} else {
104104
remangled = swift::Demangle::mangleNode(pointer);
105-
// Also accept the future mangling prefix.
106-
// TODO: remove the special "_S" handling as soon as MANGLING_PREFIX_STR
107-
// gets "_S".
108-
if (name.startswith("_S")) {
109-
assert(remangled.find(MANGLING_PREFIX_STR) == 0);
110-
remangled = "_S" + remangled.substr(3);
105+
unsigned prefixLen = swift::Demangle::getManglingPrefixLength(remangled.data());
106+
assert(prefixLen > 0);
107+
// Replace the prefix if we remangled with a different prefix.
108+
if (!name.startswith(remangled.substr(0, prefixLen))) {
109+
unsigned namePrefixLen =
110+
swift::Demangle::getManglingPrefixLength(name.data());
111+
assert(namePrefixLen > 0);
112+
remangled = name.take_front(namePrefixLen).str() +
113+
remangled.substr(prefixLen);
111114
}
112115
if (name != remangled) {
113116
llvm::errs() << "\nError: re-mangled name \n " << remangled
@@ -163,7 +166,7 @@ static int demangleSTDIN(const swift::Demangle::DemangleOptions &options) {
163166
// This doesn't handle Unicode symbols, but maybe that's okay.
164167
// Also accept the future mangling prefix.
165168
// TODO: remove the "_S" as soon as MANGLING_PREFIX_STR gets "_S".
166-
llvm::Regex maybeSymbol("(_T|_S|" MANGLING_PREFIX_STR ")[_a-zA-Z0-9$]+");
169+
llvm::Regex maybeSymbol("(_T|_*\\$S|" MANGLING_PREFIX_STR ")[_a-zA-Z0-9$]+");
167170

168171
swift::Demangle::Context DCtx;
169172
for (std::string mangled; std::getline(std::cin, mangled);) {

0 commit comments

Comments
 (0)