From 2a7fa04101bf487f4fd6dd04297573f62157d41a Mon Sep 17 00:00:00 2001 From: Roberto Raggi <roberto.raggi@nokia.com> Date: Thu, 22 Oct 2009 16:46:26 +0200 Subject: [PATCH] Released the memory allocated in the memory pool when backtracking from Parser::parseTemplateId(). --- src/shared/cplusplus/MemoryPool.cpp | 13 ++++++++++++ src/shared/cplusplus/MemoryPool.h | 16 +++++++++++++++ src/shared/cplusplus/Parser.cpp | 32 +++++++++++++++++++++++++++++ src/shared/cplusplus/Parser.h | 3 +++ 4 files changed, 64 insertions(+) diff --git a/src/shared/cplusplus/MemoryPool.cpp b/src/shared/cplusplus/MemoryPool.cpp index 2002a654350..1453c62cd69 100644 --- a/src/shared/cplusplus/MemoryPool.cpp +++ b/src/shared/cplusplus/MemoryPool.cpp @@ -110,6 +110,19 @@ void *MemoryPool::allocate_helper(size_t size) return addr; } +MemoryPool::State MemoryPool::state() const +{ return State(ptr, _blockCount); } + +void MemoryPool::rewind(const State &state) +{ + if (_blockCount == state.blockCount && state.ptr < ptr) { + if (_initializeAllocatedMemory) + memset(state.ptr, '\0', ptr - state.ptr); + + ptr = state.ptr; + } +} + Managed::Managed() { } diff --git a/src/shared/cplusplus/MemoryPool.h b/src/shared/cplusplus/MemoryPool.h index e0f1ff87017..5b6fae925ff 100644 --- a/src/shared/cplusplus/MemoryPool.h +++ b/src/shared/cplusplus/MemoryPool.h @@ -79,6 +79,22 @@ public: return allocate_helper(size); } + struct State + { + char *ptr; + char *end; + int blockCount; + + inline bool isValid() const + { return ptr != 0; } + + inline State(char *ptr = 0, int blockCount = 0) + : ptr(ptr), blockCount(blockCount) {} + }; + + State state() const; + void rewind(const State &state); + private: void *allocate_helper(size_t size); diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index 8f3bd549ce4..24851c991da 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -88,6 +88,30 @@ int DebugRule::depth = 0; # define DEBUG_THIS_RULE() do {} while (0) #endif +class Parser::Rewind +{ + Parser *_parser; + MemoryPool::State _state; + +public: + inline Rewind(Parser *parser) + : _parser(parser) {} + + inline void operator()(unsigned tokenIndex) + { rewind(tokenIndex); } + + inline void mark() + { _state = _parser->_pool->state(); } + + inline void rewind(unsigned tokenIndex) + { + _parser->rewind(tokenIndex); + + if (_state.isValid()) + _parser->_pool->rewind(_state); + } +}; + Parser::Parser(TranslationUnit *unit) : _translationUnit(unit), _control(_translationUnit->control()), @@ -302,6 +326,11 @@ bool Parser::parseClassOrNamespaceName(NameAST *&node) bool Parser::parseTemplateId(NameAST *&node) { DEBUG_THIS_RULE(); + + const unsigned start = cursor(); + Rewind rewind(this); + rewind.mark(); + if (LA() == T_IDENTIFIER && LA(2) == T_LESS) { TemplateIdAST *ast = new (_pool) TemplateIdAST; ast->identifier_token = consumeToken(); @@ -315,6 +344,9 @@ bool Parser::parseTemplateId(NameAST *&node) } } } + + rewind(start); + return false; } diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index 3ca3371d815..2a7c15dfa3e 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -298,6 +298,9 @@ private: bool _inFunctionBody: 1; bool _inObjCImplementationContext: 1; + class Rewind; + friend class Rewind; + private: Parser(const Parser& source); void operator =(const Parser& source); -- GitLab