Fixed #6538 (Symboldatabase: improve isFunction)
This commit is contained in:
parent
26c2c4a824
commit
d7ef89bbe6
|
@ -1288,6 +1288,53 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
|||
(tok->previous()->isName() || tok->strAt(-1) == ">" || tok->strAt(-1) == "&" || tok->strAt(-1) == "*" || // Either a return type in front of tok
|
||||
tok->strAt(-1) == "::" || tok->strAt(-1) == "~" || // or a scope qualifier in front of tok
|
||||
outerScope->isClassOrStruct())) { // or a ctor/dtor
|
||||
|
||||
const Token* tok1 = tok->previous();
|
||||
|
||||
// skip over destructor "~"
|
||||
if (tok1->str() == "~")
|
||||
tok1 = tok1->previous();
|
||||
|
||||
// skip over qualification
|
||||
while (Token::simpleMatch(tok1, "::")) {
|
||||
if (Token::Match(tok1->tokAt(-1), "%name%"))
|
||||
tok1 = tok1->tokAt(-2);
|
||||
else
|
||||
tok1 = tok1->tokAt(-1);
|
||||
}
|
||||
|
||||
// skip over pointers and references
|
||||
while (Token::Match(tok1, "[*&]"))
|
||||
tok1 = tok1->tokAt(-1);
|
||||
|
||||
// skip over template
|
||||
if (tok1 && tok1->str() == ">")
|
||||
tok1 = tok1->link()->previous();
|
||||
|
||||
// function can't have number or variable as return type
|
||||
if (tok1 && (tok1->isNumber() || tok1->varId()))
|
||||
return false;
|
||||
|
||||
// skip over return type
|
||||
if (Token::Match(tok1, "%name%"))
|
||||
tok1 = tok1->previous();
|
||||
|
||||
// skip over qualification
|
||||
while (Token::simpleMatch(tok1, "::")) {
|
||||
if (Token::Match(tok1->tokAt(-1), "%name%"))
|
||||
tok1 = tok1->tokAt(-2);
|
||||
else
|
||||
tok1 = tok1->tokAt(-1);
|
||||
}
|
||||
|
||||
// skip over modifiers and other stuff
|
||||
while (Token::Match(tok1, "const|static|extern|template|virtual|struct|class"))
|
||||
tok1 = tok1->previous();
|
||||
|
||||
// should be at a sequence point if this is a function
|
||||
if (!Token::Match(tok1, ">|{|}|;|public:|protected:|private:") && tok1)
|
||||
return false;
|
||||
|
||||
const Token* tok2 = tok->next()->link()->next();
|
||||
if (tok2 &&
|
||||
(Token::Match(tok2, "const| ;|{|=") ||
|
||||
|
|
|
@ -420,11 +420,11 @@ private:
|
|||
|
||||
ASSERT_THROW(checkCode("class Foo {}; class Bar : public Foo"), InternalError);
|
||||
|
||||
ASSERT_THROW(checkCode("YY_DECL { switch (yy_act) {\n"
|
||||
checkCode("YY_DECL { switch (yy_act) {\n"
|
||||
" case 65: YY_BREAK\n"
|
||||
" case YY_STATE_EOF(block):\n"
|
||||
" yyterminate(); \n"
|
||||
"} }"), InternalError); // #5663
|
||||
"} }"); // #5663
|
||||
}
|
||||
|
||||
void garbageAST() {
|
||||
|
|
|
@ -3020,7 +3020,7 @@ private:
|
|||
ASSERT_EQUALS("[test.cpp:4]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.\n", errout.str());
|
||||
|
||||
// #5707
|
||||
check("extern int i,j\n"
|
||||
check("extern int i,j;\n"
|
||||
"int foo() {\n"
|
||||
" switch(i) {\n"
|
||||
" default: j=1; break;\n"
|
||||
|
|
|
@ -228,6 +228,7 @@ private:
|
|||
TEST_CASE(symboldatabase48); // #6417
|
||||
TEST_CASE(symboldatabase49); // #6424
|
||||
TEST_CASE(symboldatabase50); // #6432
|
||||
TEST_CASE(symboldatabase51); // #6538
|
||||
|
||||
TEST_CASE(isImplicitlyVirtual);
|
||||
|
||||
|
@ -2128,6 +2129,22 @@ private:
|
|||
ASSERT_EQUALS(true, db && f && f->function() && f->function()->isConstructor());
|
||||
}
|
||||
|
||||
void symboldatabase51() { // #6538
|
||||
GET_SYMBOL_DB("static const float f1 = 2 * foo1(a, b);\n"
|
||||
"static const float f2 = 2 * ::foo2(a, b);\n"
|
||||
"static const float f3 = 2 * std::foo3(a, b);\n"
|
||||
"static const float f4 = c * foo4(a, b);\n"
|
||||
"static const int i1 = 2 & foo5(a, b);\n");
|
||||
ASSERT(db != nullptr);
|
||||
if (db) {
|
||||
ASSERT(findFunctionByName("foo1", &db->scopeList.front()) == nullptr);
|
||||
ASSERT(findFunctionByName("foo2", &db->scopeList.front()) == nullptr);
|
||||
ASSERT(findFunctionByName("foo3", &db->scopeList.front()) == nullptr);
|
||||
ASSERT(findFunctionByName("foo4", &db->scopeList.front()) == nullptr);
|
||||
ASSERT(findFunctionByName("foo5", &db->scopeList.front()) == nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void isImplicitlyVirtual() {
|
||||
{
|
||||
GET_SYMBOL_DB("class Base {\n"
|
||||
|
|
|
@ -418,7 +418,7 @@ private:
|
|||
"class A\n"
|
||||
"{\n"
|
||||
"public:\n"
|
||||
" A()\n"
|
||||
" A();\n"
|
||||
" void a();\n"
|
||||
"private:\n"
|
||||
" void b();\n"
|
||||
|
|
Loading…
Reference in New Issue