Create a symbol database
This commit is contained in:
parent
bb7484945a
commit
0bb07e6947
1237
lib/checkclass.cpp
1237
lib/checkclass.cpp
File diff suppressed because it is too large
Load Diff
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "check.h"
|
||||
#include "settings.h"
|
||||
#include <map>
|
||||
|
||||
class Token;
|
||||
|
||||
|
@ -39,9 +40,9 @@ public:
|
|||
{ }
|
||||
|
||||
/** @brief This constructor is used when running checks. */
|
||||
CheckClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
||||
: Check(tokenizer, settings, errorLogger)
|
||||
{ }
|
||||
CheckClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger);
|
||||
|
||||
~CheckClass();
|
||||
|
||||
/** @brief Run checks on the normal token list */
|
||||
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
||||
|
@ -145,6 +146,58 @@ private:
|
|||
Var& operator=(const Var&); // disallow assignments
|
||||
};
|
||||
|
||||
enum AccessControl { Public, Protected, Private };
|
||||
|
||||
struct Func
|
||||
{
|
||||
enum Type { Constructor, CopyConstructor, OperatorEqual, Destructor, Function };
|
||||
|
||||
Func()
|
||||
: tokenDef(NULL),
|
||||
token(NULL),
|
||||
access(Public),
|
||||
hasBody(false),
|
||||
isInline(false),
|
||||
isConst(false),
|
||||
isVirtual(false),
|
||||
isStatic(false),
|
||||
isOperator(false),
|
||||
type(Function)
|
||||
{
|
||||
}
|
||||
|
||||
const Token *tokenDef; // function name token in class definition
|
||||
const Token *token; // function name token in implementation
|
||||
AccessControl access; // public/protected/private
|
||||
bool hasBody; // has implementation
|
||||
bool isInline; // implementation in class definition
|
||||
bool isConst; // is const
|
||||
bool isVirtual; // is virtual
|
||||
bool isStatic; // is static
|
||||
bool isOperator; // is operator
|
||||
Type type; // constructor, destructor, ...
|
||||
};
|
||||
|
||||
struct SpaceInfo
|
||||
{
|
||||
bool isNamespace;
|
||||
std::string className;
|
||||
const Token *classDef; // class/struct/namespace token
|
||||
const Token *classStart; // '{' token
|
||||
const Token *classEnd; // '}' token
|
||||
unsigned int numConstructors;
|
||||
std::list<Func> functionList;
|
||||
Var *varlist;
|
||||
std::vector<std::string> derivedFrom;
|
||||
SpaceInfo *nest;
|
||||
AccessControl access;
|
||||
};
|
||||
|
||||
/** @brief Information about all namespaces/classes/structrues */
|
||||
std::multimap<std::string, SpaceInfo *> spaceInfoMMap;
|
||||
|
||||
bool argsMatch(const Token *first, const Token *second, const std::string &path, unsigned int depth) const;
|
||||
|
||||
/**
|
||||
* @brief parse a scope for a constructor or member function and set the "init" flags in the provided varlist
|
||||
* @param tok1 pointer to class declaration
|
||||
|
@ -163,21 +216,12 @@ private:
|
|||
*/
|
||||
Var *getVarList(const Token *tok1);
|
||||
|
||||
bool sameFunc(int nest, const Token *firstEnd, const Token *secondEnd);
|
||||
bool isMemberFunc(const Token *tok);
|
||||
bool isMemberVar(const std::string &classname, const std::vector<std::string> &derivedFrom, const Var *varlist, const Token *tok);
|
||||
bool checkConstFunc(const std::string &classname, const std::vector<std::string> &derivedFrom, const Var *varlist, const Token *tok);
|
||||
|
||||
/** @brief check if this function is virtual in the base classes */
|
||||
bool isVirtual(const std::vector<std::string> &derivedFrom, const Token *functionToken) const;
|
||||
|
||||
/**
|
||||
* @brief Helper function for operatorEqRetRefThis that checks if there are errors
|
||||
* @param tok The "operator" token in a operator=(.. function
|
||||
* @param classname Name of class
|
||||
*/
|
||||
void operatorEqRetRefThis_finderr(const Token *tok, const std::string &classname);
|
||||
|
||||
// Reporting errors..
|
||||
void noConstructorError(const Token *tok, const std::string &classname, bool isStruct);
|
||||
void uninitVarError(const Token *tok, const std::string &classname, const std::string &varname);
|
||||
|
|
|
@ -603,6 +603,16 @@ const Token *Token::findmatch(const Token *tok, const char pattern[], unsigned i
|
|||
return 0;
|
||||
}
|
||||
|
||||
const Token *Token::findmatch(const Token *tok, const char pattern[], const Token *end, unsigned int varId)
|
||||
{
|
||||
for (; tok && tok != end; tok = tok->next())
|
||||
{
|
||||
if (Token::Match(tok, pattern, varId))
|
||||
return tok;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Token::insertToken(const std::string &tokenStr)
|
||||
{
|
||||
Token *newToken = new Token(tokensBack);
|
||||
|
|
|
@ -184,6 +184,7 @@ public:
|
|||
bool isIntegerType() const;
|
||||
|
||||
static const Token *findmatch(const Token *tok, const char pattern[], unsigned int varId = 0);
|
||||
static const Token *findmatch(const Token *tok, const char pattern[], const Token *end, unsigned int varId = 0);
|
||||
|
||||
/**
|
||||
* Needle is build from multiple alternatives. If one of
|
||||
|
|
|
@ -98,6 +98,7 @@ private:
|
|||
TEST_CASE(operatorEqToSelf5); // ticket # 1233
|
||||
TEST_CASE(operatorEqToSelf6); // ticket # 1550
|
||||
TEST_CASE(memsetOnStruct);
|
||||
TEST_CASE(memsetVector);
|
||||
TEST_CASE(memsetOnClass);
|
||||
|
||||
TEST_CASE(this_subtraction); // warn about "this-x"
|
||||
|
@ -271,7 +272,7 @@ private:
|
|||
"class A\n"
|
||||
"{\n"
|
||||
"public:\n"
|
||||
" A & operator=(const A &)\n"
|
||||
" A & operator=(const A &);\n"
|
||||
"};\n"
|
||||
"A & A::operator=(const A &a) { return a; }\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (style) 'operator=' should return reference to self\n", errout.str());
|
||||
|
@ -280,7 +281,7 @@ private:
|
|||
"class A\n"
|
||||
"{\n"
|
||||
"public:\n"
|
||||
" A & operator=(const A &a)\n"
|
||||
" A & operator=(const A &a);\n"
|
||||
"};\n"
|
||||
"A & A::operator=(const A &a) { return a; }\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (style) 'operator=' should return reference to self\n", errout.str());
|
||||
|
@ -351,7 +352,7 @@ private:
|
|||
"{\n"
|
||||
" szp &operator =(int *other);\n"
|
||||
"};\n"
|
||||
"szp &szp::operator =(int *other) {};");
|
||||
"szp &szp::operator =(int *other) {}");
|
||||
ASSERT_EQUALS("[test.cpp:5]: (style) 'operator=' should return reference to self\n", errout.str());
|
||||
}
|
||||
|
||||
|
@ -2557,7 +2558,7 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// functions with a function call can't be const..
|
||||
checkConst("class foo\n"
|
||||
checkConst("class Fred\n"
|
||||
"{\n"
|
||||
"public:\n"
|
||||
" int x;\n"
|
||||
|
@ -2567,7 +2568,7 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// static functions can't be const..
|
||||
checkConst("class foo\n"
|
||||
checkConst("class Fred\n"
|
||||
"{\n"
|
||||
"public:\n"
|
||||
" static unsigned get();\n"
|
||||
|
@ -2578,7 +2579,7 @@ private:
|
|||
// assignment to variable can't be const
|
||||
checkConst("class Fred {\n"
|
||||
" std::string s;\n"
|
||||
" void foo()\n"
|
||||
" void foo();\n"
|
||||
"};\n"
|
||||
"void Fred::foo() { s = ""; }");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
@ -2628,7 +2629,7 @@ private:
|
|||
" std::string s;\n"
|
||||
" void foo(std::string & a, std::string & b);\n"
|
||||
"};\n"
|
||||
"void foo(std::string & a, std::string & b) { a = s; s = b; }");
|
||||
"void Fred::foo(std::string & a, std::string & b) { a = s; s = b; }");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// assignment to function argument pointer can be const
|
||||
|
@ -2750,8 +2751,8 @@ private:
|
|||
" };\n"
|
||||
" };\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) The function 'Fred::B::getB' can be const\n"
|
||||
"[test.cpp:7]: (style) The function 'Fred::B::A::getA' can be const\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:7]: (style) The function 'Fred::B::A::getA' can be const\n"
|
||||
"[test.cpp:4]: (style) The function 'Fred::B::getB' can be const\n", errout.str());
|
||||
|
||||
checkConst("class Fred {\n"
|
||||
" class B {\n"
|
||||
|
@ -2765,8 +2766,8 @@ private:
|
|||
" };\n"
|
||||
" int B::getB() { return b; }\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:11] -> [test.cpp:4]: (style) The function 'Fred::B::getB' can be const\n"
|
||||
"[test.cpp:9] -> [test.cpp:7]: (style) The function 'Fred::B::A::getA' can be const\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:7]: (style) The function 'Fred::B::A::getA' can be const\n"
|
||||
"[test.cpp:11] -> [test.cpp:4]: (style) The function 'Fred::B::getB' can be const\n", errout.str());
|
||||
|
||||
checkConst("class Fred {\n"
|
||||
" class B {\n"
|
||||
|
@ -2780,8 +2781,8 @@ private:
|
|||
"};\n"
|
||||
"int Fred::B::A::getA() { return a; }\n"
|
||||
"int Fred::B::getB() { return b; }\n");
|
||||
ASSERT_EQUALS("[test.cpp:12] -> [test.cpp:4]: (style) The function 'Fred::B::getB' can be const\n"
|
||||
"[test.cpp:11] -> [test.cpp:7]: (style) The function 'Fred::B::A::getA' can be const\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:11] -> [test.cpp:7]: (style) The function 'Fred::B::A::getA' can be const\n"
|
||||
"[test.cpp:12] -> [test.cpp:4]: (style) The function 'Fred::B::getB' can be const\n", errout.str());
|
||||
}
|
||||
|
||||
// operator< can often be const
|
||||
|
|
|
@ -771,7 +771,7 @@ private:
|
|||
" C();\n"
|
||||
" struct D {\n"
|
||||
" struct E { };\n"
|
||||
" E d;\n"
|
||||
" struct E d;\n"
|
||||
" D(const E &);\n"
|
||||
" };\n"
|
||||
" int c;\n"
|
||||
|
|
Loading…
Reference in New Issue