From 38b570138f9838551c1c6e15e70d457da1d4f38a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 27 Feb 2020 09:58:41 +0100 Subject: [PATCH] AST: Try to handle c++17 for properly 'for (auto [a,b]:c)' --- lib/tokenlist.cpp | 37 +++++++++++++++++++++++++++++++++++++ test/testtokenize.cpp | 1 + 2 files changed, 38 insertions(+) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 69cd2a31e..4b782d48a 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1342,6 +1342,43 @@ static Token * findAstTop(Token *tok1, Token *tok2) static Token * createAstAtToken(Token *tok, bool cpp) { if (Token::simpleMatch(tok, "for (")) { + if (cpp && Token::Match(tok, "for ( const| auto &|&&| [")) { + Token *decl = Token::findsimplematch(tok, "["); + if (Token::simpleMatch(decl->link(), "] :")) { + AST_state state1(cpp); + while (decl && decl->str() != "]") { + if (Token::Match(decl, "%name% ,|]")) { + state1.op.push(decl); + } else if (decl->str() == ",") { + if (!state1.op.empty()) { + decl->astOperand1(state1.op.top()); + state1.op.pop(); + } + if (!state1.op.empty()) { + state1.op.top()->astOperand2(decl); + state1.op.pop(); + } + state1.op.push(decl); + } + decl = decl->next(); + } + if (state1.op.size() > 1) { + Token *lastName = state1.op.top(); + state1.op.pop(); + state1.op.top()->astOperand2(lastName); + } + decl = decl->next(); + + Token *colon = decl; + compileExpression(decl, state1); + + tok->next()->astOperand1(tok); + tok->next()->astOperand2(colon); + + return decl; + } + } + Token *tok2 = skipDecl(tok->tokAt(2)); Token *init1 = nullptr; Token * const endPar = tok->next()->link(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index f55b6cc77..949ce84fb 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -7491,6 +7491,7 @@ private: ASSERT_EQUALS("forde:(", testAst("for (a::b d : e);")); ASSERT_EQUALS("forx*0=yz;;(", testAst("for(*x=0;y;z)")); ASSERT_EQUALS("forx0=y(8