diff --git a/src/libs/3rdparty/cplusplus/AST.cpp b/src/libs/3rdparty/cplusplus/AST.cpp index fd8b4fcfedd1c6411ed2ea14e6f1d56e13ca83e5..0e885862dadb2ae70750b543d748193d2cc6f548 100644 --- a/src/libs/3rdparty/cplusplus/AST.cpp +++ b/src/libs/3rdparty/cplusplus/AST.cpp @@ -403,12 +403,22 @@ unsigned CallAST::lastToken() const /** \generated */ unsigned CaptureAST::firstToken() const { + if (amper_token) + return amper_token; + if (identifier) + if (unsigned candidate = identifier->firstToken()) + return candidate; return 0; } /** \generated */ unsigned CaptureAST::lastToken() const { + if (identifier) + if (unsigned candidate = identifier->lastToken()) + return candidate; + if (amper_token) + return amper_token + 1; return 1; } diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h index c792581d42639cd4779fafeb372d88d3bbba0a69..961bc2e1a7f798a232440df2fb9ad8317133c7ba 100644 --- a/src/libs/3rdparty/cplusplus/AST.h +++ b/src/libs/3rdparty/cplusplus/AST.h @@ -4394,8 +4394,14 @@ protected: class CaptureAST: public AST { +public: + unsigned amper_token; + NameAST *identifier; + public: CaptureAST() + : amper_token(0) + , identifier(0) {} virtual CaptureAST *asCapture() { return this; } diff --git a/src/libs/3rdparty/cplusplus/ASTClone.cpp b/src/libs/3rdparty/cplusplus/ASTClone.cpp index 7c151f09f6d3d32d3dccffdb4da60ca8f0d8efb6..79e8b7818dda21b87dec79696bc4046e2686e9e5 100644 --- a/src/libs/3rdparty/cplusplus/ASTClone.cpp +++ b/src/libs/3rdparty/cplusplus/ASTClone.cpp @@ -1703,6 +1703,9 @@ LambdaCaptureAST *LambdaCaptureAST::clone(MemoryPool *pool) const CaptureAST *CaptureAST::clone(MemoryPool *pool) const { CaptureAST *ast = new (pool) CaptureAST; + ast->amper_token = amper_token; + if (identifier) + ast->identifier = identifier->clone(pool); return ast; } diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp index e2df7d75830bc4d8017414d331410f197d334325..091a5dfd84c7e43052ca41f84daa66c8c08bee01 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp +++ b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp @@ -2898,6 +2898,13 @@ bool ASTMatcher::match(CaptureAST *node, CaptureAST *pattern) (void) node; (void) pattern; + pattern->amper_token = node->amper_token; + + if (! pattern->identifier) + pattern->identifier = node->identifier; + else if (! AST::match(node->identifier, pattern->identifier, this)) + return false; + return true; } diff --git a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h index 142737d44e76be3e5268f655282d20444c7e5429..fcf1f56d0430b3efe3853a85932ceb3642796d05 100644 --- a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h +++ b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h @@ -1107,9 +1107,10 @@ public: return __ast; } - CaptureAST *Capture() + CaptureAST *Capture(NameAST *identifier = 0) { CaptureAST *__ast = new (&pool) CaptureAST; + __ast->identifier = identifier; return __ast; } diff --git a/src/libs/3rdparty/cplusplus/ASTVisit.cpp b/src/libs/3rdparty/cplusplus/ASTVisit.cpp index 6434a7c5e2b60878d64fd1914427847e780e8f6c..24c5a2372f73897cc505edb3a2276a7327023022 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisit.cpp +++ b/src/libs/3rdparty/cplusplus/ASTVisit.cpp @@ -1237,6 +1237,7 @@ void LambdaCaptureAST::accept0(ASTVisitor *visitor) void CaptureAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { + accept(identifier, visitor); } visitor->endVisit(this); } diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index 19c99ae491d3a22fcc31b8b35e9ffe44c58d21fb..ef71f2900e0b505ecf597db438f8de1205f914f1 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -1069,7 +1069,7 @@ void Bind::capture(CaptureAST *ast) if (! ast) return; - // See QTCREATORBUG-7968 + name(ast->identifier); } bool Bind::visit(LambdaDeclaratorAST *ast) diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index c7abe2002bbc482d08c367ca80595d04e1714641..c7d00c9817bb786f2a595c65daf4803542572b14 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -6294,43 +6294,56 @@ bool Parser::parseLambdaCapture(LambdaCaptureAST *&node) return true; } -bool Parser::parseCapture(CaptureAST *&) +bool Parser::parseCapture(CaptureAST *&node) { - // See QTCREATORBUG-7968 - DEBUG_THIS_RULE(); - if (LA() == T_IDENTIFIER) { - consumeToken(); - return true; - } else if (LA() == T_AMPER && LA(2) == T_IDENTIFIER) { - consumeToken(); + if (LA() == T_THIS) { consumeToken(); return true; + } - } else if (LA() == T_THIS) { + if (LA() == T_AMPER) consumeToken(); + + if (LA() == T_IDENTIFIER) { + SimpleNameAST *ast = new (_pool) SimpleNameAST; + ast->identifier_token = consumeToken(); + + node = new (_pool) CaptureAST; + node->identifier = ast; return true; } return false; } -bool Parser::parseCaptureList(CaptureListAST *&) +bool Parser::parseCaptureList(CaptureListAST *&node) { DEBUG_THIS_RULE(); CaptureAST *capture = 0; if (parseCapture(capture)) { + node = new (_pool) CaptureListAST; + node->value = capture; + + CaptureListAST **l = &node->next; while (LA() == T_COMMA) { consumeToken(); // consume `,' - + CaptureAST *capture = 0; parseCapture(capture); + if (capture) { + *l = new (_pool) CaptureListAST; + (*l)->value = capture; + l = &(*l)->next; + } } + + return true; } - return true; + return false; } bool Parser::parseLambdaDeclarator(LambdaDeclaratorAST *&node) diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp index 392f58d0ee2de1704b5a50b3153789b30f5e12e4..e83d7d220f03fb1c77f60d4e78bf3451b2567345 100644 --- a/src/libs/cplusplus/FindUsages.cpp +++ b/src/libs/cplusplus/FindUsages.cpp @@ -869,7 +869,7 @@ void FindUsages::capture(CaptureAST *ast) if (! ast) return; - // See QTCREATORBUG-7968 + this->name(ast->identifier); } bool FindUsages::visit(LambdaDeclaratorAST *ast) diff --git a/src/plugins/cpptools/cpplocalsymbols.cpp b/src/plugins/cpptools/cpplocalsymbols.cpp index 026c0274cba40d6f5103d732e5b2cc8e67628506..8522196957645eb551e8b776ec4d5a4e1e76eedc 100644 --- a/src/plugins/cpptools/cpplocalsymbols.cpp +++ b/src/plugins/cpptools/cpplocalsymbols.cpp @@ -127,6 +127,11 @@ protected: return true; } + virtual bool visit(CaptureAST *ast) + { + return checkLocalUse(ast->identifier, ast->firstToken()); + } + virtual bool visit(IdExpressionAST *ast) { return checkLocalUse(ast->name, ast->firstToken()); diff --git a/tests/auto/cplusplus/findusages/tst_findusages.cpp b/tests/auto/cplusplus/findusages/tst_findusages.cpp index e08138fe383e85b9e66be90c11da02aafbfa299e..0137ac51bfdba914c57a815303f55412d91e1caa 100644 --- a/tests/auto/cplusplus/findusages/tst_findusages.cpp +++ b/tests/auto/cplusplus/findusages/tst_findusages.cpp @@ -77,7 +77,8 @@ class tst_FindUsages: public QObject private Q_SLOTS: void inlineMethod(); -// void lambdaArg(); + void lambdaCaptureByValue(); + void lambdaCaptureByReference(); // Qt keywords void qproperty_1(); @@ -124,15 +125,46 @@ void tst_FindUsages::inlineMethod() QCOMPARE(findUsages.references().size(), 2); } -#if 0 /* see QTCREATORBUG-7968 */ -void tst_FindUsages::lambdaArg() +void tst_FindUsages::lambdaCaptureByValue() { const QByteArray src = "\n" "void f() {\n" " int test;\n" " [test] { ++test; };\n" "}\n"; - Document::Ptr doc = Document::create("lambdaArg"); + Document::Ptr doc = Document::create("lambdaCaptureByValue"); + doc->setUtf8Source(src); + doc->parse(); + doc->check(); + + QVERIFY(doc->diagnosticMessages().isEmpty()); + QCOMPARE(doc->globalSymbolCount(), 1U); + + Snapshot snapshot; + snapshot.insert(doc); + + Function *f = doc->globalSymbolAt(0)->asFunction(); + QVERIFY(f); + QCOMPARE(f->memberCount(), 1U); + Block *b = f->memberAt(0)->asBlock(); + QCOMPARE(b->memberCount(), 2U); + Declaration *d = b->memberAt(0)->asDeclaration(); + QVERIFY(d); + QCOMPARE(d->name()->identifier()->chars(), "test"); + + FindUsages findUsages(src, doc, snapshot); + findUsages(d); + QCOMPARE(findUsages.usages().size(), 3); +} + +void tst_FindUsages::lambdaCaptureByReference() +{ + const QByteArray src = "\n" + "void f() {\n" + " int test;\n" + " [&test] { ++test; };\n" + "}\n"; + Document::Ptr doc = Document::create("lambdaCaptureByReference"); doc->setUtf8Source(src); doc->parse(); doc->check(); @@ -156,7 +188,6 @@ void tst_FindUsages::lambdaArg() findUsages(d); QCOMPARE(findUsages.usages().size(), 3); } -#endif #if 0 @interface Clazz {} +(void)method:(int)arg; @end diff --git a/tests/tools/cplusplus-dump/dumpers.inc b/tests/tools/cplusplus-dump/dumpers.inc index 4ce49361e63fa62bda971bf01fe93d6a2d5228cd..a08981a8f7d64382c3172a03fb19008c57699af8 100644 --- a/tests/tools/cplusplus-dump/dumpers.inc +++ b/tests/tools/cplusplus-dump/dumpers.inc @@ -1645,6 +1645,9 @@ virtual bool visit(LambdaCaptureAST *ast) virtual bool visit(CaptureAST *ast) { + if (ast->amper_token) + terminal(ast->amper_token, ast); + nonterminal(ast->identifier); return false; }