Index: src/cxa_demangle.cpp =================================================================== --- src/cxa_demangle.cpp +++ src/cxa_demangle.cpp @@ -239,81 +239,6 @@ } #endif -namespace { -class BumpPointerAllocator { - struct BlockMeta { - BlockMeta* Next; - size_t Current; - }; - - static constexpr size_t AllocSize = 4096; - static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta); - - alignas(long double) char InitialBuffer[AllocSize]; - BlockMeta* BlockList = nullptr; - - void grow() { - char* NewMeta = static_cast(std::malloc(AllocSize)); - if (NewMeta == nullptr) - std::terminate(); - BlockList = new (NewMeta) BlockMeta{BlockList, 0}; - } - - void* allocateMassive(size_t NBytes) { - NBytes += sizeof(BlockMeta); - BlockMeta* NewMeta = reinterpret_cast(std::malloc(NBytes)); - if (NewMeta == nullptr) - std::terminate(); - BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0}; - return static_cast(NewMeta + 1); - } - -public: - BumpPointerAllocator() - : BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {} - - void* allocate(size_t N) { - N = (N + 15u) & ~15u; - if (N + BlockList->Current >= UsableAllocSize) { - if (N > UsableAllocSize) - return allocateMassive(N); - grow(); - } - BlockList->Current += N; - return static_cast(reinterpret_cast(BlockList + 1) + - BlockList->Current - N); - } - - void reset() { - while (BlockList) { - BlockMeta* Tmp = BlockList; - BlockList = BlockList->Next; - if (reinterpret_cast(Tmp) != InitialBuffer) - std::free(Tmp); - } - BlockList = new (InitialBuffer) BlockMeta{nullptr, 0}; - } - - ~BumpPointerAllocator() { reset(); } -}; - -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); - } -}; -} // unnamed namespace - //===----------------------------------------------------------------------===// // Code beyond this point should not be synchronized with LLVM. //===----------------------------------------------------------------------===// Index: src/demangle/ItaniumDemangle.h =================================================================== --- src/demangle/ItaniumDemangle.h +++ src/demangle/ItaniumDemangle.h @@ -2137,8 +2137,81 @@ } }; -template -struct Db { +class BumpPointerAllocator { + struct BlockMeta { + BlockMeta* Next; + size_t Current; + }; + + static constexpr size_t AllocSize = 4096; + static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta); + + alignas(long double) char InitialBuffer[AllocSize]; + BlockMeta* BlockList = nullptr; + + void grow() { + char* NewMeta = static_cast(std::malloc(AllocSize)); + if (NewMeta == nullptr) + std::terminate(); + BlockList = new (NewMeta) BlockMeta{BlockList, 0}; + } + + void* allocateMassive(size_t NBytes) { + NBytes += sizeof(BlockMeta); + BlockMeta* NewMeta = reinterpret_cast(std::malloc(NBytes)); + if (NewMeta == nullptr) + std::terminate(); + BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0}; + return static_cast(NewMeta + 1); + } + +public: + BumpPointerAllocator() + : BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {} + + void* allocate(size_t N) { + N = (N + 15u) & ~15u; + if (N + BlockList->Current >= UsableAllocSize) { + if (N > UsableAllocSize) + return allocateMassive(N); + grow(); + } + BlockList->Current += N; + return static_cast(reinterpret_cast(BlockList + 1) + + BlockList->Current - N); + } + + void reset() { + while (BlockList) { + BlockMeta* Tmp = BlockList; + BlockList = BlockList->Next; + if (reinterpret_cast(Tmp) != InitialBuffer) + std::free(Tmp); + } + BlockList = new (InitialBuffer) BlockMeta{nullptr, 0}; + } + + ~BumpPointerAllocator() { reset(); } +}; + +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 AbstractDb { const char *First; const char *Last; @@ -2170,7 +2243,10 @@ Alloc ASTAllocator; - Db(const char *First_, const char *Last_) : First(First_), Last(Last_) {} + AbstractDb(const char* First_, const char* Last_) + : First(First_), Last(Last_) {} + + Derived& getDerived() { return static_cast(*this); } void reset(const char *First_, const char *Last_) { First = First_; @@ -2277,7 +2353,7 @@ FunctionRefQual ReferenceQualifier = FrefQualNone; size_t ForwardTemplateRefsBegin; - NameState(Db *Enclosing) + NameState(AbstractDb* Enclosing) : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {} }; @@ -2327,35 +2403,36 @@ // // ::= // ::= -template Node *Db::parseName(NameState *State) { +template +Node* AbstractDb::parseName(NameState* State) { consumeIf('L'); // extension if (look() == 'N') - return parseNestedName(State); + return getDerived().parseNestedName(State); if (look() == 'Z') - return parseLocalName(State); + return getDerived().parseLocalName(State); // ::= if (look() == 'S' && look(1) != 't') { - Node *S = parseSubstitution(); + Node* S = getDerived().parseSubstitution(); if (S == nullptr) return nullptr; if (look() != 'I') return nullptr; - Node *TA = parseTemplateArgs(State != nullptr); + Node* TA = getDerived().parseTemplateArgs(State != nullptr); if (TA == nullptr) return nullptr; if (State) State->EndsWithTemplateArgs = true; return make(S, TA); } - Node *N = parseUnscopedName(State); + Node* N = getDerived().parseUnscopedName(State); if (N == nullptr) return nullptr; // ::= if (look() == 'I') { Subs.push_back(N); - Node *TA = parseTemplateArgs(State != nullptr); + Node* TA = getDerived().parseTemplateArgs(State != nullptr); if (TA == nullptr) return nullptr; if (State) State->EndsWithTemplateArgs = true; @@ -2368,10 +2445,11 @@ // := Z E [] // := Z E s [] // := Z Ed [ ] _ -template Node *Db::parseLocalName(NameState *State) { +template +Node* AbstractDb::parseLocalName(NameState* State) { if (!consumeIf('Z')) return nullptr; - Node *Encoding = parseEncoding(); + Node* Encoding = getDerived().parseEncoding(); if (Encoding == nullptr || !consumeIf('E')) return nullptr; @@ -2387,13 +2465,13 @@ parseNumber(true); if (!consumeIf('_')) return nullptr; - Node *N = parseName(State); + Node* N = getDerived().parseName(State); if (N == nullptr) return nullptr; return make(Encoding, N); } - Node *Entity = parseName(State); + Node* Entity = getDerived().parseName(State); if (Entity == nullptr) return nullptr; First = parse_discriminator(First, Last); @@ -2403,14 +2481,15 @@ // ::= // ::= St # ::std:: // extension ::= StL -template Node *Db::parseUnscopedName(NameState *State) { - if (consumeIf("StL") || consumeIf("St")) { - Node *R = parseUnqualifiedName(State); - if (R == nullptr) - return nullptr; - return make(R); - } - return parseUnqualifiedName(State); +template +Node* AbstractDb::parseUnscopedName(NameState* State) { + if (consumeIf("StL") || consumeIf("St")) { + Node* R = getDerived().parseUnqualifiedName(State); + if (R == nullptr) + return nullptr; + return make(R); + } + return getDerived().parseUnqualifiedName(State); } // ::= [abi-tags] @@ -2418,27 +2497,27 @@ // ::= // ::= // ::= DC + E # structured binding declaration -template -Node *Db::parseUnqualifiedName(NameState *State) { +template +Node* AbstractDb::parseUnqualifiedName(NameState* State) { // s are special-cased in parseNestedName(). Node *Result; if (look() == 'U') - Result = parseUnnamedTypeName(State); + Result = getDerived().parseUnnamedTypeName(State); else if (look() >= '1' && look() <= '9') - Result = parseSourceName(State); + Result = getDerived().parseSourceName(State); else if (consumeIf("DC")) { size_t BindingsBegin = Names.size(); do { - Node *Binding = parseSourceName(State); + Node* Binding = getDerived().parseSourceName(State); if (Binding == nullptr) return nullptr; Names.push_back(Binding); } while (!consumeIf('E')); Result = make(popTrailingNodeArray(BindingsBegin)); } else - Result = parseOperatorName(State); + Result = getDerived().parseOperatorName(State); if (Result != nullptr) - Result = parseAbiTags(Result); + Result = getDerived().parseAbiTags(Result); return Result; } @@ -2448,7 +2527,8 @@ // ::= Ul E [ ] _ // // ::= + # Parameter types or "v" if the lambda has no parameters -template Node *Db::parseUnnamedTypeName(NameState *) { +template +Node* AbstractDb::parseUnnamedTypeName(NameState*) { if (consumeIf("Ut")) { StringView Count = parseNumber(); if (!consumeIf('_')) @@ -2461,7 +2541,7 @@ if (!consumeIf("vE")) { size_t ParamsBegin = Names.size(); do { - Node *P = parseType(); + Node* P = getDerived().parseType(); if (P == nullptr) return nullptr; Names.push_back(P); @@ -2477,7 +2557,8 @@ } // ::= -template Node *Db::parseSourceName(NameState *) { +template +Node* AbstractDb::parseSourceName(NameState*) { size_t Length = 0; if (parsePositiveInteger(&Length)) return nullptr; @@ -2541,7 +2622,8 @@ // ::= rS # >>= // ::= ss # <=> C++2a // ::= v # vendor extended operator -template Node *Db::parseOperatorName(NameState *State) { +template +Node* AbstractDb::parseOperatorName(NameState* State) { switch (look()) { case 'a': switch (look(1)) { @@ -2581,7 +2663,7 @@ SwapAndRestore SavePermit(PermitForwardTemplateReferences, PermitForwardTemplateReferences || State != nullptr); - Node* Ty = parseType(); + Node* Ty = getDerived().parseType(); if (Ty == nullptr) return nullptr; if (State) State->CtorDtorConversion = true; @@ -2645,7 +2727,7 @@ // ::= li # operator "" case 'i': { First += 2; - Node *SN = parseSourceName(State); + Node* SN = getDerived().parseSourceName(State); if (SN == nullptr) return nullptr; return make(SN); @@ -2766,7 +2848,7 @@ case 'v': if (std::isdigit(look(1))) { First += 2; - Node *SN = parseSourceName(State); + Node* SN = getDerived().parseSourceName(State); if (SN == nullptr) return nullptr; return make(SN); @@ -2784,8 +2866,9 @@ // ::= D1 # complete object destructor // ::= D2 # base object destructor // extension ::= D5 # ? -template -Node *Db::parseCtorDtorName(Node *&SoFar, NameState *State) { +template +Node* AbstractDb::parseCtorDtorName(Node*& SoFar, + NameState* State) { if (SoFar->getKind() == Node::KSpecialSubstitution) { auto SSK = static_cast(SoFar)->SSK; switch (SSK) { @@ -2808,7 +2891,7 @@ ++First; if (State) State->CtorDtorConversion = true; if (IsInherited) { - if (parseName(State) == nullptr) + if (getDerived().parseName(State) == nullptr) return nullptr; } return make(SoFar, false); @@ -2841,7 +2924,8 @@ // ::=