Symbol database: bug fixes. Ticket: #1895

This commit is contained in:
Daniel Marjamäki 2010-08-18 22:42:04 +02:00
parent 0934035fcf
commit cfa7b4906e
7 changed files with 289 additions and 27 deletions

View File

@ -112,6 +112,17 @@ void CheckClass::createSymbolDatabase()
info->access = Protected;
else if (tok->str() == "public:")
info->access = Public;
else if (Token::Match(tok, "public|protected|private %var% :"))
{
if (tok->str() == "private")
info->access = Private;
else if (tok->str() == "protected")
info->access = Protected;
else if (tok->str() == "public")
info->access = Public;
tok = tok->tokAt(2);
}
// function?
else if (((Token::Match(tok, "%var% (") || Token::Match(tok, "operator %any% (")) && tok->previous()->str() != "::") &&
@ -411,8 +422,7 @@ void CheckClass::SpaceInfo::getVarList()
// Get variable list..
const Token *tok1 = classDef;
unsigned int indentlevel = 0;
bool isStruct = tok1->str() == "struct";
bool priv = !isStruct;
AccessControl varaccess = tok1->str() == "struct" ? Public : Private;
for (const Token *tok = tok1; tok; tok = tok->next())
{
if (!tok->next())
@ -434,7 +444,6 @@ void CheckClass::SpaceInfo::getVarList()
// These are automaticly initialized.
if (tok->str() == "__published:")
{
priv = false;
for (; tok; tok = tok->next())
{
if (tok->str() == "{")
@ -449,10 +458,33 @@ void CheckClass::SpaceInfo::getVarList()
}
// "private:" "public:" "protected:" etc
const bool b((tok->str()[0] != ':') && tok->str().find(":") != std::string::npos);
if (b)
priv = bool(tok->str() == "private:");
bool b = false;
if (tok->str() == "public:")
{
varaccess = Public;
b = true;
}
else if (tok->str() == "protected:")
{
varaccess = Protected;
b = true;
}
else if (tok->str() == "private:")
{
varaccess = Private;
b = true;
}
else if (Token::Match(tok, "public|protected|private %var% :"))
{
if (tok->str() == "public")
varaccess = Public;
else if (tok->str() == "protected")
varaccess = Protected;
else if (tok->str() == "private")
varaccess = Private;
tok = tok->tokAt(2);
b = true;
}
// Search for start of statement..
if (! Token::Match(tok, "[;{}]") && ! b)
@ -466,6 +498,25 @@ void CheckClass::SpaceInfo::getVarList()
if (next->str().find(":") != std::string::npos)
continue;
if (Token::Match(next, "public|protected|private %var% :"))
{
if (next->str() == "public")
varaccess = Public;
else if (next->str() == "protected")
varaccess = Protected;
else if (next->str() == "private")
varaccess = Private;
tok = tok->tokAt(2);
continue;
}
// Is it a forward declaration?
if (Token::Match(next, "class|struct|union %var% ;"))
{
tok = tok->tokAt(2);
continue;
}
// Borland C++: Ignore properties..
if (next->str() == "__property")
continue;
@ -583,7 +634,7 @@ void CheckClass::SpaceInfo::getVarList()
check->reportError(vartok, Severity::error, "cppcheckError", "Internal error. CheckClass::SpaceInfo::getVarList found variable \'" + vartok->str() + "\' with varid 0.");
}
varlist.push_back(Var(vartok, false, priv, isMutable, isStatic, isClass));
varlist.push_back(Var(vartok, false, varaccess, isMutable, isStatic, isClass));
}
}
}
@ -954,7 +1005,7 @@ void CheckClass::constructors()
std::list<Var>::const_iterator var;
for (var = info->varlist.begin(); var != info->varlist.end(); ++var)
{
if (var->priv && !var->isClass && !var->isStatic)
if (var->access == Private && !var->isClass && !var->isStatic)
{
noConstructorError(info->classDef, info->className, info->classDef->str() == "struct");
break;

View File

@ -132,10 +132,10 @@ private:
class Var
{
public:
Var(const Token *token_, bool init_ = false, bool priv_ = false, bool mutable_ = false, bool static_ = false, bool class_ = false)
Var(const Token *token_, bool init_ = false, AccessControl access_ = Public, bool mutable_ = false, bool static_ = false, bool class_ = false)
: token(token_),
init(init_),
priv(priv_),
access(access_),
isMutable(mutable_),
isStatic(static_),
isClass(class_)
@ -148,8 +148,8 @@ private:
/** @brief has this variable been initialized? */
bool init;
/** @brief is this variable declared in the private section? */
bool priv;
/** @brief what section is this variable declared in? */
AccessControl access; // public/protected/private
/** @brief is this variable mutable? */
bool isMutable;

View File

@ -1679,9 +1679,6 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
// specify array size..
arraySize();
// simplify bit fields..
simplifyBitfields();
// simplify labels..
labels();
@ -1792,6 +1789,9 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
}
}
// simplify bit fields..
simplifyBitfields();
// Remove __declspec()
simplifyDeclspec();
@ -1801,6 +1801,9 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
// remove __attribute__((?))
simplifyAttribute();
// remove Microsoft MFC..
simplifyMicrosoftMFC();
// typedef..
simplifyTypedef();
@ -1935,7 +1938,10 @@ void Tokenizer::labels()
// simplify label..
if (Token::Match(tok, "[;{}] %var% : %var%"))
tok->tokAt(2)->insertToken(";");
{
if (!Token::Match(tok->next(), "public|protected|private"))
tok->tokAt(2)->insertToken(";");
}
}
}
}
@ -2769,7 +2775,7 @@ void Tokenizer::setVarId()
if (Token::Match(tok, "else|return|typedef|delete|sizeof"))
continue;
if (Token::Match(tok, "const|static|extern|public:|private:|protected:"))
while (Token::Match(tok, "const|static|extern|public:|private:|protected:|;|mutable"))
tok = tok->next();
while (Token::Match(tok, "%var% ::"))
@ -7913,10 +7919,14 @@ void Tokenizer::simplifyBitfields()
{
for (Token *tok = _tokens; tok; tok = tok->next())
{
if (Token::Match(tok, "[;{] signed|unsigned|int|long %var% : %num% ;"))
if (Token::Match(tok, ";|{|public:|protected:|private: signed|unsigned|int|long|bool|char|short %var% : %num% ;"))
Token::eraseTokens(tok->tokAt(2), tok->tokAt(5));
if (Token::Match(tok, "[;{] signed|unsigned int|long %var% : %num% ;"))
else if (Token::Match(tok, ";|{|public:|protected:|private: signed|unsigned int|long|char|short %var% : %num% ;"))
Token::eraseTokens(tok->tokAt(3), tok->tokAt(6));
else if (Token::Match(tok, ";|{|public:|protected:|private: const signed|unsigned|int|long|bool|char|short %var% : %num% ;"))
Token::eraseTokens(tok->tokAt(3), tok->tokAt(6));
else if (Token::Match(tok, ";|{|public:|protected:|private: const signed|unsigned int|long|char|short %var% : %num% ;"))
Token::eraseTokens(tok->tokAt(4), tok->tokAt(7));
}
}
@ -7963,4 +7973,20 @@ void Tokenizer::simplifyBuiltinExpect()
}
// Remove Microsoft MFC 'DECLARE_MESSAGE_MAP()'
void Tokenizer::simplifyMicrosoftMFC()
{
for (Token *tok = _tokens; tok; tok = tok->next())
{
if (Token::simpleMatch(tok->next(), "DECLARE_MESSAGE_MAP ( )"))
{
tok->deleteNext();
tok->deleteNext();
tok->deleteNext();
}
}
}

