Fixed handling of member function pointers in setVarId and SymbolDatabase (#4577)

This commit is contained in:
PKEuS 2014-04-12 11:43:10 +02:00
parent 83f4657e69
commit 9c921ab657
4 changed files with 45 additions and 1 deletions

View File

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

View File

@ -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();
}

View File

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

View File

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