Commit 40bd4b60 authored by Milian Wolff's avatar Milian Wolff
Browse files

c++11 support: properly report uses for lamba captures

CCBUG: 279699
parent c1256541
......@@ -2410,6 +2410,23 @@ void ExpressionVisitor::createDelayedType( AST* node , bool expression ) {
m_lastInstance = Instance(true);
}
void ExpressionVisitor::visitLambdaCapture(LambdaCaptureAST *node)
{
if (node->isThis)
{
LOCKDUCHAIN;
Declaration* declaration = 0;
if (currentContext()->parentContext()
&& currentContext()->parentContext()->type() == DUContext::Class)
{
declaration = currentContext()->parentContext()->owner();
}
newUse(node, node->start_token, node->end_token, DeclarationPointer(declaration));
} else {
visit(node->identifier);
}
}
void ExpressionVisitor::visit(AST* node)
{
if (!node) {
......
......@@ -341,6 +341,7 @@ private:
virtual void visitSignalSlotExpression (SignalSlotExpressionAST*);
virtual void visitTypeIDOperator(TypeIDOperatorAST *);
virtual void visitLambdaExpression(LambdaExpressionAST *);
virtual void visitLambdaCapture(LambdaCaptureAST *);
virtual void visit(AST* node);
void putStringType();
......
......@@ -206,6 +206,7 @@ private slots:
void testBug285004();
void testLambda();
void testLambdaReturn();
void testLambdaCapture();
//END C++2011
private:
......
......@@ -548,4 +548,40 @@ void TestDUChain::testLambdaReturn()
QVERIFY(funType->returnType());
QVERIFY(funType->returnType().cast<IntegralType>());
QCOMPARE(funType->returnType().cast<IntegralType>()->dataType(), (uint) IntegralType::TypeInt);
}
\ No newline at end of file
}
void TestDUChain::testLambdaCapture()
{
// see also: https://bugs.kde.org/show_bug.cgi?id=279699
const QByteArray code = "int main() {\n"
" int i;\n"
" auto f = [&i] { i = 0; };\n"
"}\n";
LockedTopDUContext top = parse(code, DumpAll);
QVERIFY(top);
DUChainReadLocker lock;
dumpDUContext(top);
DUContext* mainCtx = top->childContexts().last();
QCOMPARE(mainCtx->childContexts().size(), 1);
// { i = 0; }
QCOMPARE(mainCtx->childContexts().last()->type(), DUContext::Other);
QCOMPARE(mainCtx->childContexts().last()->range(), RangeInRevision(2, 16, 2, 26));
// int i; in main context
QCOMPARE(mainCtx->localDeclarations().size(), 2);
Declaration* iDecl = mainCtx->localDeclarations().at(0);
// no uses
QCOMPARE(iDecl->uses().size(), 1);
QCOMPARE(iDecl->uses().begin()->size(), 2);
QCOMPARE(iDecl->uses().begin()->first(), RangeInRevision(2, 13, 2, 14));
QCOMPARE(iDecl->uses().begin()->last(), RangeInRevision(2, 18, 2, 19));
Declaration* fDecl = mainCtx->localDeclarations().at(1);
TypePtr< FunctionType > funType = fDecl->type<FunctionType>();
QVERIFY(funType);
QCOMPARE(funType->indexedArgumentsSize(), 0u);
QVERIFY(funType->returnType());
QVERIFY(funType->returnType().cast<IntegralType>());
QCOMPARE(funType->returnType().cast<IntegralType>()->dataType(), (uint) IntegralType::TypeVoid);
}
......@@ -742,7 +742,7 @@ public:
DECLARE_AST_NODE(LambdaCapture)
uint identifier;
NameAST* identifier;
bool isThis : 1;
bool isRef : 1;
......
......@@ -5383,8 +5383,10 @@ bool Parser::parseLambdaCapture(LambdaCaptureAST*& node)
advance();
}
ADVANCE(Token_identifier, "identifier");
ast->identifier = session->token_stream->cursor();
if (!parseName(ast->identifier)) {
rewind(start);
return false;
}
if (session->token_stream->lookAhead() == Token_ellipsis)
{
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment