C++: Fix expensive parsing of expressions

For expression statements like "(g(g(g(...(g(0))...))))" we reparsed
quite much again and again for nothing. The high-level trace for this
expression looks like this:

    parseCastExpression
      parseTypeId
        parseAbstractDeclarator
          parseAbstractCoreDeclarator
          parseParameterDeclarationClause (--> DEEP)
            ...

      parseUnaryExpression
        ...
        parseCorePostfixExpression
          parseTypeId (--> DEEP)
          parsePrimaryExpression (--> DEEP)

Especially parseTypeId is expensive in this case and it's called two
times, both from the same token (index).

With this patch, we remember for certain ASTs the parse results and
re-use them when needed.

Change-Id: I013d1c064c655636bc94db408097863b5e183fc2
Task-number: QTCREATORBUG-12252
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
Nikolai Kosjar
2014-07-17 12:56:28 +02:00
parent 1926493fe9
commit d3c5fff66d
3 changed files with 167 additions and 8 deletions

View File

@@ -193,6 +193,7 @@ private slots:
void incomplete_ast();
void unnamed_class();
void unnamed_class_data();
void expensiveExpression();
};
void tst_AST::gcc_attributes_1()
@@ -1790,6 +1791,46 @@ void tst_AST::unnamed_class_data()
QTest::newRow("unnamed-__attribute__") << _("class __attribute__((aligned(8))){};");
}
void tst_AST::expensiveExpression()
{
QSharedPointer<TranslationUnit> unit(parseStatement(
"void f()\n"
"{\n"
"(g1\n"
"(g2\n"
"(g3\n"
"(g4\n"
"(g5\n"
"(g6\n"
"(g7\n"
"(g8\n"
"(g9\n"
"(g10\n"
"(g11\n"
"(g12\n"
"(g13\n"
"(g14\n"
"(g15\n"
"(g16\n"
"(g17\n"
"(g18\n"
"(g19\n"
"(g20\n"
"(g21\n"
"(g22\n"
"(g23\n"
"(g24\n"
"(g25\n"
"(g26\n"
"(g27\n"
"(g28\n"
"(g29\n"
"(g30\n"
"(g31(0))))))))))))))))))))))))))))))));\n"
"}\n"));
QVERIFY(unit->ast());
}
void tst_AST::initTestCase()
{
control.setDiagnosticClient(&diag);