Create a symbol database

This commit is contained in:
Robert Reif 2010-07-26 16:46:37 +02:00 committed by Daniel Marjamäki
parent bb7484945a
commit 0bb07e6947
6 changed files with 541 additions and 804 deletions

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@
#include "check.h" #include "check.h"
#include "settings.h" #include "settings.h"
#include <map>
class Token; class Token;
@ -39,9 +40,9 @@ public:
{ } { }
/** @brief This constructor is used when running checks. */ /** @brief This constructor is used when running checks. */
CheckClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) CheckClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger);
: Check(tokenizer, settings, errorLogger)
{ } ~CheckClass();
/** @brief Run checks on the normal token list */ /** @brief Run checks on the normal token list */
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
@ -145,6 +146,58 @@ private:
Var& operator=(const Var&); // disallow assignments 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 * @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 * @param tok1 pointer to class declaration
@ -163,21 +216,12 @@ private:
*/ */
Var *getVarList(const Token *tok1); 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 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); 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 */ /** @brief check if this function is virtual in the base classes */
bool isVirtual(const std::vector<std::string> &derivedFrom, const Token *functionToken) const; 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.. // Reporting errors..
void noConstructorError(const Token *tok, const std::string &classname, bool isStruct); void noConstructorError(const Token *tok, const std::string &classname, bool isStruct);
void uninitVarError(const Token *tok, const std::string &classname, const std::string &varname); void uninitVarError(const Token *tok, const std::string &classname, const std::string &varname);

View File

@ -603,6 +603,16 @@ const Token *Token::findmatch(const Token *tok, const char pattern[], unsigned i
return 0; 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) void Token::insertToken(const std::string &tokenStr)
{ {
Token *newToken = new Token(tokensBack); Token *newToken = new Token(tokensBack);

View File

@ -184,6 +184,7 @@ public:
bool isIntegerType() const; 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[], 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 * Needle is build from multiple alternatives. If one of

View File

@ -98,6 +98,7 @@ private:
TEST_CASE(operatorEqToSelf5); // ticket # 1233 TEST_CASE(operatorEqToSelf5); // ticket # 1233
TEST_CASE(operatorEqToSelf6); // ticket # 1550 TEST_CASE(operatorEqToSelf6); // ticket # 1550
TEST_CASE(memsetOnStruct); TEST_CASE(memsetOnStruct);
TEST_CASE(memsetVector);
TEST_CASE(memsetOnClass); TEST_CASE(memsetOnClass);
TEST_CASE(this_subtraction); // warn about "this-x" TEST_CASE(this_subtraction); // warn about "this-x"
@ -271,7 +272,7 @@ private:
"class A\n" "class A\n"
"{\n" "{\n"
"public:\n" "public:\n"
" A & operator=(const A &)\n" " A & operator=(const A &);\n"
"};\n" "};\n"
"A & A::operator=(const A &a) { return a; }\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()); ASSERT_EQUALS("[test.cpp:6]: (style) 'operator=' should return reference to self\n", errout.str());
@ -280,7 +281,7 @@ private:
"class A\n" "class A\n"
"{\n" "{\n"
"public:\n" "public:\n"
" A & operator=(const A &a)\n" " A & operator=(const A &a);\n"
"};\n" "};\n"
"A & A::operator=(const A &a) { return a; }\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()); ASSERT_EQUALS("[test.cpp:6]: (style) 'operator=' should return reference to self\n", errout.str());
@ -351,7 +352,7 @@ private:
"{\n" "{\n"
" szp &operator =(int *other);\n" " szp &operator =(int *other);\n"
"};\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()); ASSERT_EQUALS("[test.cpp:5]: (style) 'operator=' should return reference to self\n", errout.str());
} }
@ -2557,7 +2558,7 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// functions with a function call can't be const.. // functions with a function call can't be const..
checkConst("class foo\n" checkConst("class Fred\n"
"{\n" "{\n"
"public:\n" "public:\n"
" int x;\n" " int x;\n"
@ -2567,7 +2568,7 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// static functions can't be const.. // static functions can't be const..
checkConst("class foo\n" checkConst("class Fred\n"
"{\n" "{\n"
"public:\n" "public:\n"
" static unsigned get();\n" " static unsigned get();\n"
@ -2578,7 +2579,7 @@ private:
// assignment to variable can't be const // assignment to variable can't be const
checkConst("class Fred {\n" checkConst("class Fred {\n"
" std::string s;\n" " std::string s;\n"
" void foo()\n" " void foo();\n"
"};\n" "};\n"
"void Fred::foo() { s = ""; }"); "void Fred::foo() { s = ""; }");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
@ -2628,7 +2629,7 @@ private:
" std::string s;\n" " std::string s;\n"
" void foo(std::string & a, std::string & b);\n" " void foo(std::string & a, std::string & b);\n"
"};\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()); ASSERT_EQUALS("", errout.str());
// assignment to function argument pointer can be const // assignment to function argument pointer can be const
@ -2750,8 +2751,8 @@ private:
" };\n" " };\n"
" };\n" " };\n"
"};"); "};");
ASSERT_EQUALS("[test.cpp:4]: (style) The function 'Fred::B::getB' can be const\n" ASSERT_EQUALS("[test.cpp:7]: (style) The function 'Fred::B::A::getA' can be const\n"
"[test.cpp:7]: (style) The function 'Fred::B::A::getA' can be const\n", errout.str()); "[test.cpp:4]: (style) The function 'Fred::B::getB' can be const\n", errout.str());
checkConst("class Fred {\n" checkConst("class Fred {\n"
" class B {\n" " class B {\n"
@ -2765,8 +2766,8 @@ private:
" };\n" " };\n"
" int B::getB() { return b; }\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" ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:7]: (style) The function 'Fred::B::A::getA' can be const\n"
"[test.cpp:9] -> [test.cpp:7]: (style) The function 'Fred::B::A::getA' can be const\n", errout.str()); "[test.cpp:11] -> [test.cpp:4]: (style) The function 'Fred::B::getB' can be const\n", errout.str());
checkConst("class Fred {\n" checkConst("class Fred {\n"
" class B {\n" " class B {\n"
@ -2780,8 +2781,8 @@ private:
"};\n" "};\n"
"int Fred::B::A::getA() { return a; }\n" "int Fred::B::A::getA() { return a; }\n"
"int Fred::B::getB() { return b; }\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" ASSERT_EQUALS("[test.cpp:11] -> [test.cpp:7]: (style) The function 'Fred::B::A::getA' can be const\n"
"[test.cpp:11] -> [test.cpp:7]: (style) The function 'Fred::B::A::getA' can be const\n", errout.str()); "[test.cpp:12] -> [test.cpp:4]: (style) The function 'Fred::B::getB' can be const\n", errout.str());
} }
// operator< can often be const // operator< can often be const

View File

@ -771,7 +771,7 @@ private:
" C();\n" " C();\n"
" struct D {\n" " struct D {\n"
" struct E { };\n" " struct E { };\n"
" E d;\n" " struct E d;\n"
" D(const E &);\n" " D(const E &);\n"
" };\n" " };\n"
" int c;\n" " int c;\n"