Fixed handling of member function pointers in setVarId and SymbolDatabase (#4577)
This commit is contained in:
parent
83f4657e69
commit
9c921ab657
|
@ -2563,6 +2563,8 @@ static const Token* skipPointers(const Token* tok)
|
|||
{
|
||||
while (Token::Match(tok, "*|&|&&") || (tok && tok->str() == "(" && Token::Match(tok->link()->next(), "(|["))) {
|
||||
tok = tok->next();
|
||||
if (tok->strAt(-1) == "(" && Token::Match(tok, "%type% ::"))
|
||||
tok = tok->tokAt(2);
|
||||
}
|
||||
|
||||
return tok;
|
||||
|
|
|
@ -2563,7 +2563,7 @@ void Tokenizer::setVarId()
|
|||
if (tok2->link()) {
|
||||
if (tok2->str() == "{")
|
||||
tok2 = tok2->link();
|
||||
else if (tok2->str() == "(")
|
||||
else if (tok2->str() == "(" && tok2->link()->strAt(1) != "(")
|
||||
tok2 = tok2->link();
|
||||
}
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ private:
|
|||
TEST_CASE(hasMissingInlineClassFunctionReturningFunctionPointer);
|
||||
TEST_CASE(hasClassFunctionReturningFunctionPointer);
|
||||
TEST_CASE(complexFunctionArrayPtr);
|
||||
TEST_CASE(pointerToMemberFunction);
|
||||
TEST_CASE(hasSubClassConstructor);
|
||||
TEST_CASE(testConstructors);
|
||||
TEST_CASE(functionDeclarationTemplate);
|
||||
|
@ -873,6 +874,21 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
}
|
||||
|
||||
void pointerToMemberFunction() {
|
||||
GET_SYMBOL_DB("bool (A::*pFun)();"); // Pointer to member function of A, returning bool and taking no parameters
|
||||
|
||||
ASSERT(db != nullptr);
|
||||
|
||||
if (db) {
|
||||
ASSERT_EQUALS(1, db->getVariableListSize() - 1);
|
||||
ASSERT_EQUALS(true, db->getVariableFromVarId(1) != nullptr);
|
||||
if (db->getVariableFromVarId(1))
|
||||
ASSERT_EQUALS("pFun", db->getVariableFromVarId(1)->name());
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
}
|
||||
|
||||
void hasSubClassConstructor() {
|
||||
GET_SYMBOL_DB("class Foo { class Sub; }; class Foo::Sub { Sub() {} };");
|
||||
ASSERT(db != nullptr);
|
||||
|
|
|
@ -324,6 +324,7 @@ private:
|
|||
TEST_CASE(varidclass13);
|
||||
TEST_CASE(varidclass14);
|
||||
TEST_CASE(varidclass15); // initializer list
|
||||
TEST_CASE(varidclass16); // #4577
|
||||
TEST_CASE(varid_classnameshaddowsvariablename) // #3990
|
||||
|
||||
TEST_CASE(file1);
|
||||
|
@ -5163,6 +5164,31 @@ private:
|
|||
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
|
||||
}
|
||||
|
||||
void varidclass16() {
|
||||
const char code[] = "struct A;\n"
|
||||
"typedef bool (A::* FuncPtr)();\n"
|
||||
"struct A {\n"
|
||||
" FuncPtr pFun;\n"
|
||||
" void setPFun(int mode);\n"
|
||||
" bool funcNorm();\n"
|
||||
"};\n"
|
||||
"void A::setPFun(int mode) {\n"
|
||||
" pFun = &A::funcNorm;\n"
|
||||
"}";
|
||||
const char expected[] = "\n\n##file 0\n"
|
||||
"1: struct A ;\n"
|
||||
"2:\n"
|
||||
"3: struct A {\n"
|
||||
"4: bool ( A :: * pFun@1 ) ( ) ;\n"
|
||||
"5: void setPFun ( int mode@2 ) ;\n"
|
||||
"6: bool funcNorm ( ) ;\n"
|
||||
"7: } ;\n"
|
||||
"8: void A :: setPFun ( int mode@3 ) {\n"
|
||||
"9: pFun@1 = & A :: funcNorm ;\n"
|
||||
"10: }\n";
|
||||
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
|
||||
}
|
||||
|
||||
void varid_classnameshaddowsvariablename() {
|
||||
const char code[] = "class Data;\n"
|
||||
"void strange_declarated(const Data& Data);\n"
|
||||
|
|
Loading…
Reference in New Issue