Symbol database: Refactorings. Ticket: #1895
This commit is contained in:
parent
35afc4c63f
commit
b1bf201a8a
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue