brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · 9cb26c4 Raw
219 lines · cpp
1//===----------------------- PartialDemangleTest.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-exception6//7//===----------------------------------------------------------------------===//8 9#include <cstdlib>10#include "llvm/Demangle/Demangle.h"11#include "gtest/gtest.h"12 13struct ChoppedName {14  const char *Mangled;15  const char *ContextName, *BaseName, *ReturnType, *Params;16};17 18static ChoppedName NamesToTest[] = {19    {"_Z1fv", "", "f", "", "()"},20    {"_ZN1a1b1cIiiiEEvm", "a::b", "c", "void", "(unsigned long)"},21    {"_ZZ5OuterIiEivEN5Inner12inner_memberEv", "int Outer<int>()::Inner",22     "inner_member", "", "()"},23    {"_Z1fIiEPFvvEv", "", "f", "void (*)()", "()"},24    {"_ZN1S1fIiEEvv", "S", "f", "void", "()"},25 26    // Call operator for a lambda in f().27    {"_ZZ1fvENK3$_0clEi", "f()::$_0", "operator()", "", "(int)"},28 29    // A call operator for a lambda in a lambda in f().30    {"_ZZZ1fvENK3$_0clEvENKUlvE_clEv",31     "f()::$_0::operator()() const::'lambda'()", "operator()", "", "()"},32 33    {"_ZZN1S1fEiiEd0_NKUlvE_clEv", "S::f(int, int)::'lambda'()", "operator()",34     "", "()"},35 36    {"_ZN1Scv7MuncherIJDpPT_EEIJFivEA_iEEEv", "S",37     "operator Muncher<int (*)(), int (*) []>", "", "()"},38 39    // Attributes.40    {"_ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi",41     "test4<double>", "f", "", "(int)"},42    {"_ZN1SC2B8ctor_tagEv", "S", "S", "", "()"},43    {"_ZN1S1fB4MERPIiEEvv", "S", "f", "void", "()"},44 45    {"_ZNSsC1EmcRKSaIcE",46     "std::basic_string<char, std::char_traits<char>, std::allocator<char>>",47     "basic_string", "", "(unsigned long, char, std::allocator<char> const&)"},48    {"_ZNSsixEm", "std::string", "operator[]", "", "(unsigned long)"},49    {"_ZSt17__throw_bad_allocv", "std", "__throw_bad_alloc", "", "()"},50 51    {"_ZN1AI1BEC2Ev", "A<B>", "A", "", "()"},52    {"_ZN1AI1BED2Ev", "A<B>", "~A", "", "()"},53    {"_ZN1AI1BECI24BaseEi", "A<B>", "A", "", "(int)"},54    {"_ZNKR1AI1BE1fIiEEiv", "A<B>", "f", "int", "()"},55 56    {"_ZN1SIJicfEE3mfnIJjcdEEEvicfDpT_", "S<int, char, float>", "mfn", "void",57     "(int, char, float, unsigned int, char, double)"},58 59    {"_Z1fDAs", "", "f", "", "(short _Accum)"},60    {"_Z1fDAt", "", "f", "", "(unsigned short _Accum)"},61    {"_Z1fDAi", "", "f", "", "(_Accum)"},62    {"_Z1fDAj", "", "f", "", "(unsigned _Accum)"},63    {"_Z1fDAl", "", "f", "", "(long _Accum)"},64    {"_Z1fDAm", "", "f", "", "(unsigned long _Accum)"},65    {"_Z1fDRs", "", "f", "", "(short _Fract)"},66    {"_Z1fDRt", "", "f", "", "(unsigned short _Fract)"},67    {"_Z1fDRi", "", "f", "", "(_Fract)"},68    {"_Z1fDRj", "", "f", "", "(unsigned _Fract)"},69    {"_Z1fDRl", "", "f", "", "(long _Fract)"},70    {"_Z1fDRm", "", "f", "", "(unsigned long _Fract)"},71    {"_Z1fDSDAs", "", "f", "", "(_Sat short _Accum)"},72    {"_Z1fDSDAt", "", "f", "", "(_Sat unsigned short _Accum)"},73    {"_Z1fDSDAi", "", "f", "", "(_Sat _Accum)"},74    {"_Z1fDSDAj", "", "f", "", "(_Sat unsigned _Accum)"},75    {"_Z1fDSDAl", "", "f", "", "(_Sat long _Accum)"},76    {"_Z1fDSDAm", "", "f", "", "(_Sat unsigned long _Accum)"},77    {"_Z1fDSDRs", "", "f", "", "(_Sat short _Fract)"},78    {"_Z1fDSDRt", "", "f", "", "(_Sat unsigned short _Fract)"},79    {"_Z1fDSDRi", "", "f", "", "(_Sat _Fract)"},80    {"_Z1fDSDRj", "", "f", "", "(_Sat unsigned _Fract)"},81    {"_Z1fDSDRl", "", "f", "", "(_Sat long _Fract)"},82    {"_Z1fDSDRm", "", "f", "", "(_Sat unsigned long _Fract)"},83};84 85TEST(PartialDemanglerTest, TestNameChopping) {86  size_t Size = 1;87  char *Buf = static_cast<char *>(std::malloc(Size));88 89  llvm::ItaniumPartialDemangler D;90 91  for (ChoppedName &N : NamesToTest) {92    EXPECT_FALSE(D.partialDemangle(N.Mangled));93    EXPECT_TRUE(D.isFunction());94    EXPECT_FALSE(D.isData());95    EXPECT_FALSE(D.isSpecialName());96 97    Buf = D.getFunctionDeclContextName(Buf, &Size);98    EXPECT_STREQ(Buf, N.ContextName);99 100    Buf = D.getFunctionBaseName(Buf, &Size);101    EXPECT_STREQ(Buf, N.BaseName);102 103    Buf = D.getFunctionReturnType(Buf, &Size);104    EXPECT_STREQ(Buf, N.ReturnType);105 106    Buf = D.getFunctionParameters(Buf, &Size);107    EXPECT_STREQ(Buf, N.Params);108  }109 110  std::free(Buf);111}112 113TEST(PartialDemanglerTest, TestNameMeta) {114  llvm::ItaniumPartialDemangler Demangler;115 116  EXPECT_FALSE(Demangler.partialDemangle("_ZNK1f1gEv"));117  EXPECT_TRUE(Demangler.isFunction());118  EXPECT_TRUE(Demangler.hasFunctionQualifiers());119  EXPECT_FALSE(Demangler.isSpecialName());120  EXPECT_FALSE(Demangler.isData());121 122  EXPECT_FALSE(Demangler.partialDemangle("_Z1fv"));123  EXPECT_FALSE(Demangler.hasFunctionQualifiers());124 125  EXPECT_FALSE(Demangler.partialDemangle("_ZTV1S"));126  EXPECT_TRUE(Demangler.isSpecialName());127  EXPECT_FALSE(Demangler.isData());128  EXPECT_FALSE(Demangler.isFunction());129 130  EXPECT_FALSE(Demangler.partialDemangle("_ZN1aDC1a1b1cEE"));131  EXPECT_FALSE(Demangler.isFunction());132  EXPECT_FALSE(Demangler.isSpecialName());133  EXPECT_TRUE(Demangler.isData());134}135 136TEST(PartialDemanglerTest, TestCtorOrDtor) {137  static const char *Pos[] = {138      "_ZN1AC1Ev",        // A::A()139      "_ZN1AC1IiEET_",    // A::A<int>(int)140      "_ZN1AD2Ev",        // A::~A()141      "_ZN1BIiEC1IcEET_", // B<int>::B<char>(char)142      "_ZN1AC1B1TEv",     // A::A[abi:T]()143      "_ZNSt1AD2Ev",      // std::A::~A()144      "_ZN2ns1AD1Ev",      // ns::A::~A()145  };146  static const char *Neg[] = {147      "_Z1fv",148      "_ZN1A1gIiEEvT_", // void A::g<int>(int)149  };150 151  llvm::ItaniumPartialDemangler D;152  for (const char *N : Pos) {153    EXPECT_FALSE(D.partialDemangle(N));154    EXPECT_TRUE(D.isCtorOrDtor());155  }156  for (const char *N : Neg) {157    EXPECT_FALSE(D.partialDemangle(N));158    EXPECT_FALSE(D.isCtorOrDtor());159  }160}161 162TEST(PartialDemanglerTest, TestMisc) {163  llvm::ItaniumPartialDemangler D1, D2;164 165  EXPECT_FALSE(D1.partialDemangle("_Z1fv"));166  EXPECT_FALSE(D2.partialDemangle("_Z1g"));167  std::swap(D1, D2);168  EXPECT_FALSE(D1.isFunction());169  EXPECT_TRUE(D2.isFunction());170 171  EXPECT_TRUE(D1.partialDemangle("Not a mangled name!"));172}173 174TEST(PartialDemanglerTest, TestPrintCases) {175  llvm::ItaniumPartialDemangler D;176 177  const size_t OriginalSize = 4;178  char *Buf = static_cast<char *>(std::malloc(OriginalSize));179  const char *OriginalBuf = Buf;180 181  // Default success case: Result fits into the given buffer.182  // Res points to Buf. N returns string size including null termination.183  {184    EXPECT_FALSE(D.partialDemangle("_ZN1a1bEv"));185 186    size_t N = OriginalSize;187    char *Res = D.getFunctionDeclContextName(Buf, &N);188    EXPECT_STREQ("a", Res);189    EXPECT_EQ(OriginalBuf, Res);190    EXPECT_EQ(strlen(Res) + 1, N);191  }192 193  // Realloc success case: Result does not fit into the given buffer.194  // Res points to the new or extended buffer. N returns string size195  // including null termination. Buf was extended or freed.196  {197    EXPECT_FALSE(D.partialDemangle("_ZN1a1b1cIiiiEEvm"));198 199    size_t N = OriginalSize;200    char *Res = D.finishDemangle(Buf, &N);201    EXPECT_STREQ("void a::b::c<int, int, int>(unsigned long)", Res);202    EXPECT_EQ(strlen(Res) + 1, N);203    Buf = Res;204  }205 206  // Failure case: a::c is not a function.207  // Res is nullptr. N remains unchanged.208  {209    EXPECT_FALSE(D.partialDemangle("_ZN1a1cE"));210 211    size_t N = OriginalSize;212    char *Res = D.getFunctionName(Buf, &N);213    EXPECT_EQ(nullptr, Res);214    EXPECT_EQ(OriginalSize, N);215  }216 217  std::free(Buf);218}219