[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:
Martin Storsjo 2019-10-15 08:29:56 +00:00
parent bbb8eade69
commit da92ed8365
6 changed files with 86 additions and 21 deletions

View File

@ -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);

View File

@ -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

View File

@ -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();

View File

@ -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);

View 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)

View File

@ -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);