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_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 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 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 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