mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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:
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.他们为什么不说中文 () -> ()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user