Skip to content

Commit 7da9da0

Browse files
authored
[demangler] Enhance demangling in llvm-cxxfilt for fixed-point types. (#114257)
This patch adds support for fixed-point type in demanger. Closes #114090.
1 parent 1f55d77 commit 7da9da0

File tree

4 files changed

+280
-39
lines changed

4 files changed

+280
-39
lines changed

libcxxabi/src/demangle/ItaniumDemangle.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4331,6 +4331,101 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
43314331
return nullptr;
43324332
return make<BinaryFPType>(DimensionNumber);
43334333
}
4334+
// ::= [DS] DA # N1169 fixed-point [_Sat] T _Accum
4335+
// ::= [DS] DR # N1169 fixed-point [_Sat] T _Frac
4336+
// <fixed-point-size>
4337+
// ::= s # short
4338+
// ::= t # unsigned short
4339+
// ::= i # plain
4340+
// ::= j # unsigned
4341+
// ::= l # long
4342+
// ::= m # unsigned long
4343+
case 'A': {
4344+
char c = look(2);
4345+
First += 3;
4346+
switch (c) {
4347+
case 's':
4348+
return make<NameType>("short _Accum");
4349+
case 't':
4350+
return make<NameType>("unsigned short _Accum");
4351+
case 'i':
4352+
return make<NameType>("_Accum");
4353+
case 'j':
4354+
return make<NameType>("unsigned _Accum");
4355+
case 'l':
4356+
return make<NameType>("long _Accum");
4357+
case 'm':
4358+
return make<NameType>("unsigned long _Accum");
4359+
default:
4360+
return nullptr;
4361+
}
4362+
}
4363+
case 'R': {
4364+
char c = look(2);
4365+
First += 3;
4366+
switch (c) {
4367+
case 's':
4368+
return make<NameType>("short _Fract");
4369+
case 't':
4370+
return make<NameType>("unsigned short _Fract");
4371+
case 'i':
4372+
return make<NameType>("_Fract");
4373+
case 'j':
4374+
return make<NameType>("unsigned _Fract");
4375+
case 'l':
4376+
return make<NameType>("long _Fract");
4377+
case 'm':
4378+
return make<NameType>("unsigned long _Fract");
4379+
default:
4380+
return nullptr;
4381+
}
4382+
}
4383+
case 'S': {
4384+
First += 2;
4385+
if (look() != 'D')
4386+
return nullptr;
4387+
if (look(1) == 'A') {
4388+
char c = look(2);
4389+
First += 3;
4390+
switch (c) {
4391+
case 's':
4392+
return make<NameType>("_Sat short _Accum");
4393+
case 't':
4394+
return make<NameType>("_Sat unsigned short _Accum");
4395+
case 'i':
4396+
return make<NameType>("_Sat _Accum");
4397+
case 'j':
4398+
return make<NameType>("_Sat unsigned _Accum");
4399+
case 'l':
4400+
return make<NameType>("_Sat long _Accum");
4401+
case 'm':
4402+
return make<NameType>("_Sat unsigned long _Accum");
4403+
default:
4404+
return nullptr;
4405+
}
4406+
}
4407+
if (look(1) == 'R') {
4408+
char c = look(2);
4409+
First += 3;
4410+
switch (c) {
4411+
case 's':
4412+
return make<NameType>("_Sat short _Fract");
4413+
case 't':
4414+
return make<NameType>("_Sat unsigned short _Fract");
4415+
case 'i':
4416+
return make<NameType>("_Sat _Fract");
4417+
case 'j':
4418+
return make<NameType>("_Sat unsigned _Fract");
4419+
case 'l':
4420+
return make<NameType>("_Sat long _Fract");
4421+
case 'm':
4422+
return make<NameType>("_Sat unsigned long _Fract");
4423+
default:
4424+
return nullptr;
4425+
}
4426+
}
4427+
return nullptr;
4428+
}
43344429
// ::= DB <number> _ # C23 signed _BitInt(N)
43354430
// ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
43364431
// ::= DU <number> _ # C23 unsigned _BitInt(N)

