Symbol database: Refactorings. Ticket: #1895

This commit is contained in:
Robert Reif 2010-08-28 11:23:23 +02:00 committed by Daniel Marjamäki
parent 35afc4c63f
commit b1bf201a8a
2 changed files with 50 additions and 40 deletions

View File

@ -62,21 +62,13 @@ void CheckClass::createSymbolDatabase()
// Locate next class // Locate next class
if (Token::Match(tok, "class|struct|namespace %var% [{:]")) if (Token::Match(tok, "class|struct|namespace %var% [{:]"))
{ {
SpaceInfo *new_info = new SpaceInfo; SpaceInfo *new_info = new SpaceInfo(this, tok, info);
new_info->check = this;
new_info->isNamespace = tok->str() == "namespace";
new_info->className = tok->next()->str();
new_info->classDef = tok;
new_info->nest = info;
new_info->access = tok->str() == "struct" ? Public : Private;
new_info->numConstructors = 0;
const Token *tok2 = tok->tokAt(2); const Token *tok2 = tok->tokAt(2);
// only create variable list and base list if not namespace // only create variable list and base list if not namespace
if (!new_info->isNamespace) if (!new_info->isNamespace)
{ {
new_info->getVarList(_settings->debugwarnings); new_info->getVarList();
// goto initial '{' // goto initial '{'
tok2 = initBaseInfo(new_info, tok); tok2 = initBaseInfo(new_info, tok);
@ -99,7 +91,7 @@ void CheckClass::createSymbolDatabase()
// check for end of space // check for end of space
if (tok == info->classEnd) if (tok == info->classEnd)
{ {
info = info->nest; info = info->nestedIn;
} }
// check if in class or structure // check if in class or structure
@ -217,7 +209,7 @@ void CheckClass::createSymbolDatabase()
Token::Match(next, ") const| = 0 ;")) Token::Match(next, ") const| = 0 ;"))
{ {
// find implementation using names on stack // find implementation using names on stack
SpaceInfo * nest = info; SpaceInfo *nest = info;
unsigned int depth = 0; unsigned int depth = 0;
std::string classPattern; std::string classPattern;
@ -235,10 +227,10 @@ void CheckClass::createSymbolDatabase()
classPath = nest->className + std::string(" :: ") + classPath; classPath = nest->className + std::string(" :: ") + classPath;
searchPattern = classPath + classPattern; searchPattern = classPath + classPattern;
depth++; depth++;
nest = nest->nest; nest = nest->nestedIn;
// start looking at end of class // start looking at end of class
SpaceInfo * top = info; SpaceInfo *top = info;
const Token *found = top->classEnd; const Token *found = top->classEnd;
while ((found = Token::findmatch(found, searchPattern.c_str(), nest ? nest->classEnd : 0)) != NULL) while ((found = Token::findmatch(found, searchPattern.c_str(), nest ? nest->classEnd : 0)) != NULL)
{ {
@ -331,7 +323,7 @@ void CheckClass::createSymbolDatabase()
{ {
if (spaceInfo->className == info->derivedFrom[i].name) if (spaceInfo->className == info->derivedFrom[i].name)
{ {
if (spaceInfo->nest == info->nest) if (spaceInfo->nestedIn == info->nestedIn)
{ {
info->derivedFrom[i].spaceInfo = spaceInfo; info->derivedFrom[i].spaceInfo = spaceInfo;
break; break;
@ -351,8 +343,6 @@ CheckClass::~CheckClass()
delete it->second; delete it->second;
} }
//---------------------------------------------------------------------------
const Token *CheckClass::initBaseInfo(SpaceInfo *info, const Token *tok) const Token *CheckClass::initBaseInfo(SpaceInfo *info, const Token *tok)
{ {
// goto initial '{' // goto initial '{'
@ -416,8 +406,23 @@ const Token *CheckClass::initBaseInfo(SpaceInfo *info, const Token *tok)
return tok2; return tok2;
} }
//---------------------------------------------------------------------------
void CheckClass::SpaceInfo::getVarList(bool debugwarnings) CheckClass::SpaceInfo::SpaceInfo(CheckClass *check_, const Token *classDef_, CheckClass::SpaceInfo *nestedIn_) :
check(check_),
classDef(classDef_),
nestedIn(nestedIn_),
numConstructors(0)
{
isNamespace = classDef->str() == "namespace";
className = classDef->next()->str();
access = classDef->str() == "struct" ? Public : Private;
if (nestedIn)
nestedIn->nestedList.push_back(this);
}
void CheckClass::SpaceInfo::getVarList()
{ {
// Get variable list.. // Get variable list..
const Token *tok1 = classDef; const Token *tok1 = classDef;
@ -629,7 +634,7 @@ void CheckClass::SpaceInfo::getVarList(bool debugwarnings)
// If the vartok was set in the if-blocks above, create a entry for this variable.. // If the vartok was set in the if-blocks above, create a entry for this variable..
if (vartok && vartok->str() != "operator") if (vartok && vartok->str() != "operator")
{ {
if (vartok->varId() == 0 && debugwarnings) if (vartok->varId() == 0 && check->_settings->debugwarnings)
{ {
check->reportError(vartok, Severity::debug, "debug", "CheckClass::SpaceInfo::getVarList found variable \'" + vartok->str() + "\' with varid 0."); check->reportError(vartok, Severity::debug, "debug", "CheckClass::SpaceInfo::getVarList found variable \'" + vartok->str() + "\' with varid 0.");
} }
@ -775,7 +780,7 @@ void CheckClass::SpaceInfo::initializeVarList(const Func &func, std::list<std::s
else if (Token::Match(ftok, "%var% (") && ftok->str() != "if") else if (Token::Match(ftok, "%var% (") && ftok->str() != "if")
{ {
// Passing "this" => assume that everything is initialized // Passing "this" => assume that everything is initialized
for (const Token * tok2 = ftok->next()->link(); tok2 && tok2 != ftok; tok2 = tok2->previous()) for (const Token *tok2 = ftok->next()->link(); tok2 && tok2 != ftok; tok2 = tok2->previous())
{ {
if (tok2->str() == "this") if (tok2->str() == "this")
{ {
@ -1438,7 +1443,7 @@ void CheckClass::operatorEqRetRefThis()
// assignment to self. // assignment to self.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static bool hasDeallocation(const Token * first, const Token * last) static bool hasDeallocation(const Token *first, const Token *last)
{ {
// This function is called when no simple check was found for assignment // This function is called when no simple check was found for assignment
// to self. We are currently looking for a specific sequence of: // to self. We are currently looking for a specific sequence of:
@ -1447,16 +1452,16 @@ static bool hasDeallocation(const Token * first, const Token * last)
// Unfortunately, this is necessary to prevent false positives. // Unfortunately, this is necessary to prevent false positives.
// This check needs to do careful analysis someday to get this // This check needs to do careful analysis someday to get this
// correct with a high degree of certainty. // correct with a high degree of certainty.
for (const Token * tok = first; tok && (tok != last); tok = tok->next()) for (const Token *tok = first; tok && (tok != last); tok = tok->next())
{ {
// check for deallocating memory // check for deallocating memory
if (Token::Match(tok, "{|;|, free ( %var%")) if (Token::Match(tok, "{|;|, free ( %var%"))
{ {
const Token * var = tok->tokAt(3); const Token *var = tok->tokAt(3);
// we should probably check that var is a pointer in this class // we should probably check that var is a pointer in this class
const Token * tok1 = tok->tokAt(4); const Token *tok1 = tok->tokAt(4);
while (tok1 && (tok1 != last)) while (tok1 && (tok1 != last))
{ {
@ -1471,11 +1476,11 @@ static bool hasDeallocation(const Token * first, const Token * last)
} }
else if (Token::Match(tok, "{|;|, delete [ ] %var%")) else if (Token::Match(tok, "{|;|, delete [ ] %var%"))
{ {
const Token * var = tok->tokAt(4); const Token *var = tok->tokAt(4);
// we should probably check that var is a pointer in this class // we should probably check that var is a pointer in this class
const Token * tok1 = tok->tokAt(5); const Token *tok1 = tok->tokAt(5);
while (tok1 && (tok1 != last)) while (tok1 && (tok1 != last))
{ {
@ -1490,11 +1495,11 @@ static bool hasDeallocation(const Token * first, const Token * last)
} }
else if (Token::Match(tok, "{|;|, delete %var%")) else if (Token::Match(tok, "{|;|, delete %var%"))
{ {
const Token * var = tok->tokAt(2); const Token *var = tok->tokAt(2);
// we should probably check that var is a pointer in this class // we should probably check that var is a pointer in this class
const Token * tok1 = tok->tokAt(3); const Token *tok1 = tok->tokAt(3);
while (tok1 && (tok1 != last)) while (tok1 && (tok1 != last))
{ {
@ -1512,14 +1517,14 @@ static bool hasDeallocation(const Token * first, const Token * last)
return false; return false;
} }
static bool hasAssignSelf(const Token * first, const Token * last, const Token * rhs) static bool hasAssignSelf(const Token *first, const Token *last, const Token *rhs)
{ {
for (const Token * tok = first; tok && tok != last; tok = tok->next()) for (const Token *tok = first; tok && tok != last; tok = tok->next())
{ {
if (Token::Match(tok, "if (")) if (Token::Match(tok, "if ("))
{ {
const Token * tok1 = tok->tokAt(2); const Token *tok1 = tok->tokAt(2);
const Token * tok2 = tok->tokAt(1)->link(); const Token *tok2 = tok->tokAt(1)->link();
if (tok1 && tok2) if (tok1 && tok2)
{ {
@ -1872,11 +1877,11 @@ void CheckClass::checkConst()
if (checkConstFunc(info, paramEnd)) if (checkConstFunc(info, paramEnd))
{ {
std::string classname = info->className; std::string classname = info->className;
SpaceInfo *nest = info->nest; SpaceInfo *nest = info->nestedIn;
while (nest) while (nest)
{ {
classname = std::string(nest->className + "::" + classname); classname = std::string(nest->className + "::" + classname);
nest = nest->nest; nest = nest->nestedIn;
} }
if (func.isInline) if (func.isInline)
@ -1925,7 +1930,7 @@ bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok)
for (unsigned int i = 0; i < info->derivedFrom.size(); ++i) for (unsigned int i = 0; i < info->derivedFrom.size(); ++i)
{ {
// find the base class // find the base class
const SpaceInfo * spaceInfo = info->derivedFrom[i].spaceInfo; const SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo;
// find the function in the base class // find the function in the base class
if (spaceInfo) if (spaceInfo)

View File

@ -161,8 +161,9 @@ private:
bool isClass; bool isClass;
}; };
struct Func class Func
{ {
public:
enum Type { Constructor, CopyConstructor, OperatorEqual, Destructor, Function }; enum Type { Constructor, CopyConstructor, OperatorEqual, Destructor, Function };
Func() Func()
@ -212,21 +213,25 @@ private:
SpaceInfo *spaceInfo; SpaceInfo *spaceInfo;
}; };
struct SpaceInfo class SpaceInfo
{ {
public:
SpaceInfo(CheckClass *check_, const Token *classDef_, SpaceInfo *nestedIn_);
CheckClass *check; CheckClass *check;
bool isNamespace; bool isNamespace;
std::string className; std::string className;
const Token *classDef; // class/struct/namespace token const Token *classDef; // class/struct/namespace token
const Token *classStart; // '{' token const Token *classStart; // '{' token
const Token *classEnd; // '}' token const Token *classEnd; // '}' token
unsigned int numConstructors;
std::list<Func> functionList; std::list<Func> functionList;
std::list<Var> varlist; std::list<Var> varlist;
std::vector<BaseInfo> derivedFrom; std::vector<BaseInfo> derivedFrom;
std::list<FriendInfo> friendList; std::list<FriendInfo> friendList;
SpaceInfo *nest; SpaceInfo *nestedIn;
std::list<SpaceInfo *> nestedList;
AccessControl access; AccessControl access;
unsigned int numConstructors;
/** /**
* @brief initialize a variable in the varlist * @brief initialize a variable in the varlist
@ -241,7 +246,7 @@ private:
void markAllVar(bool value); void markAllVar(bool value);
/** @brief initialize varlist */ /** @brief initialize varlist */
void getVarList(bool debugwarnings); void getVarList();
/** /**
* @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