Improved updateClassList(), but not yet took it into use.
findClassFunction is now non-static. updateClassList usage is currently commented out as it doesn't handle class inside a function
This commit is contained in:
parent
f561441d90
commit
1d5ba4e320
|
@ -11,7 +11,7 @@
|
|||
<Option output="cppcheck" prefix_auto="1" extension_auto="1" />
|
||||
<Option type="1" />
|
||||
<Option compiler="gcc" />
|
||||
<Option parameters="p.cpp --debug" />
|
||||
<Option parameters="p.cpp --debug --enable=all" />
|
||||
<Compiler>
|
||||
<Add option="-g" />
|
||||
</Compiler>
|
||||
|
|
|
@ -285,7 +285,7 @@ void CheckClass::initializeVarList(const Token *tok1, const Token *ftok, Var *va
|
|||
{
|
||||
callstack.push_back(ftok->str());
|
||||
int i = 0;
|
||||
const Token *ftok2 = Tokenizer::findClassFunction(tok1, classname, ftok->strAt(0), i, isStruct);
|
||||
const Token *ftok2 = _tokenizer->findClassFunction(tok1, classname, ftok->strAt(0), i, isStruct);
|
||||
if (ftok2)
|
||||
{
|
||||
initializeVarList(tok1, ftok2, varlist, classname, callstack, isStruct);
|
||||
|
@ -500,7 +500,11 @@ void CheckClass::checkConstructors(const Token *tok1, const char funcname[], boo
|
|||
Var *varlist = getVarList(tok1, withClasses, isStruct);
|
||||
|
||||
int indentlevel = 0;
|
||||
const Token *constructor_token = Tokenizer::findClassFunction(tok1, className, funcname, indentlevel, isStruct);
|
||||
const Token *constructor_token = _tokenizer->findClassFunction(tok1, className, funcname, indentlevel, isStruct);
|
||||
if (constructor_token)
|
||||
std::cout << constructor_token->str() << "\n";
|
||||
else
|
||||
std::cout << "null\n";
|
||||
std::list<std::string> callstack;
|
||||
initializeVarList(tok1, constructor_token, varlist, className, callstack, isStruct);
|
||||
while (constructor_token)
|
||||
|
@ -547,7 +551,7 @@ void CheckClass::checkConstructors(const Token *tok1, const char funcname[], boo
|
|||
for (Var *var = varlist; var; var = var->next)
|
||||
var->init = false;
|
||||
|
||||
constructor_token = Tokenizer::findClassFunction(constructor_token->next(), className, funcname, indentlevel, isStruct);
|
||||
constructor_token = _tokenizer->findClassFunction(constructor_token->next(), className, funcname, indentlevel, isStruct);
|
||||
callstack.clear();
|
||||
initializeVarList(tok1, constructor_token, varlist, className, callstack, isStruct);
|
||||
}
|
||||
|
|
|
@ -2319,7 +2319,7 @@ void CheckMemoryLeakInClass::variable(const std::string &classname, const Token
|
|||
|
||||
// Loop through all tokens. Inspect member functions
|
||||
int indent_ = 0;
|
||||
const Token *functionToken = Tokenizer::findClassFunction(_tokenizer->tokens(), classname.c_str(), "~| %var%", indent_);
|
||||
const Token *functionToken = _tokenizer->findClassFunction(_tokenizer->tokens(), classname.c_str(), "~| %var%", indent_);
|
||||
while (functionToken)
|
||||
{
|
||||
const bool constructor(Token::Match(functionToken, (classname + " :: " + classname + " (").c_str()));
|
||||
|
@ -2417,7 +2417,7 @@ void CheckMemoryLeakInClass::variable(const std::string &classname, const Token
|
|||
}
|
||||
}
|
||||
|
||||
functionToken = Tokenizer::findClassFunction(functionToken->next(), classname.c_str(), "~| %var%", indent_);
|
||||
functionToken = _tokenizer->Tokenizer::findClassFunction(functionToken->next(), classname.c_str(), "~| %var%", indent_);
|
||||
}
|
||||
|
||||
if (allocInConstructor && !deallocInDestructor)
|
||||
|
|
124
lib/tokenize.cpp
124
lib/tokenize.cpp
|
@ -1003,7 +1003,7 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
|
|||
|
||||
// simplify function pointers
|
||||
simplifyFunctionPointers();
|
||||
|
||||
//updateClassList();
|
||||
setVarId();
|
||||
if (!validate())
|
||||
return false;
|
||||
|
@ -1576,20 +1576,67 @@ void Tokenizer::simplifyTemplates()
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
std::string Tokenizer::getNameForFunctionParams(const Token *start)
|
||||
{
|
||||
if (start->next() == start->link())
|
||||
return "";
|
||||
|
||||
std::string result;
|
||||
bool findNextComma = false;
|
||||
for (const Token *tok = start->next(); tok && tok != start->link(); tok = tok->next())
|
||||
{
|
||||
if (findNextComma)
|
||||
{
|
||||
if (tok->str() == ",")
|
||||
findNextComma = false;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
result.append(tok->str() + ",");
|
||||
findNextComma = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Tokenizer::updateClassList()
|
||||
{
|
||||
const char pattern_class[] = "class %var% [{:]";
|
||||
_classInfoList.clear();
|
||||
|
||||
// Locate class
|
||||
const Token *tok1 = tokens();
|
||||
while ((tok1 = Token::findmatch(tok1, pattern_class)) != 0)
|
||||
{
|
||||
const char *className;
|
||||
className = tok1->strAt(1);
|
||||
tok1 = tok1->next();
|
||||
|
||||
// Locate implementation
|
||||
tok1 = tokens();
|
||||
std::map<std::string, std::map<std::string, std::map<std::string, const Token*> > > implementations;
|
||||
while ((tok1 = Token::findmatch(tok1, "%var% :: ~| %var% (")) != 0)
|
||||
{
|
||||
if (tok1->tokAt(2)->str() == "~")
|
||||
implementations[tok1->str()]["~ "+tok1->tokAt(3)->str()][getNameForFunctionParams(tok1->tokAt(4))] = tok1;
|
||||
else
|
||||
implementations[tok1->str()][tok1->tokAt(2)->str()][getNameForFunctionParams(tok1->tokAt(3))] = tok1;
|
||||
//std::cout <<"1."<< tok1->str() << "," << tok1->tokAt(2)->str() << ","<<getNameForFunctionParams(tok1->tokAt(3));
|
||||
tok1 = tok1->next();
|
||||
}
|
||||
|
||||
tok1 = tokens();
|
||||
while ((tok1 = Token::findmatch(tok1, "%var% :: operator %any% (")) != 0)
|
||||
{
|
||||
implementations[tok1->str()][tok1->tokAt(2)->str()+" "+tok1->tokAt(3)->str()][getNameForFunctionParams(tok1->tokAt(4))] = tok1;
|
||||
//std::cout <<"3."<< tok1->str() << "," << tok1->tokAt(2)->str()+" "+tok1->tokAt(3)->str() << ","<<getNameForFunctionParams(tok1->tokAt(4));
|
||||
tok1 = tok1->next();
|
||||
}
|
||||
|
||||
tok1 = tokens();
|
||||
while ((tok1 = Token::findmatch(tok1, "class|struct %var% [{:]")) != 0)
|
||||
{
|
||||
ClassInfo::MemberType memberType = ClassInfo::PRIVATE;
|
||||
if (tok1->str() == "struct")
|
||||
memberType = ClassInfo::PUBLIC;
|
||||
|
||||
const char *className = tok1->strAt(1);
|
||||
tok1 = tok1->next();
|
||||
int indentlevel = 0;
|
||||
for (const Token *tok = tok1; tok; tok = tok->next())
|
||||
{
|
||||
|
@ -1627,12 +1674,40 @@ void Tokenizer::updateClassList()
|
|||
|
||||
else if (Token::Match(tok, "%var% ("))
|
||||
{
|
||||
// member function
|
||||
ClassInfo::MemberFunctionInfo func;
|
||||
if (tok->previous()->str() == "~")
|
||||
{
|
||||
// destructor
|
||||
func._declaration = tok->previous();
|
||||
func._name = "~ " + tok->str();
|
||||
}
|
||||
else
|
||||
{
|
||||
// member function
|
||||
func._declaration = tok;
|
||||
func._name = tok->str();
|
||||
func._type = memberType;
|
||||
}
|
||||
|
||||
func._type = memberType;
|
||||
if (tok->next()->link()->next()->str() == "{")
|
||||
func._implementation = tok;
|
||||
else
|
||||
func._implementation = implementations[className][func._name][getNameForFunctionParams(tok->next())];
|
||||
//std::cout <<"\n2."<< className << "," << func._name << ","<<getNameForFunctionParams(tok->next())<<"\n";
|
||||
_classInfoList[className]._memberFunctions.push_back(func);
|
||||
}
|
||||
else if (Token::Match(tok, "operator %any% ("))
|
||||
{
|
||||
ClassInfo::MemberFunctionInfo func;
|
||||
func._declaration = tok;
|
||||
func._name = tok->str() + " " + tok->next()->str();
|
||||
func._type = memberType;
|
||||
if (tok->tokAt(2)->link()->next()->str() == "{")
|
||||
func._implementation = tok;
|
||||
else
|
||||
func._implementation = implementations[className][func._name][getNameForFunctionParams(tok->tokAt(2))];
|
||||
|
||||
//std::cout <<"\n4."<< className << "," << func._name << ","<<getNameForFunctionParams(tok->tokAt(2))<<"\n";
|
||||
_classInfoList[className]._memberFunctions.push_back(func);
|
||||
}
|
||||
}
|
||||
|
@ -5058,11 +5133,40 @@ std::string Tokenizer::file(const Token *tok) const
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const Token * Tokenizer::findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel, bool isStruct)
|
||||
const Token * Tokenizer::findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel, bool isStruct) const
|
||||
{
|
||||
if (indentlevel < 0 || tok == NULL)
|
||||
return NULL;
|
||||
/*
|
||||
// TODO: This is currently commented out as updateClassList doesn't
|
||||
// fully work yet and call to updateClassList is currently also
|
||||
// commented out.
|
||||
|
||||
//std::cout << tok->str()<<"--\n";
|
||||
if( tok == _tokens || tok->str() == "class" || tok->str() == "struct")
|
||||
tok = 0;
|
||||
|
||||
std::map<std::string, ClassInfo>::const_iterator iter;
|
||||
iter = _classInfoList.find(classname);
|
||||
if( iter == _classInfoList.end() )
|
||||
return NULL;
|
||||
|
||||
for( size_t i = 0; i < iter->second._memberFunctions.size(); i++ )
|
||||
if( Token::Match( iter->second._memberFunctions[i]._declaration, funcname ) )
|
||||
{
|
||||
if( tok != 0 )
|
||||
{
|
||||
if( tok == iter->second._memberFunctions[i]._implementation ||
|
||||
tok->previous() == iter->second._memberFunctions[i]._implementation)
|
||||
tok = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
return iter->second._memberFunctions[i]._implementation;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
*/
|
||||
const std::string classPattern(std::string(isStruct ? "struct " : "class ") + classname + " :|{");
|
||||
const std::string internalPattern(std::string("!!~ ") + funcname + " (");
|
||||
const std::string externalPattern(std::string(classname) + " :: " + funcname + " (");
|
||||
|
|
|
@ -115,7 +115,7 @@ public:
|
|||
* @param isStruct is it a struct
|
||||
* @return First matching token or NULL.
|
||||
*/
|
||||
static const Token *findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel, bool isStruct = false);
|
||||
const Token *findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel, bool isStruct = false) const;
|
||||
|
||||
/**
|
||||
* get error messages
|
||||
|
@ -390,6 +390,16 @@ private:
|
|||
*/
|
||||
bool simplifyDoWhileAddBracesHelper(Token *tok);
|
||||
|
||||
/**
|
||||
* This will return a short name describing function parameters
|
||||
* e.g. parameters: (int a, char b) should get name "int,char,".
|
||||
* This should help to identify functions with the same name,
|
||||
* but with different parameters.
|
||||
* @param start The "(" token
|
||||
* @return, e.g. "int,char,"
|
||||
*/
|
||||
static std::string getNameForFunctionParams(const Token *start);
|
||||
|
||||
/** Disable assignment operator */
|
||||
void operator=(const Tokenizer &);
|
||||
|
||||
|
|
|
@ -2316,9 +2316,9 @@ private:
|
|||
int i;
|
||||
|
||||
i = 0;
|
||||
const Token *tok = Tokenizer::findClassFunction(tokenizer.tokens(), "Fred", "%var%", i);
|
||||
const Token *tok = tokenizer.findClassFunction(tokenizer.tokens(), "Fred", "%var%", i);
|
||||
ASSERT_EQUALS(true, Token::simpleMatch(tok, "Fred ( ) {"));
|
||||
tok = Tokenizer::findClassFunction(tok->next(), "Fred", "%var%", i);
|
||||
tok = tokenizer.findClassFunction(tok->next(), "Fred", "%var%", i);
|
||||
ASSERT_EQUALS(0, tok ? 1 : 0);
|
||||
}
|
||||
|
||||
|
@ -2339,9 +2339,9 @@ private:
|
|||
int i;
|
||||
|
||||
i = 0;
|
||||
const Token *tok = Tokenizer::findClassFunction(tokenizer.tokens(), "Fred", "%var%", i, true);
|
||||
const Token *tok = tokenizer.findClassFunction(tokenizer.tokens(), "Fred", "%var%", i, true);
|
||||
ASSERT_EQUALS(true, Token::simpleMatch(tok, "Fred ( ) {"));
|
||||
tok = Tokenizer::findClassFunction(tok->next(), "Fred", "%var%", i, false);
|
||||
tok = tokenizer.findClassFunction(tok->next(), "Fred", "%var%", i, false);
|
||||
ASSERT_EQUALS(0, tok ? 1 : 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue