Refactorization: Use SymbolDatabase to find functions in CheckUnusedFunctions
This commit is contained in:
parent
d22da5e683
commit
02f38772cc
|
@ -21,6 +21,7 @@
|
||||||
#include "checkunusedfunctions.h"
|
#include "checkunusedfunctions.h"
|
||||||
#include "tokenize.h"
|
#include "tokenize.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
#include "symboldatabase.h"
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -33,63 +34,36 @@
|
||||||
|
|
||||||
void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char FileName[], const Settings *settings)
|
void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char FileName[], const Settings *settings)
|
||||||
{
|
{
|
||||||
|
const SymbolDatabase* symbolDatabase = tokenizer.getSymbolDatabase();
|
||||||
|
|
||||||
// Function declarations..
|
// Function declarations..
|
||||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
|
for (std::size_t i = 0; i < symbolDatabase->functionScopes.size(); i++) {
|
||||||
if (tok->fileIndex() != 0)
|
const Scope* scope = symbolDatabase->functionScopes[i];
|
||||||
continue;
|
const Function* func = scope->function;
|
||||||
|
if (!func || !func->token || scope->classStart->fileIndex() != 0)
|
||||||
// token contains a ':' => skip to next ; or {
|
|
||||||
if (tok->str().find(":") != std::string::npos) {
|
|
||||||
while (tok && tok->str().find_first_of(";{"))
|
|
||||||
tok = tok->next();
|
|
||||||
if (tok)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is a template function, skip it
|
|
||||||
if (tok->previous() && tok->previous()->str() == ">")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const Token *funcname = nullptr;
|
|
||||||
|
|
||||||
if (Token::Match(tok, "%type% %var% ("))
|
|
||||||
funcname = tok->next();
|
|
||||||
else if (Token::Match(tok, "%type% *|& %var% ("))
|
|
||||||
funcname = tok->tokAt(2);
|
|
||||||
else if (Token::Match(tok, "%type% :: %var% (") && !Token::Match(tok, tok->strAt(2).c_str()))
|
|
||||||
funcname = tok->tokAt(2);
|
|
||||||
|
|
||||||
// Don't assume throw as a function name: void foo() throw () {}
|
|
||||||
if (Token::Match(tok->previous(), ")|const") || funcname == 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Don't warn about functions that are marked by __attribute__((constructor)) or __attribute__((destructor))
|
// Don't warn about functions that are marked by __attribute__((constructor)) or __attribute__((destructor))
|
||||||
if (funcname->isAttributeConstructor() || funcname->isAttributeDestructor())
|
if (func->isAttributeConstructor() || func->isAttributeDestructor() || func->type != Function::eFunction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tok = funcname->linkAt(1);
|
// Don't care about templates
|
||||||
|
if (func->retDef->str() == "template")
|
||||||
|
continue;
|
||||||
|
|
||||||
// Check that ") {" is found..
|
FunctionUsage &usage = _functions[func->name()];
|
||||||
if (! Token::Match(tok, ") const| {") &&
|
|
||||||
! Token::Match(tok, ") const| throw ( ) {"))
|
|
||||||
funcname = 0;
|
|
||||||
|
|
||||||
if (funcname) {
|
if (!usage.lineNumber)
|
||||||
FunctionUsage &func = _functions[ funcname->str()];
|
usage.lineNumber = func->token->linenr();
|
||||||
|
|
||||||
if (!func.lineNumber)
|
|
||||||
func.lineNumber = funcname->linenr();
|
|
||||||
|
|
||||||
// No filename set yet..
|
// No filename set yet..
|
||||||
if (func.filename.empty()) {
|
if (usage.filename.empty()) {
|
||||||
func.filename = tokenizer.getSourceFilePath();
|
usage.filename = tokenizer.getSourceFilePath();
|
||||||
}
|
}
|
||||||
// Multiple files => filename = "+"
|
// Multiple files => filename = "+"
|
||||||
else if (func.filename != tokenizer.getSourceFilePath()) {
|
else if (usage.filename != tokenizer.getSourceFilePath()) {
|
||||||
//func.filename = "+";
|
//func.filename = "+";
|
||||||
func.usedOtherFile |= func.usedSameFile;
|
usage.usedOtherFile |= usage.usedSameFile;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ private:
|
||||||
" template<typename T> void foo( T t ) const;\n"
|
" template<typename T> void foo( T t ) const;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"template<typename T> void X::foo( T t ) const { }\n");
|
"template<typename T> void X::foo( T t ) const { }\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) The function 'bar' is never used.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void throwIsNotAFunction() {
|
void throwIsNotAFunction() {
|
||||||
|
|
Loading…
Reference in New Issue