forked from qt-creator/qt-creator
Use memoization to reduce the backtracking when parsing template arguments.
This commit is contained in:
@@ -328,8 +328,6 @@ bool Parser::parseTemplateId(NameAST *&node)
|
|||||||
DEBUG_THIS_RULE();
|
DEBUG_THIS_RULE();
|
||||||
|
|
||||||
const unsigned start = cursor();
|
const unsigned start = cursor();
|
||||||
Rewind rewind(this);
|
|
||||||
rewind.mark();
|
|
||||||
|
|
||||||
if (LA() == T_IDENTIFIER && LA(2) == T_LESS) {
|
if (LA() == T_IDENTIFIER && LA(2) == T_LESS) {
|
||||||
TemplateIdAST *ast = new (_pool) TemplateIdAST;
|
TemplateIdAST *ast = new (_pool) TemplateIdAST;
|
||||||
@@ -692,8 +690,26 @@ bool Parser::parseOperatorFunctionId(NameAST *&node)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Parser::TemplateArgumentListEntry *Parser::templateArgumentListEntry(unsigned tokenIndex)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < _templateArgumentList.size(); ++i) {
|
||||||
|
TemplateArgumentListEntry *entry = &_templateArgumentList[i];
|
||||||
|
if (entry->index == tokenIndex)
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool Parser::parseTemplateArgumentList(TemplateArgumentListAST *&node)
|
bool Parser::parseTemplateArgumentList(TemplateArgumentListAST *&node)
|
||||||
{
|
{
|
||||||
|
if (TemplateArgumentListEntry *entry = templateArgumentListEntry(cursor())) {
|
||||||
|
rewind(entry->cursor);
|
||||||
|
return entry->ast;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned start = cursor();
|
||||||
|
|
||||||
DEBUG_THIS_RULE();
|
DEBUG_THIS_RULE();
|
||||||
TemplateArgumentListAST **template_argument_ptr = &node;
|
TemplateArgumentListAST **template_argument_ptr = &node;
|
||||||
ExpressionAST *template_argument = 0;
|
ExpressionAST *template_argument = 0;
|
||||||
@@ -711,8 +727,13 @@ bool Parser::parseTemplateArgumentList(TemplateArgumentListAST *&node)
|
|||||||
template_argument_ptr = &(*template_argument_ptr)->next;
|
template_argument_ptr = &(*template_argument_ptr)->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_templateArgumentList.push_back(TemplateArgumentListEntry(start, cursor(), node));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_templateArgumentList.push_back(TemplateArgumentListEntry(start, cursor(), 0));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,6 @@
|
|||||||
#include "Token.h"
|
#include "Token.h"
|
||||||
#include "TranslationUnit.h"
|
#include "TranslationUnit.h"
|
||||||
|
|
||||||
|
|
||||||
namespace CPlusPlus {
|
namespace CPlusPlus {
|
||||||
|
|
||||||
class CPLUSPLUS_EXPORT Parser
|
class CPLUSPLUS_EXPORT Parser
|
||||||
@@ -287,6 +286,17 @@ private:
|
|||||||
inline void rewind(unsigned cursor)
|
inline void rewind(unsigned cursor)
|
||||||
{ _tokenIndex = cursor; }
|
{ _tokenIndex = cursor; }
|
||||||
|
|
||||||
|
struct TemplateArgumentListEntry {
|
||||||
|
unsigned index;
|
||||||
|
unsigned cursor;
|
||||||
|
TemplateArgumentListAST *ast;
|
||||||
|
|
||||||
|
TemplateArgumentListEntry(unsigned index = 0, unsigned cursor = 0, TemplateArgumentListAST *ast = 0)
|
||||||
|
: index(index), cursor(cursor), ast(ast) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
TemplateArgumentListEntry *templateArgumentListEntry(unsigned tokenIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TranslationUnit *_translationUnit;
|
TranslationUnit *_translationUnit;
|
||||||
Control *_control;
|
Control *_control;
|
||||||
@@ -298,6 +308,8 @@ private:
|
|||||||
bool _inFunctionBody: 1;
|
bool _inFunctionBody: 1;
|
||||||
bool _inObjCImplementationContext: 1;
|
bool _inObjCImplementationContext: 1;
|
||||||
|
|
||||||
|
Array<TemplateArgumentListEntry> _templateArgumentList;
|
||||||
|
|
||||||
class Rewind;
|
class Rewind;
|
||||||
friend class Rewind;
|
friend class Rewind;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user