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