Skip to content

Commit

Permalink
[lldb] change name demangling to be consistent between windows and linx
Browse files Browse the repository at this point in the history
When printing names in lldb on windows these names contain the full type information while on linux only the name is contained.

This change introduces a flag in the Microsoft demangler to control if the type information should be included.
With the flag enabled demangled name contains only the qualified name, e.g:
without flag -> with flag
int (*array2d)[10] -> array2d
int (*abc::array2d)[10] -> abc::array2d
const int *x -> x

For globals there is a second inconsistency which is not yet addressed by this change. On linux globals (in global namespace) are prefixed with :: while on windows they are not.

Reviewed By: teemperor, rnk

Differential Revision: https://reviews.llvm.org/D111715
  • Loading branch information
lfolger authored and werat committed Oct 19, 2021
1 parent cfaa5c3 commit 134e181
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 19 deletions.
6 changes: 3 additions & 3 deletions lldb/source/Core/Mangled.cpp
Expand Up @@ -131,9 +131,9 @@ void Mangled::SetValue(ConstString name) {
static char *GetMSVCDemangledStr(const char *M) {
char *demangled_cstr = llvm::microsoftDemangle(
M, nullptr, nullptr, nullptr, nullptr,
llvm::MSDemangleFlags(llvm::MSDF_NoAccessSpecifier |
llvm::MSDF_NoCallingConvention |
llvm::MSDF_NoMemberType));
llvm::MSDemangleFlags(
llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention |
llvm::MSDF_NoMemberType | llvm::MSDF_NoVariableType));

if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) {
if (demangled_cstr && demangled_cstr[0])
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Demangle/Demangle.h
Expand Up @@ -38,6 +38,7 @@ enum MSDemangleFlags {
MSDF_NoCallingConvention = 1 << 2,
MSDF_NoReturnType = 1 << 3,
MSDF_NoMemberType = 1 << 4,
MSDF_NoVariableType = 1 << 5,
};

/// Demangles the Microsoft symbol pointed at by mangled_name and returns it.
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
Expand Up @@ -80,6 +80,7 @@ enum OutputFlags {
OF_NoAccessSpecifier = 4,
OF_NoMemberType = 8,
OF_NoReturnType = 16,
OF_NoVariableType = 32,
};

// Types
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Demangle/MicrosoftDemangle.cpp
Expand Up @@ -2361,6 +2361,8 @@ char *llvm::microsoftDemangle(const char *MangledName, size_t *NMangled,
OF = OutputFlags(OF | OF_NoReturnType);
if (Flags & MSDF_NoMemberType)
OF = OutputFlags(OF | OF_NoMemberType);
if (Flags & MSDF_NoVariableType)
OF = OutputFlags(OF | OF_NoVariableType);

int InternalStatus = demangle_success;
if (D.Error)
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
Expand Up @@ -613,12 +613,12 @@ void VariableSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
if (!(Flags & OF_NoMemberType) && IsStatic)
OS << "static ";

if (Type) {
if (!(Flags & OF_NoVariableType) && Type) {
Type->outputPre(OS, Flags);
outputSpaceIfNecessary(OS);
}
Name->output(OS, Flags);
if (Type)
if (!(Flags & OF_NoVariableType) && Type)
Type->outputPost(OS, Flags);
}

Expand Down
57 changes: 43 additions & 14 deletions llvm/test/Demangle/ms-options.test
@@ -1,14 +1,43 @@
; 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)
; 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-variable-type < %s | FileCheck %s --check-prefix=CHECK-NO-VARIABLE-TYPE
; RUN: llvm-undname --no-calling-convention --no-return-type --no-access-specifier --no-member-type --no-variable-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-VARIABLE-TYPE: public: virtual int __cdecl MyClass::func(int, int)
; CHECK-NO-ALL: {{^}}MyClass::func(int, int)

?array2d@@3PAY09HA
; CHECK: int (*array2d)[10]
; CHECK-NO-CALLING-CONV: int (*array2d)[10]
; CHECK-NO-RETURN: int (*array2d)[10]
; CHECK-NO-ACCESS: int (*array2d)[10]
; CHECK-NO-MEMBER-TYPE: int (*array2d)[10]
; CHECK-NO-VARIABLE-TYPE: array2d
; CHECK-NO-ALL: array2d

?a@abc@@3PAY09HA
; CHECK: int (*abc::a)[10]
; CHECK-NO-CALLING-CONV: int (*abc::a)[10]
; CHECK-NO-RETURN: int (*abc::a)[10]
; CHECK-NO-ACCESS: int (*abc::a)[10]
; CHECK-NO-MEMBER-TYPE: int (*abc::a)[10]
; CHECK-NO-VARIABLE-TYPE: abc::a
; CHECK-NO-ALL: abc::a

?x@@3PEAEEA
; CHECK: unsigned char *x
; CHECK-NO-CALLING-CONV: unsigned char *x
; CHECK-NO-RETURN: unsigned char *x
; CHECK-NO-ACCESS: unsigned char *x
; CHECK-NO-MEMBER-TYPE: unsigned char *x
; CHECK-NO-VARIABLE-TYPE: x
; CHECK-NO-ALL: x
5 changes: 5 additions & 0 deletions llvm/tools/llvm-undname/llvm-undname.cpp
Expand Up @@ -46,6 +46,9 @@ cl::opt<bool> NoReturnType("no-return-type", cl::Optional,
cl::opt<bool> NoMemberType("no-member-type", cl::Optional,
cl::desc("skip member types"), cl::Hidden,
cl::init(false), cl::cat(UndNameCategory));
cl::opt<bool> NoVariableType("no-variable-type", cl::Optional,
cl::desc("skip variable types"), cl::Hidden,
cl::init(false), cl::cat(UndNameCategory));
cl::opt<std::string> RawFile("raw-file", cl::Optional,
cl::desc("for fuzzer data"), cl::Hidden,
cl::cat(UndNameCategory));
Expand All @@ -68,6 +71,8 @@ static bool msDemangle(const std::string &S) {
Flags = MSDemangleFlags(Flags | MSDF_NoReturnType);
if (NoMemberType)
Flags = MSDemangleFlags(Flags | MSDF_NoMemberType);
if (NoVariableType)
Flags = MSDemangleFlags(Flags | MSDF_NoVariableType);

size_t NRead;
char *ResultBuf =
Expand Down

0 comments on commit 134e181

Please sign in to comment.