libcxxabi/test/test_demangle.pass.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30218,6 +30218,32 @@ const char* cases[][2] =
3021830218
{"_ZZN3Foo3fooEiENH4Foo24foo2EOKS0_", "Foo::foo(int)::Foo2::foo2(this Foo2 const&&)"},
3021930219
{"_ZZNH3Foo3fooES_iENK4Foo24foo2Ev", "Foo::foo(this Foo, int)::Foo2::foo2() const" },
3022030220
{"_ZNH3FooclERKS_", "Foo::operator()(this Foo const&)"},
30221+
30222+
// fixed-point types as defined in the N1169 draft of ISO/IEC DTR 18037
30223+
{"_Z1fDAs", "f(short _Accum)"},
30224+
{"_Z1fDAt", "f(unsigned short _Accum)"},
30225+
{"_Z1fDAi", "f(_Accum)"},
30226+
{"_Z1fDAj", "f(unsigned _Accum)"},
30227+
{"_Z1fDAl", "f(long _Accum)"},
30228+
{"_Z1fDAm", "f(unsigned long _Accum)"},
30229+
{"_Z1fDRs", "f(short _Fract)"},
30230+
{"_Z1fDRt", "f(unsigned short _Fract)"},
30231+
{"_Z1fDRi", "f(_Fract)"},
30232+
{"_Z1fDRj", "f(unsigned _Fract)"},
30233+
{"_Z1fDRl", "f(long _Fract)"},
30234+
{"_Z1fDRm", "f(unsigned long _Fract)"},
30235+
{"_Z1fDSDAs", "f(_Sat short _Accum)"},
30236+
{"_Z1fDSDAt", "f(_Sat unsigned short _Accum)"},
30237+
{"_Z1fDSDAi", "f(_Sat _Accum)"},
30238+
{"_Z1fDSDAj", "f(_Sat unsigned _Accum)"},
30239+
{"_Z1fDSDAl", "f(_Sat long _Accum)"},
30240+
{"_Z1fDSDAm", "f(_Sat unsigned long _Accum)"},
30241+
{"_Z1fDSDRs", "f(_Sat short _Fract)"},
30242+
{"_Z1fDSDRt", "f(_Sat unsigned short _Fract)"},
30243+
{"_Z1fDSDRi", "f(_Sat _Fract)"},
30244+
{"_Z1fDSDRj", "f(_Sat unsigned _Fract)"},
30245+
{"_Z1fDSDRl", "f(_Sat long _Fract)"},
30246+
{"_Z1fDSDRm", "f(_Sat unsigned long _Fract)"},
3022130247
};
3022230248
// clang-format on
3022330249

llvm/include/llvm/Demangle/ItaniumDemangle.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4331,6 +4331,101 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
43314331
return nullptr;
43324332
return make<BinaryFPType>(DimensionNumber);
43334333
}
4334+
// ::= [DS] DA # N1169 fixed-point [_Sat] T _Accum
4335+
// ::= [DS] DR # N1169 fixed-point [_Sat] T _Frac
4336+
// <fixed-point-size>
4337+
// ::= s # short
4338+
// ::= t # unsigned short
4339+
// ::= i # plain
4340+
// ::= j # unsigned
4341+
// ::= l # long
4342+
// ::= m # unsigned long
4343+
case 'A': {
4344+
char c = look(2);
4345+
First += 3;
4346+
switch (c) {
4347+
case 's':
4348+
return make<NameType>("short _Accum");
4349+
case 't':
4350+
return make<NameType>("unsigned short _Accum");
4351+
case 'i':
4352+
return make<NameType>("_Accum");
4353+
case 'j':
4354+
return make<NameType>("unsigned _Accum");
4355+
case 'l':
4356+
return make<NameType>("long _Accum");
4357+
case 'm':
4358+
return make<NameType>("unsigned long _Accum");
4359+
default:
4360+
return nullptr;
4361+
}
4362+
}
4363+
case 'R': {
4364+
char c = look(2);
4365+
First += 3;
4366+
switch (c) {
4367+
case 's':
4368+
return make<NameType>("short _Fract");
4369+
case 't':
4370+
return make<NameType>("unsigned short _Fract");
4371+
case 'i':
4372+
return make<NameType>("_Fract");
4373+
case 'j':
4374+
return make<NameType>("unsigned _Fract");
4375+
case 'l':
4376+
return make<NameType>("long _Fract");
4377+
case 'm':
4378+
return make<NameType>("unsigned long _Fract");
4379+
default:
4380+
return nullptr;
4381+
}
4382+
}
4383+
case 'S': {
4384+
First += 2;
4385+
if (look() != 'D')
4386+
return nullptr;
4387+
if (look(1) == 'A') {
4388+
char c = look(2);
4389+
First += 3;
4390+
switch (c) {
4391+
case 's':
4392+
return make<NameType>("_Sat short _Accum");
4393+
case 't':
4394+
return make<NameType>("_Sat unsigned short _Accum");
4395+
case 'i':
4396+
return make<NameType>("_Sat _Accum");
4397+
case 'j':
4398+
return make<NameType>("_Sat unsigned _Accum");
4399+
case 'l':
4400+
return make<NameType>("_Sat long _Accum");
4401+
case 'm':
4402+
return make<NameType>("_Sat unsigned long _Accum");
4403+
default:
4404+
return nullptr;
4405+
}
4406+
}
4407+
if (look(1) == 'R') {
4408+
char c = look(2);
4409+
First += 3;
4410+
switch (c) {
4411+
case 's':
4412+
return make<NameType>("_Sat short _Fract");
4413+
case 't':
4414+
return make<NameType>("_Sat unsigned short _Fract");
4415+
case 'i':
4416+
return make<NameType>("_Sat _Fract");
4417+
case 'j':
4418+
return make<NameType>("_Sat unsigned _Fract");
4419+
case 'l':
4420+
return make<NameType>("_Sat long _Fract");
4421+
case 'm':
4422+
return make<NameType>("_Sat unsigned long _Fract");
4423+
default:
4424+
return nullptr;
4425+
}
4426+
}
4427+
return nullptr;
4428+
}
43344429
// ::= DB <number> _ # C23 signed _BitInt(N)
43354430
// ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
43364431
// ::= DU <number> _ # C23 unsigned _BitInt(N)

