From 9bb2af1893c91a36dafcffa42f6b3d58da72486d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 18 Oct 2015 13:43:39 +0200 Subject: [PATCH] Fixed #7059 (AST: handle C++ initialization with {} better) --- lib/tokenlist.cpp | 28 ++++++++++++++++++++++++++-- test/testtokenize.cpp | 3 +++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 1efb68b54..fb9b257e3 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -462,6 +462,28 @@ static bool iscast(const Token *tok) return false; } +// X{} X{} etc +static bool iscpp11init(const Token * const nameToken) +{ + const Token *endtok = nullptr; + if (Token::Match(nameToken,"%name% {")) + endtok = nameToken->linkAt(1); + else if (Token::Match(nameToken,"%name% <") && Token::simpleMatch(nameToken->linkAt(1),"> {")) + endtok = nameToken->linkAt(1)->linkAt(1); + else + return false; + // There is no initialisation for example here: 'class Fred {};' + if (!Token::simpleMatch(endtok, "} ;")) + return true; + const Token *prev = nameToken; + while (Token::Match(prev, "%name%|::|:|<|>")) { + if (Token::Match(prev, "class|struct")) + return false; + prev = prev->previous(); + } + return true; +} + static void compileUnaryOp(Token *&tok, AST_state& state, void(*f)(Token *&tok, AST_state& state)) { Token *unaryop = tok; @@ -528,9 +550,11 @@ static void compileTerm(Token *&tok, AST_state& state) } else if (Token::Match(tok, "sizeof !!(")) { compileUnaryOp(tok, state, compileExpression); state.op.pop(); - } else if (state.cpp && Token::Match(tok,"%name% {")) { + } else if (state.cpp && iscpp11init(tok)) { // X{} X{} etc state.op.push(tok); tok = tok->next(); + if (tok->str() == "<") + tok = tok->link()->next(); if (Token::simpleMatch(tok, "{ }")) compileUnaryOp(tok, state, compileExpression); @@ -969,7 +993,7 @@ static Token * createAstAtToken(Token *tok, bool cpp) if (Token::simpleMatch(tok, "( {")) return tok; - if (Token::Match(tok, "%type% <") && Token::Match(tok->linkAt(1), "> !!(")) + if (Token::Match(tok, "%type% <") && !Token::Match(tok->linkAt(1), "> [({]")) return tok->linkAt(1); if (tok->str() == "return" || !tok->previous() || Token::Match(tok, "%name% %op%|(|[|.|::|<|?") || Token::Match(tok->previous(), "[;{}] %cop%|++|--|( !!{")) { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index aa8a14230..691b3ba34 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -8174,8 +8174,11 @@ private: // C++ initializer ASSERT_EQUALS("Class{", testAst("Class{};")); ASSERT_EQUALS("Class12,{", testAst("Class{1,2};")); + ASSERT_EQUALS("Class12,{", testAst("Class{1,2};")); ASSERT_EQUALS("abc{d:?=", testAst("a=b?c{}:d;")); ASSERT_EQUALS("abc12,{d:?=", testAst("a=b?c{1,2}:d;")); + ASSERT_EQUALS("abc{d:?=", testAst("a=b?c{}:d;")); + ASSERT_EQUALS("abc12,{d:?=", testAst("a=b?c{1,2}:d;")); } void astbrackets() { // []