PartialDemangleTest.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include <cstdlib>
  9. #include "llvm/Demangle/Demangle.h"
  10. #include "gtest/gtest.h"
  11. struct ChoppedName {
  12. const char *Mangled;
  13. const char *ContextName, *BaseName, *ReturnType, *Params;
  14. };
  15. static ChoppedName NamesToTest[] = {
  16. {"_Z1fv", "", "f", "", "()"},
  17. {"_ZN1a1b1cIiiiEEvm", "a::b", "c", "void", "(unsigned long)"},
  18. {"_ZZ5OuterIiEivEN5Inner12inner_memberEv",
  19. "int Outer<int>()::Inner", "inner_member", "", "()"},
  20. {"_Z1fIiEPFvvEv", "", "f", "void (*)()", "()"},
  21. {"_ZN1S1fIiEEvv", "S", "f", "void", "()"},
  22. // Call operator for a lambda in f().
  23. {"_ZZ1fvENK3$_0clEi", "f()::$_0", "operator()", "", "(int)"},
  24. // A call operator for a lambda in a lambda in f().
  25. {"_ZZZ1fvENK3$_0clEvENKUlvE_clEv",
  26. "f()::$_0::operator()() const::'lambda'()", "operator()", "", "()"},
  27. {"_ZZN1S1fEiiEd0_NKUlvE_clEv",
  28. "S::f(int, int)::'lambda'()", "operator()", "", "()"},
  29. {"_ZN1Scv7MuncherIJDpPT_EEIJFivEA_iEEEv",
  30. "S", "operator Muncher<int (*)(), int (*) []>", "", "()"},
  31. // Attributes.
  32. {"_ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi",
  33. "test4<double>", "f", "", "(int)"},
  34. {"_ZN1SC2B8ctor_tagEv", "S", "S", "", "()"},
  35. {"_ZN1S1fB4MERPIiEEvv", "S", "f", "void", "()"},
  36. {"_ZNSsC1EmcRKSaIcE",
  37. "std::basic_string<char, std::char_traits<char>, std::allocator<char> >",
  38. "basic_string", "", "(unsigned long, char, std::allocator<char> const&)"},
  39. {"_ZNSsixEm", "std::string", "operator[]", "", "(unsigned long)"},
  40. {"_ZSt17__throw_bad_allocv", "std", "__throw_bad_alloc", "", "()"},
  41. {"_ZN1AI1BEC2Ev", "A<B>", "A", "", "()"},
  42. {"_ZN1AI1BED2Ev", "A<B>", "~A", "", "()"},
  43. {"_ZN1AI1BECI24BaseEi", "A<B>", "A", "", "(int)"},
  44. {"_ZNKR1AI1BE1fIiEEiv", "A<B>", "f", "int", "()"},
  45. {"_ZN1SIJicfEE3mfnIJjcdEEEvicfDpT_", "S<int, char, float>",
  46. "mfn", "void", "(int, char, float, unsigned int, char, double)"},
  47. };
  48. TEST(PartialDemanglerTest, TestNameChopping) {
  49. size_t Size = 1;
  50. char *Buf = static_cast<char *>(std::malloc(Size));
  51. llvm::ItaniumPartialDemangler D;
  52. for (ChoppedName &N : NamesToTest) {
  53. EXPECT_FALSE(D.partialDemangle(N.Mangled));
  54. EXPECT_TRUE(D.isFunction());
  55. EXPECT_FALSE(D.isData());
  56. EXPECT_FALSE(D.isSpecialName());
  57. Buf = D.getFunctionDeclContextName(Buf, &Size);
  58. EXPECT_STREQ(Buf, N.ContextName);
  59. Buf = D.getFunctionBaseName(Buf, &Size);
  60. EXPECT_STREQ(Buf, N.BaseName);
  61. Buf = D.getFunctionReturnType(Buf, &Size);
  62. EXPECT_STREQ(Buf, N.ReturnType);
  63. Buf = D.getFunctionParameters(Buf, &Size);
  64. EXPECT_STREQ(Buf, N.Params);
  65. }
  66. std::free(Buf);
  67. }
  68. TEST(PartialDemanglerTest, TestNameMeta) {
  69. llvm::ItaniumPartialDemangler Demangler;
  70. EXPECT_FALSE(Demangler.partialDemangle("_ZNK1f1gEv"));
  71. EXPECT_TRUE(Demangler.isFunction());
  72. EXPECT_TRUE(Demangler.hasFunctionQualifiers());
  73. EXPECT_FALSE(Demangler.isSpecialName());
  74. EXPECT_FALSE(Demangler.isData());
  75. EXPECT_FALSE(Demangler.partialDemangle("_Z1fv"));
  76. EXPECT_FALSE(Demangler.hasFunctionQualifiers());
  77. EXPECT_FALSE(Demangler.partialDemangle("_ZTV1S"));
  78. EXPECT_TRUE(Demangler.isSpecialName());
  79. EXPECT_FALSE(Demangler.isData());
  80. EXPECT_FALSE(Demangler.isFunction());
  81. EXPECT_FALSE(Demangler.partialDemangle("_ZN1aDC1a1b1cEE"));
  82. EXPECT_FALSE(Demangler.isFunction());
  83. EXPECT_FALSE(Demangler.isSpecialName());
  84. EXPECT_TRUE(Demangler.isData());
  85. }
  86. TEST(PartialDemanglerTest, TestCtorOrDtor) {
  87. static const char *Pos[] = {
  88. "_ZN1AC1Ev", // A::A()
  89. "_ZN1AC1IiEET_", // A::A<int>(int)
  90. "_ZN1AD2Ev", // A::~A()
  91. "_ZN1BIiEC1IcEET_", // B<int>::B<char>(char)
  92. "_ZN1AC1B1TEv", // A::A[abi:T]()
  93. "_ZNSt1AD2Ev", // std::A::~A()
  94. "_ZN2ns1AD1Ev", // ns::A::~A()
  95. };
  96. static const char *Neg[] = {
  97. "_Z1fv",
  98. "_ZN1A1gIiEEvT_", // void A::g<int>(int)
  99. };
  100. llvm::ItaniumPartialDemangler D;
  101. for (const char *N : Pos) {
  102. EXPECT_FALSE(D.partialDemangle(N));
  103. EXPECT_TRUE(D.isCtorOrDtor());
  104. }
  105. for (const char *N : Neg) {
  106. EXPECT_FALSE(D.partialDemangle(N));
  107. EXPECT_FALSE(D.isCtorOrDtor());
  108. }
  109. }
  110. TEST(PartialDemanglerTest, TestMisc) {
  111. llvm::ItaniumPartialDemangler D1, D2;
  112. EXPECT_FALSE(D1.partialDemangle("_Z1fv"));
  113. EXPECT_FALSE(D2.partialDemangle("_Z1g"));
  114. std::swap(D1, D2);
  115. EXPECT_FALSE(D1.isFunction());
  116. EXPECT_TRUE(D2.isFunction());
  117. EXPECT_TRUE(D1.partialDemangle("Not a mangled name!"));
  118. }
  119. TEST(PartialDemanglerTest, TestPrintCases) {
  120. llvm::ItaniumPartialDemangler D;
  121. const size_t OriginalSize = 4;
  122. char *Buf = static_cast<char *>(std::malloc(OriginalSize));
  123. const char *OriginalBuf = Buf;
  124. // Default success case: Result fits into the given buffer.
  125. // Res points to Buf. N returns string size including null termination.
  126. {
  127. EXPECT_FALSE(D.partialDemangle("_ZN1a1bEv"));
  128. size_t N = OriginalSize;
  129. char *Res = D.getFunctionDeclContextName(Buf, &N);
  130. EXPECT_STREQ("a", Res);
  131. EXPECT_EQ(OriginalBuf, Res);
  132. EXPECT_EQ(strlen(Res) + 1, N);
  133. }
  134. // Realloc success case: Result does not fit into the given buffer.
  135. // Res points to the new or extended buffer. N returns string size
  136. // including null termination. Buf was extended or freed.
  137. {
  138. EXPECT_FALSE(D.partialDemangle("_ZN1a1b1cIiiiEEvm"));
  139. size_t N = OriginalSize;
  140. char *Res = D.finishDemangle(Buf, &N);
  141. EXPECT_STREQ("void a::b::c<int, int, int>(unsigned long)", Res);
  142. EXPECT_EQ(strlen(Res) + 1, N);
  143. Buf = Res;
  144. }
  145. // Failure case: a::c is not a function.
  146. // Res is nullptr. N remains unchanged.
  147. {
  148. EXPECT_FALSE(D.partialDemangle("_ZN1a1cE"));
  149. size_t N = OriginalSize;
  150. char *Res = D.getFunctionName(Buf, &N);
  151. EXPECT_EQ(nullptr, Res);
  152. EXPECT_EQ(OriginalSize, N);
  153. }
  154. std::free(Buf);
  155. }