C++: Fix find usage to see Catch test functions bodies

Catch test functions defined with function-like macros.
To speed-up semantic analysis, find usages does not expand function-like
macros.
Semantic fails with "expected a function declarator" on such functions
and skips function body.
To avoid that, we create dummy function type specifically for this case

Change-Id: Ie2f2464ee57aa4dc86eed07b8b699458f95c0266
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Volodymyr Zibarov
2020-06-12 22:42:06 +03:00
parent af9665f785
commit 7d82741602
2 changed files with 53 additions and 0 deletions
+13
View File
@@ -2252,6 +2252,19 @@ bool Bind::visit(FunctionDefinitionAST *ast)
Function *fun = type->asFunctionType();
ast->symbol = fun;
if (!fun && ast->declarator && ast->declarator->initializer)
if (ExpressionListParenAST *exprAst = ast->declarator->initializer->asExpressionListParen()) {
// this could be non-expanded function like macro, because
// for find usages we parse without expanding them
// So we create dummy function type here for findUsages to see function body
fun = control()->newFunction(0, nullptr);
fun->setStartOffset(tokenAt(exprAst->firstToken()).utf16charsBegin());
fun->setEndOffset(tokenAt(exprAst->lastToken() - 1).utf16charsEnd());
type = fun;
ast->symbol = fun;
}
if (fun) {
setDeclSpecifiers(fun, declSpecifiers);
fun->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd());
@@ -126,6 +126,8 @@ private Q_SLOTS:
void templatePartialSpecialization_2();
void template_SFINAE_1();
void variableTemplateInExpression();
void variadicMacros();
};
void tst_FindUsages::dump(const QList<Usage> &usages) const
@@ -1624,5 +1626,43 @@ int main(){
QCOMPARE(find.usages().size(), 2);
}
void tst_FindUsages::variadicMacros()
{
const QByteArray src =
R"(
struct MyStruct { int value; };
#define FOO( ... ) int foo()
FOO(1) {
MyStruct s;
s.value;
}
int main(){}
)";
Document::Ptr doc = Document::create("variadicMacros");
doc->setUtf8Source(src);
doc->parse();
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
QVERIFY(doc->globalSymbolCount() >= 1);
Snapshot snapshot;
snapshot.insert(doc);
Class *s = doc->globalSymbolAt(0)->asClass();
QVERIFY(s);
QCOMPARE(s->name()->identifier()->chars(), "MyStruct");
QCOMPARE(s->memberCount(), 1);
Declaration *sv = s->memberAt(0)->asDeclaration();
QVERIFY(sv);
QCOMPARE(sv->name()->identifier()->chars(), "value");
FindUsages find(src, doc, snapshot);
find(sv);
QCOMPARE(find.usages().size(), 2);
}
QTEST_APPLESS_MAIN(tst_FindUsages)
#include "tst_findusages.moc"