forked from qt-creator/qt-creator
Reduce backtracking when parsing ambiguous name ids.
This commit is contained in:
@@ -58,10 +58,10 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
using namespace CPlusPlus;
|
|
||||||
|
|
||||||
#define CPLUSPLUS_NO_DEBUG_RULE
|
#define CPLUSPLUS_NO_DEBUG_RULE
|
||||||
|
|
||||||
|
using namespace CPlusPlus;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class DebugRule {
|
class DebugRule {
|
||||||
@@ -3296,16 +3296,32 @@ bool Parser::parseNameId(NameAST *&name)
|
|||||||
if (! parseName(name))
|
if (! parseName(name))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
TemplateIdAST *template_id = name->asTemplateId();
|
QualifiedNameAST *qualified_name_id = name->asQualifiedName();
|
||||||
if (LA() == T_LPAREN && template_id) {
|
|
||||||
|
TemplateIdAST *template_id = 0;
|
||||||
|
if (qualified_name_id) {
|
||||||
|
if (NameAST *unqualified_name = qualified_name_id->unqualified_name)
|
||||||
|
template_id = unqualified_name->asTemplateId();
|
||||||
|
} else {
|
||||||
|
template_id = name->asTemplateId();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! template_id)
|
||||||
|
return true; // it's not a template-id, there's nothing to rewind.
|
||||||
|
|
||||||
|
else if (LA() == T_LPAREN) {
|
||||||
|
// a template-id followed by a T_LPAREN
|
||||||
if (TemplateArgumentListAST *template_arguments = template_id->template_arguments) {
|
if (TemplateArgumentListAST *template_arguments = template_id->template_arguments) {
|
||||||
if (! template_arguments->next && template_arguments->template_argument &&
|
if (! template_arguments->next && template_arguments->template_argument &&
|
||||||
template_arguments->template_argument->asBinaryExpression()) {
|
template_arguments->template_argument->asBinaryExpression()) {
|
||||||
|
|
||||||
unsigned saved = cursor();
|
unsigned saved = cursor();
|
||||||
ExpressionAST *expr = 0;
|
ExpressionAST *expr = 0;
|
||||||
|
|
||||||
bool blocked = blockErrors(true);
|
bool blocked = blockErrors(true);
|
||||||
bool lookAtCastExpression = parseCastExpression(expr);
|
bool lookAtCastExpression = parseCastExpression(expr);
|
||||||
(void) blockErrors(blocked);
|
(void) blockErrors(blocked);
|
||||||
|
|
||||||
if (lookAtCastExpression) {
|
if (lookAtCastExpression) {
|
||||||
if (CastExpressionAST *cast_expression = expr->asCastExpression()) {
|
if (CastExpressionAST *cast_expression = expr->asCastExpression()) {
|
||||||
if (cast_expression->lparen_token && cast_expression->rparen_token
|
if (cast_expression->lparen_token && cast_expression->rparen_token
|
||||||
@@ -3322,20 +3338,27 @@ bool Parser::parseNameId(NameAST *&name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LA() == T_COMMA || LA() == T_SEMICOLON ||
|
switch (LA()) {
|
||||||
LA() == T_LBRACKET || LA() == T_LPAREN)
|
case T_COMMA:
|
||||||
|
case T_SEMICOLON:
|
||||||
|
case T_LBRACKET:
|
||||||
|
case T_LPAREN:
|
||||||
return true;
|
return true;
|
||||||
else if (LA() == T_IDENTIFIER ||
|
|
||||||
LA() == T_STATIC_CAST ||
|
case T_IDENTIFIER:
|
||||||
LA() == T_DYNAMIC_CAST ||
|
case T_STATIC_CAST:
|
||||||
LA() == T_REINTERPRET_CAST ||
|
case T_DYNAMIC_CAST:
|
||||||
LA() == T_CONST_CAST ||
|
case T_REINTERPRET_CAST:
|
||||||
tok().isLiteral() ||
|
case T_CONST_CAST:
|
||||||
tok().isOperator())
|
rewind(start);
|
||||||
{
|
return parseName(name, false);
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (tok().isLiteral() || tok().isOperator()) {
|
||||||
rewind(start);
|
rewind(start);
|
||||||
return parseName(name, false);
|
return parseName(name, false);
|
||||||
}
|
}
|
||||||
|
} // switch
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user