diff --git a/src/demangle.cc b/src/demangle.cc index 2a6126b85..632ee4a73 100644 --- a/src/demangle.cc +++ b/src/demangle.cc @@ -83,7 +83,8 @@ static const AbbrevPair kBuiltinTypeList[] = { {"n", "__int128"}, {"o", "unsigned __int128"}, {"f", "float"}, {"d", "double"}, {"e", "long double"}, {"g", "__float128"}, - {"z", "ellipsis"}, {nullptr, nullptr}}; + {"z", "ellipsis"}, {"Dn", "decltype(nullptr)"}, + {nullptr, nullptr}}; // List of substitutions Itanium C++ ABI. static const AbbrevPair kSubstitutionList[] = { @@ -1067,7 +1068,7 @@ static bool ParseTemplateArgs(State* state) { // ::= X E static bool ParseTemplateArg(State* state) { // Avoid recursion above max_levels - constexpr uint32 max_levels = 5; + constexpr uint32 max_levels = 6; if (state->arg_level > max_levels) { return false; @@ -1159,6 +1160,14 @@ static bool ParseExpression(State* state) { return true; } *state = copy; + + // Pack expansion + if (ParseTwoCharToken(state, "sp") && ParseType(state)) { + --state->expr_level; + return true; + } + *state = copy; + return false; } @@ -1286,7 +1295,7 @@ static bool ParseTopLevelMangledName(State* state) { MaybeAppend(state, state->mangled_cur); return true; } - return false; // Unconsumed suffix. + return ParseName(state); } return true; } diff --git a/src/demangle_unittest.cc b/src/demangle_unittest.cc index 6df41fe24..a85166463 100644 --- a/src/demangle_unittest.cc +++ b/src/demangle_unittest.cc @@ -145,10 +145,10 @@ TEST(Demangle, FromFile) { #endif int main(int argc, char** argv) { + InitGoogleTest(&argc, argv); #ifdef GLOG_USE_GFLAGS ParseCommandLineFlags(&argc, &argv, true); #endif - InitGoogleTest(&argc, argv); FLAGS_logtostderr = true; InitGoogleLogging(argv[0]); diff --git a/src/demangle_unittest.txt b/src/demangle_unittest.txt index 07e28bce2..3735a4f08 100644 --- a/src/demangle_unittest.txt +++ b/src/demangle_unittest.txt @@ -143,3 +143,10 @@ _Zrm1XS_ operator%() # Template argument packs can start with I or J. _Z3addIIiEEvDpT_ add<>() _Z3addIJiEEvDpT_ add<>() + +# Nested templates with pack expansion +_ZSt13__invoke_implIvPFvPiEJDnEET_St14__invoke_otherOT0_DpOT1_ std::__invoke_impl<>() +_ZSt8__invokeIPFvPiEJDnEENSt15__invoke_resultIT_JDpT0_EE4typeEOS4_DpOS5_ std::__invoke<>() +_ZNSt6thread8_InvokerISt5tupleIJPFvPiEDnEEE9_M_invokeIJLm0ELm1EEEEvSt12_Index_tupleIJXspT_EEE std::thread::_Invoker<>::_M_invoke<>() +_ZNSt6thread8_InvokerISt5tupleIJPFvPiEDnEEEclEv std::thread::_Invoker<>::operator()() +_ZNSt6thread11_State_implINS_8_InvokerISt5tupleIJPFvPiEDnEEEEE6_M_runEv std::thread::_State_impl<>::_M_run()