167d82d6eSErik Pilkington //===----------------------- PartialDemangleTest.cpp ----------------------===// 267d82d6eSErik Pilkington // 367d82d6eSErik Pilkington // The LLVM Compiler Infrastructure 467d82d6eSErik Pilkington // 567d82d6eSErik Pilkington // This file is dual licensed under the MIT and the University of Illinois Open 667d82d6eSErik Pilkington // Source Licenses. See LICENSE.TXT for details. 767d82d6eSErik Pilkington // 867d82d6eSErik Pilkington //===----------------------------------------------------------------------===// 967d82d6eSErik Pilkington 1067d82d6eSErik Pilkington #include <cstdlib> 1167d82d6eSErik Pilkington #include "llvm/Demangle/Demangle.h" 1267d82d6eSErik Pilkington #include "gtest/gtest.h" 1367d82d6eSErik Pilkington 1467d82d6eSErik Pilkington struct ChoppedName { 1567d82d6eSErik Pilkington const char *Mangled; 1667d82d6eSErik Pilkington const char *ContextName, *BaseName, *ReturnType, *Params; 1767d82d6eSErik Pilkington }; 1867d82d6eSErik Pilkington 1967d82d6eSErik Pilkington static ChoppedName NamesToTest[] = { 2067d82d6eSErik Pilkington {"_Z1fv", "", "f", "", "()"}, 2167d82d6eSErik Pilkington {"_ZN1a1b1cIiiiEEvm", "a::b", "c", "void", "(unsigned long)"}, 2267d82d6eSErik Pilkington {"_ZZ5OuterIiEivEN5Inner12inner_memberEv", 2367d82d6eSErik Pilkington "int Outer<int>()::Inner", "inner_member", "", "()"}, 2467d82d6eSErik Pilkington {"_Z1fIiEPFvvEv", "", "f", "void (*)()", "()"}, 2567d82d6eSErik Pilkington {"_ZN1S1fIiEEvv", "S", "f", "void", "()"}, 2667d82d6eSErik Pilkington 2767d82d6eSErik Pilkington // Call operator for a lambda in f(). 2867d82d6eSErik Pilkington {"_ZZ1fvENK3$_0clEi", "f()::$_0", "operator()", "", "(int)"}, 2967d82d6eSErik Pilkington 3067d82d6eSErik Pilkington // A call operator for a lambda in a lambda in f(). 3167d82d6eSErik Pilkington {"_ZZZ1fvENK3$_0clEvENKUlvE_clEv", 3267d82d6eSErik Pilkington "f()::$_0::operator()() const::'lambda'()", "operator()", "", "()"}, 3367d82d6eSErik Pilkington 3467d82d6eSErik Pilkington {"_ZZN1S1fEiiEd0_NKUlvE_clEv", 3567d82d6eSErik Pilkington "S::f(int, int)::'lambda'()", "operator()", "", "()"}, 3667d82d6eSErik Pilkington 3767d82d6eSErik Pilkington {"_ZN1Scv7MuncherIJDpPT_EEIJFivEA_iEEEv", 3867d82d6eSErik Pilkington "S", "operator Muncher<int (*)(), int (*) []>", "", "()"}, 3967d82d6eSErik Pilkington 4067d82d6eSErik Pilkington // Attributes. 4167d82d6eSErik Pilkington {"_ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi", 4267d82d6eSErik Pilkington "test4<double>", "f", "", "(int)"}, 4367d82d6eSErik Pilkington {"_ZN1SC2B8ctor_tagEv", "S", "S", "", "()"}, 4467d82d6eSErik Pilkington {"_ZN1S1fB4MERPIiEEvv", "S", "f", "void", "()"}, 4567d82d6eSErik Pilkington 4667d82d6eSErik Pilkington {"_ZNSsC1EmcRKSaIcE", 4767d82d6eSErik Pilkington "std::basic_string<char, std::char_traits<char>, std::allocator<char> >", 4867d82d6eSErik Pilkington "basic_string", "", "(unsigned long, char, std::allocator<char> const&)"}, 4967d82d6eSErik Pilkington {"_ZNSsixEm", "std::string", "operator[]", "", "(unsigned long)"}, 5067d82d6eSErik Pilkington {"_ZSt17__throw_bad_allocv", "std", "__throw_bad_alloc", "", "()"}, 5167d82d6eSErik Pilkington 5267d82d6eSErik Pilkington {"_ZN1AI1BEC2Ev", "A<B>", "A", "", "()"}, 5367d82d6eSErik Pilkington {"_ZN1AI1BED2Ev", "A<B>", "~A", "", "()"}, 5467d82d6eSErik Pilkington {"_ZN1AI1BECI24BaseEi", "A<B>", "A", "", "(int)"}, 5567d82d6eSErik Pilkington {"_ZNKR1AI1BE1fIiEEiv", "A<B>", "f", "int", "()"}, 5667d82d6eSErik Pilkington 5767d82d6eSErik Pilkington {"_ZN1SIJicfEE3mfnIJjcdEEEvicfDpT_", "S<int, char, float>", 5867d82d6eSErik Pilkington "mfn", "void", "(int, char, float, unsigned int, char, double)"}, 5967d82d6eSErik Pilkington }; 6067d82d6eSErik Pilkington 6167d82d6eSErik Pilkington TEST(PartialDemangleTest, TestNameChopping) { 6267d82d6eSErik Pilkington size_t Size = 1; 6367d82d6eSErik Pilkington char *Buf = static_cast<char *>(std::malloc(Size)); 6467d82d6eSErik Pilkington 6567d82d6eSErik Pilkington llvm::ItaniumPartialDemangler D; 6667d82d6eSErik Pilkington 6767d82d6eSErik Pilkington for (ChoppedName &N : NamesToTest) { 6867d82d6eSErik Pilkington EXPECT_FALSE(D.partialDemangle(N.Mangled)); 6967d82d6eSErik Pilkington EXPECT_TRUE(D.isFunction()); 7067d82d6eSErik Pilkington EXPECT_FALSE(D.isData()); 7167d82d6eSErik Pilkington EXPECT_FALSE(D.isSpecialName()); 7267d82d6eSErik Pilkington 7367d82d6eSErik Pilkington Buf = D.getFunctionDeclContextName(Buf, &Size); 7467d82d6eSErik Pilkington EXPECT_STREQ(Buf, N.ContextName); 7567d82d6eSErik Pilkington 7667d82d6eSErik Pilkington Buf = D.getFunctionBaseName(Buf, &Size); 7767d82d6eSErik Pilkington EXPECT_STREQ(Buf, N.BaseName); 7867d82d6eSErik Pilkington 7967d82d6eSErik Pilkington Buf = D.getFunctionReturnType(Buf, &Size); 8067d82d6eSErik Pilkington EXPECT_STREQ(Buf, N.ReturnType); 8167d82d6eSErik Pilkington 8267d82d6eSErik Pilkington Buf = D.getFunctionParameters(Buf, &Size); 8367d82d6eSErik Pilkington EXPECT_STREQ(Buf, N.Params); 8467d82d6eSErik Pilkington } 85b5757ef0SErik Pilkington 86b5757ef0SErik Pilkington std::free(Buf); 8767d82d6eSErik Pilkington } 8867d82d6eSErik Pilkington 8967d82d6eSErik Pilkington TEST(PartialDemangleTest, TestNameMeta) { 9067d82d6eSErik Pilkington llvm::ItaniumPartialDemangler Demangler; 9167d82d6eSErik Pilkington 9267d82d6eSErik Pilkington EXPECT_FALSE(Demangler.partialDemangle("_ZNK1f1gEv")); 9367d82d6eSErik Pilkington EXPECT_TRUE(Demangler.isFunction()); 9467d82d6eSErik Pilkington EXPECT_TRUE(Demangler.hasFunctionQualifiers()); 9567d82d6eSErik Pilkington EXPECT_FALSE(Demangler.isSpecialName()); 9667d82d6eSErik Pilkington EXPECT_FALSE(Demangler.isData()); 9767d82d6eSErik Pilkington 9867d82d6eSErik Pilkington EXPECT_FALSE(Demangler.partialDemangle("_Z1fv")); 9967d82d6eSErik Pilkington EXPECT_FALSE(Demangler.hasFunctionQualifiers()); 10067d82d6eSErik Pilkington 10167d82d6eSErik Pilkington EXPECT_FALSE(Demangler.partialDemangle("_ZTV1S")); 10267d82d6eSErik Pilkington EXPECT_TRUE(Demangler.isSpecialName()); 10367d82d6eSErik Pilkington EXPECT_FALSE(Demangler.isData()); 10467d82d6eSErik Pilkington EXPECT_FALSE(Demangler.isFunction()); 10567d82d6eSErik Pilkington 10667d82d6eSErik Pilkington EXPECT_FALSE(Demangler.partialDemangle("_ZN1aDC1a1b1cEE")); 10767d82d6eSErik Pilkington EXPECT_FALSE(Demangler.isFunction()); 10867d82d6eSErik Pilkington EXPECT_FALSE(Demangler.isSpecialName()); 10967d82d6eSErik Pilkington EXPECT_TRUE(Demangler.isData()); 11067d82d6eSErik Pilkington } 11167d82d6eSErik Pilkington 11279420acbSFangrui Song TEST(PartialDemanglerTest, TestCtorOrDtor) { 11379420acbSFangrui Song static const char *Pos[] = { 11479420acbSFangrui Song "_ZN1AC1Ev", // A::A() 11579420acbSFangrui Song "_ZN1AC1IiEET_", // A::A<int>(int) 11679420acbSFangrui Song "_ZN1AD2Ev", // A::~A() 11779420acbSFangrui Song "_ZN1BIiEC1IcEET_", // B<int>::B<char>(char) 11879420acbSFangrui Song "_ZN1AC1B1TEv", // A::A[abi:T]() 11979420acbSFangrui Song "_ZNSt1AD2Ev", // std::A::~A() 12079420acbSFangrui Song "_ZN2ns1AD1Ev", // ns::A::~A() 12179420acbSFangrui Song }; 12279420acbSFangrui Song static const char *Neg[] = { 12379420acbSFangrui Song "_Z1fv", 12479420acbSFangrui Song "_ZN1A1gIiEEvT_", // void A::g<int>(int) 12579420acbSFangrui Song }; 12679420acbSFangrui Song 12779420acbSFangrui Song llvm::ItaniumPartialDemangler D; 12879420acbSFangrui Song for (const char *N : Pos) { 12979420acbSFangrui Song EXPECT_FALSE(D.partialDemangle(N)); 13079420acbSFangrui Song EXPECT_TRUE(D.isCtorOrDtor()); 13179420acbSFangrui Song } 13279420acbSFangrui Song for (const char *N : Neg) { 13379420acbSFangrui Song EXPECT_FALSE(D.partialDemangle(N)); 13479420acbSFangrui Song EXPECT_FALSE(D.isCtorOrDtor()); 13579420acbSFangrui Song } 13679420acbSFangrui Song } 13779420acbSFangrui Song 13867d82d6eSErik Pilkington TEST(PartialDemanglerTest, TestMisc) { 13967d82d6eSErik Pilkington llvm::ItaniumPartialDemangler D1, D2; 14067d82d6eSErik Pilkington 14167d82d6eSErik Pilkington EXPECT_FALSE(D1.partialDemangle("_Z1fv")); 14267d82d6eSErik Pilkington EXPECT_FALSE(D2.partialDemangle("_Z1g")); 14367d82d6eSErik Pilkington std::swap(D1, D2); 14467d82d6eSErik Pilkington EXPECT_FALSE(D1.isFunction()); 14567d82d6eSErik Pilkington EXPECT_TRUE(D2.isFunction()); 14667d82d6eSErik Pilkington 14767d82d6eSErik Pilkington EXPECT_TRUE(D1.partialDemangle("Not a mangled name!")); 148*56b995b1SStefan Granitz } 14967d82d6eSErik Pilkington 150*56b995b1SStefan Granitz TEST(PartialDemanglerTest, TestPrintCases) { 151*56b995b1SStefan Granitz llvm::ItaniumPartialDemangler D; 152*56b995b1SStefan Granitz 153*56b995b1SStefan Granitz const size_t OriginalSize = 4; 154*56b995b1SStefan Granitz char *Buf = static_cast<char *>(std::malloc(OriginalSize)); 155*56b995b1SStefan Granitz const char *OriginalBuf = Buf; 156*56b995b1SStefan Granitz 157*56b995b1SStefan Granitz // Default success case: Result fits into the given buffer. 158*56b995b1SStefan Granitz // Res points to Buf. N returns string size including null termination. 159*56b995b1SStefan Granitz { 160*56b995b1SStefan Granitz EXPECT_FALSE(D.partialDemangle("_ZN1a1bEv")); 161*56b995b1SStefan Granitz 162*56b995b1SStefan Granitz size_t N = OriginalSize; 163*56b995b1SStefan Granitz char *Res = D.getFunctionDeclContextName(Buf, &N); 164*56b995b1SStefan Granitz EXPECT_STREQ("a", Res); 165*56b995b1SStefan Granitz EXPECT_EQ(OriginalBuf, Res); 166*56b995b1SStefan Granitz EXPECT_EQ(strlen(Res) + 1, N); 167*56b995b1SStefan Granitz } 168*56b995b1SStefan Granitz 169*56b995b1SStefan Granitz // Realloc success case: Result does not fit into the given buffer. 170*56b995b1SStefan Granitz // Res points to the new or extended buffer. N returns string size 171*56b995b1SStefan Granitz // including null termination. Buf was extended or freed. 172*56b995b1SStefan Granitz { 173*56b995b1SStefan Granitz EXPECT_FALSE(D.partialDemangle("_ZN1a1b1cIiiiEEvm")); 174*56b995b1SStefan Granitz 175*56b995b1SStefan Granitz size_t N = OriginalSize; 176*56b995b1SStefan Granitz char *Res = D.finishDemangle(Buf, &N); 177*56b995b1SStefan Granitz EXPECT_STREQ("void a::b::c<int, int, int>(unsigned long)", Res); 178*56b995b1SStefan Granitz EXPECT_EQ(strlen(Res) + 1, N); 179*56b995b1SStefan Granitz Buf = Res; 180*56b995b1SStefan Granitz } 181*56b995b1SStefan Granitz 182*56b995b1SStefan Granitz // Failure case: a::c is not a function. 183*56b995b1SStefan Granitz // Res is nullptr. N remains unchanged. 184*56b995b1SStefan Granitz { 185*56b995b1SStefan Granitz EXPECT_FALSE(D.partialDemangle("_ZN1a1cE")); 186*56b995b1SStefan Granitz 187*56b995b1SStefan Granitz size_t N = OriginalSize; 188*56b995b1SStefan Granitz char *Res = D.getFunctionName(Buf, &N); 189*56b995b1SStefan Granitz EXPECT_EQ(nullptr, Res); 190*56b995b1SStefan Granitz EXPECT_EQ(OriginalSize, N); 191*56b995b1SStefan Granitz } 192*56b995b1SStefan Granitz 193*56b995b1SStefan Granitz std::free(Buf); 19467d82d6eSErik Pilkington } 195