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; info->access = Protected;
else if (tok->str() == "public:") else if (tok->str() == "public:")
info->access = 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? // function?
else if (((Token::Match(tok, "%var% (") || Token::Match(tok, "operator %any% (")) && tok->previous()->str() != "::") && 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.. // Get variable list..
const Token *tok1 = classDef; const Token *tok1 = classDef;
unsigned int indentlevel = 0; unsigned int indentlevel = 0;
bool isStruct = tok1->str() == "struct"; AccessControl varaccess = tok1->str() == "struct" ? Public : Private;
bool priv = !isStruct;
for (const Token *tok = tok1; tok; tok = tok->next()) for (const Token *tok = tok1; tok; tok = tok->next())
{ {
if (!tok->next()) if (!tok->next())
@ -434,7 +444,6 @@ void CheckClass::SpaceInfo::getVarList()
// These are automaticly initialized. // These are automaticly initialized.
if (tok->str() == "__published:") if (tok->str() == "__published:")
{ {
priv = false;
for (; tok; tok = tok->next()) for (; tok; tok = tok->next())
{ {
if (tok->str() == "{") if (tok->str() == "{")
@ -449,10 +458,33 @@ void CheckClass::SpaceInfo::getVarList()
} }
// "private:" "public:" "protected:" etc // "private:" "public:" "protected:" etc
const bool b((tok->str()[0] != ':') && tok->str().find(":") != std::string::npos); bool b = false;
if (tok->str() == "public:")
if (b) {
priv = bool(tok->str() == "private:"); 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.. // Search for start of statement..
if (! Token::Match(tok, "[;{}]") && ! b) if (! Token::Match(tok, "[;{}]") && ! b)
@ -466,6 +498,25 @@ void CheckClass::SpaceInfo::getVarList()
if (next->str().find(":") != std::string::npos) if (next->str().find(":") != std::string::npos)
continue; 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.. // Borland C++: Ignore properties..
if (next->str() == "__property") if (next->str() == "__property")
continue; 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."); 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; std::list<Var>::const_iterator var;
for (var = info->varlist.begin(); var != info->varlist.end(); ++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"); noConstructorError(info->classDef, info->className, info->classDef->str() == "struct");
break; break;

View File

@ -132,10 +132,10 @@ private:
class Var class Var
{ {
public: 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_), : token(token_),
init(init_), init(init_),
priv(priv_), access(access_),
isMutable(mutable_), isMutable(mutable_),
isStatic(static_), isStatic(static_),
isClass(class_) isClass(class_)
@ -148,8 +148,8 @@ private:
/** @brief has this variable been initialized? */ /** @brief has this variable been initialized? */
bool init; bool init;
/** @brief is this variable declared in the private section? */ /** @brief what section is this variable declared in? */
bool priv; AccessControl access; // public/protected/private
/** @brief is this variable mutable? */ /** @brief is this variable mutable? */
bool isMutable; bool isMutable;

View File

@ -1679,9 +1679,6 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
// specify array size.. // specify array size..
arraySize(); arraySize();
// simplify bit fields..
simplifyBitfields();
// simplify labels.. // simplify labels..
labels(); labels();
@ -1792,6 +1789,9 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
} }
} }
// simplify bit fields..
simplifyBitfields();
// Remove __declspec() // Remove __declspec()
simplifyDeclspec(); simplifyDeclspec();
@ -1801,6 +1801,9 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
// remove __attribute__((?)) // remove __attribute__((?))
simplifyAttribute(); simplifyAttribute();
// remove Microsoft MFC..
simplifyMicrosoftMFC();
// typedef.. // typedef..
simplifyTypedef(); simplifyTypedef();
@ -1935,7 +1938,10 @@ void Tokenizer::labels()
// simplify label.. // simplify label..
if (Token::Match(tok, "[;{}] %var% : %var%")) 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")) if (Token::Match(tok, "else|return|typedef|delete|sizeof"))
continue; 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(); tok = tok->next();
while (Token::Match(tok, "%var% ::")) while (Token::Match(tok, "%var% ::"))
@ -7913,10 +7919,14 @@ void Tokenizer::simplifyBitfields()
{ {
for (Token *tok = _tokens; tok; tok = tok->next()) 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)); 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)); 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(); void simplifyBuiltinExpect();
/**
* Remove Microsoft MFC 'DECLARE_MESSAGE_MAP()'
*/
void simplifyMicrosoftMFC();
/** /**
* This will return a short name describing function parameters * This will return a short name describing function parameters
* e.g. parameters: (int a, char b) should get name "int,char,". * 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(constFriend); // ticket #1921 - fp for friend function
TEST_CASE(symboldatabase1); TEST_CASE(symboldatabase1);
TEST_CASE(symboldatabase2);
} }
// Check the operator Equal // Check the operator Equal
@ -4210,6 +4211,21 @@ private:
"};"); "};");
ASSERT_EQUALS("", errout.str()); 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) REGISTER_TEST(TestClass)

View File

@ -2585,7 +2585,8 @@ private:
{ {
const char code[] = "class NoLabels { bool varOne : 1 ; bool varTwo : 1 ; } ;"; 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(varid19);
TEST_CASE(varid20); TEST_CASE(varid20);
TEST_CASE(varid21); TEST_CASE(varid21);
TEST_CASE(varid22);
TEST_CASE(varid23);
TEST_CASE(varid24);
TEST_CASE(varid25);
TEST_CASE(varidStl); TEST_CASE(varidStl);
TEST_CASE(varid_delete); TEST_CASE(varid_delete);
TEST_CASE(varid_functions); TEST_CASE(varid_functions);
@ -238,7 +242,11 @@ private:
TEST_CASE(labels); TEST_CASE(labels);
TEST_CASE(simplifyInitVar); 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)); 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() void varidStl()
{ {
@ -4170,13 +4258,88 @@ private:
} }
} }
void bitfields() void bitfields1()
{ {
const char code1[] = "struct A { int x : 3; };"; const char code1[] = "struct A { bool x : 1; };";
ASSERT_EQUALS("struct A { int x ; } ;", tokenizeAndStringify(code1,false)); ASSERT_EQUALS("struct A { bool x ; } ;", tokenizeAndStringify(code1,false));
const char code2[] = "struct A { unsigned long x : 3; };"; const char code2[] = "struct A { char x : 3; };";
ASSERT_EQUALS("struct A { unsigned long x ; } ;", tokenizeAndStringify(code2,false)); 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));
} }
}; };