blob: 8bb4a3abcddadfc85c03a87567f18b489a70a497 [file] [log] [blame]
Erik Pilkingtond0381b62018-04-12 20:41:38 +00001//===----------------------- PartialDemangleTest.cpp ----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include <cstdlib>
11#include "llvm/Demangle/Demangle.h"
12#include "gtest/gtest.h"
13
14struct ChoppedName {
15 const char *Mangled;
16 const char *ContextName, *BaseName, *ReturnType, *Params;
17};
18
19static ChoppedName NamesToTest[] = {
20 {"_Z1fv", "", "f", "", "()"},
21 {"_ZN1a1b1cIiiiEEvm", "a::b", "c", "void", "(unsigned long)"},
22 {"_ZZ5OuterIiEivEN5Inner12inner_memberEv",
23 "int Outer<int>()::Inner", "inner_member", "", "()"},
24 {"_Z1fIiEPFvvEv", "", "f", "void (*)()", "()"},
25 {"_ZN1S1fIiEEvv", "S", "f", "void", "()"},
26
27 // Call operator for a lambda in f().
28 {"_ZZ1fvENK3$_0clEi", "f()::$_0", "operator()", "", "(int)"},
29
30 // A call operator for a lambda in a lambda in f().
31 {"_ZZZ1fvENK3$_0clEvENKUlvE_clEv",
32 "f()::$_0::operator()() const::'lambda'()", "operator()", "", "()"},
33
34 {"_ZZN1S1fEiiEd0_NKUlvE_clEv",
35 "S::f(int, int)::'lambda'()", "operator()", "", "()"},
36
37 {"_ZN1Scv7MuncherIJDpPT_EEIJFivEA_iEEEv",
38 "S", "operator Muncher<int (*)(), int (*) []>", "", "()"},
39
40 // Attributes.
41 {"_ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi",
42 "test4<double>", "f", "", "(int)"},
43 {"_ZN1SC2B8ctor_tagEv", "S", "S", "", "()"},
44 {"_ZN1S1fB4MERPIiEEvv", "S", "f", "void", "()"},
45
46 {"_ZNSsC1EmcRKSaIcE",
47 "std::basic_string<char, std::char_traits<char>, std::allocator<char> >",
48 "basic_string", "", "(unsigned long, char, std::allocator<char> const&)"},
49 {"_ZNSsixEm", "std::string", "operator[]", "", "(unsigned long)"},
50 {"_ZSt17__throw_bad_allocv", "std", "__throw_bad_alloc", "", "()"},
51
52 {"_ZN1AI1BEC2Ev", "A<B>", "A", "", "()"},
53 {"_ZN1AI1BED2Ev", "A<B>", "~A", "", "()"},
54 {"_ZN1AI1BECI24BaseEi", "A<B>", "A", "", "(int)"},
55 {"_ZNKR1AI1BE1fIiEEiv", "A<B>", "f", "int", "()"},
56
57 {"_ZN1SIJicfEE3mfnIJjcdEEEvicfDpT_", "S<int, char, float>",
58 "mfn", "void", "(int, char, float, unsigned int, char, double)"},
59};
60
Erik Pilkington77d3f022018-08-13 16:37:47 +000061TEST(PartialDemanglerTest, TestNameChopping) {
Erik Pilkingtond0381b62018-04-12 20:41:38 +000062 size_t Size = 1;
63 char *Buf = static_cast<char *>(std::malloc(Size));
64
65 llvm::ItaniumPartialDemangler D;
66
67 for (ChoppedName &N : NamesToTest) {
68 EXPECT_FALSE(D.partialDemangle(N.Mangled));
69 EXPECT_TRUE(D.isFunction());
70 EXPECT_FALSE(D.isData());
71 EXPECT_FALSE(D.isSpecialName());
72
73 Buf = D.getFunctionDeclContextName(Buf, &Size);
74 EXPECT_STREQ(Buf, N.ContextName);
75
76 Buf = D.getFunctionBaseName(Buf, &Size);
77 EXPECT_STREQ(Buf, N.BaseName);
78
79 Buf = D.getFunctionReturnType(Buf, &Size);
80 EXPECT_STREQ(Buf, N.ReturnType);
81
82 Buf = D.getFunctionParameters(Buf, &Size);
83 EXPECT_STREQ(Buf, N.Params);
84 }
Erik Pilkingtona51cdcd2018-04-12 22:54:47 +000085
86 std::free(Buf);
Erik Pilkingtond0381b62018-04-12 20:41:38 +000087}
88
Erik Pilkington77d3f022018-08-13 16:37:47 +000089TEST(PartialDemanglerTest, TestNameMeta) {
Erik Pilkingtond0381b62018-04-12 20:41:38 +000090 llvm::ItaniumPartialDemangler Demangler;
91
92 EXPECT_FALSE(Demangler.partialDemangle("_ZNK1f1gEv"));
93 EXPECT_TRUE(Demangler.isFunction());
94 EXPECT_TRUE(Demangler.hasFunctionQualifiers());
95 EXPECT_FALSE(Demangler.isSpecialName());
96 EXPECT_FALSE(Demangler.isData());
97
98 EXPECT_FALSE(Demangler.partialDemangle("_Z1fv"));
99 EXPECT_FALSE(Demangler.hasFunctionQualifiers());
100
101 EXPECT_FALSE(Demangler.partialDemangle("_ZTV1S"));
102 EXPECT_TRUE(Demangler.isSpecialName());
103 EXPECT_FALSE(Demangler.isData());
104 EXPECT_FALSE(Demangler.isFunction());
105
106 EXPECT_FALSE(Demangler.partialDemangle("_ZN1aDC1a1b1cEE"));
107 EXPECT_FALSE(Demangler.isFunction());
108 EXPECT_FALSE(Demangler.isSpecialName());
109 EXPECT_TRUE(Demangler.isData());
110}
111
Fangrui Song109abe02018-05-24 06:57:57 +0000112TEST(PartialDemanglerTest, TestCtorOrDtor) {
113 static const char *Pos[] = {
114 "_ZN1AC1Ev", // A::A()
115 "_ZN1AC1IiEET_", // A::A<int>(int)
116 "_ZN1AD2Ev", // A::~A()
117 "_ZN1BIiEC1IcEET_", // B<int>::B<char>(char)
118 "_ZN1AC1B1TEv", // A::A[abi:T]()
119 "_ZNSt1AD2Ev", // std::A::~A()
120 "_ZN2ns1AD1Ev", // ns::A::~A()
121 };
122 static const char *Neg[] = {
123 "_Z1fv",
124 "_ZN1A1gIiEEvT_", // void A::g<int>(int)
125 };
126
127 llvm::ItaniumPartialDemangler D;
128 for (const char *N : Pos) {
129 EXPECT_FALSE(D.partialDemangle(N));
130 EXPECT_TRUE(D.isCtorOrDtor());
131 }
132 for (const char *N : Neg) {
133 EXPECT_FALSE(D.partialDemangle(N));
134 EXPECT_FALSE(D.isCtorOrDtor());
135 }
136}
137
Erik Pilkingtond0381b62018-04-12 20:41:38 +0000138TEST(PartialDemanglerTest, TestMisc) {
139 llvm::ItaniumPartialDemangler D1, D2;
140
141 EXPECT_FALSE(D1.partialDemangle("_Z1fv"));
142 EXPECT_FALSE(D2.partialDemangle("_Z1g"));
143 std::swap(D1, D2);
144 EXPECT_FALSE(D1.isFunction());
145 EXPECT_TRUE(D2.isFunction());
146
147 EXPECT_TRUE(D1.partialDemangle("Not a mangled name!"));
Stefan Granitze52df162018-08-08 22:38:23 +0000148}
Erik Pilkingtond0381b62018-04-12 20:41:38 +0000149
Stefan Granitze52df162018-08-08 22:38:23 +0000150TEST(PartialDemanglerTest, TestPrintCases) {
151 llvm::ItaniumPartialDemangler D;
152
153 const size_t OriginalSize = 4;
154 char *Buf = static_cast<char *>(std::malloc(OriginalSize));
155 const char *OriginalBuf = Buf;
156
157 // Default success case: Result fits into the given buffer.
158 // Res points to Buf. N returns string size including null termination.
159 {
160 EXPECT_FALSE(D.partialDemangle("_ZN1a1bEv"));
161
162 size_t N = OriginalSize;
163 char *Res = D.getFunctionDeclContextName(Buf, &N);
164 EXPECT_STREQ("a", Res);
165 EXPECT_EQ(OriginalBuf, Res);
166 EXPECT_EQ(strlen(Res) + 1, N);
167 }
168
169 // Realloc success case: Result does not fit into the given buffer.
170 // Res points to the new or extended buffer. N returns string size
171 // including null termination. Buf was extended or freed.
172 {
173 EXPECT_FALSE(D.partialDemangle("_ZN1a1b1cIiiiEEvm"));
174
175 size_t N = OriginalSize;
176 char *Res = D.finishDemangle(Buf, &N);
177 EXPECT_STREQ("void a::b::c<int, int, int>(unsigned long)", Res);
178 EXPECT_EQ(strlen(Res) + 1, N);
179 Buf = Res;
180 }
181
182 // Failure case: a::c is not a function.
183 // Res is nullptr. N remains unchanged.
184 {
185 EXPECT_FALSE(D.partialDemangle("_ZN1a1cE"));
186
187 size_t N = OriginalSize;
188 char *Res = D.getFunctionName(Buf, &N);
189 EXPECT_EQ(nullptr, Res);
190 EXPECT_EQ(OriginalSize, N);
191 }
192
193 std::free(Buf);
Erik Pilkingtond0381b62018-04-12 20:41:38 +0000194}