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);
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);
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;
}
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;
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);
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);
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;
}
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;