demangle_test.cc (60590B)
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 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 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 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 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 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 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 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 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 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 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 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 163 TEST(Demangle, ConstrainedFriendFunctionTemplate) { 164 char tmp[100]; 165 166 // Source: 167 // 168 // namespace ns { 169 // template <class T> struct Y { 170 // friend void y(Y) requires true {} 171 // }; 172 // } // namespace ns 173 // 174 // y(ns::Y<int>{}); 175 // 176 // LLVM demangling: 177 // 178 // ns::Y<int>::friend y(ns::Y<int>) requires true 179 ASSERT_TRUE(Demangle("_ZN2ns1YIiEF1yES1_QLb1E", tmp, sizeof(tmp))); 180 EXPECT_STREQ(tmp, "ns::Y<>::friend y()"); 181 } 182 183 TEST(Demangle, ConstrainedFriendOperatorTemplate) { 184 char tmp[100]; 185 186 // ns::Y<int>::friend operator*(ns::Y<int>) requires true 187 ASSERT_TRUE(Demangle("_ZN2ns1YIiEFdeES1_QLb1E", tmp, sizeof(tmp))); 188 EXPECT_STREQ(tmp, "ns::Y<>::friend operator*()"); 189 } 190 191 TEST(Demangle, NonTemplateBuiltinType) { 192 char tmp[100]; 193 194 // void foo(__my_builtin_type t); 195 // 196 // foo({}); 197 ASSERT_TRUE(Demangle("_Z3foou17__my_builtin_type", tmp, sizeof(tmp))); 198 EXPECT_STREQ(tmp, "foo()"); 199 } 200 201 TEST(Demangle, SingleArgTemplateBuiltinType) { 202 char tmp[100]; 203 204 // template <typename T> 205 // __my_builtin_type<T> foo(); 206 // 207 // foo<int>(); 208 ASSERT_TRUE(Demangle("_Z3fooIiEu17__my_builtin_typeIT_Ev", tmp, sizeof(tmp))); 209 EXPECT_STREQ(tmp, "foo<>()"); 210 } 211 212 TEST(Demangle, TwoArgTemplateBuiltinType) { 213 char tmp[100]; 214 215 // template <typename T, typename U> 216 // __my_builtin_type<T, U> foo(); 217 // 218 // foo<int, char>(); 219 ASSERT_TRUE( 220 Demangle("_Z3fooIicEu17__my_builtin_typeIT_T0_Ev", tmp, sizeof(tmp))); 221 EXPECT_STREQ(tmp, "foo<>()"); 222 } 223 224 TEST(Demangle, TypeNestedUnderTemplatedBuiltinType) { 225 char tmp[100]; 226 227 // Source: 228 // 229 // template <typename T> 230 // typename std::remove_reference_t<T>::type f(T t); 231 // 232 // struct C { using type = C; }; 233 // 234 // f<const C&>(C{}); 235 // 236 // These days std::remove_reference_t is implemented in terms of a vendor 237 // builtin __remove_reference_t. A full demangling might look like: 238 // 239 // __remove_reference_t<C const&>::type f<C const&>(C const&) 240 ASSERT_TRUE(Demangle("_Z1fIRK1CENu20__remove_reference_tIT_E4typeES3_", 241 tmp, sizeof(tmp))); 242 EXPECT_STREQ("f<>()", tmp); 243 } 244 245 TEST(Demangle, TemplateTemplateParamSubstitution) { 246 char tmp[100]; 247 248 // template <typename T> 249 // concept True = true; 250 // 251 // template<std::integral T, T> struct Foolable {}; 252 // template<template<typename T, T> typename> void foo() {} 253 // 254 // template void foo<Foolable>(); 255 ASSERT_TRUE(Demangle("_Z3fooITtTyTnTL0__E8FoolableEvv", tmp, sizeof(tmp))); 256 EXPECT_STREQ(tmp, "foo<>()"); 257 } 258 259 TEST(Demangle, TemplateParamSubstitutionWithGenericLambda) { 260 char tmp[100]; 261 262 // template <typename> 263 // struct Fooer { 264 // template <typename> 265 // void foo(decltype([](auto x, auto y) {})) {} 266 // }; 267 // 268 // Fooer<int> f; 269 // f.foo<int>({}); 270 ASSERT_TRUE( 271 Demangle("_ZN5FooerIiE3fooIiEEvNS0_UlTL0__TL0_0_E_E", tmp, sizeof(tmp))); 272 EXPECT_STREQ(tmp, "Fooer<>::foo<>()"); 273 } 274 275 TEST(Demangle, LambdaRequiresTrue) { 276 char tmp[100]; 277 278 // auto $_0::operator()<int>(int) const requires true 279 ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QLb1E", tmp, sizeof(tmp))); 280 EXPECT_STREQ(tmp, "$_0::operator()<>()"); 281 } 282 283 TEST(Demangle, LambdaRequiresSimpleExpression) { 284 char tmp[100]; 285 286 // auto $_0::operator()<int>(int) const requires 2 + 2 == 4 287 ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QeqplLi2ELi2ELi4E", 288 tmp, sizeof(tmp))); 289 EXPECT_STREQ(tmp, "$_0::operator()<>()"); 290 } 291 292 TEST(Demangle, LambdaRequiresRequiresExpressionContainingTrue) { 293 char tmp[100]; 294 295 // auto $_0::operator()<int>(int) const requires requires { true; } 296 ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqXLb1EE", tmp, sizeof(tmp))); 297 EXPECT_STREQ(tmp, "$_0::operator()<>()"); 298 } 299 300 TEST(Demangle, LambdaRequiresRequiresExpressionContainingConcept) { 301 char tmp[100]; 302 303 // auto $_0::operator()<int>(int) const 304 // requires requires { std::same_as<decltype(fp), int>; } 305 ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqXsr3stdE7same_asIDtfp_EiEE", 306 tmp, sizeof(tmp))); 307 EXPECT_STREQ(tmp, "$_0::operator()<>()"); 308 } 309 310 TEST(Demangle, LambdaRequiresRequiresExpressionContainingNoexceptExpression) { 311 char tmp[100]; 312 313 // auto $_0::operator()<int>(int) const 314 // requires requires { {fp + fp} noexcept; } 315 ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqXplfp_fp_NE", tmp, sizeof(tmp))); 316 EXPECT_STREQ(tmp, "$_0::operator()<>()"); 317 } 318 319 TEST(Demangle, LambdaRequiresRequiresExpressionContainingReturnTypeConstraint) { 320 char tmp[100]; 321 322 // auto $_0::operator()<int>(int) const 323 // requires requires { {fp + fp} -> std::same_as<decltype(fp)>; } 324 ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqXplfp_fp_RNSt7same_asIDtfp_EEEE", 325 tmp, sizeof(tmp))); 326 EXPECT_STREQ(tmp, "$_0::operator()<>()"); 327 } 328 329 TEST(Demangle, LambdaRequiresRequiresExpressionWithBothNoexceptAndReturnType) { 330 char tmp[100]; 331 332 // auto $_0::operator()<int>(int) const 333 // requires requires { {fp + fp} noexcept -> std::same_as<decltype(fp)>; } 334 ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqXplfp_fp_NRNSt7same_asIDtfp_EEEE", 335 tmp, sizeof(tmp))); 336 EXPECT_STREQ(tmp, "$_0::operator()<>()"); 337 } 338 339 TEST(Demangle, LambdaRequiresRequiresExpressionContainingType) { 340 char tmp[100]; 341 342 // auto $_0::operator()<S>(S) const 343 // requires requires { typename S::T; } 344 ASSERT_TRUE(Demangle("_ZNK3$_0clI1SEEDaT_QrqTNS2_1TEE", tmp, sizeof(tmp))); 345 EXPECT_STREQ(tmp, "$_0::operator()<>()"); 346 } 347 348 TEST(Demangle, LambdaRequiresRequiresExpressionNestingAnotherRequires) { 349 char tmp[100]; 350 351 // auto $_0::operator()<int>(int) const requires requires { requires true; } 352 ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqQLb1EE", tmp, sizeof(tmp))); 353 EXPECT_STREQ(tmp, "$_0::operator()<>()"); 354 } 355 356 TEST(Demangle, LambdaRequiresRequiresExpressionContainingTwoRequirements) { 357 char tmp[100]; 358 359 // auto $_0::operator()<int>(int) const 360 // requires requires { requires true; requires 2 + 2 == 4; } 361 ASSERT_TRUE(Demangle("_ZNK3$_0clIiEEDaT_QrqXLb1EXeqplLi2ELi2ELi4EE", 362 tmp, sizeof(tmp))); 363 EXPECT_STREQ(tmp, "$_0::operator()<>()"); 364 } 365 366 TEST(Demangle, RequiresExpressionWithItsOwnParameter) { 367 char tmp[100]; 368 369 // S<requires (int) { fp + fp; }> f<int>(int) 370 ASSERT_TRUE(Demangle("_Z1fIiE1SIXrQT__XplfL0p_fp_EEES1_", tmp, sizeof(tmp))); 371 EXPECT_STREQ(tmp, "f<>()"); 372 } 373 374 TEST(Demangle, LambdaWithExplicitTypeArgument) { 375 char tmp[100]; 376 377 // Source: 378 // 379 // template <class T> T f(T t) { 380 // return []<class U>(U u) { return u + u; }(t); 381 // } 382 // 383 // template int f<int>(int); 384 // 385 // Full LLVM demangling of the lambda call operator: 386 // 387 // auto int f<int>(int)::'lambda'<typename $T>(int):: 388 // operator()<int>(int) const 389 ASSERT_TRUE(Demangle("_ZZ1fIiET_S0_ENKUlTyS0_E_clIiEEDaS0_", 390 tmp, sizeof(tmp))); 391 EXPECT_STREQ(tmp, "f<>()::{lambda()#1}::operator()<>()"); 392 } 393 394 TEST(Demangle, LambdaWithExplicitPackArgument) { 395 char tmp[100]; 396 397 // Source: 398 // 399 // template <class T> T h(T t) { 400 // return []<class... U>(U... u) { 401 // return ((u + u) + ... + 0); 402 // }(t); 403 // } 404 // 405 // template int h<int>(int); 406 // 407 // Full LLVM demangling of the lambda call operator: 408 // 409 // auto int f<int>(int)::'lambda'<typename ...$T>($T...):: 410 // operator()<int>($T...) const 411 ASSERT_TRUE(Demangle("_ZZ1fIiET_S0_ENKUlTpTyDpT_E_clIJiEEEDaS2_", 412 tmp, sizeof(tmp))); 413 EXPECT_STREQ(tmp, "f<>()::{lambda()#1}::operator()<>()"); 414 } 415 416 TEST(Demangle, LambdaInClassMemberDefaultArgument) { 417 char tmp[100]; 418 419 // Source: 420 // 421 // struct S { 422 // static auto f(void (*g)() = [] {}) { return g; } 423 // }; 424 // void (*p)() = S::f(); 425 // 426 // Full LLVM demangling of the lambda call operator: 427 // 428 // S::f(void (*)())::'lambda'()::operator()() const 429 // 430 // Full GNU binutils demangling: 431 // 432 // S::f(void (*)())::{default arg#1}::{lambda()#1}::operator()() const 433 ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd_NKUlvE_clEv", tmp, sizeof(tmp))); 434 EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()"); 435 436 // The same but in the second rightmost default argument. 437 ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd0_NKUlvE_clEv", tmp, sizeof(tmp))); 438 EXPECT_STREQ(tmp, "S::f()::{default arg#2}::{lambda()#1}::operator()()"); 439 440 // Reject negative <(parameter) number> values. 441 ASSERT_FALSE(Demangle("_ZZN1S1fEPFvvEEdn1_NKUlvE_clEv", tmp, sizeof(tmp))); 442 } 443 444 TEST(Demangle, AvoidSignedOverflowForUnfortunateParameterNumbers) { 445 char tmp[100]; 446 447 // Here <number> + 2 fits in an int, but just barely. (We expect no such 448 // input in practice: real functions don't have billions of arguments.) 449 ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd2147483645_NKUlvE_clEv", 450 tmp, sizeof(tmp))); 451 EXPECT_STREQ(tmp, 452 "S::f()::{default arg#2147483647}::{lambda()#1}::operator()()"); 453 454 // Now <number> is an int, but <number> + 2 is not. 455 ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd2147483646_NKUlvE_clEv", 456 tmp, sizeof(tmp))); 457 EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()"); 458 459 // <number> is the largest int. 460 ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd2147483647_NKUlvE_clEv", 461 tmp, sizeof(tmp))); 462 EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()"); 463 464 // <number> itself does not fit into an int. ParseNumber truncates the value 465 // to int, yielding a large negative number, which we strain out. 466 ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd2147483648_NKUlvE_clEv", 467 tmp, sizeof(tmp))); 468 EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()"); 469 } 470 471 TEST(Demangle, SubstpackNotationForTroublesomeTemplatePack) { 472 char tmp[100]; 473 474 // Source: 475 // 476 // template <template <class> class, template <class> class> struct B {}; 477 // 478 // template <template <class> class... T> struct A { 479 // template <template <class> class... U> void f(B<T, U>&&...) {} 480 // }; 481 // 482 // template void A<>::f<>(); 483 // 484 // LLVM can't demangle its own _SUBSTPACK_ notation. 485 ASSERT_TRUE(Demangle("_ZN1AIJEE1fIJEEEvDpO1BI_SUBSTPACK_T_E", 486 tmp, sizeof(tmp))); 487 EXPECT_STREQ(tmp, "A<>::f<>()"); 488 } 489 490 TEST(Demangle, TemplateTemplateParamAppearingAsBackrefFollowedByTemplateArgs) { 491 char tmp[100]; 492 493 // Source: 494 // 495 // template <template <class> class C> struct W { 496 // template <class T> static decltype(C<T>::m()) f() { return {}; } 497 // }; 498 // 499 // template <class T> struct S { static int m() { return 0; } }; 500 // template decltype(S<int>::m()) W<S>::f<int>(); 501 ASSERT_TRUE(Demangle("_ZN1WI1SE1fIiEEDTclsrS0_IT_EE1mEEv", tmp, sizeof(tmp))); 502 EXPECT_STREQ(tmp, "W<>::f<>()"); 503 } 504 505 // Test corner cases of boundary conditions. 506 TEST(Demangle, CornerCases) { 507 char tmp[10]; 508 EXPECT_TRUE(Demangle("_Z6foobarv", tmp, sizeof(tmp))); 509 // sizeof("foobar()") == 9 510 EXPECT_STREQ("foobar()", tmp); 511 EXPECT_TRUE(Demangle("_Z6foobarv", tmp, 9)); 512 EXPECT_STREQ("foobar()", tmp); 513 EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 8)); // Not enough. 514 EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 1)); 515 EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 0)); 516 EXPECT_FALSE(Demangle("_Z6foobarv", nullptr, 0)); // Should not cause SEGV. 517 EXPECT_FALSE(Demangle("_Z1000000", tmp, 9)); 518 } 519 520 // Test handling of functions suffixed with .clone.N, which is used 521 // by GCC 4.5.x (and our locally-modified version of GCC 4.4.x), and 522 // .constprop.N and .isra.N, which are used by GCC 4.6.x. These 523 // suffixes are used to indicate functions which have been cloned 524 // during optimization. We ignore these suffixes. 525 TEST(Demangle, Clones) { 526 char tmp[20]; 527 EXPECT_TRUE(Demangle("_ZL3Foov", tmp, sizeof(tmp))); 528 EXPECT_STREQ("Foo()", tmp); 529 EXPECT_TRUE(Demangle("_ZL3Foov.clone.3", tmp, sizeof(tmp))); 530 EXPECT_STREQ("Foo()", tmp); 531 EXPECT_TRUE(Demangle("_ZL3Foov.constprop.80", tmp, sizeof(tmp))); 532 EXPECT_STREQ("Foo()", tmp); 533 EXPECT_TRUE(Demangle("_ZL3Foov.isra.18", tmp, sizeof(tmp))); 534 EXPECT_STREQ("Foo()", tmp); 535 EXPECT_TRUE(Demangle("_ZL3Foov.isra.2.constprop.18", tmp, sizeof(tmp))); 536 EXPECT_STREQ("Foo()", tmp); 537 // Demangle suffixes produced by -funique-internal-linkage-names. 538 EXPECT_TRUE(Demangle("_ZL3Foov.__uniq.12345", tmp, sizeof(tmp))); 539 EXPECT_STREQ("Foo()", tmp); 540 EXPECT_TRUE(Demangle("_ZL3Foov.__uniq.12345.isra.2.constprop.18", tmp, 541 sizeof(tmp))); 542 EXPECT_STREQ("Foo()", tmp); 543 // Suffixes without the number should also demangle. 544 EXPECT_TRUE(Demangle("_ZL3Foov.clo", tmp, sizeof(tmp))); 545 EXPECT_STREQ("Foo()", tmp); 546 // Suffixes with just the number should also demangle. 547 EXPECT_TRUE(Demangle("_ZL3Foov.123", tmp, sizeof(tmp))); 548 EXPECT_STREQ("Foo()", tmp); 549 // (.clone. followed by non-number), should also demangle. 550 EXPECT_TRUE(Demangle("_ZL3Foov.clone.foo", tmp, sizeof(tmp))); 551 EXPECT_STREQ("Foo()", tmp); 552 // (.clone. followed by multiple numbers), should also demangle. 553 EXPECT_TRUE(Demangle("_ZL3Foov.clone.123.456", tmp, sizeof(tmp))); 554 EXPECT_STREQ("Foo()", tmp); 555 // (a long valid suffix), should demangle. 556 EXPECT_TRUE(Demangle("_ZL3Foov.part.9.165493.constprop.775.31805", tmp, 557 sizeof(tmp))); 558 EXPECT_STREQ("Foo()", tmp); 559 // Invalid (. without anything else), should not demangle. 560 EXPECT_FALSE(Demangle("_ZL3Foov.", tmp, sizeof(tmp))); 561 // Invalid (. with mix of alpha and digits), should not demangle. 562 EXPECT_FALSE(Demangle("_ZL3Foov.abc123", tmp, sizeof(tmp))); 563 // Invalid (.clone. not followed by number), should not demangle. 564 EXPECT_FALSE(Demangle("_ZL3Foov.clone.", tmp, sizeof(tmp))); 565 // Invalid (.constprop. not followed by number), should not demangle. 566 EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp))); 567 } 568 569 TEST(Demangle, Discriminators) { 570 char tmp[80]; 571 572 // Source: 573 // 574 // using Thunk = void (*)(); 575 // 576 // Thunk* f() { 577 // static Thunk thunks[12] = {}; 578 // 579 // #define THUNK(i) [backslash here] 580 // do { struct S { static void g() {} }; thunks[i] = &S::g; } while (0) 581 // 582 // THUNK(0); 583 // [... repeat for 1 to 10 ...] 584 // THUNK(11); 585 // 586 // return thunks; 587 // } 588 // 589 // The test inputs are manglings of some of the S::g member functions. 590 591 // The first one omits the discriminator. 592 EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gEv", tmp, sizeof(tmp))); 593 EXPECT_STREQ("f()::S::g()", tmp); 594 595 // The second one encodes 0. 596 EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE_0v", tmp, sizeof(tmp))); 597 EXPECT_STREQ("f()::S::g()", tmp); 598 599 // The eleventh one encodes 9. 600 EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE_9v", tmp, sizeof(tmp))); 601 EXPECT_STREQ("f()::S::g()", tmp); 602 603 // The twelfth one encodes 10 with extra underscores delimiting it. 604 EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE__10_v", tmp, sizeof(tmp))); 605 EXPECT_STREQ("f()::S::g()", tmp); 606 } 607 608 TEST(Demangle, SingleDigitDiscriminatorFollowedByADigit) { 609 char tmp[80]; 610 611 // Don't parse 911 as a number. 612 EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE_911return_type", tmp, sizeof(tmp))); 613 EXPECT_STREQ("f()::S::g()", tmp); 614 } 615 616 TEST(Demangle, LiteralOfGlobalNamespaceEnumType) { 617 char tmp[80]; 618 619 // void f<(E)42>() 620 EXPECT_TRUE(Demangle("_Z1fIL1E42EEvv", tmp, sizeof(tmp))); 621 EXPECT_STREQ("f<>()", tmp); 622 } 623 624 TEST(Demangle, NullptrLiterals) { 625 char tmp[80]; 626 627 // void f<nullptr>() 628 EXPECT_TRUE(Demangle("_Z1fILDnEEvv", tmp, sizeof(tmp))); 629 EXPECT_STREQ("f<>()", tmp); 630 631 // also void f<nullptr>() 632 EXPECT_TRUE(Demangle("_Z1fILDn0EEvv", tmp, sizeof(tmp))); 633 EXPECT_STREQ("f<>()", tmp); 634 } 635 636 TEST(Demangle, StringLiterals) { 637 char tmp[80]; 638 639 // void f<"<char const [42]>">() 640 EXPECT_TRUE(Demangle("_Z1fILA42_KcEEvv", tmp, sizeof(tmp))); 641 EXPECT_STREQ("f<>()", tmp); 642 } 643 644 TEST(Demangle, ComplexFloatingPointLiterals) { 645 char tmp[80]; 646 647 // Source (use g++ -fext-numeric-literals to compile): 648 // 649 // using C = double _Complex; 650 // template <class T> void f(char (&)[sizeof(C{sizeof(T)} + 4.0j)]) {} 651 // template void f<int>(char (&)[sizeof(C{sizeof(int)} + 4.0j)]); 652 // 653 // GNU demangling: 654 // 655 // void f<int>(char (&) [sizeof (double _Complex{sizeof (int)}+ 656 // ((double _Complex)0000000000000000_4010000000000000))]) 657 EXPECT_TRUE(Demangle( 658 "_Z1fIiEvRAszpltlCdstT_ELS0_0000000000000000_4010000000000000E_c", 659 tmp, sizeof(tmp))); 660 EXPECT_STREQ("f<>()", tmp); 661 } 662 663 TEST(Demangle, Float128) { 664 char tmp[80]; 665 666 // S::operator _Float128() const 667 EXPECT_TRUE(Demangle("_ZNK1ScvDF128_Ev", tmp, sizeof(tmp))); 668 EXPECT_STREQ("S::operator _Float128()", tmp); 669 } 670 671 TEST(Demangle, Float128x) { 672 char tmp[80]; 673 674 // S::operator _Float128x() const 675 EXPECT_TRUE(Demangle("_ZNK1ScvDF128xEv", tmp, sizeof(tmp))); 676 EXPECT_STREQ("S::operator _Float128x()", tmp); 677 } 678 679 TEST(Demangle, Bfloat16) { 680 char tmp[80]; 681 682 // S::operator std::bfloat16_t() const 683 EXPECT_TRUE(Demangle("_ZNK1ScvDF16bEv", tmp, sizeof(tmp))); 684 EXPECT_STREQ("S::operator std::bfloat16_t()", tmp); 685 } 686 687 TEST(Demangle, SimpleSignedBitInt) { 688 char tmp[80]; 689 690 // S::operator _BitInt(256)() const 691 EXPECT_TRUE(Demangle("_ZNK1ScvDB256_Ev", tmp, sizeof(tmp))); 692 EXPECT_STREQ("S::operator _BitInt(256)()", tmp); 693 } 694 695 TEST(Demangle, SimpleUnsignedBitInt) { 696 char tmp[80]; 697 698 // S::operator unsigned _BitInt(256)() const 699 EXPECT_TRUE(Demangle("_ZNK1ScvDU256_Ev", tmp, sizeof(tmp))); 700 EXPECT_STREQ("S::operator unsigned _BitInt(256)()", tmp); 701 } 702 703 TEST(Demangle, DependentBitInt) { 704 char tmp[80]; 705 706 // S::operator _BitInt(256)<256>() const 707 EXPECT_TRUE(Demangle("_ZNK1ScvDBT__ILi256EEEv", tmp, sizeof(tmp))); 708 EXPECT_STREQ("S::operator _BitInt(?)<>()", tmp); 709 } 710 711 TEST(Demangle, ConversionToPointerType) { 712 char tmp[80]; 713 714 // S::operator int*() const 715 EXPECT_TRUE(Demangle("_ZNK1ScvPiEv", tmp, sizeof(tmp))); 716 EXPECT_STREQ("S::operator int*()", tmp); 717 } 718 719 TEST(Demangle, ConversionToLvalueReferenceType) { 720 char tmp[80]; 721 722 // S::operator int&() const 723 EXPECT_TRUE(Demangle("_ZNK1ScvRiEv", tmp, sizeof(tmp))); 724 EXPECT_STREQ("S::operator int&()", tmp); 725 } 726 727 TEST(Demangle, ConversionToRvalueReferenceType) { 728 char tmp[80]; 729 730 // S::operator int&&() const 731 EXPECT_TRUE(Demangle("_ZNK1ScvOiEv", tmp, sizeof(tmp))); 732 EXPECT_STREQ("S::operator int&&()", tmp); 733 } 734 735 TEST(Demangle, ConversionToComplexFloatingPointType) { 736 char tmp[80]; 737 738 // S::operator float _Complex() const 739 EXPECT_TRUE(Demangle("_ZNK1ScvCfEv", tmp, sizeof(tmp))); 740 EXPECT_STREQ("S::operator float _Complex()", tmp); 741 } 742 743 TEST(Demangle, ConversionToImaginaryFloatingPointType) { 744 char tmp[80]; 745 746 // S::operator float _Imaginary() const 747 EXPECT_TRUE(Demangle("_ZNK1ScvGfEv", tmp, sizeof(tmp))); 748 EXPECT_STREQ("S::operator float _Imaginary()", tmp); 749 } 750 751 TEST(Demangle, ConversionToPointerToCvQualifiedType) { 752 char tmp[80]; 753 754 // S::operator int const volatile restrict*() const 755 EXPECT_TRUE(Demangle("_ZNK1ScvPrVKiEv", tmp, sizeof(tmp))); 756 EXPECT_STREQ("S::operator int const volatile restrict*()", tmp); 757 } 758 759 TEST(Demangle, ConversionToLayeredPointerType) { 760 char tmp[80]; 761 762 // S::operator int const* const*() const 763 EXPECT_TRUE(Demangle("_ZNK1ScvPKPKiEv", tmp, sizeof(tmp))); 764 EXPECT_STREQ("S::operator int const* const*()", tmp); 765 } 766 767 TEST(Demangle, ConversionToTypeWithExtendedQualifier) { 768 char tmp[80]; 769 770 // S::operator int const AS128*() const 771 // 772 // Because our scan of easy type constructors stops at the extended qualifier, 773 // the demangling preserves the * but loses the const. 774 EXPECT_TRUE(Demangle("_ZNK1ScvPU5AS128KiEv", tmp, sizeof(tmp))); 775 EXPECT_STREQ("S::operator int*()", tmp); 776 } 777 778 TEST(Demangle, GlobalInitializers) { 779 char tmp[80]; 780 781 // old form without suffix 782 EXPECT_TRUE(Demangle("_ZGR1v", tmp, sizeof(tmp))); 783 EXPECT_STREQ("reference temporary for v", tmp); 784 785 // modern form for the whole initializer 786 EXPECT_TRUE(Demangle("_ZGR1v_", tmp, sizeof(tmp))); 787 EXPECT_STREQ("reference temporary for v", tmp); 788 789 // next subobject in depth-first preorder traversal 790 EXPECT_TRUE(Demangle("_ZGR1v0_", tmp, sizeof(tmp))); 791 EXPECT_STREQ("reference temporary for v", tmp); 792 793 // subobject with a larger seq-id 794 EXPECT_TRUE(Demangle("_ZGR1v1Z_", tmp, sizeof(tmp))); 795 EXPECT_STREQ("reference temporary for v", tmp); 796 } 797 798 TEST(Demangle, StructuredBindings) { 799 char tmp[80]; 800 801 // Source: 802 // 803 // struct S { int a, b; }; 804 // const auto& [x, y] = S{1, 2}; 805 806 // [x, y] 807 EXPECT_TRUE(Demangle("_ZDC1x1yE", tmp, sizeof(tmp))); 808 809 // reference temporary for [x, y] 810 EXPECT_TRUE(Demangle("_ZGRDC1x1yE_", tmp, sizeof(tmp))); 811 } 812 813 // Test the GNU abi_tag extension. 814 TEST(Demangle, AbiTags) { 815 char tmp[80]; 816 817 // Mangled name generated via: 818 // struct [[gnu::abi_tag("abc")]] A{}; 819 // A a; 820 EXPECT_TRUE(Demangle("_Z1aB3abc", tmp, sizeof(tmp))); 821 EXPECT_STREQ("a[abi:abc]", tmp); 822 823 // Mangled name generated via: 824 // struct B { 825 // B [[gnu::abi_tag("xyz")]] (){}; 826 // }; 827 // B b; 828 EXPECT_TRUE(Demangle("_ZN1BC2B3xyzEv", tmp, sizeof(tmp))); 829 EXPECT_STREQ("B::B[abi:xyz]()", tmp); 830 831 // Mangled name generated via: 832 // [[gnu::abi_tag("foo", "bar")]] void C() {} 833 EXPECT_TRUE(Demangle("_Z1CB3barB3foov", tmp, sizeof(tmp))); 834 EXPECT_STREQ("C[abi:bar][abi:foo]()", tmp); 835 } 836 837 TEST(Demangle, SimpleGnuVectorSize) { 838 char tmp[80]; 839 840 // Source: 841 // 842 // #define VECTOR(size) __attribute__((vector_size(size))) 843 // void f(int x VECTOR(32)) {} 844 // 845 // The attribute's size is a number of bytes. The compiler verifies that this 846 // value corresponds to a whole number of elements and emits the number of 847 // elements as a <number> in the mangling. With sizeof(int) == 4, that yields 848 // 32/4 = 8. 849 // 850 // LLVM demangling: 851 // 852 // f(int vector[8]) 853 EXPECT_TRUE(Demangle("_Z1fDv8_i", tmp, sizeof(tmp))); 854 EXPECT_STREQ("f()", tmp); 855 } 856 857 TEST(Demangle, GnuVectorSizeIsATemplateParameter) { 858 char tmp[80]; 859 860 // Source: 861 // 862 // #define VECTOR(size) __attribute__((vector_size(size))) 863 // template <int n> void f(int x VECTOR(n)) {} 864 // template void f<32>(int x VECTOR(32)); 865 // 866 // LLVM demangling: 867 // 868 // void f<32>(int vector[32]) 869 // 870 // Because the size was dependent on a template parameter, it was encoded 871 // using the general expression encoding. Nothing in the mangling says how 872 // big the element type is, so the demangler is unable to show the element 873 // count 8 instead of the byte count 32. Arguably it would have been better 874 // to make the narrow production encode the byte count, so that nondependent 875 // and dependent versions of a 32-byte vector would both come out as 876 // vector[32]. 877 EXPECT_TRUE(Demangle("_Z1fILi32EEvDvT__i", tmp, sizeof(tmp))); 878 EXPECT_STREQ("f<>()", tmp); 879 } 880 881 TEST(Demangle, GnuVectorSizeIsADependentOperatorExpression) { 882 char tmp[80]; 883 884 // Source: 885 // 886 // #define VECTOR(size) __attribute__((vector_size(size))) 887 // template <int n> void f(int x VECTOR(2 * n)) {} 888 // template void f<32>(int x VECTOR(2 * 32)); 889 // 890 // LLVM demangling: 891 // 892 // void f<32>(int vector[2 * 32]) 893 EXPECT_TRUE(Demangle("_Z1fILi32EEvDvmlLi2ET__i", tmp, sizeof(tmp))); 894 EXPECT_STREQ("f<>()", tmp); 895 } 896 897 TEST(Demangle, SimpleAddressSpace) { 898 char tmp[80]; 899 900 // Source: 901 // 902 // void f(const int __attribute__((address_space(128)))*) {} 903 // 904 // LLVM demangling: 905 // 906 // f(int const AS128*) 907 // 908 // Itanium ABI 5.1.5.1, "Qualified types", notes that address_space is mangled 909 // nonuniformly as a legacy exception: the number is part of the source-name 910 // if nondependent but is an expression in template-args if dependent. Thus 911 // it is a convenient test case for both forms. 912 EXPECT_TRUE(Demangle("_Z1fPU5AS128Ki", tmp, sizeof(tmp))); 913 EXPECT_STREQ("f()", tmp); 914 } 915 916 TEST(Demangle, DependentAddressSpace) { 917 char tmp[80]; 918 919 // Source: 920 // 921 // template <int n> void f (const int __attribute__((address_space(n)))*) {} 922 // template void f<128>(const int __attribute__((address_space(128)))*); 923 // 924 // LLVM demangling: 925 // 926 // void f<128>(int AS<128>*) 927 EXPECT_TRUE(Demangle("_Z1fILi128EEvPU2ASIT_Ei", tmp, sizeof(tmp))); 928 EXPECT_STREQ("f<>()", tmp); 929 } 930 931 TEST(Demangle, TransactionSafeEntryPoint) { 932 char tmp[80]; 933 934 EXPECT_TRUE(Demangle("_ZGTt1fv", tmp, sizeof(tmp))); 935 EXPECT_STREQ("transaction clone for f()", tmp); 936 } 937 938 TEST(Demangle, TransactionSafeFunctionType) { 939 char tmp[80]; 940 941 // GNU demangling: f(void (*)() transaction_safe) 942 EXPECT_TRUE(Demangle("_Z1fPDxFvvE", tmp, sizeof(tmp))); 943 EXPECT_STREQ("f()", tmp); 944 } 945 946 TEST(Demangle, TemplateParameterObject) { 947 char tmp[80]; 948 949 // Source: 950 // 951 // struct S { int x, y; }; 952 // template <S s, const S* p = &s> void f() {} 953 // template void f<S{1, 2}>(); 954 // 955 // LLVM demangling: 956 // 957 // void f<S{1, 2}, &template parameter object for S{1, 2}>() 958 EXPECT_TRUE(Demangle("_Z1fIXtl1SLi1ELi2EEEXadL_ZTAXtlS0_Li1ELi2EEEEEEvv", 959 tmp, sizeof(tmp))); 960 EXPECT_STREQ("f<>()", tmp); 961 962 // The name of the object standing alone. 963 // 964 // LLVM demangling: template parameter object for S{1, 2} 965 EXPECT_TRUE(Demangle("_ZTAXtl1SLi1ELi2EEE", tmp, sizeof(tmp))); 966 EXPECT_STREQ("template parameter object", tmp); 967 } 968 969 TEST(Demangle, EnableIfAttributeOnGlobalFunction) { 970 char tmp[80]; 971 972 // int f(long l) __attribute__((enable_if(l >= 0, ""))) { return l; } 973 // 974 // f(long) [enable_if:fp >= 0] 975 EXPECT_TRUE(Demangle("_Z1fUa9enable_ifIXgefL0p_Li0EEEl", tmp, sizeof(tmp))); 976 EXPECT_STREQ("f()", tmp); 977 } 978 979 TEST(Demangle, EnableIfAttributeOnNamespaceScopeFunction) { 980 char tmp[80]; 981 982 // namespace ns { 983 // int f(long l) __attribute__((enable_if(l >= 0, ""))) { return l; } 984 // } // namespace ns 985 // 986 // ns::f(long) [enable_if:fp >= 0] 987 EXPECT_TRUE(Demangle("_ZN2ns1fEUa9enable_ifIXgefL0p_Li0EEEl", 988 tmp, sizeof(tmp))); 989 EXPECT_STREQ("ns::f()", tmp); 990 } 991 992 TEST(Demangle, EnableIfAttributeOnFunctionTemplate) { 993 char tmp[80]; 994 995 // template <class T> 996 // T f(T t) __attribute__((enable_if(t >= T{}, ""))) { return t; } 997 // template int f<int>(int); 998 // 999 // int f<int>(int) [enable_if:fp >= int{}] 1000 EXPECT_TRUE(Demangle("_Z1fIiEUa9enable_ifIXgefL0p_tliEEET_S0_", 1001 tmp, sizeof(tmp))); 1002 EXPECT_STREQ("f<>()", tmp); 1003 } 1004 1005 TEST(Demangle, ThisPointerInDependentSignature) { 1006 char tmp[80]; 1007 1008 // decltype(g<int>(this)) S::f<int>() 1009 EXPECT_TRUE(Demangle("_ZN1S1fIiEEDTcl1gIT_EfpTEEv", tmp, sizeof(tmp))); 1010 EXPECT_STREQ("S::f<>()", tmp); 1011 } 1012 1013 TEST(Demangle, DependentMemberOperatorCall) { 1014 char tmp[80]; 1015 1016 // decltype(fp.operator()()) f<C>(C) 1017 EXPECT_TRUE(Demangle("_Z1fI1CEDTcldtfp_onclEET_", tmp, sizeof(tmp))); 1018 EXPECT_STREQ("f<>()", tmp); 1019 } 1020 1021 TEST(Demangle, TypeNestedUnderDecltype) { 1022 char tmp[80]; 1023 1024 // Source: 1025 // 1026 // template <class T> struct S { using t = int; }; 1027 // template <class T> decltype(S<T>{})::t f() { return {}; } 1028 // void g() { f<int>(); } 1029 // 1030 // Full LLVM demangling of the instantiation of f: 1031 // 1032 // decltype(S<int>{})::t f<int>() 1033 EXPECT_TRUE(Demangle("_Z1fIiENDTtl1SIT_EEE1tEv", tmp, sizeof(tmp))); 1034 EXPECT_STREQ("f<>()", tmp); 1035 } 1036 1037 TEST(Demangle, ElaboratedTypes) { 1038 char tmp[80]; 1039 1040 // Source: 1041 // 1042 // template <class T> struct S { class C {}; }; 1043 // template <class T> void f(class S<T>::C) {} 1044 // template void f<int>(class S<int>::C); 1045 // 1046 // LLVM demangling: 1047 // 1048 // void f<int>(struct S<int>::C) 1049 EXPECT_TRUE(Demangle("_Z1fIiEvTsN1SIT_E1CE", tmp, sizeof(tmp))); 1050 EXPECT_STREQ("f<>()", tmp); 1051 1052 // The like for unions. 1053 EXPECT_TRUE(Demangle("_Z1fIiEvTuN1SIT_E1CE", tmp, sizeof(tmp))); 1054 EXPECT_STREQ("f<>()", tmp); 1055 1056 // The like for enums. 1057 EXPECT_TRUE(Demangle("_Z1fIiEvTeN1SIT_E1CE", tmp, sizeof(tmp))); 1058 EXPECT_STREQ("f<>()", tmp); 1059 } 1060 1061 // Test subobject-address template parameters. 1062 TEST(Demangle, SubobjectAddresses) { 1063 char tmp[80]; 1064 1065 // void f<a.<char const at offset 123>>() 1066 EXPECT_TRUE(Demangle("_Z1fIXsoKcL_Z1aE123EEEvv", tmp, sizeof(tmp))); 1067 EXPECT_STREQ("f<>()", tmp); 1068 1069 // void f<&a.<char const at offset 0>>() 1070 EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aEEEEvv", tmp, sizeof(tmp))); 1071 EXPECT_STREQ("f<>()", tmp); 1072 1073 // void f<&a.<char const at offset 123>>() 1074 EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aE123EEEvv", tmp, sizeof(tmp))); 1075 EXPECT_STREQ("f<>()", tmp); 1076 1077 // void f<&a.<char const at offset 123>>(), past the end this time 1078 EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aE123pEEEvv", tmp, sizeof(tmp))); 1079 EXPECT_STREQ("f<>()", tmp); 1080 1081 // void f<&a.<char const at offset 0>>() with union-selectors 1082 EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aE__1_234EEEvv", tmp, sizeof(tmp))); 1083 EXPECT_STREQ("f<>()", tmp); 1084 1085 // void f<&a.<char const at offset 123>>(), past the end, with union-selector 1086 EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aE123_456pEEEvv", tmp, sizeof(tmp))); 1087 EXPECT_STREQ("f<>()", tmp); 1088 } 1089 1090 TEST(Demangle, Preincrement) { 1091 char tmp[80]; 1092 1093 // Source: 1094 // 1095 // template <class T> auto f(T t) -> decltype(T{++t}) { return t; } 1096 // template auto f<int>(int t) -> decltype(int{++t}); 1097 // 1098 // Full LLVM demangling of the instantiation of f: 1099 // 1100 // decltype(int{++fp}) f<int>(int) 1101 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_pp_fp_EES0_", tmp, sizeof(tmp))); 1102 EXPECT_STREQ("f<>()", tmp); 1103 } 1104 1105 TEST(Demangle, Postincrement) { 1106 char tmp[80]; 1107 1108 // Source: 1109 // 1110 // template <class T> auto f(T t) -> decltype(T{t++}) { return t; } 1111 // template auto f<int>(int t) -> decltype(int{t++}); 1112 // 1113 // Full LLVM demangling of the instantiation of f: 1114 // 1115 // decltype(int{fp++}) f<int>(int) 1116 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_ppfp_EES0_", tmp, sizeof(tmp))); 1117 EXPECT_STREQ("f<>()", tmp); 1118 } 1119 1120 TEST(Demangle, Predecrement) { 1121 char tmp[80]; 1122 1123 // Source: 1124 // 1125 // template <class T> auto f(T t) -> decltype(T{--t}) { return t; } 1126 // template auto f<int>(int t) -> decltype(int{--t}); 1127 // 1128 // Full LLVM demangling of the instantiation of f: 1129 // 1130 // decltype(int{--fp}) f<int>(int) 1131 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_mm_fp_EES0_", tmp, sizeof(tmp))); 1132 EXPECT_STREQ("f<>()", tmp); 1133 } 1134 1135 TEST(Demangle, Postdecrement) { 1136 char tmp[80]; 1137 1138 // Source: 1139 // 1140 // template <class T> auto f(T t) -> decltype(T{t--}) { return t; } 1141 // template auto f<int>(int t) -> decltype(int{t--}); 1142 // 1143 // Full LLVM demangling of the instantiation of f: 1144 // 1145 // decltype(int{fp--}) f<int>(int) 1146 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_mmfp_EES0_", tmp, sizeof(tmp))); 1147 EXPECT_STREQ("f<>()", tmp); 1148 } 1149 1150 TEST(Demangle, UnaryFoldExpressions) { 1151 char tmp[80]; 1152 1153 // Source: 1154 // 1155 // template <bool b> struct S {}; 1156 // 1157 // template <class... T> auto f(T... t) -> S<((sizeof(T) == 4) || ...)> { 1158 // return {}; 1159 // } 1160 // 1161 // void g() { f(1, 2L); } 1162 // 1163 // Full LLVM demangling of the instantiation of f: 1164 // 1165 // S<((sizeof (int) == 4, sizeof (long) == 4) || ...)> f<int, long>(int, long) 1166 EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXfrooeqstT_Li4EEEDpS1_", 1167 tmp, sizeof(tmp))); 1168 EXPECT_STREQ("f<>()", tmp); 1169 1170 // The like with a left fold. 1171 // 1172 // S<(... || (sizeof (int) == 4, sizeof (long) == 4))> f<int, long>(int, long) 1173 EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXflooeqstT_Li4EEEDpS1_", 1174 tmp, sizeof(tmp))); 1175 EXPECT_STREQ("f<>()", tmp); 1176 } 1177 1178 TEST(Demangle, BinaryFoldExpressions) { 1179 char tmp[80]; 1180 1181 // Source: 1182 // 1183 // template <bool b> struct S {}; 1184 // 1185 // template <class... T> auto f(T... t) 1186 // -> S<((sizeof(T) == 4) || ... || false)> { 1187 // return {}; 1188 // } 1189 // 1190 // void g() { f(1, 2L); } 1191 // 1192 // Full LLVM demangling of the instantiation of f: 1193 // 1194 // S<((sizeof (int) == 4, sizeof (long) == 4) || ... || false)> 1195 // f<int, long>(int, long) 1196 EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXfRooeqstT_Li4ELb0EEEDpS1_", 1197 tmp, sizeof(tmp))); 1198 EXPECT_STREQ("f<>()", tmp); 1199 1200 // The like with a left fold. 1201 // 1202 // S<(false || ... || (sizeof (int) == 4, sizeof (long) == 4))> 1203 // f<int, long>(int, long) 1204 EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXfLooLb0EeqstT_Li4EEEDpS1_", 1205 tmp, sizeof(tmp))); 1206 EXPECT_STREQ("f<>()", tmp); 1207 } 1208 1209 TEST(Demangle, SizeofPacks) { 1210 char tmp[80]; 1211 1212 // template <size_t i> struct S {}; 1213 // 1214 // template <class... T> auto f(T... p) -> S<sizeof...(T)> { return {}; } 1215 // template auto f<int, long>(int, long) -> S<2>; 1216 // 1217 // template <class... T> auto g(T... p) -> S<sizeof...(p)> { return {}; } 1218 // template auto g<int, long>(int, long) -> S<2>; 1219 1220 // S<sizeof...(int, long)> f<int, long>(int, long) 1221 EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXsZT_EEDpT_", tmp, sizeof(tmp))); 1222 EXPECT_STREQ("f<>()", tmp); 1223 1224 // S<sizeof... (fp)> g<int, long>(int, long) 1225 EXPECT_TRUE(Demangle("_Z1gIJilEE1SIXsZfp_EEDpT_", tmp, sizeof(tmp))); 1226 EXPECT_STREQ("g<>()", tmp); 1227 } 1228 1229 TEST(Demangle, SizeofPackInvolvingAnAliasTemplate) { 1230 char tmp[80]; 1231 1232 // Source: 1233 // 1234 // template <class... T> using A = char[sizeof...(T)]; 1235 // template <class... U> void f(const A<U..., int>&) {} 1236 // template void f<int>(const A<int, int>&); 1237 // 1238 // Full LLVM demangling of the instantiation of f: 1239 // 1240 // void f<int>(char const (&) [sizeof... (int, int)]) 1241 EXPECT_TRUE(Demangle("_Z1fIJiEEvRAsPDpT_iE_Kc", tmp, sizeof(tmp))); 1242 EXPECT_STREQ("f<>()", tmp); 1243 } 1244 1245 TEST(Demangle, UserDefinedLiteral) { 1246 char tmp[80]; 1247 1248 // Source: 1249 // 1250 // unsigned long long operator""_lit(unsigned long long x) { return x; } 1251 // 1252 // LLVM demangling: 1253 // 1254 // operator"" _lit(unsigned long long) 1255 EXPECT_TRUE(Demangle("_Zli4_lity", tmp, sizeof(tmp))); 1256 EXPECT_STREQ("operator\"\" _lit()", tmp); 1257 } 1258 1259 TEST(Demangle, Spaceship) { 1260 char tmp[80]; 1261 1262 // #include <compare> 1263 // 1264 // struct S { auto operator<=>(const S&) const = default; }; 1265 // auto (S::*f) = &S::operator<=>; // make sure S::operator<=> is emitted 1266 // 1267 // template <class T> auto g(T x, T y) -> decltype(x <=> y) { 1268 // return x <=> y; 1269 // } 1270 // template auto g<S>(S x, S y) -> decltype(x <=> y); 1271 1272 // S::operator<=>(S const&) const 1273 EXPECT_TRUE(Demangle("_ZNK1SssERKS_", tmp, sizeof(tmp))); 1274 EXPECT_STREQ("S::operator<=>()", tmp); 1275 1276 // decltype(fp <=> fp0) g<S>(S, S) 1277 EXPECT_TRUE(Demangle("_Z1gI1SEDTssfp_fp0_ET_S2_", tmp, sizeof(tmp))); 1278 EXPECT_STREQ("g<>()", tmp); 1279 } 1280 1281 TEST(Demangle, CoAwait) { 1282 char tmp[80]; 1283 1284 // ns::Awaitable::operator co_await() const 1285 EXPECT_TRUE(Demangle("_ZNK2ns9AwaitableawEv", tmp, sizeof(tmp))); 1286 EXPECT_STREQ("ns::Awaitable::operator co_await()", tmp); 1287 } 1288 1289 TEST(Demangle, VendorExtendedExpressions) { 1290 char tmp[80]; 1291 1292 // void f<__e()>() 1293 EXPECT_TRUE(Demangle("_Z1fIXu3__eEEEvv", tmp, sizeof(tmp))); 1294 EXPECT_STREQ("f<>()", tmp); 1295 1296 // void f<__e(int, long)>() 1297 EXPECT_TRUE(Demangle("_Z1fIXu3__eilEEEvv", tmp, sizeof(tmp))); 1298 EXPECT_STREQ("f<>()", tmp); 1299 } 1300 1301 TEST(Demangle, DirectListInitialization) { 1302 char tmp[80]; 1303 1304 // template <class T> decltype(T{}) f() { return T{}; } 1305 // template decltype(int{}) f<int>(); 1306 // 1307 // struct XYZ { int x, y, z; }; 1308 // template <class T> decltype(T{1, 2, 3}) g() { return T{1, 2, 3}; } 1309 // template decltype(XYZ{1, 2, 3}) g<XYZ>(); 1310 // 1311 // template <class T> decltype(T{.x = 1, .y = 2, .z = 3}) h() { 1312 // return T{.x = 1, .y = 2, .z = 3}; 1313 // } 1314 // template decltype(XYZ{.x = 1, .y = 2, .z = 3}) h<XYZ>(); 1315 // 1316 // // The following two cases require full C99 designated initializers, 1317 // // not part of C++ but likely available as an extension if you ask your 1318 // // compiler nicely. 1319 // 1320 // struct A { int a[4]; }; 1321 // template <class T> decltype(T{.a[2] = 42}) i() { return T{.a[2] = 42}; } 1322 // template decltype(A{.a[2] = 42}) i<A>(); 1323 // 1324 // template <class T> decltype(T{.a[1 ... 3] = 42}) j() { 1325 // return T{.a[1 ... 3] = 42}; 1326 // } 1327 // template decltype(A{.a[1 ... 3] = 42}) j<A>(); 1328 1329 // decltype(int{}) f<int>() 1330 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_EEv", tmp, sizeof(tmp))); 1331 EXPECT_STREQ("f<>()", tmp); 1332 1333 // decltype(XYZ{1, 2, 3}) g<XYZ>() 1334 EXPECT_TRUE(Demangle("_Z1gI3XYZEDTtlT_Li1ELi2ELi3EEEv", tmp, sizeof(tmp))); 1335 EXPECT_STREQ("g<>()", tmp); 1336 1337 // decltype(XYZ{.x = 1, .y = 2, .z = 3}) h<XYZ>() 1338 EXPECT_TRUE(Demangle("_Z1hI3XYZEDTtlT_di1xLi1Edi1yLi2Edi1zLi3EEEv", 1339 tmp, sizeof(tmp))); 1340 EXPECT_STREQ("h<>()", tmp); 1341 1342 // decltype(A{.a[2] = 42}) i<A>() 1343 EXPECT_TRUE(Demangle("_Z1iI1AEDTtlT_di1adxLi2ELi42EEEv", tmp, sizeof(tmp))); 1344 EXPECT_STREQ("i<>()", tmp); 1345 1346 // decltype(A{.a[1 ... 3] = 42}) j<A>() 1347 EXPECT_TRUE(Demangle("_Z1jI1AEDTtlT_di1adXLi1ELi3ELi42EEEv", 1348 tmp, sizeof(tmp))); 1349 EXPECT_STREQ("j<>()", tmp); 1350 } 1351 1352 TEST(Demangle, SimpleInitializerLists) { 1353 char tmp[80]; 1354 1355 // Common preamble of source-code examples in this test function: 1356 // 1357 // #include <initializer_list> 1358 // 1359 // template <class T> void g(std::initializer_list<T>) {} 1360 1361 // Source: 1362 // 1363 // template <class T> auto f() -> decltype(g<T>({})) {} 1364 // template auto f<int>() -> decltype(g<int>({})); 1365 // 1366 // Full LLVM demangling of the instantiation of f: 1367 // 1368 // decltype(g<int>({})) f<int>() 1369 EXPECT_TRUE(Demangle("_Z1fIiEDTcl1gIT_EilEEEv", tmp, sizeof(tmp))); 1370 EXPECT_STREQ("f<>()", tmp); 1371 1372 // Source: 1373 // 1374 // template <class T> auto f(T x) -> decltype(g({x})) {} 1375 // template auto f<int>(int x) -> decltype(g({x})); 1376 // 1377 // Full LLVM demangling of the instantiation of f: 1378 // 1379 // decltype(g({fp})) f<int>(int) 1380 EXPECT_TRUE(Demangle("_Z1fIiEDTcl1gilfp_EEET_", tmp, sizeof(tmp))); 1381 EXPECT_STREQ("f<>()", tmp); 1382 1383 // Source: 1384 // 1385 // template <class T> auto f(T x, T y) -> decltype(g({x, y})) {} 1386 // template auto f<int>(int x, int y) -> decltype(g({x, y})); 1387 // 1388 // Full LLVM demangling of the instantiation of f: 1389 // 1390 // decltype(g({fp, fp0})) f<int>(int, int) 1391 EXPECT_TRUE(Demangle("_Z1fIiEDTcl1gilfp_fp0_EEET_S1_", tmp, sizeof(tmp))); 1392 EXPECT_STREQ("f<>()", tmp); 1393 } 1394 1395 TEST(Demangle, BracedListImplicitlyConstructingAClassObject) { 1396 char tmp[80]; 1397 1398 // Source: 1399 // 1400 // struct S { int v; }; 1401 // void g(S) {} 1402 // template <class T> auto f(T x) -> decltype(g({.v = x})) {} 1403 // template auto f<int>(int x) -> decltype(g({.v = x})); 1404 // 1405 // Full LLVM demangling of the instantiation of f: 1406 // 1407 // decltype(g({.v = fp})) f<int>(int) 1408 EXPECT_TRUE(Demangle("_Z1fIiEDTcl1gildi1vfp_EEET_", tmp, sizeof(tmp))); 1409 EXPECT_STREQ("f<>()", tmp); 1410 } 1411 1412 TEST(Demangle, SimpleNewExpression) { 1413 char tmp[80]; 1414 1415 // Source: 1416 // 1417 // template <class T> decltype(T{*new T}) f() { return T{}; } 1418 // template decltype(int{*new int}) f<int>(); 1419 // 1420 // Full LLVM demangling of the instantiation of f: 1421 // 1422 // decltype(int{*(new int)}) f<int>() 1423 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_denw_S0_EEEv", tmp, sizeof(tmp))); 1424 EXPECT_STREQ("f<>()", tmp); 1425 } 1426 1427 TEST(Demangle, NewExpressionWithEmptyParentheses) { 1428 char tmp[80]; 1429 1430 // Source: 1431 // 1432 // template <class T> decltype(T{*new T()}) f() { return T{}; } 1433 // template decltype(int{*new int()}) f<int>(); 1434 // 1435 // Full LLVM demangling of the instantiation of f: 1436 // 1437 // decltype(int{*(new int)}) f<int>() 1438 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_denw_S0_piEEEv", tmp, sizeof(tmp))); 1439 EXPECT_STREQ("f<>()", tmp); 1440 } 1441 1442 TEST(Demangle, NewExpressionWithNonemptyParentheses) { 1443 char tmp[80]; 1444 1445 // Source: 1446 // 1447 // template <class T> decltype(T{*new T(42)}) f() { return T{}; } 1448 // template decltype(int{*new int(42)}) f<int>(); 1449 // 1450 // Full LLVM demangling of the instantiation of f: 1451 // 1452 // decltype(int{*(new int(42))}) f<int>() 1453 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_denw_S0_piLi42EEEEv", tmp, sizeof(tmp))); 1454 EXPECT_STREQ("f<>()", tmp); 1455 } 1456 1457 TEST(Demangle, PlacementNewExpression) { 1458 char tmp[80]; 1459 1460 // Source: 1461 // 1462 // #include <new> 1463 // 1464 // template <class T> auto f(T t) -> decltype(T{*new (&t) T(42)}) { 1465 // return t; 1466 // } 1467 // template auto f<int>(int t) -> decltype(int{*new (&t) int(42)}); 1468 // 1469 // Full LLVM demangling of the instantiation of f: 1470 // 1471 // decltype(int{*(new(&fp) int(42))}) f<int>(int) 1472 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_denwadfp__S0_piLi42EEEES0_", 1473 tmp, sizeof(tmp))); 1474 EXPECT_STREQ("f<>()", tmp); 1475 } 1476 1477 TEST(Demangle, GlobalScopeNewExpression) { 1478 char tmp[80]; 1479 1480 // Source: 1481 // 1482 // template <class T> decltype(T{*::new T}) f() { return T{}; } 1483 // template decltype(int{*::new int}) f<int>(); 1484 // 1485 // Full LLVM demangling of the instantiation of f: 1486 // 1487 // decltype(int{*(::new int)}) f<int>() 1488 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_degsnw_S0_EEEv", tmp, sizeof(tmp))); 1489 EXPECT_STREQ("f<>()", tmp); 1490 } 1491 1492 TEST(Demangle, NewExpressionWithEmptyBraces) { 1493 char tmp[80]; 1494 1495 // Source: 1496 // 1497 // template <class T> decltype(T{*new T{}}) f() { return T{}; } 1498 // template decltype(int{*new int{}}) f<int>(); 1499 // 1500 // GNU demangling: 1501 // 1502 // decltype (int{*(new int{})}) f<int>() 1503 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_denw_S0_ilEEEv", tmp, sizeof(tmp))); 1504 EXPECT_STREQ("f<>()", tmp); 1505 } 1506 1507 TEST(Demangle, NewExpressionWithNonemptyBraces) { 1508 char tmp[80]; 1509 1510 // Source: 1511 // 1512 // template <class T> decltype(T{*new T{42}}) f() { return T{}; } 1513 // template decltype(int{*new int{42}}) f<int>(); 1514 // 1515 // GNU demangling: 1516 // 1517 // decltype (int{*(new int{42})}) f<int>() 1518 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_denw_S0_ilLi42EEEEv", tmp, sizeof(tmp))); 1519 EXPECT_STREQ("f<>()", tmp); 1520 } 1521 1522 TEST(Demangle, SimpleArrayNewExpression) { 1523 char tmp[80]; 1524 1525 // Source: 1526 // 1527 // template <class T> decltype(T{*new T[1]}) f() { return T{}; } 1528 // template decltype(int{*new int[1]}) f<int>(); 1529 // 1530 // Full LLVM demangling of the instantiation of f: 1531 // 1532 // decltype(int{*(new[] int)}) f<int>() 1533 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_dena_S0_EEEv", tmp, sizeof(tmp))); 1534 EXPECT_STREQ("f<>()", tmp); 1535 } 1536 1537 TEST(Demangle, ArrayNewExpressionWithEmptyParentheses) { 1538 char tmp[80]; 1539 1540 // Source: 1541 // 1542 // template <class T> decltype(T{*new T[1]()}) f() { return T{}; } 1543 // template decltype(int{*new int[1]()}) f<int>(); 1544 // 1545 // Full LLVM demangling of the instantiation of f: 1546 // 1547 // decltype(int{*(new[] int)}) f<int>() 1548 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_dena_S0_piEEEv", tmp, sizeof(tmp))); 1549 EXPECT_STREQ("f<>()", tmp); 1550 } 1551 1552 TEST(Demangle, ArrayPlacementNewExpression) { 1553 char tmp[80]; 1554 1555 // Source: 1556 // 1557 // #include <new> 1558 // 1559 // template <class T> auto f(T t) -> decltype(T{*new (&t) T[1]}) { 1560 // return T{}; 1561 // } 1562 // template auto f<int>(int t) -> decltype(int{*new (&t) int[1]}); 1563 // 1564 // Full LLVM demangling of the instantiation of f: 1565 // 1566 // decltype(int{*(new[](&fp) int)}) f<int>(int) 1567 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_denaadfp__S0_EEES0_", tmp, sizeof(tmp))); 1568 EXPECT_STREQ("f<>()", tmp); 1569 } 1570 1571 TEST(Demangle, GlobalScopeArrayNewExpression) { 1572 char tmp[80]; 1573 1574 // Source: 1575 // 1576 // template <class T> decltype(T{*::new T[1]}) f() { return T{}; } 1577 // template decltype(int{*::new int[1]}) f<int>(); 1578 // 1579 // Full LLVM demangling of the instantiation of f: 1580 // 1581 // decltype(int{*(::new[] int)}) f<int>() 1582 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_degsna_S0_EEEv", tmp, sizeof(tmp))); 1583 EXPECT_STREQ("f<>()", tmp); 1584 } 1585 1586 TEST(Demangle, ArrayNewExpressionWithTwoElementsInBraces) { 1587 char tmp[80]; 1588 1589 // Source: 1590 // 1591 // template <class T> decltype(T{*new T[2]{1, 2}}) f() { return T{}; } 1592 // template decltype(int{*new int[2]{1, 2}}) f<int>(); 1593 // 1594 // GNU demangling: 1595 // 1596 // decltype (int{*(new int{1, 2})}) f<int>() 1597 EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_dena_S0_ilLi1ELi2EEEEv", 1598 tmp, sizeof(tmp))); 1599 EXPECT_STREQ("f<>()", tmp); 1600 } 1601 1602 TEST(Demangle, SimpleDeleteExpression) { 1603 char tmp[80]; 1604 1605 // Source: 1606 // 1607 // template <class T> auto f(T* p) -> decltype(delete p) {} 1608 // template auto f<int>(int* p) -> decltype(delete p); 1609 // 1610 // LLVM demangling: 1611 // 1612 // decltype(delete fp) f<int>(int*) 1613 EXPECT_TRUE(Demangle("_Z1fIiEDTdlfp_EPT_", tmp, sizeof(tmp))); 1614 EXPECT_STREQ("f<>()", tmp); 1615 } 1616 1617 TEST(Demangle, GlobalScopeDeleteExpression) { 1618 char tmp[80]; 1619 1620 // Source: 1621 // 1622 // template <class T> auto f(T* p) -> decltype(::delete p) {} 1623 // template auto f<int>(int* p) -> decltype(::delete p); 1624 // 1625 // LLVM demangling: 1626 // 1627 // decltype(::delete fp) f<int>(int*) 1628 EXPECT_TRUE(Demangle("_Z1fIiEDTgsdlfp_EPT_", tmp, sizeof(tmp))); 1629 EXPECT_STREQ("f<>()", tmp); 1630 } 1631 1632 TEST(Demangle, SimpleArrayDeleteExpression) { 1633 char tmp[80]; 1634 1635 // Source: 1636 // 1637 // template <class T> auto f(T* a) -> decltype(delete[] a) {} 1638 // template auto f<int>(int* a) -> decltype(delete[] a); 1639 // 1640 // LLVM demangling: 1641 // 1642 // decltype(delete[] fp) f<int>(int*) 1643 EXPECT_TRUE(Demangle("_Z1fIiEDTdafp_EPT_", tmp, sizeof(tmp))); 1644 EXPECT_STREQ("f<>()", tmp); 1645 } 1646 1647 TEST(Demangle, GlobalScopeArrayDeleteExpression) { 1648 char tmp[80]; 1649 1650 // Source: 1651 // 1652 // template <class T> auto f(T* a) -> decltype(::delete[] a) {} 1653 // template auto f<int>(int* a) -> decltype(::delete[] a); 1654 // 1655 // LLVM demangling: 1656 // 1657 // decltype(::delete[] fp) f<int>(int*) 1658 EXPECT_TRUE(Demangle("_Z1fIiEDTgsdafp_EPT_", tmp, sizeof(tmp))); 1659 EXPECT_STREQ("f<>()", tmp); 1660 } 1661 1662 TEST(Demangle, ReferenceQualifiedFunctionTypes) { 1663 char tmp[80]; 1664 1665 // void f(void (*)() const &, int) 1666 EXPECT_TRUE(Demangle("_Z1fPKFvvREi", tmp, sizeof(tmp))); 1667 EXPECT_STREQ("f()", tmp); 1668 1669 // void f(void (*)() &&, int) 1670 EXPECT_TRUE(Demangle("_Z1fPFvvOEi", tmp, sizeof(tmp))); 1671 EXPECT_STREQ("f()", tmp); 1672 1673 // void f(void (*)(int&) &, int) 1674 EXPECT_TRUE(Demangle("_Z1fPFvRiREi", tmp, sizeof(tmp))); 1675 EXPECT_STREQ("f()", tmp); 1676 1677 // void f(void (*)(S&&) &&, int) 1678 EXPECT_TRUE(Demangle("_Z1fPFvO1SOEi", tmp, sizeof(tmp))); 1679 EXPECT_STREQ("f()", tmp); 1680 } 1681 1682 TEST(Demangle, DynamicCast) { 1683 char tmp[80]; 1684 1685 // Source: 1686 // 1687 // template <class T> auto f(T* p) -> decltype(dynamic_cast<const T*>(p)) { 1688 // return p; 1689 // } 1690 // struct S {}; 1691 // void g(S* p) { f(p); } 1692 // 1693 // Full LLVM demangling of the instantiation of f: 1694 // 1695 // decltype(dynamic_cast<S const*>(fp)) f<S>(S*) 1696 EXPECT_TRUE(Demangle("_Z1fI1SEDTdcPKT_fp_EPS1_", tmp, sizeof(tmp))); 1697 EXPECT_STREQ("f<>()", tmp); 1698 } 1699 1700 TEST(Demangle, StaticCast) { 1701 char tmp[80]; 1702 1703 // Source: 1704 // 1705 // template <class T> auto f(T* p) -> decltype(static_cast<const T*>(p)) { 1706 // return p; 1707 // } 1708 // void g(int* p) { f(p); } 1709 // 1710 // Full LLVM demangling of the instantiation of f: 1711 // 1712 // decltype(static_cast<int const*>(fp)) f<int>(int*) 1713 EXPECT_TRUE(Demangle("_Z1fIiEDTscPKT_fp_EPS0_", tmp, sizeof(tmp))); 1714 EXPECT_STREQ("f<>()", tmp); 1715 } 1716 1717 TEST(Demangle, ConstCast) { 1718 char tmp[80]; 1719 1720 // Source: 1721 // 1722 // template <class T> auto f(T* p) -> decltype(const_cast<const T*>(p)) { 1723 // return p; 1724 // } 1725 // void g(int* p) { f(p); } 1726 // 1727 // Full LLVM demangling of the instantiation of f: 1728 // 1729 // decltype(const_cast<int const*>(fp)) f<int>(int*) 1730 EXPECT_TRUE(Demangle("_Z1fIiEDTccPKT_fp_EPS0_", tmp, sizeof(tmp))); 1731 EXPECT_STREQ("f<>()", tmp); 1732 } 1733 1734 TEST(Demangle, ReinterpretCast) { 1735 char tmp[80]; 1736 1737 // Source: 1738 // 1739 // template <class T> auto f(T* p) 1740 // -> decltype(reinterpret_cast<const T*>(p)) { 1741 // return p; 1742 // } 1743 // void g(int* p) { f(p); } 1744 // 1745 // Full LLVM demangling of the instantiation of f: 1746 // 1747 // decltype(reinterpret_cast<int const*>(fp)) f<int>(int*) 1748 EXPECT_TRUE(Demangle("_Z1fIiEDTrcPKT_fp_EPS0_", tmp, sizeof(tmp))); 1749 EXPECT_STREQ("f<>()", tmp); 1750 } 1751 1752 TEST(Demangle, TypeidType) { 1753 char tmp[80]; 1754 1755 // Source: 1756 // 1757 // #include <typeinfo> 1758 // 1759 // template <class T> decltype(typeid(T).name()) f(T) { return nullptr; } 1760 // template decltype(typeid(int).name()) f<int>(int); 1761 // 1762 // Full LLVM demangling of the instantiation of f: 1763 // 1764 // decltype(typeid (int).name()) f<int>(int) 1765 EXPECT_TRUE(Demangle("_Z1fIiEDTcldttiT_4nameEES0_", tmp, sizeof(tmp))); 1766 EXPECT_STREQ("f<>()", tmp); 1767 } 1768 1769 TEST(Demangle, TypeidExpression) { 1770 char tmp[80]; 1771 1772 // Source: 1773 // 1774 // #include <typeinfo> 1775 // 1776 // template <class T> decltype(typeid(T{}).name()) f(T) { return nullptr; } 1777 // template decltype(typeid(int{}).name()) f<int>(int); 1778 // 1779 // Full LLVM demangling of the instantiation of f: 1780 // 1781 // decltype(typeid (int{}).name()) f<int>(int) 1782 EXPECT_TRUE(Demangle("_Z1fIiEDTcldttetlT_E4nameEES0_", tmp, sizeof(tmp))); 1783 EXPECT_STREQ("f<>()", tmp); 1784 } 1785 1786 TEST(Demangle, AlignofType) { 1787 char tmp[80]; 1788 1789 // Source: 1790 // 1791 // template <class T> T f(T (&a)[alignof(T)]) { return a[0]; } 1792 // template int f<int>(int (&)[alignof(int)]); 1793 // 1794 // Full LLVM demangling of the instantiation of f: 1795 // 1796 // int f<int>(int (&) [alignof (int)]) 1797 EXPECT_TRUE(Demangle("_Z1fIiET_RAatS0__S0_", tmp, sizeof(tmp))); 1798 EXPECT_STREQ("f<>()", tmp); 1799 } 1800 1801 TEST(Demangle, AlignofExpression) { 1802 char tmp[80]; 1803 1804 // Source (note that this uses a GNU extension; it is not standard C++): 1805 // 1806 // template <class T> T f(T (&a)[alignof(T{})]) { return a[0]; } 1807 // template int f<int>(int (&)[alignof(int{})]); 1808 // 1809 // Full LLVM demangling of the instantiation of f: 1810 // 1811 // int f<int>(int (&) [alignof (int{})]) 1812 EXPECT_TRUE(Demangle("_Z1fIiET_RAaztlS0_E_S0_", tmp, sizeof(tmp))); 1813 EXPECT_STREQ("f<>()", tmp); 1814 } 1815 1816 TEST(Demangle, NoexceptExpression) { 1817 char tmp[80]; 1818 1819 // Source: 1820 // 1821 // template <class T> void f(T (&a)[noexcept(T{})]) {} 1822 // template void f<int>(int (&)[noexcept(int{})]); 1823 // 1824 // Full LLVM demangling of the instantiation of f: 1825 // 1826 // void f<int>(int (&) [noexcept (int{})]) 1827 EXPECT_TRUE(Demangle("_Z1fIiEvRAnxtlT_E_S0_", tmp, sizeof(tmp))); 1828 EXPECT_STREQ("f<>()", tmp); 1829 } 1830 1831 TEST(Demangle, UnaryThrow) { 1832 char tmp[80]; 1833 1834 // Source: 1835 // 1836 // template <bool b> decltype(b ? throw b : 0) f() { return 0; } 1837 // template decltype(false ? throw false : 0) f<false>(); 1838 // 1839 // Full LLVM demangling of the instantiation of f: 1840 // 1841 // decltype(false ? throw false : 0) f<false>() 1842 EXPECT_TRUE(Demangle("_Z1fILb0EEDTquT_twT_Li0EEv", tmp, sizeof(tmp))); 1843 EXPECT_STREQ("f<>()", tmp); 1844 } 1845 1846 TEST(Demangle, NullaryThrow) { 1847 char tmp[80]; 1848 1849 // Source: 1850 // 1851 // template <bool b> decltype(b ? throw : 0) f() { return 0; } 1852 // template decltype(false ? throw : 0) f<false>(); 1853 // 1854 // Full LLVM demangling of the instantiation of f: 1855 // 1856 // decltype(false ? throw : 0) f<false>() 1857 EXPECT_TRUE(Demangle("_Z1fILb0EEDTquT_trLi0EEv", tmp, sizeof(tmp))); 1858 EXPECT_STREQ("f<>()", tmp); 1859 } 1860 1861 TEST(Demangle, ThreadLocalWrappers) { 1862 char tmp[80]; 1863 1864 EXPECT_TRUE(Demangle("_ZTWN2ns3varE", tmp, sizeof(tmp))); 1865 EXPECT_STREQ("thread-local wrapper routine for ns::var", tmp); 1866 1867 EXPECT_TRUE(Demangle("_ZTHN2ns3varE", tmp, sizeof(tmp))); 1868 EXPECT_STREQ("thread-local initialization routine for ns::var", tmp); 1869 } 1870 1871 TEST(Demangle, DubiousSrStSymbols) { 1872 char tmp[80]; 1873 1874 // GNU demangling (not accepted by LLVM): 1875 // 1876 // S<std::u<char>::v> f<char>() 1877 EXPECT_TRUE(Demangle("_Z1fIcE1SIXsrSt1uIT_E1vEEv", tmp, sizeof(tmp))); 1878 EXPECT_STREQ("f<>()", tmp); 1879 1880 // A real case from the wild. 1881 // 1882 // GNU demangling (not accepted by LLVM) with line breaks and indentation 1883 // added for readability: 1884 // 1885 // __gnu_cxx::__enable_if<std::__is_char<char>::__value, bool>::__type 1886 // std::operator==<char>( 1887 // std::__cxx11::basic_string<char, std::char_traits<char>, 1888 // std::allocator<char> > const&, 1889 // std::__cxx11::basic_string<char, std::char_traits<char>, 1890 // std::allocator<char> > const&) 1891 EXPECT_TRUE(Demangle( 1892 "_ZSteqIcEN9__gnu_cxx11__enable_if" 1893 "IXsrSt9__is_charIT_E7__valueEbE" 1894 "6__typeE" 1895 "RKNSt7__cxx1112basic_stringIS3_St11char_traitsIS3_ESaIS3_EEESE_", 1896 tmp, sizeof(tmp))); 1897 EXPECT_STREQ("std::operator==<>()", tmp); 1898 } 1899 1900 // Test one Rust symbol to exercise Demangle's delegation path. Rust demangling 1901 // itself is more thoroughly tested in demangle_rust_test.cc. 1902 TEST(Demangle, DelegatesToDemangleRustSymbolEncoding) { 1903 char tmp[80]; 1904 1905 EXPECT_TRUE(Demangle("_RNvC8my_crate7my_func", tmp, sizeof(tmp))); 1906 EXPECT_STREQ("my_crate::my_func", tmp); 1907 } 1908 1909 // Tests that verify that Demangle footprint is within some limit. 1910 // They are not to be run under sanitizers as the sanitizers increase 1911 // stack consumption by about 4x. 1912 #if defined(ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION) && \ 1913 !defined(ABSL_HAVE_ADDRESS_SANITIZER) && \ 1914 !defined(ABSL_HAVE_MEMORY_SANITIZER) && \ 1915 !defined(ABSL_HAVE_THREAD_SANITIZER) 1916 1917 static const char *g_mangled; 1918 static char g_demangle_buffer[4096]; 1919 static char *g_demangle_result; 1920 1921 static void DemangleSignalHandler(int signo) { 1922 if (Demangle(g_mangled, g_demangle_buffer, sizeof(g_demangle_buffer))) { 1923 g_demangle_result = g_demangle_buffer; 1924 } else { 1925 g_demangle_result = nullptr; 1926 } 1927 } 1928 1929 // Call Demangle and figure out the stack footprint of this call. 1930 static const char *DemangleStackConsumption(const char *mangled, 1931 int *stack_consumed) { 1932 g_mangled = mangled; 1933 *stack_consumed = GetSignalHandlerStackConsumption(DemangleSignalHandler); 1934 LOG(INFO) << "Stack consumption of Demangle: " << *stack_consumed; 1935 return g_demangle_result; 1936 } 1937 1938 // Demangle stack consumption should be within 8kB for simple mangled names 1939 // with some level of nesting. With alternate signal stack we have 64K, 1940 // but some signal handlers run on thread stack, and could have arbitrarily 1941 // little space left (so we don't want to make this number too large). 1942 const int kStackConsumptionUpperLimit = 8192; 1943 1944 // Returns a mangled name nested to the given depth. 1945 static std::string NestedMangledName(int depth) { 1946 std::string mangled_name = "_Z1a"; 1947 if (depth > 0) { 1948 mangled_name += "IXL"; 1949 mangled_name += NestedMangledName(depth - 1); 1950 mangled_name += "EEE"; 1951 } 1952 return mangled_name; 1953 } 1954 1955 TEST(Demangle, DemangleStackConsumption) { 1956 // Measure stack consumption of Demangle for nested mangled names of varying 1957 // depth. Since Demangle is implemented as a recursive descent parser, 1958 // stack consumption will grow as the nesting depth increases. By measuring 1959 // the stack consumption for increasing depths, we can see the growing 1960 // impact of any stack-saving changes made to the code for Demangle. 1961 int stack_consumed = 0; 1962 1963 const char *demangled = 1964 DemangleStackConsumption("_Z6foobarv", &stack_consumed); 1965 EXPECT_STREQ("foobar()", demangled); 1966 EXPECT_GT(stack_consumed, 0); 1967 EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); 1968 1969 const std::string nested_mangled_name0 = NestedMangledName(0); 1970 demangled = DemangleStackConsumption(nested_mangled_name0.c_str(), 1971 &stack_consumed); 1972 EXPECT_STREQ("a", demangled); 1973 EXPECT_GT(stack_consumed, 0); 1974 EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); 1975 1976 const std::string nested_mangled_name1 = NestedMangledName(1); 1977 demangled = DemangleStackConsumption(nested_mangled_name1.c_str(), 1978 &stack_consumed); 1979 EXPECT_STREQ("a<>", demangled); 1980 EXPECT_GT(stack_consumed, 0); 1981 EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); 1982 1983 const std::string nested_mangled_name2 = NestedMangledName(2); 1984 demangled = DemangleStackConsumption(nested_mangled_name2.c_str(), 1985 &stack_consumed); 1986 EXPECT_STREQ("a<>", demangled); 1987 EXPECT_GT(stack_consumed, 0); 1988 EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); 1989 1990 const std::string nested_mangled_name3 = NestedMangledName(3); 1991 demangled = DemangleStackConsumption(nested_mangled_name3.c_str(), 1992 &stack_consumed); 1993 EXPECT_STREQ("a<>", demangled); 1994 EXPECT_GT(stack_consumed, 0); 1995 EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); 1996 } 1997 1998 #endif // Stack consumption tests 1999 2000 static void TestOnInput(const char* input) { 2001 static const int kOutSize = 1048576; 2002 auto out = absl::make_unique<char[]>(kOutSize); 2003 Demangle(input, out.get(), kOutSize); 2004 } 2005 2006 TEST(DemangleRegression, NegativeLength) { 2007 TestOnInput("_ZZn4"); 2008 } 2009 2010 TEST(DemangleRegression, DeeplyNestedArrayType) { 2011 const int depth = 100000; 2012 std::string data = "_ZStI"; 2013 data.reserve(data.size() + 3 * depth + 1); 2014 for (int i = 0; i < depth; i++) { 2015 data += "A1_"; 2016 } 2017 TestOnInput(data.c_str()); 2018 } 2019 2020 TEST(DemangleRegression, ShortOutputBuffer) { 2021 // This should not crash. 2022 char buffer[1]; 2023 EXPECT_FALSE( 2024 absl::debugging_internal::Demangle("_ZZ2wwE", buffer, sizeof(buffer))); 2025 } 2026 2027 struct Base { 2028 virtual ~Base() = default; 2029 }; 2030 2031 struct Derived : public Base {}; 2032 2033 TEST(DemangleStringTest, SupportsSymbolNameReturnedByTypeId) { 2034 EXPECT_EQ(DemangleString(typeid(int).name()), "int"); 2035 // We want to test that `DemangleString` can demangle the symbol names 2036 // returned by `typeid`, but without hard-coding the actual demangled values 2037 // (because they are platform-specific). 2038 EXPECT_THAT( 2039 DemangleString(typeid(Base).name()), 2040 ContainsRegex("absl.*debugging_internal.*anonymous namespace.*::Base")); 2041 EXPECT_THAT(DemangleString(typeid(Derived).name()), 2042 ContainsRegex( 2043 "absl.*debugging_internal.*anonymous namespace.*::Derived")); 2044 } 2045 2046 } // namespace 2047 } // namespace debugging_internal 2048 ABSL_NAMESPACE_END 2049 } // namespace absl