diff options
author | Nathan Sidwell <nathan@acm.org> | 2022-01-25 23:23:31 +0300 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2022-02-11 15:22:06 +0300 |
commit | fbded4f42db1e52e3e0bc0fe2c7e3440ace455a4 (patch) | |
tree | 03fb3150414e032724ebbb7bb9d1ae3845ac8a33 /libcxxabi/src/demangle | |
parent | 2a1b1f1b1be86732ff345c6f6dbad7c64743a0d5 (diff) |
[demangler] Adjust unqualified name parsing
The unqualified name grammar includes <ctor-dtor-name>, but we handle
that specially in parseNestedName. This is a little awkward. We can
pass in the current scope and have parseUnqualifiedName deal with
cdtors too. That also allows a couple of other simplifications:
1) parseUnqualifiedName can also build up the NestedName, when the
provided scope is non-null. Which means ...
2) parseUnscopedName can pass a "std" scope in (and tailcall).
3) ... and also parseNestedName need not construct the nestedname itself.
4) also parseNestedName's detection of a cdtor-name doesn't have to
rule out a decomposition name anymore.
This change also makes adding module demangling more
straight-forwards, btw.
Reviewed By: ChuanqiXu
Differential Revision: https://reviews.llvm.org/D119154
Diffstat (limited to 'libcxxabi/src/demangle')
-rw-r--r-- | libcxxabi/src/demangle/ItaniumDemangle.h | 60 |
1 files changed, 24 insertions, 36 deletions
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h index 8d90a10aa446..7d28f4da87c1 100644 --- a/libcxxabi/src/demangle/ItaniumDemangle.h +++ b/libcxxabi/src/demangle/ItaniumDemangle.h @@ -2547,7 +2547,7 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser { Node *parseName(NameState *State = nullptr); Node *parseLocalName(NameState *State); Node *parseOperatorName(NameState *State); - Node *parseUnqualifiedName(NameState *State); + Node *parseUnqualifiedName(NameState *State, Node *Scope); Node *parseUnnamedTypeName(NameState *State); Node *parseSourceName(NameState *State); Node *parseUnscopedName(NameState *State); @@ -2659,37 +2659,33 @@ Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) { template <typename Derived, typename Alloc> Node * AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State) { - bool IsStd = consumeIf("St"); - consumeIf('L'); - - Node *Result = getDerived().parseUnqualifiedName(State); - if (Result == nullptr) - return nullptr; - if (IsStd) { - if (auto *Std = make<NameType>("std")) - Result = make<NestedName>(Std, Result); - else + Node *Std = nullptr; + if (consumeIf("St")) { + Std = make<NameType>("std"); + if (Std == nullptr) return nullptr; } + consumeIf('L'); - return Result; + return getDerived().parseUnqualifiedName(State, Std); } // <unqualified-name> ::= <operator-name> [abi-tags] -// ::= <ctor-dtor-name> -// ::= <source-name> -// ::= <unnamed-type-name> +// ::= <ctor-dtor-name> [<abi-tags>] +// ::= <source-name> [<abi-tags>] +// ::= <unnamed-type-name> [<abi-tags>] // ::= DC <source-name>+ E # structured binding declaration template <typename Derived, typename Alloc> Node * -AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(NameState *State) { - // <ctor-dtor-name>s are special-cased in parseNestedName(). +AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(NameState *State, + Node *Scope) { Node *Result; if (look() == 'U') Result = getDerived().parseUnnamedTypeName(State); else if (look() >= '1' && look() <= '9') Result = getDerived().parseSourceName(State); else if (consumeIf("DC")) { + // Structured binding size_t BindingsBegin = Names.size(); do { Node *Binding = getDerived().parseSourceName(State); @@ -2698,10 +2694,18 @@ AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(NameState *State) { Names.push_back(Binding); } while (!consumeIf('E')); Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin)); - } else + } else if (look() == 'C' || look() == 'D') { + // A <ctor-dtor-name>. + if (Scope == nullptr) + return nullptr; + Result = getDerived().parseCtorDtorName(Scope, State); + } else { Result = getDerived().parseOperatorName(State); + } if (Result != nullptr) Result = getDerived().parseAbiTags(Result); + if (Result != nullptr && Scope != nullptr) + Result = make<NestedName>(Scope, Result); return Result; } @@ -3237,24 +3241,8 @@ AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) { return nullptr; continue; // Do not push a new substitution. } else { - Node *N = nullptr; - if (look() == 'C' || (look() == 'D' && look(1) != 'C')) { - // An <unqualified-name> that's actually a <ctor-dtor-name>. - if (SoFar == nullptr) - return nullptr; - N = getDerived().parseCtorDtorName(SoFar, State); - if (N != nullptr) - N = getDerived().parseAbiTags(N); - } else { - // ::= <prefix> <unqualified-name> - N = getDerived().parseUnqualifiedName(State); - } - if (N == nullptr) - return nullptr; - if (SoFar) - SoFar = make<NestedName>(SoFar, N); - else - SoFar = N; + // ::= [<prefix>] <unqualified-name> + SoFar = getDerived().parseUnqualifiedName(State, SoFar); } if (SoFar == nullptr) return nullptr; |