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