167d82d6eSErik Pilkington //===----------------------- PartialDemangleTest.cpp ----------------------===//
267d82d6eSErik Pilkington //
3*57b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*57b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*57b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
667d82d6eSErik Pilkington //
767d82d6eSErik Pilkington //===----------------------------------------------------------------------===//
867d82d6eSErik Pilkington
967d82d6eSErik Pilkington #include <cstdlib>
1067d82d6eSErik Pilkington #include "llvm/Demangle/Demangle.h"
1167d82d6eSErik Pilkington #include "gtest/gtest.h"
1267d82d6eSErik Pilkington
1367d82d6eSErik Pilkington struct ChoppedName {
1467d82d6eSErik Pilkington const char *Mangled;
1567d82d6eSErik Pilkington const char *ContextName, *BaseName, *ReturnType, *Params;
1667d82d6eSErik Pilkington };
1767d82d6eSErik Pilkington
1867d82d6eSErik Pilkington static ChoppedName NamesToTest[] = {
1967d82d6eSErik Pilkington {"_Z1fv", "", "f", "", "()"},
2067d82d6eSErik Pilkington {"_ZN1a1b1cIiiiEEvm", "a::b", "c", "void", "(unsigned long)"},
2167d82d6eSErik Pilkington {"_ZZ5OuterIiEivEN5Inner12inner_memberEv",
2267d82d6eSErik Pilkington "int Outer<int>()::Inner", "inner_member", "", "()"},
2367d82d6eSErik Pilkington {"_Z1fIiEPFvvEv", "", "f", "void (*)()", "()"},
2467d82d6eSErik Pilkington {"_ZN1S1fIiEEvv", "S", "f", "void", "()"},
2567d82d6eSErik Pilkington
2667d82d6eSErik Pilkington // Call operator for a lambda in f().
2767d82d6eSErik Pilkington {"_ZZ1fvENK3$_0clEi", "f()::$_0", "operator()", "", "(int)"},
2867d82d6eSErik Pilkington
2967d82d6eSErik Pilkington // A call operator for a lambda in a lambda in f().
3067d82d6eSErik Pilkington {"_ZZZ1fvENK3$_0clEvENKUlvE_clEv",
3167d82d6eSErik Pilkington "f()::$_0::operator()() const::'lambda'()", "operator()", "", "()"},
3267d82d6eSErik Pilkington
3367d82d6eSErik Pilkington {"_ZZN1S1fEiiEd0_NKUlvE_clEv",
3467d82d6eSErik Pilkington "S::f(int, int)::'lambda'()", "operator()", "", "()"},
3567d82d6eSErik Pilkington
3667d82d6eSErik Pilkington {"_ZN1Scv7MuncherIJDpPT_EEIJFivEA_iEEEv",
3767d82d6eSErik Pilkington "S", "operator Muncher<int (*)(), int (*) []>", "", "()"},
3867d82d6eSErik Pilkington
3967d82d6eSErik Pilkington // Attributes.
4067d82d6eSErik Pilkington {"_ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi",
4167d82d6eSErik Pilkington "test4<double>", "f", "", "(int)"},
4267d82d6eSErik Pilkington {"_ZN1SC2B8ctor_tagEv", "S", "S", "", "()"},
4367d82d6eSErik Pilkington {"_ZN1S1fB4MERPIiEEvv", "S", "f", "void", "()"},
4467d82d6eSErik Pilkington
4567d82d6eSErik Pilkington {"_ZNSsC1EmcRKSaIcE",
4667d82d6eSErik Pilkington "std::basic_string<char, std::char_traits<char>, std::allocator<char>>",
4767d82d6eSErik Pilkington "basic_string", "", "(unsigned long, char, std::allocator<char> const&)"},
4867d82d6eSErik Pilkington {"_ZNSsixEm", "std::string", "operator[]", "", "(unsigned long)"},
4967d82d6eSErik Pilkington {"_ZSt17__throw_bad_allocv", "std", "__throw_bad_alloc", "", "()"},
5067d82d6eSErik Pilkington
5167d82d6eSErik Pilkington {"_ZN1AI1BEC2Ev", "A<B>", "A", "", "()"},
5267d82d6eSErik Pilkington {"_ZN1AI1BED2Ev", "A<B>", "~A", "", "()"},
5367d82d6eSErik Pilkington {"_ZN1AI1BECI24BaseEi", "A<B>", "A", "", "(int)"},
5467d82d6eSErik Pilkington {"_ZNKR1AI1BE1fIiEEiv", "A<B>", "f", "int", "()"},
5567d82d6eSErik Pilkington
5667d82d6eSErik Pilkington {"_ZN1SIJicfEE3mfnIJjcdEEEvicfDpT_", "S<int, char, float>",
5767d82d6eSErik Pilkington "mfn", "void", "(int, char, float, unsigned int, char, double)"},
5867d82d6eSErik Pilkington };
5967d82d6eSErik Pilkington
TEST(PartialDemanglerTest,TestNameChopping)60ac6a801cSErik Pilkington TEST(PartialDemanglerTest, TestNameChopping) {
6167d82d6eSErik Pilkington size_t Size = 1;
6267d82d6eSErik Pilkington char *Buf = static_cast<char *>(std::malloc(Size));
6367d82d6eSErik Pilkington
6467d82d6eSErik Pilkington llvm::ItaniumPartialDemangler D;
6567d82d6eSErik Pilkington
6667d82d6eSErik Pilkington for (ChoppedName &N : NamesToTest) {
6767d82d6eSErik Pilkington EXPECT_FALSE(D.partialDemangle(N.Mangled));
6867d82d6eSErik Pilkington EXPECT_TRUE(D.isFunction());
6967d82d6eSErik Pilkington EXPECT_FALSE(D.isData());
7067d82d6eSErik Pilkington EXPECT_FALSE(D.isSpecialName());
7167d82d6eSErik Pilkington
7267d82d6eSErik Pilkington Buf = D.getFunctionDeclContextName(Buf, &Size);
7367d82d6eSErik Pilkington EXPECT_STREQ(Buf, N.ContextName);
7467d82d6eSErik Pilkington
7567d82d6eSErik Pilkington Buf = D.getFunctionBaseName(Buf, &Size);
7667d82d6eSErik Pilkington EXPECT_STREQ(Buf, N.BaseName);
7767d82d6eSErik Pilkington
7867d82d6eSErik Pilkington Buf = D.getFunctionReturnType(Buf, &Size);
7967d82d6eSErik Pilkington EXPECT_STREQ(Buf, N.ReturnType);
8067d82d6eSErik Pilkington
8167d82d6eSErik Pilkington Buf = D.getFunctionParameters(Buf, &Size);
8267d82d6eSErik Pilkington EXPECT_STREQ(Buf, N.Params);
8367d82d6eSErik Pilkington }
84b5757ef0SErik Pilkington
85b5757ef0SErik Pilkington std::free(Buf);
8667d82d6eSErik Pilkington }
8767d82d6eSErik Pilkington
TEST(PartialDemanglerTest,TestNameMeta)88ac6a801cSErik Pilkington TEST(PartialDemanglerTest, TestNameMeta) {
8967d82d6eSErik Pilkington llvm::ItaniumPartialDemangler Demangler;
9067d82d6eSErik Pilkington
9167d82d6eSErik Pilkington EXPECT_FALSE(Demangler.partialDemangle("_ZNK1f1gEv"));
9267d82d6eSErik Pilkington EXPECT_TRUE(Demangler.isFunction());
9367d82d6eSErik Pilkington EXPECT_TRUE(Demangler.hasFunctionQualifiers());
9467d82d6eSErik Pilkington EXPECT_FALSE(Demangler.isSpecialName());
9567d82d6eSErik Pilkington EXPECT_FALSE(Demangler.isData());
9667d82d6eSErik Pilkington
9767d82d6eSErik Pilkington EXPECT_FALSE(Demangler.partialDemangle("_Z1fv"));
9867d82d6eSErik Pilkington EXPECT_FALSE(Demangler.hasFunctionQualifiers());
9967d82d6eSErik Pilkington
10067d82d6eSErik Pilkington EXPECT_FALSE(Demangler.partialDemangle("_ZTV1S"));
10167d82d6eSErik Pilkington EXPECT_TRUE(Demangler.isSpecialName());
10267d82d6eSErik Pilkington EXPECT_FALSE(Demangler.isData());
10367d82d6eSErik Pilkington EXPECT_FALSE(Demangler.isFunction());
10467d82d6eSErik Pilkington
10567d82d6eSErik Pilkington EXPECT_FALSE(Demangler.partialDemangle("_ZN1aDC1a1b1cEE"));
10667d82d6eSErik Pilkington EXPECT_FALSE(Demangler.isFunction());
10767d82d6eSErik Pilkington EXPECT_FALSE(Demangler.isSpecialName());
10867d82d6eSErik Pilkington EXPECT_TRUE(Demangler.isData());
10967d82d6eSErik Pilkington }
11067d82d6eSErik Pilkington
TEST(PartialDemanglerTest,TestCtorOrDtor)11179420acbSFangrui Song TEST(PartialDemanglerTest, TestCtorOrDtor) {
11279420acbSFangrui Song static const char *Pos[] = {
11379420acbSFangrui Song "_ZN1AC1Ev", // A::A()
11479420acbSFangrui Song "_ZN1AC1IiEET_", // A::A<int>(int)
11579420acbSFangrui Song "_ZN1AD2Ev", // A::~A()
11679420acbSFangrui Song "_ZN1BIiEC1IcEET_", // B<int>::B<char>(char)
11779420acbSFangrui Song "_ZN1AC1B1TEv", // A::A[abi:T]()
11879420acbSFangrui Song "_ZNSt1AD2Ev", // std::A::~A()
11979420acbSFangrui Song "_ZN2ns1AD1Ev", // ns::A::~A()
12079420acbSFangrui Song };
12179420acbSFangrui Song static const char *Neg[] = {
12279420acbSFangrui Song "_Z1fv",
12379420acbSFangrui Song "_ZN1A1gIiEEvT_", // void A::g<int>(int)
12479420acbSFangrui Song };
12579420acbSFangrui Song
12679420acbSFangrui Song llvm::ItaniumPartialDemangler D;
12779420acbSFangrui Song for (const char *N : Pos) {
12879420acbSFangrui Song EXPECT_FALSE(D.partialDemangle(N));
12979420acbSFangrui Song EXPECT_TRUE(D.isCtorOrDtor());
13079420acbSFangrui Song }
13179420acbSFangrui Song for (const char *N : Neg) {
13279420acbSFangrui Song EXPECT_FALSE(D.partialDemangle(N));
13379420acbSFangrui Song EXPECT_FALSE(D.isCtorOrDtor());
13479420acbSFangrui Song }
13579420acbSFangrui Song }
13679420acbSFangrui Song
TEST(PartialDemanglerTest,TestMisc)13767d82d6eSErik Pilkington TEST(PartialDemanglerTest, TestMisc) {
13867d82d6eSErik Pilkington llvm::ItaniumPartialDemangler D1, D2;
13967d82d6eSErik Pilkington
14067d82d6eSErik Pilkington EXPECT_FALSE(D1.partialDemangle("_Z1fv"));
14167d82d6eSErik Pilkington EXPECT_FALSE(D2.partialDemangle("_Z1g"));
14267d82d6eSErik Pilkington std::swap(D1, D2);
14367d82d6eSErik Pilkington EXPECT_FALSE(D1.isFunction());
14467d82d6eSErik Pilkington EXPECT_TRUE(D2.isFunction());
14567d82d6eSErik Pilkington
14667d82d6eSErik Pilkington EXPECT_TRUE(D1.partialDemangle("Not a mangled name!"));
14756b995b1SStefan Granitz }
14867d82d6eSErik Pilkington
TEST(PartialDemanglerTest,TestPrintCases)14956b995b1SStefan Granitz TEST(PartialDemanglerTest, TestPrintCases) {
15056b995b1SStefan Granitz llvm::ItaniumPartialDemangler D;
15156b995b1SStefan Granitz
15256b995b1SStefan Granitz const size_t OriginalSize = 4;
15356b995b1SStefan Granitz char *Buf = static_cast<char *>(std::malloc(OriginalSize));
15456b995b1SStefan Granitz const char *OriginalBuf = Buf;
15556b995b1SStefan Granitz
15656b995b1SStefan Granitz // Default success case: Result fits into the given buffer.
15756b995b1SStefan Granitz // Res points to Buf. N returns string size including null termination.
15856b995b1SStefan Granitz {
15956b995b1SStefan Granitz EXPECT_FALSE(D.partialDemangle("_ZN1a1bEv"));
16056b995b1SStefan Granitz
16156b995b1SStefan Granitz size_t N = OriginalSize;
16256b995b1SStefan Granitz char *Res = D.getFunctionDeclContextName(Buf, &N);
16356b995b1SStefan Granitz EXPECT_STREQ("a", Res);
16456b995b1SStefan Granitz EXPECT_EQ(OriginalBuf, Res);
16556b995b1SStefan Granitz EXPECT_EQ(strlen(Res) + 1, N);
16656b995b1SStefan Granitz }
16756b995b1SStefan Granitz
16856b995b1SStefan Granitz // Realloc success case: Result does not fit into the given buffer.
16956b995b1SStefan Granitz // Res points to the new or extended buffer. N returns string size
17056b995b1SStefan Granitz // including null termination. Buf was extended or freed.
17156b995b1SStefan Granitz {
17256b995b1SStefan Granitz EXPECT_FALSE(D.partialDemangle("_ZN1a1b1cIiiiEEvm"));
17356b995b1SStefan Granitz
17456b995b1SStefan Granitz size_t N = OriginalSize;
17556b995b1SStefan Granitz char *Res = D.finishDemangle(Buf, &N);
17656b995b1SStefan Granitz EXPECT_STREQ("void a::b::c<int, int, int>(unsigned long)", Res);
17756b995b1SStefan Granitz EXPECT_EQ(strlen(Res) + 1, N);
17856b995b1SStefan Granitz Buf = Res;
17956b995b1SStefan Granitz }
18056b995b1SStefan Granitz
18156b995b1SStefan Granitz // Failure case: a::c is not a function.
18256b995b1SStefan Granitz // Res is nullptr. N remains unchanged.
18356b995b1SStefan Granitz {
18456b995b1SStefan Granitz EXPECT_FALSE(D.partialDemangle("_ZN1a1cE"));
18556b995b1SStefan Granitz
18656b995b1SStefan Granitz size_t N = OriginalSize;
18756b995b1SStefan Granitz char *Res = D.getFunctionName(Buf, &N);
18856b995b1SStefan Granitz EXPECT_EQ(nullptr, Res);
18956b995b1SStefan Granitz EXPECT_EQ(OriginalSize, N);
19056b995b1SStefan Granitz }
19156b995b1SStefan Granitz
19256b995b1SStefan Granitz std::free(Buf);
19367d82d6eSErik Pilkington }
194