llvm/unittests/Demangle/PartialDemangleTest.cpp

Lines changed: 64 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,70 @@ struct ChoppedName {
1616
};
1717

1818
static ChoppedName NamesToTest[] = {
19-
{"_Z1fv", "", "f", "", "()"},
20-
{"_ZN1a1b1cIiiiEEvm", "a::b", "c", "void", "(unsigned long)"},
21-
{"_ZZ5OuterIiEivEN5Inner12inner_memberEv",
22-
"int Outer<int>()::Inner", "inner_member", "", "()"},
23-
{"_Z1fIiEPFvvEv", "", "f", "void (*)()", "()"},
24-
{"_ZN1S1fIiEEvv", "S", "f", "void", "()"},
25-
26-
// Call operator for a lambda in f().
27-
{"_ZZ1fvENK3$_0clEi", "f()::$_0", "operator()", "", "(int)"},
28-
29-
// A call operator for a lambda in a lambda in f().
30-
{"_ZZZ1fvENK3$_0clEvENKUlvE_clEv",
31-
"f()::$_0::operator()() const::'lambda'()", "operator()", "", "()"},
32-
33-
{"_ZZN1S1fEiiEd0_NKUlvE_clEv",
34-
"S::f(int, int)::'lambda'()", "operator()", "", "()"},
35-
36-
{"_ZN1Scv7MuncherIJDpPT_EEIJFivEA_iEEEv",
37-
"S", "operator Muncher<int (*)(), int (*) []>", "", "()"},
38-
39-
// Attributes.
40-
{"_ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi",
41-
"test4<double>", "f", "", "(int)"},
42-
{"_ZN1SC2B8ctor_tagEv", "S", "S", "", "()"},
43-
{"_ZN1S1fB4MERPIiEEvv", "S", "f", "void", "()"},
44-
45-
{"_ZNSsC1EmcRKSaIcE",
46-
"std::basic_string<char, std::char_traits<char>, std::allocator<char>>",
47-
"basic_string", "", "(unsigned long, char, std::allocator<char> const&)"},
48-
{"_ZNSsixEm", "std::string", "operator[]", "", "(unsigned long)"},
49-
{"_ZSt17__throw_bad_allocv", "std", "__throw_bad_alloc", "", "()"},
50-
51-
{"_ZN1AI1BEC2Ev", "A<B>", "A", "", "()"},
52-
{"_ZN1AI1BED2Ev", "A<B>", "~A", "", "()"},
53-
{"_ZN1AI1BECI24BaseEi", "A<B>", "A", "", "(int)"},
54-
{"_ZNKR1AI1BE1fIiEEiv", "A<B>", "f", "int", "()"},
55-
56-
{"_ZN1SIJicfEE3mfnIJjcdEEEvicfDpT_", "S<int, char, float>",
57-
"mfn", "void", "(int, char, float, unsigned int, char, double)"},
19+
{"_Z1fv", "", "f", "", "()"},
20+
{"_ZN1a1b1cIiiiEEvm", "a::b", "c", "void", "(unsigned long)"},
21+
{"_ZZ5OuterIiEivEN5Inner12inner_memberEv", "int Outer<int>()::Inner",
22+
"inner_member", "", "()"},
23+
{"_Z1fIiEPFvvEv", "", "f", "void (*)()", "()"},
24+
{"_ZN1S1fIiEEvv", "S", "f", "void", "()"},
25+
26+
// Call operator for a lambda in f().
27+
{"_ZZ1fvENK3$_0clEi", "f()::$_0", "operator()", "", "(int)"},
28+
29+
// A call operator for a lambda in a lambda in f().
30+
{"_ZZZ1fvENK3$_0clEvENKUlvE_clEv",
31+
"f()::$_0::operator()() const::'lambda'()", "operator()", "", "()"},
32+
33+
{"_ZZN1S1fEiiEd0_NKUlvE_clEv", "S::f(int, int)::'lambda'()", "operator()",
34+
"", "()"},
35+
36+
{"_ZN1Scv7MuncherIJDpPT_EEIJFivEA_iEEEv", "S",
37+
"operator Muncher<int (*)(), int (*) []>", "", "()"},
38+
39+
// Attributes.
40+
{"_ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi",
41+
"test4<double>", "f", "", "(int)"},
42+
{"_ZN1SC2B8ctor_tagEv", "S", "S", "", "()"},
43+
{"_ZN1S1fB4MERPIiEEvv", "S", "f", "void", "()"},
44+
45+
{"_ZNSsC1EmcRKSaIcE",
46+
"std::basic_string<char, std::char_traits<char>, std::allocator<char>>",
47+
"basic_string", "", "(unsigned long, char, std::allocator<char> const&)"},
48+
{"_ZNSsixEm", "std::string", "operator[]", "", "(unsigned long)"},
49+
{"_ZSt17__throw_bad_allocv", "std", "__throw_bad_alloc", "", "()"},
50+
51+
{"_ZN1AI1BEC2Ev", "A<B>", "A", "", "()"},
52+
{"_ZN1AI1BED2Ev", "A<B>", "~A", "", "()"},
53+
{"_ZN1AI1BECI24BaseEi", "A<B>", "A", "", "(int)"},
54+
{"_ZNKR1AI1BE1fIiEEiv", "A<B>", "f", "int", "()"},
55+
56+
{"_ZN1SIJicfEE3mfnIJjcdEEEvicfDpT_", "S<int, char, float>", "mfn", "void",
57+
"(int, char, float, unsigned int, char, double)"},
58+
59+
{"_Z1fDAs", "", "f", "", "(short _Accum)"},
60+
{"_Z1fDAt", "", "f", "", "(unsigned short _Accum)"},
61+
{"_Z1fDAi", "", "f", "", "(_Accum)"},
62+
{"_Z1fDAj", "", "f", "", "(unsigned _Accum)"},
63+
{"_Z1fDAl", "", "f", "", "(long _Accum)"},
64+
{"_Z1fDAm", "", "f", "", "(unsigned long _Accum)"},
65+
{"_Z1fDRs", "", "f", "", "(short _Fract)"},
66+
{"_Z1fDRt", "", "f", "", "(unsigned short _Fract)"},
67+
{"_Z1fDRi", "", "f", "", "(_Fract)"},
68+
{"_Z1fDRj", "", "f", "", "(unsigned _Fract)"},
69+
{"_Z1fDRl", "", "f", "", "(long _Fract)"},
70+
{"_Z1fDRm", "", "f", "", "(unsigned long _Fract)"},
71+
{"_Z1fDSDAs", "", "f", "", "(_Sat short _Accum)"},
72+
{"_Z1fDSDAt", "", "f", "", "(_Sat unsigned short _Accum)"},
73+
{"_Z1fDSDAi", "", "f", "", "(_Sat _Accum)"},
74+
{"_Z1fDSDAj", "", "f", "", "(_Sat unsigned _Accum)"},
75+
{"_Z1fDSDAl", "", "f", "", "(_Sat long _Accum)"},
76+
{"_Z1fDSDAm", "", "f", "", "(_Sat unsigned long _Accum)"},
77+
{"_Z1fDSDRs", "", "f", "", "(_Sat short _Fract)"},
78+
{"_Z1fDSDRt", "", "f", "", "(_Sat unsigned short _Fract)"},
79+
{"_Z1fDSDRi", "", "f", "", "(_Sat _Fract)"},
80+
{"_Z1fDSDRj", "", "f", "", "(_Sat unsigned _Fract)"},
81+
{"_Z1fDSDRl", "", "f", "", "(_Sat long _Fract)"},
82+
{"_Z1fDSDRm", "", "f", "", "(_Sat unsigned long _Fract)"},
5883
};
5984

6085
TEST(PartialDemanglerTest, TestNameChopping) {

0 commit comments

Comments
 (0)