View File

@ -473,6 +473,11 @@ public:
*/
void simplifyBuiltinExpect();
/**
* Remove Microsoft MFC 'DECLARE_MESSAGE_MAP()'
*/
void simplifyMicrosoftMFC();
/**
* This will return a short name describing function parameters
* e.g. parameters: (int a, char b) should get name "int,char,".

View File

@ -149,6 +149,7 @@ private:
TEST_CASE(constFriend); // ticket #1921 - fp for friend function
TEST_CASE(symboldatabase1);
TEST_CASE(symboldatabase2);
}
// Check the operator Equal
@ -4210,6 +4211,21 @@ private:
"};");
ASSERT_EQUALS("", errout.str());
}
void symboldatabase2()
{
checkConst("class foo {\n"
"public slots :\n"
"foo() { }\n"
"};");
ASSERT_EQUALS("", errout.str());
checkConst("class foo {\n"
"class bar;\n"
"foo() { }\n"
"};");
ASSERT_EQUALS("", errout.str());
}
};
REGISTER_TEST(TestClass)

View File

@ -2585,7 +2585,8 @@ private:
{
const char code[] = "class NoLabels { bool varOne : 1 ; bool varTwo : 1 ; } ;";
ASSERT_EQUALS(code, tok(code));
const char expect[] = "class NoLabels { bool varOne ; bool varTwo ; } ;";
ASSERT_EQUALS(expect, tok(code));
}
{

View File

@ -144,6 +144,10 @@ private:
TEST_CASE(varid19);
TEST_CASE(varid20);
TEST_CASE(varid21);
TEST_CASE(varid22);
TEST_CASE(varid23);
TEST_CASE(varid24);
TEST_CASE(varid25);
TEST_CASE(varidStl);
TEST_CASE(varid_delete);
TEST_CASE(varid_functions);
@ -238,7 +242,11 @@ private:
TEST_CASE(labels);
TEST_CASE(simplifyInitVar);
TEST_CASE(bitfields);
TEST_CASE(bitfields1);
TEST_CASE(bitfields2);
TEST_CASE(bitfields3);
TEST_CASE(microsoftMFC);
}
@ -2304,6 +2312,86 @@ private:
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
}
void varid22()
{
const std::string code("class foo()\n"
"{\n"
"public:\n"
" vector<const std::string &> x;\n"
"};\n");
const std::string expected("\n\n##file 0\n"
"1: class foo ( )\n"
"2: {\n"
"3: public:\n"
"4: vector < const std :: string & > x@1 ;\n"
"5: } ;\n");
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
}
void varid23()
{
const std::string code("class foo()\n"
"{\n"
"public:\n"
" static vector<const std::string &> x;\n"
"};\n");
const std::string expected("\n\n##file 0\n"
"1: class foo ( )\n"
"2: {\n"
"3: public:\n"
"4: static vector < const std :: string & > x@1 ;\n"
"5: } ;\n");
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
}
void varid24()
{
const std::string code("class foo()\n"
"{\n"
"public:\n"
" ;\n"
"private:\n"
" static int i;\n"
"};\n");
const std::string expected("\n\n##file 0\n"
"1: class foo ( )\n"
"2: {\n"
"3: public:\n"
"4: ;\n"
"5: private:\n"
"6: static int i@1 ;\n"
"7: } ;\n");
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
}
void varid25()
{
const std::string code("class foo()\n"
"{\n"
"public:\n"
" ;\n"
"private:\n"
" mutable int i;\n"
"};\n");
const std::string expected("\n\n##file 0\n"
"1: class foo ( )\n"
"2: {\n"
"3: public:\n"
"4: ;\n"
"5: private:\n"
"6: mutable int i@1 ;\n"
"7: } ;\n");
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
}
void varidStl()
{
@ -4170,13 +4258,88 @@ private:
}
}
void bitfields()
void bitfields1()
{
const char code1[] = "struct A { int x : 3; };";
ASSERT_EQUALS("struct A { int x ; } ;", tokenizeAndStringify(code1,false));
const char code1[] = "struct A { bool x : 1; };";
ASSERT_EQUALS("struct A { bool x ; } ;", tokenizeAndStringify(code1,false));
const char code2[] = "struct A { unsigned long x : 3; };";
ASSERT_EQUALS("struct A { unsigned long x ; } ;", tokenizeAndStringify(code2,false));
const char code2[] = "struct A { char x : 3; };";
ASSERT_EQUALS("struct A { char x ; } ;", tokenizeAndStringify(code2,false));
const char code3[] = "struct A { short x : 3; };";
ASSERT_EQUALS("struct A { short x ; } ;", tokenizeAndStringify(code3,false));
const char code4[] = "struct A { int x : 3; };";
ASSERT_EQUALS("struct A { int x ; } ;", tokenizeAndStringify(code4,false));
const char code5[] = "struct A { long x : 3; };";
ASSERT_EQUALS("struct A { long x ; } ;", tokenizeAndStringify(code5,false));
const char code6[] = "struct A { unsigned char x : 3; };";
ASSERT_EQUALS("struct A { unsigned char x ; } ;", tokenizeAndStringify(code6,false));
const char code7[] = "struct A { unsigned short x : 3; };";
ASSERT_EQUALS("struct A { unsigned short x ; } ;", tokenizeAndStringify(code7,false));
const char code8[] = "struct A { unsigned int x : 3; };";
ASSERT_EQUALS("struct A { unsigned int x ; } ;", tokenizeAndStringify(code8,false));
const char code9[] = "struct A { unsigned long x : 3; };";
ASSERT_EQUALS("struct A { unsigned long x ; } ;", tokenizeAndStringify(code9,false));
const char code10[] = "struct A { signed char x : 3; };";
ASSERT_EQUALS("struct A { signed char x ; } ;", tokenizeAndStringify(code10,false));
const char code11[] = "struct A { signed short x : 3; };";
ASSERT_EQUALS("struct A { signed short x ; } ;", tokenizeAndStringify(code11,false));
const char code12[] = "struct A { signed int x : 3; };";
ASSERT_EQUALS("struct A { signed int x ; } ;", tokenizeAndStringify(code12,false));
const char code13[] = "struct A { signed long x : 3; };";
ASSERT_EQUALS("struct A { signed long x ; } ;", tokenizeAndStringify(code13,false));
}
void bitfields2()
{
const char code1[] = "struct A { public: int x : 3; };";
ASSERT_EQUALS("struct A { public: int x ; } ;", tokenizeAndStringify(code1,false));
const char code2[] = "struct A { public: unsigned long x : 3; };";
ASSERT_EQUALS("struct A { public: unsigned long x ; } ;", tokenizeAndStringify(code2,false));
const char code3[] = "struct A { protected: int x : 3; };";
ASSERT_EQUALS("struct A { protected: int x ; } ;", tokenizeAndStringify(code3,false));
const char code4[] = "struct A { protected: unsigned long x : 3; };";
ASSERT_EQUALS("struct A { protected: unsigned long x ; } ;", tokenizeAndStringify(code4,false));
const char code5[] = "struct A { private: int x : 3; };";
ASSERT_EQUALS("struct A { private: int x ; } ;", tokenizeAndStringify(code5,false));
const char code6[] = "struct A { private: unsigned long x : 3; };";
ASSERT_EQUALS("struct A { private: unsigned long x ; } ;", tokenizeAndStringify(code6,false));
}
void bitfields3()
{
const char code1[] = "struct A { const int x : 3; };";
ASSERT_EQUALS("struct A { const int x ; } ;", tokenizeAndStringify(code1,false));
const char code2[] = "struct A { const unsigned long x : 3; };";
ASSERT_EQUALS("struct A { const unsigned long x ; } ;", tokenizeAndStringify(code2,false));
const char code3[] = "struct A { public: const int x : 3; };";
ASSERT_EQUALS("struct A { public: const int x ; } ;", tokenizeAndStringify(code3,false));
const char code4[] = "struct A { public: const unsigned long x : 3; };";
ASSERT_EQUALS("struct A { public: const unsigned long x ; } ;", tokenizeAndStringify(code4,false));
}
void microsoftMFC()
{
const char code1[] = "class MyDialog : public CDialog { DECLARE_MESSAGE_MAP() private: CString text; };";
ASSERT_EQUALS("class MyDialog : public CDialog { private: CString text ; } ;", tokenizeAndStringify(code1,false));
}
};