1 //===----------------------- PartialDemangleTest.cpp ----------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #include "llvm/Demangle/Demangle.h"
11 #include "gtest/gtest.h"
15 const char *ContextName
, *BaseName
, *ReturnType
, *Params
;
18 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", "()"},
26 // Call operator for a lambda in f().
27 {"_ZZ1fvENK3$_0clEi", "f()::$_0", "operator()", "", "(int)"},
29 // A call operator for a lambda in a lambda in f().
30 {"_ZZZ1fvENK3$_0clEvENKUlvE_clEv",
31 "f()::$_0::operator()() const::'lambda'()", "operator()", "", "()"},
33 {"_ZZN1S1fEiiEd0_NKUlvE_clEv",
34 "S::f(int, int)::'lambda'()", "operator()", "", "()"},
36 {"_ZN1Scv7MuncherIJDpPT_EEIJFivEA_iEEEv",
37 "S", "operator Muncher<int (*)(), int (*) []>", "", "()"},
40 {"_ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi",
41 "test4<double>", "f", "", "(int)"},
42 {"_ZN1SC2B8ctor_tagEv", "S", "S", "", "()"},
43 {"_ZN1S1fB4MERPIiEEvv", "S", "f", "void", "()"},
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", "", "()"},
51 {"_ZN1AI1BEC2Ev", "A<B>", "A", "", "()"},
52 {"_ZN1AI1BED2Ev", "A<B>", "~A", "", "()"},
53 {"_ZN1AI1BECI24BaseEi", "A<B>", "A", "", "(int)"},
54 {"_ZNKR1AI1BE1fIiEEiv", "A<B>", "f", "int", "()"},
56 {"_ZN1SIJicfEE3mfnIJjcdEEEvicfDpT_", "S<int, char, float>",
57 "mfn", "void", "(int, char, float, unsigned int, char, double)"},
60 TEST(PartialDemanglerTest
, TestNameChopping
) {
62 char *Buf
= static_cast<char *>(std::malloc(Size
));
64 llvm::ItaniumPartialDemangler D
;
66 for (ChoppedName
&N
: NamesToTest
) {
67 EXPECT_FALSE(D
.partialDemangle(N
.Mangled
));
68 EXPECT_TRUE(D
.isFunction());
69 EXPECT_FALSE(D
.isData());
70 EXPECT_FALSE(D
.isSpecialName());
72 Buf
= D
.getFunctionDeclContextName(Buf
, &Size
);
73 EXPECT_STREQ(Buf
, N
.ContextName
);
75 Buf
= D
.getFunctionBaseName(Buf
, &Size
);
76 EXPECT_STREQ(Buf
, N
.BaseName
);
78 Buf
= D
.getFunctionReturnType(Buf
, &Size
);
79 EXPECT_STREQ(Buf
, N
.ReturnType
);
81 Buf
= D
.getFunctionParameters(Buf
, &Size
);
82 EXPECT_STREQ(Buf
, N
.Params
);
88 TEST(PartialDemanglerTest
, TestNameMeta
) {
89 llvm::ItaniumPartialDemangler Demangler
;
91 EXPECT_FALSE(Demangler
.partialDemangle("_ZNK1f1gEv"));
92 EXPECT_TRUE(Demangler
.isFunction());
93 EXPECT_TRUE(Demangler
.hasFunctionQualifiers());
94 EXPECT_FALSE(Demangler
.isSpecialName());
95 EXPECT_FALSE(Demangler
.isData());
97 EXPECT_FALSE(Demangler
.partialDemangle("_Z1fv"));
98 EXPECT_FALSE(Demangler
.hasFunctionQualifiers());
100 EXPECT_FALSE(Demangler
.partialDemangle("_ZTV1S"));
101 EXPECT_TRUE(Demangler
.isSpecialName());
102 EXPECT_FALSE(Demangler
.isData());
103 EXPECT_FALSE(Demangler
.isFunction());
105 EXPECT_FALSE(Demangler
.partialDemangle("_ZN1aDC1a1b1cEE"));
106 EXPECT_FALSE(Demangler
.isFunction());
107 EXPECT_FALSE(Demangler
.isSpecialName());
108 EXPECT_TRUE(Demangler
.isData());
111 TEST(PartialDemanglerTest
, TestCtorOrDtor
) {
112 static const char *Pos
[] = {
113 "_ZN1AC1Ev", // A::A()
114 "_ZN1AC1IiEET_", // A::A<int>(int)
115 "_ZN1AD2Ev", // A::~A()
116 "_ZN1BIiEC1IcEET_", // B<int>::B<char>(char)
117 "_ZN1AC1B1TEv", // A::A[abi:T]()
118 "_ZNSt1AD2Ev", // std::A::~A()
119 "_ZN2ns1AD1Ev", // ns::A::~A()
121 static const char *Neg
[] = {
123 "_ZN1A1gIiEEvT_", // void A::g<int>(int)
126 llvm::ItaniumPartialDemangler D
;
127 for (const char *N
: Pos
) {
128 EXPECT_FALSE(D
.partialDemangle(N
));
129 EXPECT_TRUE(D
.isCtorOrDtor());
131 for (const char *N
: Neg
) {
132 EXPECT_FALSE(D
.partialDemangle(N
));
133 EXPECT_FALSE(D
.isCtorOrDtor());
137 TEST(PartialDemanglerTest
, TestMisc
) {
138 llvm::ItaniumPartialDemangler D1
, D2
;
140 EXPECT_FALSE(D1
.partialDemangle("_Z1fv"));
141 EXPECT_FALSE(D2
.partialDemangle("_Z1g"));
143 EXPECT_FALSE(D1
.isFunction());
144 EXPECT_TRUE(D2
.isFunction());
146 EXPECT_TRUE(D1
.partialDemangle("Not a mangled name!"));
149 TEST(PartialDemanglerTest
, TestPrintCases
) {
150 llvm::ItaniumPartialDemangler D
;
152 const size_t OriginalSize
= 4;
153 char *Buf
= static_cast<char *>(std::malloc(OriginalSize
));
154 const char *OriginalBuf
= Buf
;
156 // Default success case: Result fits into the given buffer.
157 // Res points to Buf. N returns string size including null termination.
159 EXPECT_FALSE(D
.partialDemangle("_ZN1a1bEv"));
161 size_t N
= OriginalSize
;
162 char *Res
= D
.getFunctionDeclContextName(Buf
, &N
);
163 EXPECT_STREQ("a", Res
);
164 EXPECT_EQ(OriginalBuf
, Res
);
165 EXPECT_EQ(strlen(Res
) + 1, N
);
168 // Realloc success case: Result does not fit into the given buffer.
169 // Res points to the new or extended buffer. N returns string size
170 // including null termination. Buf was extended or freed.
172 EXPECT_FALSE(D
.partialDemangle("_ZN1a1b1cIiiiEEvm"));
174 size_t N
= OriginalSize
;
175 char *Res
= D
.finishDemangle(Buf
, &N
);
176 EXPECT_STREQ("void a::b::c<int, int, int>(unsigned long)", Res
);
177 EXPECT_EQ(strlen(Res
) + 1, N
);
181 // Failure case: a::c is not a function.
182 // Res is nullptr. N remains unchanged.
184 EXPECT_FALSE(D
.partialDemangle("_ZN1a1cE"));
186 size_t N
= OriginalSize
;
187 char *Res
= D
.getFunctionName(Buf
, &N
);
188 EXPECT_EQ(nullptr, Res
);
189 EXPECT_EQ(OriginalSize
, N
);