forked from qt-creator/qt-creator
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:
Vendored
+13
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user