diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 6d723b60246..e05001b6896 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2578,8 +2578,6 @@ Function::Function(const Token *tok, // constructor of any kind else type = FunctionType::eConstructor; - - isExplicit(tokenDef->strAt(-1) == "explicit" || tokenDef->strAt(-2) == "explicit"); } const Token *tok1 = setFlags(tok, scope); @@ -2653,6 +2651,14 @@ Function::Function(const Token *tok, isInline(true); hasBody(true); } + + for (tok = tokenDef->previous(); Token::Match(tok, "&|&&|*|::|)|]|%name%"); tok = tok->previous()) { + // We should set other keywords here as well + if (tok->str() == "explicit") + isExplicit(true); + if (tok->str() == "]" || tok->str() == ")") + tok = tok->link(); + } } Function::Function(const Token *tokenDef, const std::string &clangType) diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index ca23ecea050..9aaa7359abf 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -430,6 +430,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(symboldatabase109); // #13553 TEST_CASE(symboldatabase110); TEST_CASE(symboldatabase111); // [[fallthrough]] + TEST_CASE(symboldatabase112); // explicit operator TEST_CASE(createSymbolDatabaseFindAllScopes1); TEST_CASE(createSymbolDatabaseFindAllScopes2); @@ -5841,6 +5842,17 @@ class TestSymbolDatabase : public TestFixture { ASSERT(case3 && case3->isAttributeFallthrough()); } + void symboldatabase112() { // explicit operator + GET_SYMBOL_DB("class S {\n" + " explicit constexpr operator bool() const noexcept { return ptr_ != nullptr; }\n" + "private:\n" + " void *ptr_{nullptr};\n" + "};\n"); + const Token *f = db ? Token::findsimplematch(tokenizer.tokens(), "operatorbool") : nullptr; + ASSERT(f != nullptr); + ASSERT(f && f->function() && f->function()->isExplicit()); + } + void createSymbolDatabaseFindAllScopes1() { GET_SYMBOL_DB("void f() { union {int x; char *p;} a={0}; }"); ASSERT(db->scopeList.size() == 3);