mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-08 09:03:18 +00:00
[Demangle] Add a few more options to the microsoft demangler
This corresponds to commonly used options to UnDecorateSymbolName within llvm. Add them as hidden options in llvm-undname. MS undname.exe takes numeric flags, corresponding to the UNDNAME_* constants, but instead of hardcoding in mappings for those numbers, just add textual options instead, as it the use of them here is primarily intended for testing. Differential Revision: https://reviews.llvm.org/D68917 llvm-svn: 374865
This commit is contained in:
parent
bbb8eade69
commit
da92ed8365
@ -32,7 +32,14 @@ char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n,
|
||||
int *status);
|
||||
|
||||
|
||||
enum MSDemangleFlags { MSDF_None = 0, MSDF_DumpBackrefs = 1 << 0 };
|
||||
enum MSDemangleFlags {
|
||||
MSDF_None = 0,
|
||||
MSDF_DumpBackrefs = 1 << 0,
|
||||
MSDF_NoAccessSpecifier = 1 << 1,
|
||||
MSDF_NoCallingConvention = 1 << 2,
|
||||
MSDF_NoReturnType = 1 << 3,
|
||||
MSDF_NoMemberType = 1 << 4,
|
||||
};
|
||||
char *microsoftDemangle(const char *mangled_name, char *buf, size_t *n,
|
||||
int *status, MSDemangleFlags Flags = MSDF_None);
|
||||
|
||||
|
@ -75,6 +75,9 @@ enum OutputFlags {
|
||||
OF_Default = 0,
|
||||
OF_NoCallingConvention = 1,
|
||||
OF_NoTagSpecifier = 2,
|
||||
OF_NoAccessSpecifier = 4,
|
||||
OF_NoMemberType = 8,
|
||||
OF_NoReturnType = 16,
|
||||
};
|
||||
|
||||
// Types
|
||||
|
@ -2346,12 +2346,22 @@ char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
|
||||
if (Flags & MSDF_DumpBackrefs)
|
||||
D.dumpBackReferences();
|
||||
|
||||
OutputFlags OF = OF_Default;
|
||||
if (Flags & MSDF_NoCallingConvention)
|
||||
OF = OutputFlags(OF | OF_NoCallingConvention);
|
||||
if (Flags & MSDF_NoAccessSpecifier)
|
||||
OF = OutputFlags(OF | OF_NoAccessSpecifier);
|
||||
if (Flags & MSDF_NoReturnType)
|
||||
OF = OutputFlags(OF | OF_NoReturnType);
|
||||
if (Flags & MSDF_NoMemberType)
|
||||
OF = OutputFlags(OF | OF_NoMemberType);
|
||||
|
||||
if (D.Error)
|
||||
InternalStatus = demangle_invalid_mangled_name;
|
||||
else if (!initializeOutputStream(Buf, N, S, 1024))
|
||||
InternalStatus = demangle_memory_alloc_failure;
|
||||
else {
|
||||
AST->output(S, OF_Default);
|
||||
AST->output(S, OF);
|
||||
S += '\0';
|
||||
if (N != nullptr)
|
||||
*N = S.getCurrentPosition();
|
||||
|
@ -378,24 +378,28 @@ void LiteralOperatorIdentifierNode::output(OutputStream &OS,
|
||||
|
||||
void FunctionSignatureNode::outputPre(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
if (FunctionClass & FC_Public)
|
||||
OS << "public: ";
|
||||
if (FunctionClass & FC_Protected)
|
||||
OS << "protected: ";
|
||||
if (FunctionClass & FC_Private)
|
||||
OS << "private: ";
|
||||
|
||||
if (!(FunctionClass & FC_Global)) {
|
||||
if (FunctionClass & FC_Static)
|
||||
OS << "static ";
|
||||
if (!(Flags & OF_NoAccessSpecifier)) {
|
||||
if (FunctionClass & FC_Public)
|
||||
OS << "public: ";
|
||||
if (FunctionClass & FC_Protected)
|
||||
OS << "protected: ";
|
||||
if (FunctionClass & FC_Private)
|
||||
OS << "private: ";
|
||||
}
|
||||
if (FunctionClass & FC_Virtual)
|
||||
OS << "virtual ";
|
||||
|
||||
if (FunctionClass & FC_ExternC)
|
||||
OS << "extern \"C\" ";
|
||||
if (!(Flags & OF_NoMemberType)) {
|
||||
if (!(FunctionClass & FC_Global)) {
|
||||
if (FunctionClass & FC_Static)
|
||||
OS << "static ";
|
||||
}
|
||||
if (FunctionClass & FC_Virtual)
|
||||
OS << "virtual ";
|
||||
|
||||
if (ReturnType) {
|
||||
if (FunctionClass & FC_ExternC)
|
||||
OS << "extern \"C\" ";
|
||||
}
|
||||
|
||||
if (!(Flags & OF_NoReturnType) && ReturnType) {
|
||||
ReturnType->outputPre(OS, Flags);
|
||||
OS << " ";
|
||||
}
|
||||
@ -438,7 +442,7 @@ void FunctionSignatureNode::outputPost(OutputStream &OS,
|
||||
else if (RefQualifier == FunctionRefQualifier::RValueReference)
|
||||
OS << " &&";
|
||||
|
||||
if (ReturnType)
|
||||
if (!(Flags & OF_NoReturnType) && ReturnType)
|
||||
ReturnType->outputPost(OS, Flags);
|
||||
}
|
||||
|
||||
@ -580,19 +584,26 @@ void FunctionSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
}
|
||||
|
||||
void VariableSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
const char *AccessSpec = nullptr;
|
||||
bool IsStatic = true;
|
||||
switch (SC) {
|
||||
case StorageClass::PrivateStatic:
|
||||
OS << "private: static ";
|
||||
AccessSpec = "private";
|
||||
break;
|
||||
case StorageClass::PublicStatic:
|
||||
OS << "public: static ";
|
||||
AccessSpec = "public";
|
||||
break;
|
||||
case StorageClass::ProtectedStatic:
|
||||
OS << "protected: static ";
|
||||
AccessSpec = "protected";
|
||||
break;
|
||||
default:
|
||||
IsStatic = false;
|
||||
break;
|
||||
}
|
||||
if (!(Flags & OF_NoAccessSpecifier) && AccessSpec)
|
||||
OS << AccessSpec << ": ";
|
||||
if (!(Flags & OF_NoMemberType) && IsStatic)
|
||||
OS << "static ";
|
||||
|
||||
if (Type) {
|
||||
Type->outputPre(OS, Flags);
|
||||
|
14
llvm/test/Demangle/ms-options.test
Normal file
14
llvm/test/Demangle/ms-options.test
Normal file
@ -0,0 +1,14 @@
|
||||
; RUN: llvm-undname < %s | FileCheck %s
|
||||
; RUN: llvm-undname --no-calling-convention < %s | FileCheck %s --check-prefix=CHECK-NO-CALLING-CONV
|
||||
; RUN: llvm-undname --no-return-type < %s | FileCheck %s --check-prefix=CHECK-NO-RETURN
|
||||
; RUN: llvm-undname --no-access-specifier < %s | FileCheck %s --check-prefix=CHECK-NO-ACCESS
|
||||
; RUN: llvm-undname --no-member-type < %s | FileCheck %s --check-prefix=CHECK-NO-MEMBER-TYPE
|
||||
; RUN: llvm-undname --no-calling-convention --no-return-type --no-access-specifier --no-member-type < %s | FileCheck %s --check-prefix=CHECK-NO-ALL
|
||||
|
||||
?func@MyClass@@UEAAHHH@Z
|
||||
; CHECK: public: virtual int __cdecl MyClass::func(int, int)
|
||||
; CHECK-NO-CALLING-CONV: public: virtual int MyClass::func(int, int)
|
||||
; CHECK-NO-RETURN: public: virtual __cdecl MyClass::func(int, int)
|
||||
; CHECK-NO-ACCESS: {{^}}virtual int __cdecl MyClass::func(int, int)
|
||||
; CHECK-NO-MEMBER-TYPE: public: int __cdecl MyClass::func(int, int)
|
||||
; CHECK-NO-ALL: {{^}}MyClass::func(int, int)
|
@ -31,6 +31,18 @@ using namespace llvm;
|
||||
cl::opt<bool> DumpBackReferences("backrefs", cl::Optional,
|
||||
cl::desc("dump backreferences"), cl::Hidden,
|
||||
cl::init(false));
|
||||
cl::opt<bool> NoAccessSpecifier("no-access-specifier", cl::Optional,
|
||||
cl::desc("skip access specifiers"), cl::Hidden,
|
||||
cl::init(false));
|
||||
cl::opt<bool> NoCallingConvention("no-calling-convention", cl::Optional,
|
||||
cl::desc("skip calling convention"),
|
||||
cl::Hidden, cl::init(false));
|
||||
cl::opt<bool> NoReturnType("no-return-type", cl::Optional,
|
||||
cl::desc("skip return types"), cl::Hidden,
|
||||
cl::init(false));
|
||||
cl::opt<bool> NoMemberType("no-member-type", cl::Optional,
|
||||
cl::desc("skip member types"), cl::Hidden,
|
||||
cl::init(false));
|
||||
cl::opt<std::string> RawFile("raw-file", cl::Optional,
|
||||
cl::desc("for fuzzer data"), cl::Hidden);
|
||||
cl::list<std::string> Symbols(cl::Positional, cl::desc("<input symbols>"),
|
||||
@ -41,6 +53,14 @@ static bool msDemangle(const std::string &S) {
|
||||
MSDemangleFlags Flags = MSDF_None;
|
||||
if (DumpBackReferences)
|
||||
Flags = MSDemangleFlags(Flags | MSDF_DumpBackrefs);
|
||||
if (NoAccessSpecifier)
|
||||
Flags = MSDemangleFlags(Flags | MSDF_NoAccessSpecifier);
|
||||
if (NoCallingConvention)
|
||||
Flags = MSDemangleFlags(Flags | MSDF_NoCallingConvention);
|
||||
if (NoReturnType)
|
||||
Flags = MSDemangleFlags(Flags | MSDF_NoReturnType);
|
||||
if (NoMemberType)
|
||||
Flags = MSDemangleFlags(Flags | MSDF_NoMemberType);
|
||||
|
||||
char *ResultBuf =
|
||||
microsoftDemangle(S.c_str(), nullptr, nullptr, &Status, Flags);
|
||||
|
Loading…
Reference in New Issue
Block a user