AST; Fixed problem with initializer list and cleanup of compileScope

This commit is contained in:
Daniel Marjamäki 2021-05-03 20:22:08 +02:00
parent 7fefdf2bf7
commit 70ab30e3c6
2 changed files with 30 additions and 13 deletions

View File

@ -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;

View File

@ -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<double>::epsilon();")); // #6195
ASSERT_EQUALS("ab::c(de::(<=return", testAst("return a::b(c) <= d<double>::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<int> && 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<bool> { };"));
ASSERT_NO_THROW(testAst("class C : public ::a::b<bool> { };"));
ASSERT_EQUALS("AB: abc+=", testAst("struct A : public B<C*> { void f() { a=b+c; } };"));
ASSERT_EQUALS("xfts(=", testAst("; auto x = f(ts...);"));