From 9be284e80f298dc2fdf8313233ee0fb00dd00200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 18 Oct 2015 16:58:15 +0200 Subject: [PATCH] AST: proper operator precedence for c++11 initializer {} and :: --- lib/tokenlist.cpp | 27 +++++++++++++++++++-------- test/testtokenize.cpp | 1 + 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index fb9b257e3..6957eea64 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -463,8 +463,18 @@ static bool iscast(const Token *tok) } // X{} X{} etc -static bool iscpp11init(const Token * const nameToken) +static bool iscpp11init(const Token * const tok) { + const Token *nameToken = nullptr; + if (tok->isName()) + nameToken = tok; + else if (Token::Match(tok->previous(), "%name% {")) + nameToken = tok->previous(); + else if (tok->linkAt(-1) && Token::simpleMatch(tok->previous(), "> {") && Token::Match(tok->linkAt(-1)->previous(),"%name% <")) + nameToken = tok->linkAt(-1)->previous(); + if (!nameToken) + return false; + const Token *endtok = nullptr; if (Token::Match(nameToken,"%name% {")) endtok = nameToken->linkAt(1); @@ -479,6 +489,7 @@ static bool iscpp11init(const Token * const nameToken) while (Token::Match(prev, "%name%|::|:|<|>")) { if (Token::Match(prev, "class|struct")) return false; + prev = prev->previous(); } return true; @@ -555,13 +566,6 @@ static void compileTerm(Token *&tok, AST_state& state) tok = tok->next(); if (tok->str() == "<") tok = tok->link()->next(); - - if (Token::simpleMatch(tok, "{ }")) - compileUnaryOp(tok, state, compileExpression); - else - compileBinOp(tok, state, compileExpression); - if (Token::simpleMatch(tok, "}")) - tok = tok->next(); } else if (!state.cpp || !Token::Match(tok, "new|delete %name%|*|&|::|(|[")) { while (tok->next() && tok->next()->isName()) tok = tok->next(); @@ -678,6 +682,13 @@ static void compilePrecedence2(Token *&tok, AST_state& state) compileUnaryOp(tok, state, nullptr); } tok = tok->link()->next(); + } else if (state.cpp && tok->str() == "{" && iscpp11init(tok)) { + if (Token::simpleMatch(tok, "{ }")) + compileUnaryOp(tok, state, compileExpression); + else + compileBinOp(tok, state, compileExpression); + if (Token::simpleMatch(tok, "}")) + tok = tok->next(); } else break; } } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 691b3ba34..cce4c64b0 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -8179,6 +8179,7 @@ private: 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;")); + ASSERT_EQUALS("a::12,{", testAst("::a{1,2};")); // operator precedence } void astbrackets() { // []