diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h --- a/libcxxabi/src/demangle/ItaniumDemangle.h +++ b/libcxxabi/src/demangle/ItaniumDemangle.h @@ -2551,7 +2551,7 @@ Node *parseAbiTags(Node *N); /// Parse the production. - Node *parseUnresolvedName(); + Node *parseUnresolvedName(bool Global); Node *parseSimpleId(); Node *parseBaseUnresolvedName(); Node *parseUnresolvedType(); @@ -3353,6 +3353,7 @@ // ::= [gs] # x or (with "gs") ::x // ::= [gs] sr + E // # A::x, N::y, A::z; "gs" means leading "::" +// [gs] has been parsed by caller. // ::= sr # T::x / decltype(p)::x // extension ::= sr // # T::N::x /decltype(p)::N::x @@ -3360,7 +3361,7 @@ // // ::= template -Node *AbstractManglingParser::parseUnresolvedName() { +Node *AbstractManglingParser::parseUnresolvedName(bool Global) { Node *SoFar = nullptr; // srN [] * E @@ -3394,8 +3395,6 @@ return make(SoFar, Base); } - bool Global = consumeIf("gs"); - // [gs] # x or (with "gs") ::x if (!consumeIf("sr")) { SoFar = getDerived().parseBaseUnresolvedName(); @@ -4695,7 +4694,7 @@ return make(E, Global, /*is_array=*/false); } case 'n': - return getDerived().parseUnresolvedName(); + return getDerived().parseUnresolvedName(Global); case 's': { First += 2; Node *LHS = getDerived().parseExpr(); @@ -4840,7 +4839,7 @@ case 'o': switch (First[1]) { case 'n': - return getDerived().parseUnresolvedName(); + return getDerived().parseUnresolvedName(Global); case 'o': First += 2; return getDerived().parseBinaryExpr("||"); @@ -4951,7 +4950,7 @@ return make(Child); } case 'r': - return getDerived().parseUnresolvedName(); + return getDerived().parseUnresolvedName(Global); case 't': { First += 2; Node *Ty = getDerived().parseType(); @@ -5084,7 +5083,7 @@ case '7': case '8': case '9': - return getDerived().parseUnresolvedName(); + return getDerived().parseUnresolvedName(Global); } return nullptr; } diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp --- a/libcxxabi/test/test_demangle.pass.cpp +++ b/libcxxabi/test/test_demangle.pass.cpp @@ -29856,6 +29856,8 @@ // See https://llvm.org/PR51407 {"_Zcv1BIRT_EIS1_E", "operator B<><>"}, + {"_ZN2FnIXgs4BaseEX4BaseEEEvv","void Fn<::Base, Base>()"}, + {"_Z3TPLIiET_S0_", "int TPL(int)"}, }; diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h --- a/llvm/include/llvm/Demangle/ItaniumDemangle.h +++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -2551,7 +2551,7 @@ Node *parseAbiTags(Node *N); /// Parse the production. - Node *parseUnresolvedName(); + Node *parseUnresolvedName(bool Global); Node *parseSimpleId(); Node *parseBaseUnresolvedName(); Node *parseUnresolvedType(); @@ -3353,6 +3353,7 @@ // ::= [gs] # x or (with "gs") ::x // ::= [gs] sr + E // # A::x, N::y, A::z; "gs" means leading "::" +// [gs] has been parsed by caller. // ::= sr # T::x / decltype(p)::x // extension ::= sr // # T::N::x /decltype(p)::N::x @@ -3360,7 +3361,7 @@ // // ::= template -Node *AbstractManglingParser::parseUnresolvedName() { +Node *AbstractManglingParser::parseUnresolvedName(bool Global) { Node *SoFar = nullptr; // srN [] * E @@ -3394,8 +3395,6 @@ return make(SoFar, Base); } - bool Global = consumeIf("gs"); - // [gs] # x or (with "gs") ::x if (!consumeIf("sr")) { SoFar = getDerived().parseBaseUnresolvedName(); @@ -4695,7 +4694,7 @@ return make(E, Global, /*is_array=*/false); } case 'n': - return getDerived().parseUnresolvedName(); + return getDerived().parseUnresolvedName(Global); case 's': { First += 2; Node *LHS = getDerived().parseExpr(); @@ -4840,7 +4839,7 @@ case 'o': switch (First[1]) { case 'n': - return getDerived().parseUnresolvedName(); + return getDerived().parseUnresolvedName(Global); case 'o': First += 2; return getDerived().parseBinaryExpr("||"); @@ -4951,7 +4950,7 @@ return make(Child); } case 'r': - return getDerived().parseUnresolvedName(); + return getDerived().parseUnresolvedName(Global); case 't': { First += 2; Node *Ty = getDerived().parseType(); @@ -5084,7 +5083,7 @@ case '7': case '8': case '9': - return getDerived().parseUnresolvedName(); + return getDerived().parseUnresolvedName(Global); } return nullptr; }