1 //===----------------------- 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 
14 struct ChoppedName {
15   const char *Mangled;
16   const char *ContextName, *BaseName, *ReturnType, *Params;
17 };
18 
19 static 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 
61 TEST(PartialDemangleTest, TestNameChopping) {
62   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   }
85 
86   std::free(Buf);
87 }
88 
89 TEST(PartialDemangleTest, TestNameMeta) {
90   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 
112 TEST(PartialDemanglerTest, TestMisc) {
113   llvm::ItaniumPartialDemangler D1, D2;
114 
115   EXPECT_FALSE(D1.partialDemangle("_Z1fv"));
116   EXPECT_FALSE(D2.partialDemangle("_Z1g"));
117   std::swap(D1, D2);
118   EXPECT_FALSE(D1.isFunction());
119   EXPECT_TRUE(D2.isFunction());
120 
121   EXPECT_TRUE(D1.partialDemangle("Not a mangled name!"));
122 
123 }
124