1 //===-- RichManglingContextTest.cpp -----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Core/RichManglingContext.h"
11 
12 #include "lldb/Utility/ConstString.h"
13 
14 #include "gtest/gtest.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 
19 TEST(RichManglingContextTest, Basic) {
20   RichManglingContext RMC;
21   ConstString mangled("_ZN3foo3barEv");
22   EXPECT_TRUE(RMC.FromItaniumName(mangled));
23 
24   EXPECT_TRUE(RMC.IsFunction());
25   EXPECT_FALSE(RMC.IsCtorOrDtor());
26 
27   RMC.ParseFunctionDeclContextName();
28   EXPECT_EQ("foo", RMC.GetBufferRef());
29 
30   RMC.ParseFunctionBaseName();
31   EXPECT_EQ("bar", RMC.GetBufferRef());
32 
33   RMC.ParseFullName();
34   EXPECT_EQ("foo::bar()", RMC.GetBufferRef());
35 }
36 
37 TEST(RichManglingContextTest, FromCxxMethodName) {
38   RichManglingContext ItaniumRMC;
39   ConstString mangled("_ZN3foo3barEv");
40   EXPECT_TRUE(ItaniumRMC.FromItaniumName(mangled));
41 
42   RichManglingContext CxxMethodRMC;
43   ConstString demangled("foo::bar()");
44   EXPECT_TRUE(CxxMethodRMC.FromCxxMethodName(demangled));
45 
46   EXPECT_TRUE(ItaniumRMC.IsFunction() == CxxMethodRMC.IsFunction());
47   EXPECT_TRUE(ItaniumRMC.IsCtorOrDtor() == CxxMethodRMC.IsCtorOrDtor());
48 
49   ItaniumRMC.ParseFunctionDeclContextName();
50   CxxMethodRMC.ParseFunctionDeclContextName();
51   EXPECT_TRUE(ItaniumRMC.GetBufferRef() == CxxMethodRMC.GetBufferRef());
52 
53   ItaniumRMC.ParseFunctionBaseName();
54   CxxMethodRMC.ParseFunctionBaseName();
55   EXPECT_TRUE(ItaniumRMC.GetBufferRef() == CxxMethodRMC.GetBufferRef());
56 
57   ItaniumRMC.ParseFullName();
58   CxxMethodRMC.ParseFullName();
59   EXPECT_TRUE(ItaniumRMC.GetBufferRef() == CxxMethodRMC.GetBufferRef());
60 
61   // Construct with a random name.
62   {
63     RichManglingContext CxxMethodRMC;
64     EXPECT_TRUE(CxxMethodRMC.FromCxxMethodName(ConstString("X")));
65 
66     // We expect it is not a function.
67     EXPECT_FALSE(CxxMethodRMC.IsFunction());
68   }
69 
70   // Construct with a function without a context.
71   {
72     RichManglingContext CxxMethodRMC;
73     EXPECT_TRUE(CxxMethodRMC.FromCxxMethodName(
74         ConstString("void * operator new(unsigned __int64)")));
75 
76     // We expect it is a function.
77     EXPECT_TRUE(CxxMethodRMC.IsFunction());
78 
79     // We expect its context is empty.
80     CxxMethodRMC.ParseFunctionDeclContextName();
81     EXPECT_TRUE(CxxMethodRMC.GetBufferRef().empty());
82   }
83 }
84 
85 TEST(RichManglingContextTest, SwitchProvider) {
86   RichManglingContext RMC;
87   llvm::StringRef mangled = "_ZN3foo3barEv";
88   llvm::StringRef demangled = "foo::bar()";
89 
90   EXPECT_TRUE(RMC.FromItaniumName(ConstString(mangled)));
91   RMC.ParseFullName();
92   EXPECT_EQ("foo::bar()", RMC.GetBufferRef());
93 
94   EXPECT_TRUE(RMC.FromCxxMethodName(ConstString(demangled)));
95   RMC.ParseFullName();
96   EXPECT_EQ("foo::bar()", RMC.GetBufferRef());
97 
98   EXPECT_TRUE(RMC.FromItaniumName(ConstString(mangled)));
99   RMC.ParseFullName();
100   EXPECT_EQ("foo::bar()", RMC.GetBufferRef());
101 }
102 
103 TEST(RichManglingContextTest, IPDRealloc) {
104   // The demangled name should fit into the Itanium default buffer.
105   const char *ShortMangled = "_ZN3foo3barEv";
106 
107   // The demangled name for this will certainly not fit into the default buffer.
108   const char *LongMangled =
109       "_ZNK3shk6detail17CallbackPublisherIZNS_5ThrowERKNSt15__exception_"
110       "ptr13exception_ptrEEUlOT_E_E9SubscribeINS0_9ConcatMapINS0_"
111       "18CallbackSubscriberIZNS_6GetAllIiNS1_IZZNS_9ConcatMapIZNS_6ConcatIJNS1_"
112       "IZZNS_3MapIZZNS_7IfEmptyIS9_EEDaS7_ENKUlS6_E_clINS1_IZZNS_4TakeIiEESI_"
113       "S7_ENKUlS6_E_clINS1_IZZNS_6FilterIZNS_9ElementAtEmEUlS7_E_EESI_S7_"
114       "ENKUlS6_E_clINS1_IZZNSL_ImEESI_S7_ENKUlS6_E_clINS1_IZNS_4FromINS0_"
115       "22InfiniteRangeContainerIiEEEESI_S7_EUlS7_E_EEEESI_S6_EUlS7_E_EEEESI_S6_"
116       "EUlS7_E_EEEESI_S6_EUlS7_E_EEEESI_S6_EUlS7_E_EESI_S7_ENKUlS6_E_clIS14_"
117       "EESI_S6_EUlS7_E_EERNS1_IZZNSH_IS9_EESI_S7_ENKSK_IS14_EESI_S6_EUlS7_E0_"
118       "EEEEESI_DpOT_EUlS7_E_EESI_S7_ENKUlS6_E_clINS1_IZNS_5StartIJZNS_"
119       "4JustIJS19_S1C_EEESI_S1F_EUlvE_ZNS1K_IJS19_S1C_EEESI_S1F_EUlvE0_EEESI_"
120       "S1F_EUlS7_E_EEEESI_S6_EUlS7_E_EEEESt6vectorIS6_SaIS6_EERKT0_NS_"
121       "12ElementCountEbEUlS7_E_ZNSD_IiS1Q_EES1T_S1W_S1X_bEUlOS3_E_ZNSD_IiS1Q_"
122       "EES1T_S1W_S1X_bEUlvE_EES1G_S1O_E25ConcatMapValuesSubscriberEEEDaS7_";
123 
124   RichManglingContext RMC;
125 
126   // Demangle the short one.
127   EXPECT_TRUE(RMC.FromItaniumName(ConstString(ShortMangled)));
128   RMC.ParseFullName();
129   const char *ShortDemangled = RMC.GetBufferRef().data();
130 
131   // Demangle the long one.
132   EXPECT_TRUE(RMC.FromItaniumName(ConstString(LongMangled)));
133   RMC.ParseFullName();
134   const char *LongDemangled = RMC.GetBufferRef().data();
135 
136   // Make sure a new buffer was allocated or the default buffer was extended.
137   bool AllocatedNewBuffer = (ShortDemangled != LongDemangled);
138   bool ExtendedExistingBuffer = (strlen(LongDemangled) > 2048);
139   EXPECT_TRUE(AllocatedNewBuffer || ExtendedExistingBuffer);
140 }
141