Index: src/cxa_demangle.cpp =================================================================== --- src/cxa_demangle.cpp +++ src/cxa_demangle.cpp @@ -4343,6 +4343,8 @@ // # base is the nominal target function of thunk // ::= GV # Guard variable for one-time initialization // # No +// ::= TW # Thread-local wrapper +// ::= TH # Thread-local initialization // extension ::= TC _ # construction vtable for second-in-first // extension ::= GR # reference temporary for object @@ -4446,6 +4448,28 @@ } } break; + case 'W': + // TW # Thread-local wrapper + t = parse_name(first + 2, last, db); + if (t != first + 2) + { + if (db.names.empty()) + return first; + db.names.back().first.insert(0, "thread-local wrapper routine for "); + first = t; + } + break; + case 'H': + //TH # Thread-local initialization + t = parse_name(first + 2, last, db); + if (t != first + 2) + { + if (db.names.empty()) + return first; + db.names.back().first.insert(0, "thread-local initialization routine for "); + first = t; + } + break; default: // T { Index: test/test_demangle.pass.cpp =================================================================== --- test/test_demangle.pass.cpp +++ test/test_demangle.pass.cpp @@ -29594,6 +29594,8 @@ // NOTE: disable this test since it is a negative test case, you cannot demangle a non-mangled symbol // {"\x6D", nullptr}, // This use to crash with ASAN {"_ZTIU4_farrVKPi", "typeinfo for int* const volatile restrict _far"}, + {"_ZTW1x", "thread-local wrapper routine for x"}, + {"_ZTHN3fooE", "thread-local initialization routine for foo"}, }; const unsigned N = sizeof(cases) / sizeof(cases[0]);