diff --git a/libcxxabi/src/cxa_demangle.cpp b/libcxxabi/src/cxa_demangle.cpp index 9f58a0c6e4c1..a961968c9e44 100644 --- a/libcxxabi/src/cxa_demangle.cpp +++ b/libcxxabi/src/cxa_demangle.cpp @@ -1953,6 +1953,23 @@ public: } }; +class DefaultAllocator { + BumpPointerAllocator Alloc; + +public: + void reset() { Alloc.reset(); } + + template T *makeNode(Args &&...args) { + return new (Alloc.allocate(sizeof(T))) + T(std::forward(args)...); + } + + void *allocateNodeArray(size_t sz) { + return Alloc.allocate(sizeof(Node *) * sz); + } +}; + +template struct Db { const char *First; const char *Last; @@ -1983,7 +2000,7 @@ struct Db { bool PermitForwardTemplateReferences = false; bool ParsingLambdaParams = false; - BumpPointerAllocator ASTAllocator; + Alloc ASTAllocator; Db(const char *First_, const char *Last_) : First(First_), Last(Last_) {} @@ -2000,13 +2017,12 @@ struct Db { } template T *make(Args &&... args) { - return new (ASTAllocator.allocate(sizeof(T))) - T(std::forward(args)...); + return ASTAllocator.template makeNode(std::forward(args)...); } template NodeArray makeNodeArray(It begin, It end) { size_t sz = static_cast(end - begin); - void *mem = ASTAllocator.allocate(sizeof(Node *) * sz); + void *mem = ASTAllocator.allocateNodeArray(sz); Node **data = new (mem) Node *[sz]; std::copy(begin, end, data); return NodeArray(data, sz); @@ -2143,7 +2159,7 @@ const char* parse_discriminator(const char* first, const char* last); // // ::= // ::= -Node *Db::parseName(NameState *State) { +template Node *Db::parseName(NameState *State) { consumeIf('L'); // extension if (look() == 'N') @@ -2184,7 +2200,7 @@ Node *Db::parseName(NameState *State) { // := Z E [] // := Z E s [] // := Z Ed [ ] _ -Node *Db::parseLocalName(NameState *State) { +template Node *Db::parseLocalName(NameState *State) { if (!consumeIf('Z')) return nullptr; Node *Encoding = parseEncoding(); @@ -2216,7 +2232,7 @@ Node *Db::parseLocalName(NameState *State) { // ::= // ::= St # ::std:: // extension ::= StL -Node *Db::parseUnscopedName(NameState *State) { +template Node *Db::parseUnscopedName(NameState *State) { if (consumeIf("StL") || consumeIf("St")) { Node *R = parseUnqualifiedName(State); if (R == nullptr) @@ -2231,27 +2247,28 @@ Node *Db::parseUnscopedName(NameState *State) { // ::= // ::= // ::= DC + E # structured binding declaration -Node *Db::parseUnqualifiedName(NameState *State) { - // s are special-cased in parseNestedName(). - Node *Result; - if (look() == 'U') - Result = parseUnnamedTypeName(State); - else if (look() >= '1' && look() <= '9') - Result = parseSourceName(State); - else if (consumeIf("DC")) { - size_t BindingsBegin = Names.size(); - do { - Node *Binding = parseSourceName(State); - if (Binding == nullptr) - return nullptr; - Names.push_back(Binding); - } while (!consumeIf('E')); - Result = make(popTrailingNodeArray(BindingsBegin)); - } else - Result = parseOperatorName(State); - if (Result != nullptr) - Result = parseAbiTags(Result); - return Result; +template +Node *Db::parseUnqualifiedName(NameState *State) { + // s are special-cased in parseNestedName(). + Node *Result; + if (look() == 'U') + Result = parseUnnamedTypeName(State); + else if (look() >= '1' && look() <= '9') + Result = parseSourceName(State); + else if (consumeIf("DC")) { + size_t BindingsBegin = Names.size(); + do { + Node *Binding = parseSourceName(State); + if (Binding == nullptr) + return nullptr; + Names.push_back(Binding); + } while (!consumeIf('E')); + Result = make(popTrailingNodeArray(BindingsBegin)); + } else + Result = parseOperatorName(State); + if (Result != nullptr) + Result = parseAbiTags(Result); + return Result; } // ::= Ut [] _ @@ -2260,7 +2277,7 @@ Node *Db::parseUnqualifiedName(NameState *State) { // ::= Ul E [ ] _ // // ::= + # Parameter types or "v" if the lambda has no parameters -Node *Db::parseUnnamedTypeName(NameState *) { +template Node *Db::parseUnnamedTypeName(NameState *) { if (consumeIf("Ut")) { StringView Count = parseNumber(); if (!consumeIf('_')) @@ -2289,7 +2306,7 @@ Node *Db::parseUnnamedTypeName(NameState *) { } // ::= -Node *Db::parseSourceName(NameState *) { +template Node *Db::parseSourceName(NameState *) { size_t Length = 0; if (parsePositiveInteger(&Length)) return nullptr; @@ -2353,7 +2370,7 @@ Node *Db::parseSourceName(NameState *) { // ::= rS # >>= // ::= ss # <=> C++2a // ::= v # vendor extended operator -Node *Db::parseOperatorName(NameState *State) { +template Node *Db::parseOperatorName(NameState *State) { switch (look()) { case 'a': switch (look(1)) { @@ -2596,7 +2613,8 @@ Node *Db::parseOperatorName(NameState *State) { // ::= D1 # complete object destructor // ::= D2 # base object destructor // extension ::= D5 # ? -Node *Db::parseCtorDtorName(Node *&SoFar, NameState *State) { +template +Node *Db::parseCtorDtorName(Node *&SoFar, NameState *State) { if (SoFar->K == Node::KSpecialSubstitution) { auto SSK = static_cast(SoFar)->SSK; switch (SSK) { @@ -2650,7 +2668,7 @@ Node *Db::parseCtorDtorName(Node *&SoFar, NameState *State) { // ::=