Index: libcxxabi/src/demangle/ItaniumDemangle.h =================================================================== --- libcxxabi/src/demangle/ItaniumDemangle.h +++ libcxxabi/src/demangle/ItaniumDemangle.h @@ -2570,8 +2570,6 @@ // ::= template Node *AbstractManglingParser::parseName(NameState *State) { - consumeIf('L'); // extension - if (look() == 'N') return getDerived().parseNestedName(State); if (look() == 'Z') @@ -2647,15 +2645,14 @@ return make(Encoding, Entity); } -// ::= -// ::= St # ::std:: -// extension ::= StL +// ::= [L]* +// ::= St [L]* # ::std:: +// [*] extension template Node * AbstractManglingParser::parseUnscopedName(NameState *State) { bool IsStd = consumeIf("St"); - if (IsStd) - consumeIf('L'); + consumeIf('L'); Node *Result = getDerived().parseUnqualifiedName(State); if (Result == nullptr) @@ -3146,14 +3143,14 @@ // ::= N [] [] E // ::= N [] [] E // -// ::= +// ::= [L]* // ::= // ::= // ::= // ::= # empty // ::= // ::= -// extension ::= L +// [*] extension // // := [] M // @@ -3173,88 +3170,78 @@ if (State) State->ReferenceQualifier = FrefQualRValue; } else if (consumeIf('R')) { if (State) State->ReferenceQualifier = FrefQualLValue; - } else + } else { if (State) State->ReferenceQualifier = FrefQualNone; - - Node *SoFar = nullptr; - auto PushComponent = [&](Node *Comp) { - if (!Comp) return false; - if (SoFar) SoFar = make(SoFar, Comp); - else SoFar = Comp; - if (State) State->EndsWithTemplateArgs = false; - return SoFar != nullptr; - }; - - if (consumeIf("St")) { - SoFar = make("std"); - if (!SoFar) - return nullptr; } + Node *SoFar = nullptr; while (!consumeIf('E')) { consumeIf('L'); // extension - // := [] M if (consumeIf('M')) { + // := [] M if (SoFar == nullptr) return nullptr; continue; } - // ::= + if (State) + State->EndsWithTemplateArgs = false; + if (look() == 'T') { - if (!PushComponent(getDerived().parseTemplateParam())) + // ::= + if (SoFar != nullptr) return nullptr; - Subs.push_back(SoFar); - continue; - } - - // ::= - if (look() == 'I') { + SoFar = getDerived().parseTemplateParam(); + } else if (look() == 'I') { + // ::= Node *TA = getDerived().parseTemplateArgs(State != nullptr); if (TA == nullptr || SoFar == nullptr) return nullptr; - SoFar = make(SoFar, TA); - if (!SoFar) - return nullptr; - if (State) State->EndsWithTemplateArgs = true; - Subs.push_back(SoFar); - continue; - } - - // ::= - if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) { - if (!PushComponent(getDerived().parseDecltype())) + if (SoFar->getKind() == Node::KNameWithTemplateArgs) return nullptr; - Subs.push_back(SoFar); - continue; - } - - // ::= - if (look() == 'S' && look(1) != 't') { - Node *S = getDerived().parseSubstitution(); - if (!PushComponent(S)) - return nullptr; - if (SoFar != S) - Subs.push_back(S); - continue; - } - - // Parse an thats actually a . - if (look() == 'C' || (look() == 'D' && look(1) != 'C')) { - if (SoFar == nullptr) + if (State) + State->EndsWithTemplateArgs = true; + SoFar = make(SoFar, TA); + } else if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) { + // ::= + if (SoFar != nullptr) return nullptr; - if (!PushComponent(getDerived().parseCtorDtorName(SoFar, State))) + SoFar = getDerived().parseDecltype(); + } else if (look() == 'S') { + // ::= + if (SoFar != nullptr) return nullptr; - SoFar = getDerived().parseAbiTags(SoFar); + if (look(1) == 't') { + First += 2; + SoFar = make("std"); + } else { + SoFar = getDerived().parseSubstitution(); + } if (SoFar == nullptr) return nullptr; - Subs.push_back(SoFar); continue; + } else { + Node *N = nullptr; + if (look() == 'C' || (look() == 'D' && look(1) != 'C')) { + // An that's actually a . + if (SoFar == nullptr) + return nullptr; + N = getDerived().parseCtorDtorName(SoFar, State); + if (N != nullptr) + N = getDerived().parseAbiTags(N); + } else { + // ::= + N = getDerived().parseUnqualifiedName(State); + } + if (N == nullptr) + return nullptr; + if (SoFar) + SoFar = make(SoFar, N); + else + SoFar = N; } - - // ::= - if (!PushComponent(getDerived().parseUnqualifiedName(State))) + if (SoFar == nullptr) return nullptr; Subs.push_back(SoFar); } Index: libcxxabi/test/test_demangle.pass.cpp =================================================================== --- libcxxabi/test/test_demangle.pass.cpp +++ libcxxabi/test/test_demangle.pass.cpp @@ -29934,6 +29934,11 @@ "FSiIJEENT_IoE ", "ZTVSiIZTVSiIZTVSiIZTVSiINIJEET_T_T_T_T_ ", "Ana_T_E_T_IJEffffffffffffffersfffffrsrsffffffbgE", + + "_ZN3TPLS_E", + "_ZN3CLSIiEIiEE", + "_ZN3CLSDtLi0EEE", + "_ZN3CLSIiEEvNS_T_Ev", }; const unsigned NI = sizeof(invalid_cases) / sizeof(invalid_cases[0]); Index: llvm/include/llvm/Demangle/ItaniumDemangle.h =================================================================== --- llvm/include/llvm/Demangle/ItaniumDemangle.h +++ llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -2570,8 +2570,6 @@ // ::= template Node *AbstractManglingParser::parseName(NameState *State) { - consumeIf('L'); // extension - if (look() == 'N') return getDerived().parseNestedName(State); if (look() == 'Z') @@ -2647,15 +2645,14 @@ return make(Encoding, Entity); } -// ::= -// ::= St # ::std:: -// extension ::= StL +// ::= [L]* +// ::= St [L]* # ::std:: +// [*] extension template Node * AbstractManglingParser::parseUnscopedName(NameState *State) { bool IsStd = consumeIf("St"); - if (IsStd) - consumeIf('L'); + consumeIf('L'); Node *Result = getDerived().parseUnqualifiedName(State); if (Result == nullptr) @@ -3146,14 +3143,14 @@ // ::= N [] [] E // ::= N [] [] E // -// ::= +// ::= [L]* // ::= // ::= // ::= // ::= # empty // ::= // ::= -// extension ::= L +// [*] extension // // := [] M // @@ -3173,88 +3170,78 @@ if (State) State->ReferenceQualifier = FrefQualRValue; } else if (consumeIf('R')) { if (State) State->ReferenceQualifier = FrefQualLValue; - } else + } else { if (State) State->ReferenceQualifier = FrefQualNone; - - Node *SoFar = nullptr; - auto PushComponent = [&](Node *Comp) { - if (!Comp) return false; - if (SoFar) SoFar = make(SoFar, Comp); - else SoFar = Comp; - if (State) State->EndsWithTemplateArgs = false; - return SoFar != nullptr; - }; - - if (consumeIf("St")) { - SoFar = make("std"); - if (!SoFar) - return nullptr; } + Node *SoFar = nullptr; while (!consumeIf('E')) { consumeIf('L'); // extension - // := [] M if (consumeIf('M')) { + // := [] M if (SoFar == nullptr) return nullptr; continue; } - // ::= + if (State) + State->EndsWithTemplateArgs = false; + if (look() == 'T') { - if (!PushComponent(getDerived().parseTemplateParam())) + // ::= + if (SoFar != nullptr) return nullptr; - Subs.push_back(SoFar); - continue; - } - - // ::= - if (look() == 'I') { + SoFar = getDerived().parseTemplateParam(); + } else if (look() == 'I') { + // ::= Node *TA = getDerived().parseTemplateArgs(State != nullptr); if (TA == nullptr || SoFar == nullptr) return nullptr; - SoFar = make(SoFar, TA); - if (!SoFar) - return nullptr; - if (State) State->EndsWithTemplateArgs = true; - Subs.push_back(SoFar); - continue; - } - - // ::= - if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) { - if (!PushComponent(getDerived().parseDecltype())) + if (SoFar->getKind() == Node::KNameWithTemplateArgs) return nullptr; - Subs.push_back(SoFar); - continue; - } - - // ::= - if (look() == 'S' && look(1) != 't') { - Node *S = getDerived().parseSubstitution(); - if (!PushComponent(S)) - return nullptr; - if (SoFar != S) - Subs.push_back(S); - continue; - } - - // Parse an thats actually a . - if (look() == 'C' || (look() == 'D' && look(1) != 'C')) { - if (SoFar == nullptr) + if (State) + State->EndsWithTemplateArgs = true; + SoFar = make(SoFar, TA); + } else if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) { + // ::= + if (SoFar != nullptr) return nullptr; - if (!PushComponent(getDerived().parseCtorDtorName(SoFar, State))) + SoFar = getDerived().parseDecltype(); + } else if (look() == 'S') { + // ::= + if (SoFar != nullptr) return nullptr; - SoFar = getDerived().parseAbiTags(SoFar); + if (look(1) == 't') { + First += 2; + SoFar = make("std"); + } else { + SoFar = getDerived().parseSubstitution(); + } if (SoFar == nullptr) return nullptr; - Subs.push_back(SoFar); continue; + } else { + Node *N = nullptr; + if (look() == 'C' || (look() == 'D' && look(1) != 'C')) { + // An that's actually a . + if (SoFar == nullptr) + return nullptr; + N = getDerived().parseCtorDtorName(SoFar, State); + if (N != nullptr) + N = getDerived().parseAbiTags(N); + } else { + // ::= + N = getDerived().parseUnqualifiedName(State); + } + if (N == nullptr) + return nullptr; + if (SoFar) + SoFar = make(SoFar, N); + else + SoFar = N; } - - // ::= - if (!PushComponent(getDerived().parseUnqualifiedName(State))) + if (SoFar == nullptr) return nullptr; Subs.push_back(SoFar); }