diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index f5ffa4e1604..340b8e246e0 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -714,7 +714,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } // function prototype? else if (declEnd && declEnd->str() == ";") { - if (tok->astParent() && tok->astParent()->str() == "::" && + if ((Token::simpleMatch(tok->tokAt(-1), "::") || (tok->tokAt(-1) && Token::simpleMatch(tok->tokAt(-2), ":: ~"))) && Token::Match(declEnd->previous(), "default|delete")) { addClassFunction(scope, tok, argStart); continue; diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 1138b410ddd..aca098a99ae 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1787,8 +1787,9 @@ static Token * createAstAtToken(Token *tok) } } - if (Token::Match(tok, "%type% %name%|*|&|&&|::") && !Token::Match(tok, "return|new|delete")) { - int typecount = 0; + if ((Token::Match(tok, "%type% %name%|*|&|&&|::") && !Token::Match(tok, "return|new|delete")) || + (Token::Match(tok, ":: %type%") && !tok->next()->isKeyword())) { + int typecount = tok->str() == "::" ? 1 : 0; Token *typetok = tok; while (Token::Match(typetok, "%type%|::|*|&|&&|<")) { if (typetok->isName() && !Token::simpleMatch(typetok->previous(), "::")) @@ -1811,7 +1812,7 @@ static Token * createAstAtToken(Token *tok) !Token::Match(tok, "return|throw") && Token::Match(typetok->previous(), "%name% ( !!*") && typetok->previous()->varId() == 0 && - !typetok->previous()->isKeyword() && + (!typetok->previous()->isKeyword() || typetok->previous()->isOperatorKeyword()) && (skipMethodDeclEnding(typetok->link()) || Token::Match(typetok->link(), ") ;|{"))) return typetok; } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index eff4a8d44f2..5cd508c5359 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -425,6 +425,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(astrvaluedecl); TEST_CASE(astorkeyword); TEST_CASE(astenumdecl); + TEST_CASE(astfuncdecl); TEST_CASE(startOfExecutableScope); @@ -6400,8 +6401,13 @@ class TestTokenizer : public TestFixture { Z3 }; + enum class ListSimplification : std::uint8_t { + Partial, + Full + }; + template - std::string testAst(const char (&data)[size], AstStyle style = AstStyle::Simple) { + std::string testAst(const char (&data)[size], AstStyle style = AstStyle::Simple, ListSimplification ls = ListSimplification::Partial) { // tokenize given code.. TokenList tokenlist{settings0, Standards::Language::CPP}; tokenlist.appendFileIfNew("test.cpp"); @@ -6409,13 +6415,17 @@ class TestTokenizer : public TestFixture { return "ERROR"; TokenizerTest tokenizer(std::move(tokenlist), *this); - tokenizer.combineStringAndCharLiterals(); - tokenizer.combineOperators(); - tokenizer.simplifySpaceshipOperator(); - tokenizer.createLinks(); - tokenizer.createLinks2(); - tokenizer.simplifyCAlternativeTokens(); - tokenizer.list.front()->assignIndexes(); + if (ls == ListSimplification::Partial) { + tokenizer.combineStringAndCharLiterals(); + tokenizer.combineOperators(); + tokenizer.simplifySpaceshipOperator(); + tokenizer.createLinks(); + tokenizer.createLinks2(); + tokenizer.simplifyCAlternativeTokens(); + tokenizer.list.front()->assignIndexes(); + } else { // Full + tokenizer.simplifyTokens1(""); + } // set varid.. for (Token *tok = tokenizer.list.front(); tok; tok = tok->next()) { @@ -7408,6 +7418,11 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("A0U=", testAst("enum myclass : unsigned char { A = 0U, };")); } + void astfuncdecl() { + ASSERT_EQUALS("", testAst("bool operator==(const S& a, const S& b);", AstStyle::Simple, ListSimplification::Full)); + ASSERT_EQUALS("", testAst("::int32_t f();")); + } + #define isStartOfExecutableScope(offset, code) isStartOfExecutableScope_(offset, code, __FILE__, __LINE__) template bool isStartOfExecutableScope_(int offset, const char (&code)[size], const char* file, int line) {