• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/debugging/internal/demangle.h"
16 
17 #include <cstdlib>
18 #include <string>
19 
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 #include "absl/base/config.h"
23 #include "absl/debugging/internal/stack_consumption.h"
24 #include "absl/log/log.h"
25 #include "absl/memory/memory.h"
26 
27 namespace absl {
28 ABSL_NAMESPACE_BEGIN
29 namespace debugging_internal {
30 namespace {
31 
32 using ::testing::ContainsRegex;
33 
TEST(Demangle,FunctionTemplate)34 TEST(Demangle, FunctionTemplate) {
35   char tmp[100];
36 
37   // template <typename T>
38   // int foo(T);
39   //
40   // foo<int>(5);
41   ASSERT_TRUE(Demangle("_Z3fooIiEiT_", tmp, sizeof(tmp)));
42   EXPECT_STREQ(tmp, "foo<>()");
43 }
44 
TEST(Demangle,FunctionTemplateWithNesting)45 TEST(Demangle, FunctionTemplateWithNesting) {
46   char tmp[100];
47 
48   // template <typename T>
49   // int foo(T);
50   //
51   // foo<Wrapper<int>>({ .value = 5 });
52   ASSERT_TRUE(Demangle("_Z3fooI7WrapperIiEEiT_", tmp, sizeof(tmp)));
53   EXPECT_STREQ(tmp, "foo<>()");
54 }
55 
TEST(Demangle,FunctionTemplateWithNonTypeParamConstraint)56 TEST(Demangle, FunctionTemplateWithNonTypeParamConstraint) {
57   char tmp[100];
58 
59   // template <std::integral T>
60   // int foo(T);
61   //
62   // foo<int>(5);
63   ASSERT_TRUE(Demangle("_Z3fooITkSt8integraliEiT_", tmp, sizeof(tmp)));
64   EXPECT_STREQ(tmp, "foo<>()");
65 }
66 
TEST(Demangle,FunctionTemplateWithFunctionRequiresClause)67 TEST(Demangle, FunctionTemplateWithFunctionRequiresClause) {
68   char tmp[100];
69 
70   // template <typename T>
71   // int foo() requires std::integral<T>;
72   //
73   // foo<int>();
74   ASSERT_TRUE(Demangle("_Z3fooIiEivQsr3stdE8integralIT_E", tmp, sizeof(tmp)));
75   EXPECT_STREQ(tmp, "foo<>()");
76 }
77 
TEST(Demangle,FunctionWithTemplateParamRequiresClause)78 TEST(Demangle, FunctionWithTemplateParamRequiresClause) {
79   char tmp[100];
80 
81   // template <typename T>
82   //     requires std::integral<T>
83   // int foo();
84   //
85   // foo<int>();
86   ASSERT_TRUE(Demangle("_Z3fooIiQsr3stdE8integralIT_EEiv", tmp, sizeof(tmp)));
87   EXPECT_STREQ(tmp, "foo<>()");
88 }
89 
TEST(Demangle,FunctionWithTemplateParamAndFunctionRequiresClauses)90 TEST(Demangle, FunctionWithTemplateParamAndFunctionRequiresClauses) {
91   char tmp[100];
92 
93   // template <typename T>
94   //     requires std::integral<T>
95   // int foo() requires std::integral<T>;
96   //
97   // foo<int>();
98   ASSERT_TRUE(Demangle("_Z3fooIiQsr3stdE8integralIT_EEivQsr3stdE8integralIS0_E",
99                        tmp, sizeof(tmp)));
100   EXPECT_STREQ(tmp, "foo<>()");
101 }
102 
TEST(Demangle,FunctionTemplateBacktracksOnMalformedRequiresClause)103 TEST(Demangle, FunctionTemplateBacktracksOnMalformedRequiresClause) {
104   char tmp[100];
105 
106   // template <typename T>
107   // int foo(T);
108   //
109   // foo<int>(5);
110   // Except there's an extra `Q` where the mangled requires clause would be.
111   ASSERT_FALSE(Demangle("_Z3fooIiQEiT_", tmp, sizeof(tmp)));
112 }
113 
TEST(Demangle,FunctionTemplateWithAutoParam)114 TEST(Demangle, FunctionTemplateWithAutoParam) {
115   char tmp[100];
116 
117   // template <auto>
118   // void foo();
119   //
120   // foo<1>();
121   ASSERT_TRUE(Demangle("_Z3fooITnDaLi1EEvv", tmp, sizeof(tmp)));
122   EXPECT_STREQ(tmp, "foo<>()");
123 }
124 
TEST(Demangle,FunctionTemplateWithNonTypeParamPack)125 TEST(Demangle, FunctionTemplateWithNonTypeParamPack) {
126   char tmp[100];
127 
128   // template <int&..., typename T>
129   // void foo(T);
130   //
131   // foo(2);
132   ASSERT_TRUE(Demangle("_Z3fooITpTnRiJEiEvT0_", tmp, sizeof(tmp)));
133   EXPECT_STREQ(tmp, "foo<>()");
134 }
135 
TEST(Demangle,FunctionTemplateTemplateParamWithConstrainedArg)136 TEST(Demangle, FunctionTemplateTemplateParamWithConstrainedArg) {
137   char tmp[100];
138 
139   // template <typename T>
140   // concept True = true;
141   //
142   // template <typename T> requires True<T>
143   // struct Fooer {};
144   //
145   // template <template <typename T> typename>
146   // void foo() {}
147   //
148   // foo<Fooer>();
149   ASSERT_TRUE(Demangle("_Z3fooITtTyE5FooerEvv", tmp, sizeof(tmp)));
150   EXPECT_STREQ(tmp, "foo<>()");
151 }
152 
TEST(Demangle,ConstrainedAutoInFunctionTemplate)153 TEST(Demangle, ConstrainedAutoInFunctionTemplate) {
154   char tmp[100];
155 
156   // template <typename T> concept C = true;
157   // template <C auto N> void f() {}
158   // template void f<0>();
159   ASSERT_TRUE(Demangle("_Z1fITnDk1CLi0EEvv", tmp, sizeof(tmp)));
160   EXPECT_STREQ(tmp, "f<>()");
161 }
162 
TEST(Demangle,NonTemplateBuiltinType)163 TEST(Demangle, NonTemplateBuiltinType) {
164   char tmp[100];
165 
166   // void foo(__my_builtin_type t);
167   //
168   // foo({});
169   ASSERT_TRUE(Demangle("_Z3foou17__my_builtin_type", tmp, sizeof(tmp)));
170   EXPECT_STREQ(tmp, "foo()");
171 }
172 
TEST(Demangle,SingleArgTemplateBuiltinType)173 TEST(Demangle, SingleArgTemplateBuiltinType) {
174   char tmp[100];
175 
176   // template <typename T>
177   // __my_builtin_type<T> foo();
178   //
179   // foo<int>();
180   ASSERT_TRUE(Demangle("_Z3fooIiEu17__my_builtin_typeIT_Ev", tmp, sizeof(tmp)));
181   EXPECT_STREQ(tmp, "foo<>()");
182 }
183 
TEST(Demangle,FailsOnTwoArgTemplateBuiltinType)184 TEST(Demangle, FailsOnTwoArgTemplateBuiltinType) {
185   char tmp[100];
186 
187   // template <typename T, typename U>
188   // __my_builtin_type<T, U> foo();
189   //
190   // foo<int, char>();
191   ASSERT_FALSE(
192       Demangle("_Z3fooIicEu17__my_builtin_typeIT_T0_Ev", tmp, sizeof(tmp)));
193 }
194 
TEST(Demangle,TypeNestedUnderTemplatedBuiltinType)195 TEST(Demangle, TypeNestedUnderTemplatedBuiltinType) {
196   char tmp[100];
197 
198   // Source:
199   //
200   // template <typename T>
201   // typename std::remove_reference_t<T>::type f(T t);
202   //
203   // struct C { using type = C; };
204   //
205   // f<const C&>(C{});
206   //
207   // These days std::remove_reference_t is implemented in terms of a vendor
208   // builtin __remove_reference_t.  A full demangling might look like:
209   //
210   // __remove_reference_t<C const&>::type f<C const&>(C const&)
211   ASSERT_TRUE(Demangle("_Z1fIRK1CENu20__remove_reference_tIT_E4typeES3_",
212                        tmp, sizeof(tmp)));
213   EXPECT_STREQ("f<>()", tmp);
214 }
215 
TEST(Demangle,TemplateTemplateParamSubstitution)216 TEST(Demangle, TemplateTemplateParamSubstitution) {
217   char tmp[100];
218 
219   // template <typename T>
220   // concept True = true;
221   //
222   // template<std::integral T, T> struct Foolable {};
223   // template<template<typename T, T> typename> void foo() {}
224   //
225   // template void foo<Foolable>();
226   ASSERT_TRUE(Demangle("_Z3fooITtTyTnTL0__E8FoolableEvv", tmp, sizeof(tmp)));
227   EXPECT_STREQ(tmp, "foo<>()");
228 }
229 
TEST(Demangle,TemplateParamSubstitutionWithGenericLambda)230 TEST(Demangle, TemplateParamSubstitutionWithGenericLambda) {
231   char tmp[100];
232 
233   // template <typename>
234   // struct Fooer {
235   //     template <typename>
236   //     void foo(decltype([](auto x, auto y) {})) {}
237   // };
238   //
239   // Fooer<int> f;
240   // f.foo<int>({});
241   ASSERT_TRUE(
242       Demangle("_ZN5FooerIiE3fooIiEEvNS0_UlTL0__TL0_0_E_E", tmp, sizeof(tmp)));
243   EXPECT_STREQ(tmp, "Fooer<>::foo<>()");
244 }
245 
TEST(Demangle,LambdaRequiresTrue)246 TEST(Demangle, LambdaRequiresTrue) {
247   char tmp[100];
248 
249   // auto $_0::operator()<int>(int) const requires true
250   ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QLb1E", tmp, sizeof(tmp)));
251   EXPECT_STREQ(tmp, "$_0::operator()<>()");
252 }
253 
TEST(Demangle,LambdaRequiresSimpleExpression)254 TEST(Demangle, LambdaRequiresSimpleExpression) {
255   char tmp[100];
256 
257   // auto $_0::operator()<int>(int) const requires 2 + 2 == 4
258   ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QeqplLi2ELi2ELi4E",
259                        tmp, sizeof(tmp)));
260   EXPECT_STREQ(tmp, "$_0::operator()<>()");
261 }
262 
TEST(Demangle,LambdaRequiresRequiresExpressionContainingTrue)263 TEST(Demangle, LambdaRequiresRequiresExpressionContainingTrue) {
264   char tmp[100];
265 
266   // auto $_0::operator()<int>(int) const requires requires { true; }
267   ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqXLb1EE", tmp, sizeof(tmp)));
268   EXPECT_STREQ(tmp, "$_0::operator()<>()");
269 }
270 
TEST(Demangle,LambdaRequiresRequiresExpressionContainingConcept)271 TEST(Demangle, LambdaRequiresRequiresExpressionContainingConcept) {
272   char tmp[100];
273 
274   // auto $_0::operator()<int>(int) const
275   // requires requires { std::same_as<decltype(fp), int>; }
276   ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqXsr3stdE7same_asIDtfp_EiEE",
277                        tmp, sizeof(tmp)));
278   EXPECT_STREQ(tmp, "$_0::operator()<>()");
279 }
280 
TEST(Demangle,LambdaRequiresRequiresExpressionContainingNoexceptExpression)281 TEST(Demangle, LambdaRequiresRequiresExpressionContainingNoexceptExpression) {
282   char tmp[100];
283 
284   // auto $_0::operator()<int>(int) const
285   // requires requires { {fp + fp} noexcept; }
286   ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqXplfp_fp_NE", tmp, sizeof(tmp)));
287   EXPECT_STREQ(tmp, "$_0::operator()<>()");
288 }
289 
TEST(Demangle,LambdaRequiresRequiresExpressionContainingReturnTypeConstraint)290 TEST(Demangle, LambdaRequiresRequiresExpressionContainingReturnTypeConstraint) {
291   char tmp[100];
292 
293   // auto $_0::operator()<int>(int) const
294   // requires requires { {fp + fp} -> std::same_as<decltype(fp)>; }
295   ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqXplfp_fp_RNSt7same_asIDtfp_EEEE",
296                        tmp, sizeof(tmp)));
297   EXPECT_STREQ(tmp, "$_0::operator()<>()");
298 }
299 
TEST(Demangle,LambdaRequiresRequiresExpressionWithBothNoexceptAndReturnType)300 TEST(Demangle, LambdaRequiresRequiresExpressionWithBothNoexceptAndReturnType) {
301   char tmp[100];
302 
303   // auto $_0::operator()<int>(int) const
304   // requires requires { {fp + fp} noexcept -> std::same_as<decltype(fp)>; }
305   ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqXplfp_fp_NRNSt7same_asIDtfp_EEEE",
306                        tmp, sizeof(tmp)));
307   EXPECT_STREQ(tmp, "$_0::operator()<>()");
308 }
309 
TEST(Demangle,LambdaRequiresRequiresExpressionContainingType)310 TEST(Demangle, LambdaRequiresRequiresExpressionContainingType) {
311   char tmp[100];
312 
313   // auto $_0::operator()<S>(S) const
314   // requires requires { typename S::T; }
315   ASSERT_TRUE(Demangle("_ZNK3$_0clI1SEEDaT_QrqTNS2_1TEE", tmp, sizeof(tmp)));
316   EXPECT_STREQ(tmp, "$_0::operator()<>()");
317 }
318 
TEST(Demangle,LambdaRequiresRequiresExpressionNestingAnotherRequires)319 TEST(Demangle, LambdaRequiresRequiresExpressionNestingAnotherRequires) {
320   char tmp[100];
321 
322   // auto $_0::operator()<int>(int) const requires requires { requires true; }
323   ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqQLb1EE", tmp, sizeof(tmp)));
324   EXPECT_STREQ(tmp, "$_0::operator()<>()");
325 }
326 
TEST(Demangle,LambdaRequiresRequiresExpressionContainingTwoRequirements)327 TEST(Demangle, LambdaRequiresRequiresExpressionContainingTwoRequirements) {
328   char tmp[100];
329 
330   // auto $_0::operator()<int>(int) const
331   // requires requires { requires true; requires 2 + 2 == 4; }
332   ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqXLb1EXeqplLi2ELi2ELi4EE",
333                        tmp, sizeof(tmp)));
334   EXPECT_STREQ(tmp, "$_0::operator()<>()");
335 }
336 
TEST(Demangle,RequiresExpressionWithItsOwnParameter)337 TEST(Demangle, RequiresExpressionWithItsOwnParameter) {
338   char tmp[100];
339 
340   // S<requires (int) { fp + fp; }> f<int>(int)
341   ASSERT_TRUE(Demangle("_Z1fIiE1SIXrQT__XplfL0p_fp_EEES1_", tmp, sizeof(tmp)));
342   EXPECT_STREQ(tmp, "f<>()");
343 }
344 
TEST(Demangle,LambdaWithExplicitTypeArgument)345 TEST(Demangle, LambdaWithExplicitTypeArgument) {
346   char tmp[100];
347 
348   // Source:
349   //
350   // template <class T> T f(T t) {
351   //   return []<class U>(U u) { return u + u; }(t);
352   // }
353   //
354   // template int f<int>(int);
355   //
356   // Full LLVM demangling of the lambda call operator:
357   //
358   // auto int f<int>(int)::'lambda'<typename $T>(int)::
359   // operator()<int>(int) const
360   ASSERT_TRUE(Demangle("_ZZ1fIiET_S0_ENKUlTyS0_E_clIiEEDaS0_",
361                        tmp, sizeof(tmp)));
362   EXPECT_STREQ(tmp, "f<>()::{lambda()#1}::operator()<>()");
363 }
364 
TEST(Demangle,LambdaWithExplicitPackArgument)365 TEST(Demangle, LambdaWithExplicitPackArgument) {
366   char tmp[100];
367 
368   // Source:
369   //
370   // template <class T> T h(T t) {
371   //   return []<class... U>(U... u) {
372   //     return ((u + u) + ... + 0);
373   //   }(t);
374   // }
375   //
376   // template int h<int>(int);
377   //
378   // Full LLVM demangling of the lambda call operator:
379   //
380   // auto int f<int>(int)::'lambda'<typename ...$T>($T...)::
381   // operator()<int>($T...) const
382   ASSERT_TRUE(Demangle("_ZZ1fIiET_S0_ENKUlTpTyDpT_E_clIJiEEEDaS2_",
383                        tmp, sizeof(tmp)));
384   EXPECT_STREQ(tmp, "f<>()::{lambda()#1}::operator()<>()");
385 }
386 
TEST(Demangle,LambdaInClassMemberDefaultArgument)387 TEST(Demangle, LambdaInClassMemberDefaultArgument) {
388   char tmp[100];
389 
390   // Source:
391   //
392   // struct S {
393   //   static auto f(void (*g)() = [] {}) { return g; }
394   // };
395   // void (*p)() = S::f();
396   //
397   // Full LLVM demangling of the lambda call operator:
398   //
399   // S::f(void (*)())::'lambda'()::operator()() const
400   //
401   // Full GNU binutils demangling:
402   //
403   // S::f(void (*)())::{default arg#1}::{lambda()#1}::operator()() const
404   ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd_NKUlvE_clEv", tmp, sizeof(tmp)));
405   EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()");
406 
407   // The same but in the second rightmost default argument.
408   ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd0_NKUlvE_clEv", tmp, sizeof(tmp)));
409   EXPECT_STREQ(tmp, "S::f()::{default arg#2}::{lambda()#1}::operator()()");
410 
411   // Reject negative <(parameter) number> values.
412   ASSERT_FALSE(Demangle("_ZZN1S1fEPFvvEEdn1_NKUlvE_clEv", tmp, sizeof(tmp)));
413 }
414 
TEST(Demangle,AvoidSignedOverflowForUnfortunateParameterNumbers)415 TEST(Demangle, AvoidSignedOverflowForUnfortunateParameterNumbers) {
416   char tmp[100];
417 
418   // Here <number> + 2 fits in an int, but just barely.  (We expect no such
419   // input in practice: real functions don't have billions of arguments.)
420   ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd2147483645_NKUlvE_clEv",
421                        tmp, sizeof(tmp)));
422   EXPECT_STREQ(tmp,
423                "S::f()::{default arg#2147483647}::{lambda()#1}::operator()()");
424 
425   // Now <number> is an int, but <number> + 2 is not.
426   ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd2147483646_NKUlvE_clEv",
427                        tmp, sizeof(tmp)));
428   EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()");
429 
430   // <number> is the largest int.
431   ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd2147483647_NKUlvE_clEv",
432                        tmp, sizeof(tmp)));
433   EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()");
434 
435   // <number> itself does not fit into an int.  ParseNumber truncates the value
436   // to int, yielding a large negative number, which we strain out.
437   ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd2147483648_NKUlvE_clEv",
438                        tmp, sizeof(tmp)));
439   EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()");
440 }
441 
TEST(Demangle,SubstpackNotationForTroublesomeTemplatePack)442 TEST(Demangle, SubstpackNotationForTroublesomeTemplatePack) {
443   char tmp[100];
444 
445   // Source:
446   //
447   // template <template <class> class, template <class> class> struct B {};
448   //
449   // template <template <class> class... T> struct A {
450   //   template <template <class> class... U> void f(B<T, U>&&...) {}
451   // };
452   //
453   // template void A<>::f<>();
454   //
455   // LLVM can't demangle its own _SUBSTPACK_ notation.
456   ASSERT_TRUE(Demangle("_ZN1AIJEE1fIJEEEvDpO1BI_SUBSTPACK_T_E",
457                        tmp, sizeof(tmp)));
458   EXPECT_STREQ(tmp, "A<>::f<>()");
459 }
460 
TEST(Demangle,TemplateTemplateParamAppearingAsBackrefFollowedByTemplateArgs)461 TEST(Demangle, TemplateTemplateParamAppearingAsBackrefFollowedByTemplateArgs) {
462   char tmp[100];
463 
464   // Source:
465   //
466   // template <template <class> class C> struct W {
467   //   template <class T> static decltype(C<T>::m()) f() { return {}; }
468   // };
469   //
470   // template <class T> struct S { static int m() { return 0; } };
471   // template decltype(S<int>::m()) W<S>::f<int>();
472   ASSERT_TRUE(Demangle("_ZN1WI1SE1fIiEEDTclsrS0_IT_EE1mEEv", tmp, sizeof(tmp)));
473   EXPECT_STREQ(tmp, "W<>::f<>()");
474 }
475 
476 // Test corner cases of boundary conditions.
TEST(Demangle,CornerCases)477 TEST(Demangle, CornerCases) {
478   char tmp[10];
479   EXPECT_TRUE(Demangle("_Z6foobarv", tmp, sizeof(tmp)));
480   // sizeof("foobar()") == 9
481   EXPECT_STREQ("foobar()", tmp);
482   EXPECT_TRUE(Demangle("_Z6foobarv", tmp, 9));
483   EXPECT_STREQ("foobar()", tmp);
484   EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 8));  // Not enough.
485   EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 1));
486   EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 0));
487   EXPECT_FALSE(Demangle("_Z6foobarv", nullptr, 0));  // Should not cause SEGV.
488   EXPECT_FALSE(Demangle("_Z1000000", tmp, 9));
489 }
490 
491 // Test handling of functions suffixed with .clone.N, which is used
492 // by GCC 4.5.x (and our locally-modified version of GCC 4.4.x), and
493 // .constprop.N and .isra.N, which are used by GCC 4.6.x.  These
494 // suffixes are used to indicate functions which have been cloned
495 // during optimization.  We ignore these suffixes.
TEST(Demangle,Clones)496 TEST(Demangle, Clones) {
497   char tmp[20];
498   EXPECT_TRUE(Demangle("_ZL3Foov", tmp, sizeof(tmp)));
499   EXPECT_STREQ("Foo()", tmp);
500   EXPECT_TRUE(Demangle("_ZL3Foov.clone.3", tmp, sizeof(tmp)));
501   EXPECT_STREQ("Foo()", tmp);
502   EXPECT_TRUE(Demangle("_ZL3Foov.constprop.80", tmp, sizeof(tmp)));
503   EXPECT_STREQ("Foo()", tmp);
504   EXPECT_TRUE(Demangle("_ZL3Foov.isra.18", tmp, sizeof(tmp)));
505   EXPECT_STREQ("Foo()", tmp);
506   EXPECT_TRUE(Demangle("_ZL3Foov.isra.2.constprop.18", tmp, sizeof(tmp)));
507   EXPECT_STREQ("Foo()", tmp);
508   // Demangle suffixes produced by -funique-internal-linkage-names.
509   EXPECT_TRUE(Demangle("_ZL3Foov.__uniq.12345", tmp, sizeof(tmp)));
510   EXPECT_STREQ("Foo()", tmp);
511   EXPECT_TRUE(Demangle("_ZL3Foov.__uniq.12345.isra.2.constprop.18", tmp,
512                        sizeof(tmp)));
513   EXPECT_STREQ("Foo()", tmp);
514   // Suffixes without the number should also demangle.
515   EXPECT_TRUE(Demangle("_ZL3Foov.clo", tmp, sizeof(tmp)));
516   EXPECT_STREQ("Foo()", tmp);
517   // Suffixes with just the number should also demangle.
518   EXPECT_TRUE(Demangle("_ZL3Foov.123", tmp, sizeof(tmp)));
519   EXPECT_STREQ("Foo()", tmp);
520   // (.clone. followed by non-number), should also demangle.
521   EXPECT_TRUE(Demangle("_ZL3Foov.clone.foo", tmp, sizeof(tmp)));
522   EXPECT_STREQ("Foo()", tmp);
523   // (.clone. followed by multiple numbers), should also demangle.
524   EXPECT_TRUE(Demangle("_ZL3Foov.clone.123.456", tmp, sizeof(tmp)));
525   EXPECT_STREQ("Foo()", tmp);
526   // (a long valid suffix), should demangle.
527   EXPECT_TRUE(Demangle("_ZL3Foov.part.9.165493.constprop.775.31805", tmp,
528                        sizeof(tmp)));
529   EXPECT_STREQ("Foo()", tmp);
530   // Invalid (. without anything else), should not demangle.
531   EXPECT_FALSE(Demangle("_ZL3Foov.", tmp, sizeof(tmp)));
532   // Invalid (. with mix of alpha and digits), should not demangle.
533   EXPECT_FALSE(Demangle("_ZL3Foov.abc123", tmp, sizeof(tmp)));
534   // Invalid (.clone. not followed by number), should not demangle.
535   EXPECT_FALSE(Demangle("_ZL3Foov.clone.", tmp, sizeof(tmp)));
536   // Invalid (.constprop. not followed by number), should not demangle.
537   EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp)));
538 }
539 
TEST(Demangle,Discriminators)540 TEST(Demangle, Discriminators) {
541   char tmp[80];
542 
543   // Source:
544   //
545   // using Thunk = void (*)();
546   //
547   // Thunk* f() {
548   //   static Thunk thunks[12] = {};
549   //
550   // #define THUNK(i) [backslash here]
551   //   do { struct S { static void g() {} }; thunks[i] = &S::g; } while (0)
552   //
553   //   THUNK(0);
554   //   [... repeat for 1 to 10 ...]
555   //   THUNK(11);
556   //
557   //   return thunks;
558   // }
559   //
560   // The test inputs are manglings of some of the S::g member functions.
561 
562   // The first one omits the discriminator.
563   EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gEv", tmp, sizeof(tmp)));
564   EXPECT_STREQ("f()::S::g()", tmp);
565 
566   // The second one encodes 0.
567   EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE_0v", tmp, sizeof(tmp)));
568   EXPECT_STREQ("f()::S::g()", tmp);
569 
570   // The eleventh one encodes 9.
571   EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE_9v", tmp, sizeof(tmp)));
572   EXPECT_STREQ("f()::S::g()", tmp);
573 
574   // The twelfth one encodes 10 with extra underscores delimiting it.
575   EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE__10_v", tmp, sizeof(tmp)));
576   EXPECT_STREQ("f()::S::g()", tmp);
577 }
578 
TEST(Demangle,SingleDigitDiscriminatorFollowedByADigit)579 TEST(Demangle, SingleDigitDiscriminatorFollowedByADigit) {
580   char tmp[80];
581 
582   // Don't parse 911 as a number.
583   EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE_911return_type", tmp, sizeof(tmp)));
584   EXPECT_STREQ("f()::S::g()", tmp);
585 }
586 
TEST(Demangle,LiteralOfGlobalNamespaceEnumType)587 TEST(Demangle, LiteralOfGlobalNamespaceEnumType) {
588   char tmp[80];
589 
590   // void f<(E)42>()
591   EXPECT_TRUE(Demangle("_Z1fIL1E42EEvv", tmp, sizeof(tmp)));
592   EXPECT_STREQ("f<>()", tmp);
593 }
594 
TEST(Demangle,NullptrLiterals)595 TEST(Demangle, NullptrLiterals) {
596   char tmp[80];
597 
598   // void f<nullptr>()
599   EXPECT_TRUE(Demangle("_Z1fILDnEEvv", tmp, sizeof(tmp)));
600   EXPECT_STREQ("f<>()", tmp);
601 
602   // also void f<nullptr>()
603   EXPECT_TRUE(Demangle("_Z1fILDn0EEvv", tmp, sizeof(tmp)));
604   EXPECT_STREQ("f<>()", tmp);
605 }
606 
TEST(Demangle,StringLiterals)607 TEST(Demangle, StringLiterals) {
608   char tmp[80];
609 
610   // void f<"<char const [42]>">()
611   EXPECT_TRUE(Demangle("_Z1fILA42_KcEEvv", tmp, sizeof(tmp)));
612   EXPECT_STREQ("f<>()", tmp);
613 }
614 
615 // Test the GNU abi_tag extension.
TEST(Demangle,AbiTags)616 TEST(Demangle, AbiTags) {
617   char tmp[80];
618 
619   // Mangled name generated via:
620   // struct [[gnu::abi_tag("abc")]] A{};
621   // A a;
622   EXPECT_TRUE(Demangle("_Z1aB3abc", tmp, sizeof(tmp)));
623   EXPECT_STREQ("a[abi:abc]", tmp);
624 
625   // Mangled name generated via:
626   // struct B {
627   //   B [[gnu::abi_tag("xyz")]] (){};
628   // };
629   // B b;
630   EXPECT_TRUE(Demangle("_ZN1BC2B3xyzEv", tmp, sizeof(tmp)));
631   EXPECT_STREQ("B::B[abi:xyz]()", tmp);
632 
633   // Mangled name generated via:
634   // [[gnu::abi_tag("foo", "bar")]] void C() {}
635   EXPECT_TRUE(Demangle("_Z1CB3barB3foov", tmp, sizeof(tmp)));
636   EXPECT_STREQ("C[abi:bar][abi:foo]()", tmp);
637 }
638 
TEST(Demangle,EnableIfAttributeOnGlobalFunction)639 TEST(Demangle, EnableIfAttributeOnGlobalFunction) {
640   char tmp[80];
641 
642   // int f(long l) __attribute__((enable_if(l >= 0, ""))) { return l; }
643   //
644   // f(long) [enable_if:fp >= 0]
645   EXPECT_TRUE(Demangle("_Z1fUa9enable_ifIXgefL0p_Li0EEEl", tmp, sizeof(tmp)));
646   EXPECT_STREQ("f()", tmp);
647 }
648 
TEST(Demangle,EnableIfAttributeOnNamespaceScopeFunction)649 TEST(Demangle, EnableIfAttributeOnNamespaceScopeFunction) {
650   char tmp[80];
651 
652   // namespace ns {
653   // int f(long l) __attribute__((enable_if(l >= 0, ""))) { return l; }
654   // }  // namespace ns
655   //
656   // ns::f(long) [enable_if:fp >= 0]
657   EXPECT_TRUE(Demangle("_ZN2ns1fEUa9enable_ifIXgefL0p_Li0EEEl",
658               tmp, sizeof(tmp)));
659   EXPECT_STREQ("ns::f()", tmp);
660 }
661 
TEST(Demangle,EnableIfAttributeOnFunctionTemplate)662 TEST(Demangle, EnableIfAttributeOnFunctionTemplate) {
663   char tmp[80];
664 
665   // template <class T>
666   // T f(T t) __attribute__((enable_if(t >= T{}, ""))) { return t; }
667   // template int f<int>(int);
668   //
669   // int f<int>(int) [enable_if:fp >= int{}]
670   EXPECT_TRUE(Demangle("_Z1fIiEUa9enable_ifIXgefL0p_tliEEET_S0_",
671               tmp, sizeof(tmp)));
672   EXPECT_STREQ("f<>()", tmp);
673 }
674 
TEST(Demangle,ThisPointerInDependentSignature)675 TEST(Demangle, ThisPointerInDependentSignature) {
676   char tmp[80];
677 
678   // decltype(g<int>(this)) S::f<int>()
679   EXPECT_TRUE(Demangle("_ZN1S1fIiEEDTcl1gIT_EfpTEEv", tmp, sizeof(tmp)));
680   EXPECT_STREQ("S::f<>()", tmp);
681 }
682 
TEST(Demangle,DependentMemberOperatorCall)683 TEST(Demangle, DependentMemberOperatorCall) {
684   char tmp[80];
685 
686   // decltype(fp.operator()()) f<C>(C)
687   EXPECT_TRUE(Demangle("_Z1fI1CEDTcldtfp_onclEET_", tmp, sizeof(tmp)));
688   EXPECT_STREQ("f<>()", tmp);
689 }
690 
TEST(Demangle,TypeNestedUnderDecltype)691 TEST(Demangle, TypeNestedUnderDecltype) {
692   char tmp[80];
693 
694   // Source:
695   //
696   // template <class T> struct S { using t = int; };
697   // template <class T> decltype(S<T>{})::t f() { return {}; }
698   // void g() { f<int>(); }
699   //
700   // Full LLVM demangling of the instantiation of f:
701   //
702   // decltype(S<int>{})::t f<int>()
703   EXPECT_TRUE(Demangle("_Z1fIiENDTtl1SIT_EEE1tEv", tmp, sizeof(tmp)));
704   EXPECT_STREQ("f<>()", tmp);
705 }
706 
707 // Test subobject-address template parameters.
TEST(Demangle,SubobjectAddresses)708 TEST(Demangle, SubobjectAddresses) {
709   char tmp[80];
710 
711   // void f<a.<char const at offset 123>>()
712   EXPECT_TRUE(Demangle("_Z1fIXsoKcL_Z1aE123EEEvv", tmp, sizeof(tmp)));
713   EXPECT_STREQ("f<>()", tmp);
714 
715   // void f<&a.<char const at offset 0>>()
716   EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aEEEEvv", tmp, sizeof(tmp)));
717   EXPECT_STREQ("f<>()", tmp);
718 
719   // void f<&a.<char const at offset 123>>()
720   EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aE123EEEvv", tmp, sizeof(tmp)));
721   EXPECT_STREQ("f<>()", tmp);
722 
723   // void f<&a.<char const at offset 123>>(), past the end this time
724   EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aE123pEEEvv", tmp, sizeof(tmp)));
725   EXPECT_STREQ("f<>()", tmp);
726 
727   // void f<&a.<char const at offset 0>>() with union-selectors
728   EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aE__1_234EEEvv", tmp, sizeof(tmp)));
729   EXPECT_STREQ("f<>()", tmp);
730 
731   // void f<&a.<char const at offset 123>>(), past the end, with union-selector
732   EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aE123_456pEEEvv", tmp, sizeof(tmp)));
733   EXPECT_STREQ("f<>()", tmp);
734 }
735 
TEST(Demangle,UnaryFoldExpressions)736 TEST(Demangle, UnaryFoldExpressions) {
737   char tmp[80];
738 
739   // Source:
740   //
741   // template <bool b> struct S {};
742   //
743   // template <class... T> auto f(T... t) -> S<((sizeof(T) == 4) || ...)> {
744   //   return {};
745   // }
746   //
747   // void g() { f(1, 2L); }
748   //
749   // Full LLVM demangling of the instantiation of f:
750   //
751   // S<((sizeof (int) == 4, sizeof (long) == 4) || ...)> f<int, long>(int, long)
752   EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXfrooeqstT_Li4EEEDpS1_",
753                        tmp, sizeof(tmp)));
754   EXPECT_STREQ("f<>()", tmp);
755 
756   // The like with a left fold.
757   //
758   // S<(... || (sizeof (int) == 4, sizeof (long) == 4))> f<int, long>(int, long)
759   EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXflooeqstT_Li4EEEDpS1_",
760                        tmp, sizeof(tmp)));
761   EXPECT_STREQ("f<>()", tmp);
762 }
763 
TEST(Demangle,BinaryFoldExpressions)764 TEST(Demangle, BinaryFoldExpressions) {
765   char tmp[80];
766 
767   // Source:
768   //
769   // template <bool b> struct S {};
770   //
771   // template <class... T> auto f(T... t)
772   //     -> S<((sizeof(T) == 4) || ... || false)> {
773   //   return {};
774   // }
775   //
776   // void g() { f(1, 2L); }
777   //
778   // Full LLVM demangling of the instantiation of f:
779   //
780   // S<((sizeof (int) == 4, sizeof (long) == 4) || ... || false)>
781   // f<int, long>(int, long)
782   EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXfRooeqstT_Li4ELb0EEEDpS1_",
783                        tmp, sizeof(tmp)));
784   EXPECT_STREQ("f<>()", tmp);
785 
786   // The like with a left fold.
787   //
788   // S<(false || ... || (sizeof (int) == 4, sizeof (long) == 4))>
789   // f<int, long>(int, long)
790   EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXfLooLb0EeqstT_Li4EEEDpS1_",
791                        tmp, sizeof(tmp)));
792   EXPECT_STREQ("f<>()", tmp);
793 }
794 
TEST(Demangle,SizeofPacks)795 TEST(Demangle, SizeofPacks) {
796   char tmp[80];
797 
798   // template <std::size_t i> struct S {};
799   //
800   // template <class... T> auto f(T... p) -> S<sizeof...(T)> { return {}; }
801   // template auto f<int, long>(int, long) -> S<2>;
802   //
803   // template <class... T> auto g(T... p) -> S<sizeof...(p)> { return {}; }
804   // template auto g<int, long>(int, long) -> S<2>;
805 
806   // S<sizeof...(int, long)> f<int, long>(int, long)
807   EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXsZT_EEDpT_", tmp, sizeof(tmp)));
808   EXPECT_STREQ("f<>()", tmp);
809 
810   // S<sizeof... (fp)> g<int, long>(int, long)
811   EXPECT_TRUE(Demangle("_Z1gIJilEE1SIXsZfp_EEDpT_", tmp, sizeof(tmp)));
812   EXPECT_STREQ("g<>()", tmp);
813 }
814 
TEST(Demangle,SizeofPackInvolvingAnAliasTemplate)815 TEST(Demangle, SizeofPackInvolvingAnAliasTemplate) {
816   char tmp[80];
817 
818   // Source:
819   //
820   // template <class... T> using A = char[sizeof...(T)];
821   // template <class... U> void f(const A<U..., int>&) {}
822   // template void f<int>(const A<int, int>&);
823   //
824   // Full LLVM demangling of the instantiation of f:
825   //
826   // void f<int>(char const (&) [sizeof... (int, int)])
827   EXPECT_TRUE(Demangle("_Z1fIJiEEvRAsPDpT_iE_Kc", tmp, sizeof(tmp)));
828   EXPECT_STREQ("f<>()", tmp);
829 }
830 
TEST(Demangle,Spaceship)831 TEST(Demangle, Spaceship) {
832   char tmp[80];
833 
834   // #include <compare>
835   //
836   // struct S { auto operator<=>(const S&) const = default; };
837   // auto (S::*f) = &S::operator<=>;  // make sure S::operator<=> is emitted
838   //
839   // template <class T> auto g(T x, T y) -> decltype(x <=> y) {
840   //   return x <=> y;
841   // }
842   // template auto g<S>(S x, S y) -> decltype(x <=> y);
843 
844   // S::operator<=>(S const&) const
845   EXPECT_TRUE(Demangle("_ZNK1SssERKS_", tmp, sizeof(tmp)));
846   EXPECT_STREQ("S::operator<=>()", tmp);
847 
848   // decltype(fp <=> fp0) g<S>(S, S)
849   EXPECT_TRUE(Demangle("_Z1gI1SEDTssfp_fp0_ET_S2_", tmp, sizeof(tmp)));
850   EXPECT_STREQ("g<>()", tmp);
851 }
852 
TEST(Demangle,VendorExtendedExpressions)853 TEST(Demangle, VendorExtendedExpressions) {
854   char tmp[80];
855 
856   // void f<__e()>()
857   EXPECT_TRUE(Demangle("_Z1fIXu3__eEEEvv", tmp, sizeof(tmp)));
858   EXPECT_STREQ("f<>()", tmp);
859 
860   // void f<__e(int, long)>()
861   EXPECT_TRUE(Demangle("_Z1fIXu3__eilEEEvv", tmp, sizeof(tmp)));
862   EXPECT_STREQ("f<>()", tmp);
863 }
864 
TEST(Demangle,DirectListInitialization)865 TEST(Demangle, DirectListInitialization) {
866   char tmp[80];
867 
868   // template <class T> decltype(T{}) f() { return T{}; }
869   // template decltype(int{}) f<int>();
870   //
871   // struct XYZ { int x, y, z; };
872   // template <class T> decltype(T{1, 2, 3}) g() { return T{1, 2, 3}; }
873   // template decltype(XYZ{1, 2, 3}) g<XYZ>();
874   //
875   // template <class T> decltype(T{.x = 1, .y = 2, .z = 3}) h() {
876   //   return T{.x = 1, .y = 2, .z = 3};
877   // }
878   // template decltype(XYZ{.x = 1, .y = 2, .z = 3}) h<XYZ>();
879   //
880   // // The following two cases require full C99 designated initializers,
881   // // not part of C++ but likely available as an extension if you ask your
882   // // compiler nicely.
883   //
884   // struct A { int a[4]; };
885   // template <class T> decltype(T{.a[2] = 42}) i() { return T{.a[2] = 42}; }
886   // template decltype(A{.a[2] = 42}) i<A>();
887   //
888   // template <class T> decltype(T{.a[1 ... 3] = 42}) j() {
889   //   return T{.a[1 ... 3] = 42};
890   // }
891   // template decltype(A{.a[1 ... 3] = 42}) j<A>();
892 
893   // decltype(int{}) f<int>()
894   EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_EEv", tmp, sizeof(tmp)));
895   EXPECT_STREQ("f<>()", tmp);
896 
897   // decltype(XYZ{1, 2, 3}) g<XYZ>()
898   EXPECT_TRUE(Demangle("_Z1gI3XYZEDTtlT_Li1ELi2ELi3EEEv", tmp, sizeof(tmp)));
899   EXPECT_STREQ("g<>()", tmp);
900 
901   // decltype(XYZ{.x = 1, .y = 2, .z = 3}) h<XYZ>()
902   EXPECT_TRUE(Demangle("_Z1hI3XYZEDTtlT_di1xLi1Edi1yLi2Edi1zLi3EEEv",
903                        tmp, sizeof(tmp)));
904   EXPECT_STREQ("h<>()", tmp);
905 
906   // decltype(A{.a[2] = 42}) i<A>()
907   EXPECT_TRUE(Demangle("_Z1iI1AEDTtlT_di1adxLi2ELi42EEEv", tmp, sizeof(tmp)));
908   EXPECT_STREQ("i<>()", tmp);
909 
910   // decltype(A{.a[1 ... 3] = 42}) j<A>()
911   EXPECT_TRUE(Demangle("_Z1jI1AEDTtlT_di1adXLi1ELi3ELi42EEEv",
912                        tmp, sizeof(tmp)));
913   EXPECT_STREQ("j<>()", tmp);
914 }
915 
TEST(Demangle,SimpleInitializerLists)916 TEST(Demangle, SimpleInitializerLists) {
917   char tmp[80];
918 
919   // Common preamble of source-code examples in this test function:
920   //
921   // #include <initializer_list>
922   //
923   // template <class T> void g(std::initializer_list<T>) {}
924 
925   // Source:
926   //
927   // template <class T> auto f() -> decltype(g<T>({})) {}
928   // template auto f<int>() -> decltype(g<int>({}));
929   //
930   // Full LLVM demangling of the instantiation of f:
931   //
932   // decltype(g<int>({})) f<int>()
933   EXPECT_TRUE(Demangle("_Z1fIiEDTcl1gIT_EilEEEv", tmp, sizeof(tmp)));
934   EXPECT_STREQ("f<>()", tmp);
935 
936   // Source:
937   //
938   // template <class T> auto f(T x) -> decltype(g({x})) {}
939   // template auto f<int>(int x) -> decltype(g({x}));
940   //
941   // Full LLVM demangling of the instantiation of f:
942   //
943   // decltype(g({fp})) f<int>(int)
944   EXPECT_TRUE(Demangle("_Z1fIiEDTcl1gilfp_EEET_", tmp, sizeof(tmp)));
945   EXPECT_STREQ("f<>()", tmp);
946 
947   // Source:
948   //
949   // template <class T> auto f(T x, T y) -> decltype(g({x, y})) {}
950   // template auto f<int>(int x, int y) -> decltype(g({x, y}));
951   //
952   // Full LLVM demangling of the instantiation of f:
953   //
954   // decltype(g({fp, fp0})) f<int>(int, int)
955   EXPECT_TRUE(Demangle("_Z1fIiEDTcl1gilfp_fp0_EEET_S1_", tmp, sizeof(tmp)));
956   EXPECT_STREQ("f<>()", tmp);
957 }
958 
TEST(Demangle,BracedListImplicitlyConstructingAClassObject)959 TEST(Demangle, BracedListImplicitlyConstructingAClassObject) {
960   char tmp[80];
961 
962   // Source:
963   //
964   // struct S { int v; };
965   // void g(S) {}
966   // template <class T> auto f(T x) -> decltype(g({.v = x})) {}
967   // template auto f<int>(int x) -> decltype(g({.v = x}));
968   //
969   // Full LLVM demangling of the instantiation of f:
970   //
971   // decltype(g({.v = fp})) f<int>(int)
972   EXPECT_TRUE(Demangle("_Z1fIiEDTcl1gildi1vfp_EEET_", tmp, sizeof(tmp)));
973   EXPECT_STREQ("f<>()", tmp);
974 }
975 
TEST(Demangle,ReferenceQualifiedFunctionTypes)976 TEST(Demangle, ReferenceQualifiedFunctionTypes) {
977   char tmp[80];
978 
979   // void f(void (*)() const &, int)
980   EXPECT_TRUE(Demangle("_Z1fPKFvvREi", tmp, sizeof(tmp)));
981   EXPECT_STREQ("f()", tmp);
982 
983   // void f(void (*)() &&, int)
984   EXPECT_TRUE(Demangle("_Z1fPFvvOEi", tmp, sizeof(tmp)));
985   EXPECT_STREQ("f()", tmp);
986 
987   // void f(void (*)(int&) &, int)
988   EXPECT_TRUE(Demangle("_Z1fPFvRiREi", tmp, sizeof(tmp)));
989   EXPECT_STREQ("f()", tmp);
990 
991   // void f(void (*)(S&&) &&, int)
992   EXPECT_TRUE(Demangle("_Z1fPFvO1SOEi", tmp, sizeof(tmp)));
993   EXPECT_STREQ("f()", tmp);
994 }
995 
TEST(Demangle,DynamicCast)996 TEST(Demangle, DynamicCast) {
997   char tmp[80];
998 
999   // Source:
1000   //
1001   // template <class T> auto f(T* p) -> decltype(dynamic_cast<const T*>(p)) {
1002   //   return p;
1003   // }
1004   // struct S {};
1005   // void g(S* p) { f(p); }
1006   //
1007   // Full LLVM demangling of the instantiation of f:
1008   //
1009   // decltype(dynamic_cast<S const*>(fp)) f<S>(S*)
1010   EXPECT_TRUE(Demangle("_Z1fI1SEDTdcPKT_fp_EPS1_", tmp, sizeof(tmp)));
1011   EXPECT_STREQ("f<>()", tmp);
1012 }
1013 
TEST(Demangle,StaticCast)1014 TEST(Demangle, StaticCast) {
1015   char tmp[80];
1016 
1017   // Source:
1018   //
1019   // template <class T> auto f(T* p) -> decltype(static_cast<const T*>(p)) {
1020   //   return p;
1021   // }
1022   // void g(int* p) { f(p); }
1023   //
1024   // Full LLVM demangling of the instantiation of f:
1025   //
1026   // decltype(static_cast<int const*>(fp)) f<int>(int*)
1027   EXPECT_TRUE(Demangle("_Z1fIiEDTscPKT_fp_EPS0_", tmp, sizeof(tmp)));
1028   EXPECT_STREQ("f<>()", tmp);
1029 }
1030 
TEST(Demangle,ConstCast)1031 TEST(Demangle, ConstCast) {
1032   char tmp[80];
1033 
1034   // Source:
1035   //
1036   // template <class T> auto f(T* p) -> decltype(const_cast<const T*>(p)) {
1037   //   return p;
1038   // }
1039   // void g(int* p) { f(p); }
1040   //
1041   // Full LLVM demangling of the instantiation of f:
1042   //
1043   // decltype(const_cast<int const*>(fp)) f<int>(int*)
1044   EXPECT_TRUE(Demangle("_Z1fIiEDTccPKT_fp_EPS0_", tmp, sizeof(tmp)));
1045   EXPECT_STREQ("f<>()", tmp);
1046 }
1047 
TEST(Demangle,ReinterpretCast)1048 TEST(Demangle, ReinterpretCast) {
1049   char tmp[80];
1050 
1051   // Source:
1052   //
1053   // template <class T> auto f(T* p)
1054   //     -> decltype(reinterpret_cast<const T*>(p)) {
1055   //   return p;
1056   // }
1057   // void g(int* p) { f(p); }
1058   //
1059   // Full LLVM demangling of the instantiation of f:
1060   //
1061   // decltype(reinterpret_cast<int const*>(fp)) f<int>(int*)
1062   EXPECT_TRUE(Demangle("_Z1fIiEDTrcPKT_fp_EPS0_", tmp, sizeof(tmp)));
1063   EXPECT_STREQ("f<>()", tmp);
1064 }
1065 
TEST(Demangle,ThreadLocalWrappers)1066 TEST(Demangle, ThreadLocalWrappers) {
1067   char tmp[80];
1068 
1069   EXPECT_TRUE(Demangle("_ZTWN2ns3varE", tmp, sizeof(tmp)));
1070   EXPECT_STREQ("thread-local wrapper routine for ns::var", tmp);
1071 
1072   EXPECT_TRUE(Demangle("_ZTHN2ns3varE", tmp, sizeof(tmp)));
1073   EXPECT_STREQ("thread-local initialization routine for ns::var", tmp);
1074 }
1075 
1076 // Test one Rust symbol to exercise Demangle's delegation path.  Rust demangling
1077 // itself is more thoroughly tested in demangle_rust_test.cc.
TEST(Demangle,DelegatesToDemangleRustSymbolEncoding)1078 TEST(Demangle, DelegatesToDemangleRustSymbolEncoding) {
1079   char tmp[80];
1080 
1081   EXPECT_TRUE(Demangle("_RNvC8my_crate7my_func", tmp, sizeof(tmp)));
1082   EXPECT_STREQ("my_crate::my_func", tmp);
1083 }
1084 
1085 // Tests that verify that Demangle footprint is within some limit.
1086 // They are not to be run under sanitizers as the sanitizers increase
1087 // stack consumption by about 4x.
1088 #if defined(ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION) && \
1089     !defined(ABSL_HAVE_ADDRESS_SANITIZER) &&                   \
1090     !defined(ABSL_HAVE_MEMORY_SANITIZER) &&                    \
1091     !defined(ABSL_HAVE_THREAD_SANITIZER)
1092 
1093 static const char *g_mangled;
1094 static char g_demangle_buffer[4096];
1095 static char *g_demangle_result;
1096 
DemangleSignalHandler(int signo)1097 static void DemangleSignalHandler(int signo) {
1098   if (Demangle(g_mangled, g_demangle_buffer, sizeof(g_demangle_buffer))) {
1099     g_demangle_result = g_demangle_buffer;
1100   } else {
1101     g_demangle_result = nullptr;
1102   }
1103 }
1104 
1105 // Call Demangle and figure out the stack footprint of this call.
DemangleStackConsumption(const char * mangled,int * stack_consumed)1106 static const char *DemangleStackConsumption(const char *mangled,
1107                                             int *stack_consumed) {
1108   g_mangled = mangled;
1109   *stack_consumed = GetSignalHandlerStackConsumption(DemangleSignalHandler);
1110   LOG(INFO) << "Stack consumption of Demangle: " << *stack_consumed;
1111   return g_demangle_result;
1112 }
1113 
1114 // Demangle stack consumption should be within 8kB for simple mangled names
1115 // with some level of nesting. With alternate signal stack we have 64K,
1116 // but some signal handlers run on thread stack, and could have arbitrarily
1117 // little space left (so we don't want to make this number too large).
1118 const int kStackConsumptionUpperLimit = 8192;
1119 
1120 // Returns a mangled name nested to the given depth.
NestedMangledName(int depth)1121 static std::string NestedMangledName(int depth) {
1122   std::string mangled_name = "_Z1a";
1123   if (depth > 0) {
1124     mangled_name += "IXL";
1125     mangled_name += NestedMangledName(depth - 1);
1126     mangled_name += "EEE";
1127   }
1128   return mangled_name;
1129 }
1130 
TEST(Demangle,DemangleStackConsumption)1131 TEST(Demangle, DemangleStackConsumption) {
1132   // Measure stack consumption of Demangle for nested mangled names of varying
1133   // depth.  Since Demangle is implemented as a recursive descent parser,
1134   // stack consumption will grow as the nesting depth increases.  By measuring
1135   // the stack consumption for increasing depths, we can see the growing
1136   // impact of any stack-saving changes made to the code for Demangle.
1137   int stack_consumed = 0;
1138 
1139   const char *demangled =
1140       DemangleStackConsumption("_Z6foobarv", &stack_consumed);
1141   EXPECT_STREQ("foobar()", demangled);
1142   EXPECT_GT(stack_consumed, 0);
1143   EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
1144 
1145   const std::string nested_mangled_name0 = NestedMangledName(0);
1146   demangled = DemangleStackConsumption(nested_mangled_name0.c_str(),
1147                                        &stack_consumed);
1148   EXPECT_STREQ("a", demangled);
1149   EXPECT_GT(stack_consumed, 0);
1150   EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
1151 
1152   const std::string nested_mangled_name1 = NestedMangledName(1);
1153   demangled = DemangleStackConsumption(nested_mangled_name1.c_str(),
1154                                        &stack_consumed);
1155   EXPECT_STREQ("a<>", demangled);
1156   EXPECT_GT(stack_consumed, 0);
1157   EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
1158 
1159   const std::string nested_mangled_name2 = NestedMangledName(2);
1160   demangled = DemangleStackConsumption(nested_mangled_name2.c_str(),
1161                                        &stack_consumed);
1162   EXPECT_STREQ("a<>", demangled);
1163   EXPECT_GT(stack_consumed, 0);
1164   EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
1165 
1166   const std::string nested_mangled_name3 = NestedMangledName(3);
1167   demangled = DemangleStackConsumption(nested_mangled_name3.c_str(),
1168                                        &stack_consumed);
1169   EXPECT_STREQ("a<>", demangled);
1170   EXPECT_GT(stack_consumed, 0);
1171   EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
1172 }
1173 
1174 #endif  // Stack consumption tests
1175 
TestOnInput(const char * input)1176 static void TestOnInput(const char* input) {
1177   static const int kOutSize = 1048576;
1178   auto out = absl::make_unique<char[]>(kOutSize);
1179   Demangle(input, out.get(), kOutSize);
1180 }
1181 
TEST(DemangleRegression,NegativeLength)1182 TEST(DemangleRegression, NegativeLength) {
1183   TestOnInput("_ZZn4");
1184 }
1185 
TEST(DemangleRegression,DeeplyNestedArrayType)1186 TEST(DemangleRegression, DeeplyNestedArrayType) {
1187   const int depth = 100000;
1188   std::string data = "_ZStI";
1189   data.reserve(data.size() + 3 * depth + 1);
1190   for (int i = 0; i < depth; i++) {
1191     data += "A1_";
1192   }
1193   TestOnInput(data.c_str());
1194 }
1195 
1196 struct Base {
1197   virtual ~Base() = default;
1198 };
1199 
1200 struct Derived : public Base {};
1201 
TEST(DemangleStringTest,SupportsSymbolNameReturnedByTypeId)1202 TEST(DemangleStringTest, SupportsSymbolNameReturnedByTypeId) {
1203   EXPECT_EQ(DemangleString(typeid(int).name()), "int");
1204   // We want to test that `DemangleString` can demangle the symbol names
1205   // returned by `typeid`, but without hard-coding the actual demangled values
1206   // (because they are platform-specific).
1207   EXPECT_THAT(
1208       DemangleString(typeid(Base).name()),
1209       ContainsRegex("absl.*debugging_internal.*anonymous namespace.*::Base"));
1210   EXPECT_THAT(DemangleString(typeid(Derived).name()),
1211               ContainsRegex(
1212                   "absl.*debugging_internal.*anonymous namespace.*::Derived"));
1213 }
1214 
1215 }  // namespace
1216 }  // namespace debugging_internal
1217 ABSL_NAMESPACE_END
1218 }  // namespace absl
1219