Refactoring: Added CheckClass::isMemberFunc

This commit is contained in:
Robert Reif 2010-03-28 11:46:42 +02:00 committed by Daniel Marjamäki
parent 16124ce646
commit 2dc4222c9a
3 changed files with 109 additions and 34 deletions

View File

@ -1578,40 +1578,7 @@ void CheckClass::checkConst()
continue;
// member function?
if (Token::Match(tok2, "%type% %var% (") ||
Token::Match(tok2, "%type% %type% %var% (") ||
Token::Match(tok2, "%type% < %type% > %var% (") ||
Token::Match(tok2, "%type% < %type% , %type% > %var% (") ||
Token::Match(tok2, "%type% :: %type% %var% (") ||
Token::Match(tok2, "%type% :: %type% < %type% > %var% (") ||
Token::Match(tok2, "%type% :: %type% < %type% , %type% > %var% (") ||
Token::Match(tok2, "%type% :: %type% < %type% :: %type% < %type% > , %type% > %var% (") ||
Token::Match(tok2, "%type% < %type% < %type% > , %type% > %var% (") ||
Token::Match(tok2, "%type% :: %type% < %type% , %type% :: %type% < %type% > > %var% (") ||
Token::Match(tok2, "%type% < %type% , %type% < %type% > > %var% (") ||
Token::Match(tok2, "%type% :: %type% < %type% :: %type% < %type% > , %type% :: %type% < %type% > > %var% (") ||
Token::Match(tok2, "%type% < %type% < %type% > , %type% < %type% > > %var% (") ||
Token::Match(tok2, "%type% :: %type% < %type% :: %type% < %type% , %type% > , %type% > %var% (") ||
Token::Match(tok2, "%type% < %type% < %type% , %type% > , %type% > %var% (") ||
Token::Match(tok2, "%type% :: %type% < %type% , %type% :: %type% < %type% , %type% > > %var% (") ||
Token::Match(tok2, "%type% < %type% , %type% < %type% , %type% > > %var% (") ||
Token::Match(tok2, "const %type% < %type% > &|* %var% (") ||
Token::Match(tok2, "const %type% < %type% , %type% > &|* %var% (") ||
Token::Match(tok2, "const %type% &|* %var% (") ||
Token::Match(tok2, "const %type% :: %type% &|*| %var% (") ||
Token::Match(tok2, "const %type% :: %type% < %type% > *|& %var% (") ||
Token::Match(tok2, "const %type% :: %type% < %type% , %type% > *|& %var% (") ||
Token::Match(tok2, "const %type% :: %type% < %type% :: %type% < %type% > , %type% > *|& %var% (") ||
Token::Match(tok2, "const %type% < %type% < %type% > , %type% > *|& %var% (") ||
Token::Match(tok2, "const %type% :: %type% < %type% , %type% :: %type% < %type% > > *|& %var% (") ||
Token::Match(tok2, "const %type% < %type% , %type% < %type% > > *|& %var% (") ||
Token::Match(tok2, "const %type% :: %type% < %type% :: %type% < %type% > , %type% :: %type% < %type% > > *|& %var% (") ||
Token::Match(tok2, "const %type% < %type% < %type% > , %type% < %type% > > *|& %var% (") ||
Token::Match(tok2, "const %type% :: %type% < %type% :: %type% < %type% , %type% > , %type% > *|& %var% (") ||
Token::Match(tok2, "const %type% < %type% < %type% , %type% > , %type% > *|& %var% (") ||
Token::Match(tok2, "const %type% :: %type% < %type% , %type% :: %type% < %type% , %type% > > *|& %var% (") ||
Token::Match(tok2, "const %type% < %type% , %type% < %type% , %type% > > *|& %var% (") ||
Token::Match(tok2, "%type% operator %any% ("))
if (isMemberFunc(tok2))
{
// goto function name..
while (tok2->next()->str() != "(")
@ -1794,6 +1761,90 @@ bool CheckClass::sameFunc(int nest, const Token *firstEnd, const Token *secondEn
return true;
}
// A const member function can return either a copy of or
// a const reference or pointer to something.
// Is this a member function with these signatures:
// type var ( returns a copy of something
// const type var ( returns a const copy of something
// const type & var ( returns a const reference to something
// const type * var ( returns a const pointer to something
// type operator any ( returns a copy of something
// const type operator any ( returns a const copy of something
// const type & operator any ( returns a const reference to something
// const type * operator any ( returns a const pointer to something
// Type can be anything from a standard type to a complex template.
bool CheckClass::isMemberFunc(const Token *tok)
{
bool isConst = false;
if (tok->str() == "const")
{
isConst = true;
tok = tok->next();
}
if (Token::Match(tok, "%type%"))
{
tok = tok->next();
if (Token::Match(tok, "%var% ("))
return true;
else if (Token::Match(tok, "operator %any% ("))
return true;
else if (Token::Match(tok, "%type%"))
tok = tok->next();
while (Token::Match(tok, ":: %type%"))
tok = tok->tokAt(2);
// template with parameter(s)?
if (Token::Match(tok, "< %type%"))
{
unsigned int level = 1;
tok = tok->tokAt(2);
while (tok)
{
if (tok->str() == "<")
level++;
else if (tok->str() == ">")
{
level--;
if (level == 0)
{
tok = tok->next();
break;
}
}
tok = tok->next();
}
}
// template with default type
else if (Token::Match(tok, "< >"))
tok = tok->tokAt(2);
// operator something
else if (Token::Match(tok, "operator %any% ("))
return true;
if (isConst)
{
while (Token::Match(tok, "*|&"))
{
tok = tok->next();
if (tok->str() == "const")
tok = tok->next();
}
}
if (Token::Match(tok, "%var% ("))
return true;
}
return false;
}
bool CheckClass::isMemberVar(const Var *varlist, const Token *tok)
{
while (tok->previous() && !Token::Match(tok->previous(), "}|{|;|public:|protected:|private:|return|:|?"))

View File

@ -164,6 +164,7 @@ private:
void checkConstructors(const Token *tok1, const std::string &funcname, bool hasPrivateConstructor, bool isStruct);
bool sameFunc(int nest, const Token *firstEnd, const Token *secondEnd);
bool isMemberFunc(const Token *tok);
bool isMemberVar(const Var *varlist, const Token *tok);
bool checkConstFunc(const Var *varlist, const Token *tok);

View File

@ -2646,6 +2646,29 @@ private:
ASSERT_EQUALS("", errout.str());
checkConst("class A {\n"
"public:\n"
" int * const * foo() { return &x; }\n"
"private:\n"
" const int * x;\n"
"}");
ASSERT_EQUALS("", errout.str());
checkConst("class A {\n"
"public:\n"
" const int ** foo() { return &x; }\n"
"private:\n"
" const int * x;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) The function 'A::foo' can be const\n", errout.str());
checkConst("class A {\n"
"public:\n"
" const int * const * foo() { return &x; }\n"
"private:\n"
" const int * x;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) The function 'A::foo' can be const\n", errout.str());
}
// increment/decrement => not const