summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus/Parser.cpp
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2009-10-20 15:29:00 +0200
committerRoberto Raggi <roberto.raggi@nokia.com>2009-10-20 15:29:00 +0200
commit18ef2f26150e5244119ca686d8d14106ed98ac78 (patch)
treec062f100aa29042fe83f6adf09f82dae4b8ef6b3 /src/shared/cplusplus/Parser.cpp
parent3ed4a743c0bef8a8bf911c7fd5bce1760e43003a (diff)
downloadqt-creator-18ef2f26150e5244119ca686d8d14106ed98ac78.tar.gz
Reduce backtracking when parsing ambiguous name ids.
Diffstat (limited to 'src/shared/cplusplus/Parser.cpp')
-rw-r--r--src/shared/cplusplus/Parser.cpp53
1 files changed, 38 insertions, 15 deletions
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index b7507c45ce..7d7074dd17 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -58,10 +58,10 @@
#include <iostream>
#include <cassert>
-using namespace CPlusPlus;
-
#define CPLUSPLUS_NO_DEBUG_RULE
+using namespace CPlusPlus;
+
namespace {
class DebugRule {
@@ -3296,16 +3296,32 @@ bool Parser::parseNameId(NameAST *&name)
if (! parseName(name))
return false;
- TemplateIdAST *template_id = name->asTemplateId();
- if (LA() == T_LPAREN && template_id) {
+ QualifiedNameAST *qualified_name_id = name->asQualifiedName();
+
+ 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 (! template_arguments->next && template_arguments->template_argument &&
template_arguments->template_argument->asBinaryExpression()) {
+
unsigned saved = cursor();
ExpressionAST *expr = 0;
+
bool blocked = blockErrors(true);
bool lookAtCastExpression = parseCastExpression(expr);
(void) blockErrors(blocked);
+
if (lookAtCastExpression) {
if (CastExpressionAST *cast_expression = expr->asCastExpression()) {
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 ||
- LA() == T_LBRACKET || LA() == T_LPAREN)
+ switch (LA()) {
+ case T_COMMA:
+ case T_SEMICOLON:
+ case T_LBRACKET:
+ case T_LPAREN:
return true;
- else if (LA() == T_IDENTIFIER ||
- LA() == T_STATIC_CAST ||
- LA() == T_DYNAMIC_CAST ||
- LA() == T_REINTERPRET_CAST ||
- LA() == T_CONST_CAST ||
- tok().isLiteral() ||
- tok().isOperator())
- {
+
+ case T_IDENTIFIER:
+ case T_STATIC_CAST:
+ case T_DYNAMIC_CAST:
+ case T_REINTERPRET_CAST:
+ case T_CONST_CAST:
rewind(start);
return parseName(name, false);
- }
+
+ default:
+ if (tok().isLiteral() || tok().isOperator()) {
+ rewind(start);
+ return parseName(name, false);
+ }
+ } // switch
return true;
}