From 70ab30e3c6951f72bdbc99cd4525a4b3ae88fd4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 3 May 2021 20:22:08 +0200 Subject: [PATCH] AST; Fixed problem with initializer list and cleanup of compileScope --- lib/tokenlist.cpp | 38 +++++++++++++++++++++++++++----------- test/testtokenize.cpp | 5 +++-- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index a3eab7714..4d3242768 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -722,6 +722,8 @@ static void compileBinOp(Token *&tok, AST_state& state, void(*f)(Token *&tok, AS Token *binop = tok; if (f) { tok = tok->next(); + if (Token::simpleMatch(binop, ":: ~")) + tok = tok->next(); state.depth++; if (tok && state.depth <= AST_MAX_DEPTH) f(tok, state); @@ -885,17 +887,12 @@ static void compileScope(Token *&tok, AST_state& state) compileTerm(tok, state); while (tok) { if (tok->str() == "::") { - Token *binop = tok; - tok = tok->next(); - if (tok && tok->str() == "~") // Jump over ~ of destructor definition - tok = tok->next(); - if (tok) - compileTerm(tok, state); - - if (binop->previous() && (binop->previous()->isName() || (binop->previous()->link() && binop->strAt(-1) == ">"))) - compileBinOp(binop, state, nullptr); + const Token *lastOp = state.op.empty() ? nullptr : state.op.top(); + if (Token::Match(lastOp, "%name%") && + (lastOp->next() == tok || (Token::Match(lastOp, "%name% <") && lastOp->linkAt(1) && tok == lastOp->linkAt(1)->next()))) + compileBinOp(tok, state, compileTerm); else - compileUnaryOp(binop, state, nullptr); + compileUnaryOp(tok, state, compileTerm); } else break; } } @@ -1011,7 +1008,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state) compileUnaryOp(tok, state, compileExpression); else compileBinOp(tok, state, compileExpression); - while (Token::simpleMatch(tok, "}")) + if (Token::simpleMatch(tok, "}")) tok = tok->next(); } else break; } @@ -1544,6 +1541,25 @@ static Token * createAstAtToken(Token *tok, bool cpp) if (Token::Match(tok, "%type% <") && tok->linkAt(1) && !Token::Match(tok->linkAt(1), "> [({]")) return tok->linkAt(1); + if (cpp && Token::Match(tok, "%type% ::|<|%name%")) { + Token *tok2 = tok; + while (true) { + if (Token::Match(tok2, "%name%|> :: %name%")) + tok2 = tok2->tokAt(2); + else if (Token::Match(tok2, "%name% <") && tok2->linkAt(1)) + tok2 = tok2->linkAt(1); + else + break; + } + if (Token::Match(tok2, "%name%|> %name% {") && tok2->next()->varId() && iscpp11init(tok2->tokAt(2))) { + Token *const tok1 = tok = tok2->next(); + AST_state state(cpp); + compileExpression(tok, state); + createAstAtTokenInner(tok1->next(), tok1->linkAt(1), cpp); + return tok; + } + } + if (Token::Match(tok, "%type% %name%|*|&|::") && tok->str() != "return") { int typecount = 0; Token *typetok = tok; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 041f6e708..ebd4db14c 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -5796,7 +5796,7 @@ private: "void f(struct cmd *) { for (; field; field++) {} }")); // template parentheses: <> - ASSERT_EQUALS("stdfabs::m_similarity(numeric_limitsepsilon::(<=return", testAst("return std::fabs(m_similarity) <= numeric_limits::epsilon();")); // #6195 + ASSERT_EQUALS("ab::c(de::(<=return", testAst("return a::b(c) <= d::e();")); // #6195 // C++ initializer ASSERT_EQUALS("Class{", testAst("Class{};")); @@ -5814,6 +5814,7 @@ private: ASSERT_EQUALS("abR{{,P(,((", testAst("a(b(R{},{},P()));")); ASSERT_EQUALS("f1{2{,3{,{x,(", testAst("f({{1},{2},{3}},x);")); ASSERT_EQUALS("a1{ b2{", testAst("auto a{1}; auto b{2};")); + ASSERT_EQUALS("var1ab::23,{,{4ab::56,{,{,{", testAst("auto var{{1,a::b{2,3}}, {4,a::b{5,6}}};")); } void astbrackets() { // [] @@ -5890,7 +5891,7 @@ private: ASSERT_EQUALS("bcd.(=", testAst(";a && b = c->d();")); // This two unit tests were added to avoid a crash. The actual correct AST result for non-executable code has not been determined so far. - ASSERT_EQUALS("Cpublica::b:::", testAst("class C : public ::a::b { };")); + ASSERT_NO_THROW(testAst("class C : public ::a::b { };")); ASSERT_EQUALS("AB: abc+=", testAst("struct A : public B { void f() { a=b+c; } };")); ASSERT_EQUALS("xfts(=", testAst("; auto x = f(ts...);"));