demangler: Add API functions for classifying symbols.

To be used by lldb.
Also add a -classify option in swift-demangler to test those new API functions.
This commit is contained in:
Erik Eckstein
2017-01-31 17:17:29 -08:00
parent 28992176d5
commit 81384b6f82
5 changed files with 94 additions and 5 deletions

View File

@@ -207,6 +207,15 @@ public:
}
};
/// Returns true if the mangledName starts with the swift mangling prefix.
bool isSwiftSymbol(const char *mangledName, size_t mangledNameLength);
/// Returns true if the mangledName refers to a thunk function.
///
/// Thunk functions are either (ObjC) partial apply forwarder, swift-as-ObjC or
/// ObjC-as-swift thunks.
bool isThunkSymbol(const char *mangledName, size_t mangledNameLength);
/// \brief Demangle the given string as a Swift symbol.
///
/// Typical usage:

View File

@@ -2335,6 +2335,67 @@ private:
};
} // end anonymous namespace
bool
swift::Demangle::isSwiftSymbol(const char *mangledName,
size_t mangledNameLength) {
StringRef Name(mangledName, mangledNameLength);
// The old mangling.
if (Name.startswith("_T"))
return true;
#ifndef NO_NEW_DEMANGLING
// The new mangling.
if (Name.startswith(MANGLING_PREFIX_STR))
return true;
#endif // !NO_NEW_DEMANGLING
return false;
}
bool
swift::Demangle::isThunkSymbol(const char *mangledName,
size_t mangledNameLength) {
StringRef Name(mangledName, mangledNameLength);
#ifndef NO_NEW_DEMANGLING
if (Name.startswith(MANGLING_PREFIX_STR)) {
// First do a quick check
if (Name.endswith("TA") || // partial application forwarder
Name.endswith("Ta") || // ObjC partial application forwarder
Name.endswith("To") || // swift-as-ObjC thunk
Name.endswith("TO")) { // ObjC-as-swift thunk
// To avoid false positives, we need to fully demangle the symbol.
NodePointer Nd = demangleSymbolAsNode(mangledName, mangledNameLength);
if (!Nd || Nd->getKind() != Node::Kind::Global ||
Nd->getNumChildren() == 0)
return false;
switch (Nd->getFirstChild()->getKind()) {
case Node::Kind::ObjCAttribute:
case Node::Kind::NonObjCAttribute:
case Node::Kind::PartialApplyObjCForwarder:
case Node::Kind::PartialApplyForwarder:
return true;
default:
break;
}
}
return false;
}
#endif // !NO_NEW_DEMANGLING
if (Name.startswith("_T")) {
// Old mangling.
StringRef Remaining = Name.substr(2);
if (Remaining.startswith("To") || // swift-as-ObjC thunk
Remaining.startswith("TO") || // ObjC-as-swift thunk
Remaining.startswith("PA")) { // (ObjC) partial application forwarder
return true;
}
}
return false;
}
NodePointer
swift::Demangle::demangleSymbolAsNode(const char *MangledName,
size_t MangledNameLength,

View File

@@ -77,8 +77,10 @@ _TF3foolp3barSi ---> foo.bar.nativePinningAddressor : Swift.Int
_TF3foog3barSi ---> foo.bar.getter : Swift.Int
_TF3foos3barSi ---> foo.bar.setter : Swift.Int
_TFC3foo3bar3basfT3zimCS_3zim_T_ ---> foo.bar.bas (zim : foo.zim) -> ()
_TToFC3foo3bar3basfT3zimCS_3zim_T_ ---> @objc foo.bar.bas (zim : foo.zim) -> ()
_TTOFSC3fooFTSdSd_Sd ---> @nonobjc __C.foo (Swift.Double, Swift.Double) -> Swift.Double
_TToFC3foo3bar3basfT3zimCS_3zim_T_ ---> {T} @objc foo.bar.bas (zim : foo.zim) -> ()
_TTOFSC3fooFTSdSd_Sd ---> {T} @nonobjc __C.foo (Swift.Double, Swift.Double) -> Swift.Double
_T03foo3barC3basyAA3zimCAE_tFTo ---> {T} @objc foo.bar.bas (zim : foo.zim) -> ()
_T0SC3fooSdSd_SdtFTO ---> {T} @nonobjc __C.foo (Swift.Double, Swift.Double) -> Swift.Double
_TTDFC3foo3bar3basfT3zimCS_3zim_T_ ---> dynamic foo.bar.bas (zim : foo.zim) -> ()
_TFC3foo3bar3basfT3zimCS_3zim_T_ ---> foo.bar.bas (zim : foo.zim) -> ()
_TF3foooi1pFTCS_3barVS_3bas_OS_3zim ---> foo.+ infix (foo.bar, foo.bas) -> foo.zim
@@ -139,7 +141,7 @@ _Tw ---> _Tw
_TWa ---> _TWa
_Twal ---> _Twal
_T ---> _T
_TTo ---> _TTo
_TTo ---> {T} _TTo
_TC ---> _TC
_TM ---> _TM
_TM ---> _TM
@@ -185,7 +187,10 @@ _TTSgSiS_ ---> _TTSgSiS_
_TTSgSi__xyz ---> _TTSgSi__xyz
_TTSr5Si___TF4test7genericurFxx ---> generic not re-abstracted specialization <Swift.Int> of test.generic <A> (A) -> A
_TTSrq5Si___TF4test7genericurFxx ---> generic not re-abstracted specialization <preserving fragile attribute, Swift.Int> of test.generic <A> (A) -> A
_TPA__TTRXFo_oSSoSS_dSb_XFo_iSSiSS_dSb_31 ---> partial apply forwarder for reabstraction thunk helper from @callee_owned (@owned Swift.String, @owned Swift.String) -> (@unowned Swift.Bool) to @callee_owned (@in Swift.String, @in Swift.String) -> (@unowned Swift.Bool) with unmangled suffix "31"
_TPA__TTRXFo_oSSoSS_dSb_XFo_iSSiSS_dSb_ ---> {T} partial apply forwarder for reabstraction thunk helper from @callee_owned (@owned Swift.String, @owned Swift.String) -> (@unowned Swift.Bool) to @callee_owned (@in Swift.String, @in Swift.String) -> (@unowned Swift.Bool)
_TPAo__TTRGrXFo_dGSPx__dGSPx_zoPs5Error__XFo_iGSPx__iGSPx_zoPS___ ---> {T} partial apply ObjC forwarder for reabstraction thunk helper <A> from @callee_owned (@unowned Swift.UnsafePointer<A>) -> (@unowned Swift.UnsafePointer<A>, @error @owned Swift.Error) to @callee_owned (@in Swift.UnsafePointer<A>) -> (@out Swift.UnsafePointer<A>, @error @owned Swift.Error)
_T0SSSSSbIxxxd_SSSSSbIxiid_TRTA ---> {T} partial apply forwarder for reabstraction thunk helper from @callee_owned (@owned Swift.String, @owned Swift.String) -> (@unowned Swift.Bool) to @callee_owned (@in Swift.String, @in Swift.String) -> (@unowned Swift.Bool)
_T0SPyxGSPyxGs5Error_pIxydzo_SPyxGSPyxGsAA_pIxirzo_lTRTa ---> {T} partial apply ObjC forwarder for reabstraction thunk helper <A> from @callee_owned (@unowned Swift.UnsafePointer<A>) -> (@unowned Swift.UnsafePointer<A>, @error @owned Swift.Error) to @callee_owned (@in Swift.UnsafePointer<A>) -> (@out Swift.UnsafePointer<A>, @error @owned Swift.Error)
_TiC4Meow5MyCls9subscriptFT1iSi_Sf ---> Meow.MyCls.subscript (i : Swift.Int) -> Swift.Float
_TF8manglingX22egbpdajGbuEbxfgehfvwxnFT_T_ ---> mangling.ليهمابتكلموشعربي؟ () -> ()
_TF8manglingX24ihqwcrbEcvIaIdqgAFGpqjyeFT_T_ ---> mangling.他们为什么不说中文 () -> ()

View File

@@ -6,7 +6,7 @@ RUN: sed -ne '/--->/s/ *--->.*$//p' < %S/Inputs/manglings.txt > %t.input
%t.check: "A ---> B" ==> "B"
RUN: sed -ne '/--->/s/^.*---> *//p' < %S/Inputs/manglings.txt > %t.check
RUN: swift-demangle < %t.input > %t.output
RUN: swift-demangle -classify < %t.input > %t.output
RUN: diff %t.check %t.output
; RUN: swift-demangle __TtSi | %FileCheck %s -check-prefix=DOUBLE

View File

@@ -60,6 +60,10 @@ static llvm::cl::opt<bool>
Simplified("simplified",
llvm::cl::desc("Don't display module names or implicit self types"));
static llvm::cl::opt<bool>
Classify("classify",
llvm::cl::desc("Display symbol classification characters"));
static llvm::cl::list<std::string>
InputNames(llvm::cl::Positional, llvm::cl::desc("[mangled name...]"),
llvm::cl::ZeroOrMore);
@@ -120,6 +124,16 @@ static void demangle(llvm::raw_ostream &os, llvm::StringRef name,
std::string string = swift::Demangle::nodeToString(pointer, options);
if (!CompactMode)
llvm::outs() << name << " ---> ";
if (Classify) {
std::string Classifications;
if (!swift::Demangle::isSwiftSymbol(name.data(), name.size()))
Classifications += 'N';
if (swift::Demangle::isThunkSymbol(name.data(), name.size()))
Classifications += 'T';
if (!Classifications.empty())
llvm::outs() << '{' << Classifications << "} ";
}
llvm::outs() << (string.empty() ? name : llvm::StringRef(string));
}
}