diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index 86eeaa2f2a4..75970b16715 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -165,6 +165,7 @@ public: Expression, ExpressionList, ParameterDeclarationClause, + TemplateId, TypeId }; @@ -510,6 +511,7 @@ bool Parser::parseClassOrNamespaceName(NameAST *&node) bool Parser::parseTemplateId(NameAST *&node, unsigned template_token) { DEBUG_THIS_RULE(); + CHECK_CACHE(ASTCache::TemplateId, NameAST); const unsigned start = cursor(); @@ -523,14 +525,17 @@ bool Parser::parseTemplateId(NameAST *&node, unsigned template_token) if (maybeSplitGreaterGreaterToken() || LA() == T_GREATER) { ast->greater_token = consumeToken(); node = ast; - return true; + const bool result = true; + _astCache->insert(ASTCache::TemplateId, start, node, cursor(), result); + return result; } } } + const bool result = false; + _astCache->insert(ASTCache::TemplateId, start, 0, cursor(), result); rewind(start); - - return false; + return result; } bool Parser::parseNestedNameSpecifier(NestedNameSpecifierListAST *&node, diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp index a01e103d551..750abbbcf0b 100644 --- a/tests/auto/cplusplus/ast/tst_ast.cpp +++ b/tests/auto/cplusplus/ast/tst_ast.cpp @@ -199,6 +199,7 @@ private slots: void unnamed_class(); void unnamed_class_data(); void expensiveExpression(); + void invalidCode_data(); void invalidCode(); }; @@ -1857,13 +1858,66 @@ void tst_AST::expensiveExpression() QVERIFY(unit->ast()); } +void tst_AST::invalidCode_data() +{ + QTest::addColumn("source"); + + typedef QByteArray _; + QTest::newRow("simple") << + _("static inValidLine()\n"); + + QTest::newRow("hard") << + _("typedef\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_,\n" + "if_ unit(parse(invalidCode, TranslationUnit::ParseTranlationUnit, - false, false, false)); + source += "\nclass Foo {};\n"; + const QSharedPointer unit(parse(source, TranslationUnit::ParseTranlationUnit, + false, false, true)); + + // Check that we find the class coming after the invalid garbage. QVERIFY(unit->ast()); TranslationUnitAST *unitAST = unit->ast()->asTranslationUnit(); QVERIFY(unitAST->declaration_list);