51     std::string name = funcName;
 
   52     const auto pos = name.find(
'<');
 
   53     if (pos > 0 && pos != std::string::npos)
 
   64     const char * 
const FileName = tokenizer.
list.
getFiles().front().c_str();
 
   73             if (!func || !func->
token)
 
   92             const std::string& fileName = tokenizer.
list.
file(func->
token);
 
   99             else if (usage.
filename != fileName) {
 
  107     const Token *lambdaEndToken = 
nullptr;
 
  110         if (tok == lambdaEndToken)
 
  111             lambdaEndToken = 
nullptr;
 
  112         else if (!lambdaEndToken && tok->
str() == 
"[")
 
  124             while ((scope || start) && markupVarToken) {
 
  134                     else if (markupVarToken->
next()->
str() == 
"(") {
 
  143                 markupVarToken = markupVarToken->
next();
 
  150             while (propToken && propToken->
str() != 
")") {
 
  152                     const Token* nextPropToken = propToken->
next();
 
  153                     const std::string& value = nextPropToken->
str();
 
  161                     const std::string& value = prevPropToken->
str();
 
  167                 propToken = propToken->
next();
 
  171         if (doMarkup && settings.
library.
isimporter(FileName, tok->str()) && tok->next()) {
 
  173             if (propToken->
next()) {
 
  174                 propToken = propToken->
next();
 
  175                 while (propToken && propToken->
str() != 
")") {
 
  176                     const std::string& value = propToken->
str();
 
  177                     if (!value.empty()) {
 
  182                     propToken = propToken->
next();
 
  194                     if (funcToken->
str()==
",") {
 
  195                         if (++index == argIndex)
 
  199                         value += funcToken->
str();
 
  200                     funcToken = funcToken->
next();
 
  202                 if (index == argIndex) {
 
  203                     value = value.substr(1, value.length() - 2);
 
  210         const Token *funcname = 
nullptr;
 
  213             funcname = 
Token::Match(tok, 
"%name% (") ? tok : 
nullptr;
 
  214         else if ((lambdaEndToken || tok->
scope()->isExecutable()) && 
Token::Match(tok, 
"%name% (")) {
 
  218         } 
else if (
Token::Match(tok, 
"< %name%") && tok->link()) {
 
  219             funcname = tok->
next();
 
  221                 funcname = funcname->
tokAt(2);
 
  222         } 
else if (tok->scope()->type != Scope::ScopeType::eEnum && (
Token::Match(tok, 
"[;{}.,()[=+-/|!?:]") || 
Token::Match(tok, 
"return|throw"))) {
 
  223             funcname = tok->
next();
 
  224             if (funcname && funcname->
str() == 
"&")
 
  225                 funcname = funcname->
next();
 
  226             if (funcname && funcname->
str() == 
"::")
 
  227                 funcname = funcname->
next();
 
  229                 funcname = funcname->
tokAt(2);
 
  241             if (ftok->
str() == 
"<")
 
  283     const std::string operatorPrefix = 
"operator";
 
  284     if (funcName.compare(0, operatorPrefix.length(), operatorPrefix) != 0) {
 
  289     if (funcName.length() == operatorPrefix.length()) {
 
  293     const char firstOperatorChar = funcName[operatorPrefix.length()];
 
  294     if (firstOperatorChar == 
'_') {
 
  298     if (!std::isalnum(firstOperatorChar)) {
 
  302     const std::vector<std::string> additionalOperators = {
 
  303         "new", 
"new[]", 
"delete", 
"delete[]" 
  307     return std::find(additionalOperators.cbegin(), additionalOperators.cend(), funcName.substr(operatorPrefix.length())) != additionalOperators.cend();
 
  310 #define logChecker(id) \ 
  312         const ErrorMessage errmsg({}, nullptr, Severity::internal, "logChecker", (id), CWE(0U), Certainty::normal); \
 
  313         errorLogger.reportErr(errmsg); \
 
  320     using ErrorParams = std::tuple<std::string, unsigned int, unsigned int, std::string>;
 
  321     std::vector<ErrorParams> errors; 
 
  323     for (std::unordered_map<std::string, FunctionUsage>::const_iterator it = 
mFunctions.cbegin(); it != 
mFunctions.cend(); ++it) {
 
  332             std::string filename;
 
  346     std::sort(errors.begin(), errors.end());
 
  347     for (
const auto& e : errors)
 
  348         unusedFunctionError(errorLogger, std::get<0>(e), std::get<1>(e), std::get<2>(e), std::get<3>(e));
 
  349     return !errors.empty();
 
  353                                                const std::string &filename, 
unsigned int fileIndex, 
unsigned int lineNumber,
 
  354                                                const std::string &funcname)
 
  356     std::list<ErrorMessage::FileLocation> locationList;
 
  357     if (!filename.empty()) {
 
  358         locationList.emplace_back(filename, lineNumber, 0);
 
  359         locationList.back().fileIndex = fileIndex;
 
  367     : functionName(f->name()), lineNumber(f->token->linenr())
 
  372     std::ostringstream ret;
 
  374         ret << 
"    <functiondecl" 
  376             << 
" lineNumber=\"" << functionDecl.lineNumber << 
"\"/>\n";
 
  386         Location() : lineNumber(0) {}
 
  387         Location(std::string f, 
const int l) : fileName(std::move(f)), lineNumber(l) {}
 
  388         std::string fileName;
 
  395     std::map<std::string, Location> decls;
 
  396     std::set<std::string> calls;
 
  398     const std::string filesTxt(buildDir + 
"/files.txt");
 
  399     std::ifstream fin(filesTxt.c_str());
 
  400     std::string filesTxtLine;
 
  401     while (std::getline(fin, filesTxtLine)) {
 
  402         const std::string::size_type firstColon = filesTxtLine.find(
':');
 
  403         if (firstColon == std::string::npos)
 
  405         const std::string::size_type secondColon = filesTxtLine.find(
':', firstColon+1);
 
  406         if (secondColon == std::string::npos)
 
  408         const std::string xmlfile = buildDir + 
'/' + filesTxtLine.substr(0,firstColon);
 
  409         const std::string sourcefile = filesTxtLine.substr(secondColon+1);
 
  411         tinyxml2::XMLDocument doc;
 
  412         const tinyxml2::XMLError 
error = doc.LoadFile(xmlfile.c_str());
 
  413         if (
error != tinyxml2::XML_SUCCESS)
 
  416         const tinyxml2::XMLElement * 
const rootNode = doc.FirstChildElement();
 
  417         if (rootNode == 
nullptr)
 
  420         for (
const tinyxml2::XMLElement *e = rootNode->FirstChildElement(); e; e = e->NextSiblingElement()) {
 
  421             if (std::strcmp(e->Name(), 
"FileInfo") != 0)
 
  423             const char *checkattr = e->Attribute(
"check");
 
  424             if (checkattr == 
nullptr || std::strcmp(checkattr,
"CheckUnusedFunctions") != 0)
 
  426             for (
const tinyxml2::XMLElement *e2 = e->FirstChildElement(); e2; e2 = e2->NextSiblingElement()) {
 
  427                 const char* functionName = e2->Attribute(
"functionName");
 
  428                 if (functionName == 
nullptr)
 
  430                 if (std::strcmp(e2->Name(),
"functioncall") == 0) {
 
  431                     calls.insert(functionName);
 
  434                 if (std::strcmp(e2->Name(),
"functiondecl") == 0) {
 
  435                     const char* lineNumber = e2->Attribute(
"lineNumber");
 
  438                         decls[functionName] = Location(sourcefile, strToInt<int>(lineNumber));
 
  445     for (std::map<std::string, Location>::const_iterator decl = decls.cbegin(); decl != decls.cend(); ++decl) {
 
  452             const Location &loc = decl->second;
 
  460     for (
const auto& entry : 
check.mFunctions)
 
  466         usage.
fileIndex = entry.second.fileIndex;
 
  468             usage.
filename = entry.second.filename;
 
const Token * findLambdaEndToken(const Token *first)
find lambda function end token
 
static bool isOperatorFunction(const std::string &funcName)
 
static const CWE CWE561(561U)
 
static std::string stripTemplateParameters(const std::string &funcName)
 
FunctionDecl(const Function *f)
 
Check for functions never called.
 
std::unordered_map< std::string, FunctionUsage > mFunctions
 
void parseTokens(const Tokenizer &tokenizer, const Settings &settings)
 
static void unusedFunctionError(ErrorLogger &errorLogger, const std::string &filename, unsigned int fileIndex, unsigned int lineNumber, const std::string &funcname)
 
static void analyseWholeProgram(const Settings &settings, ErrorLogger &errorLogger, const std::string &buildDir)
 
std::list< FunctionDecl > mFunctionDecl
 
void updateFunctionData(const CheckUnusedFunctions &check)
 
std::string analyzerInfo() const
 
bool check(const Settings &settings, ErrorLogger &errorLogger) const
 
std::set< std::string > mFunctionCalls
 
This is an interface, which the class responsible of error logging should implement.
 
virtual void reportErr(const ErrorMessage &msg)=0
Information about found errors and warnings is directed here.
 
static std::string toxml(const std::string &str)
Convert XML-sensitive characters into XML entities.
 
Wrapper for error messages, provided by reportErr()
 
const std::string & name() const
 
bool isAttributeConstructor() const
 
Type type
constructor, destructor, ...
 
const Token * token
function name token in implementation
 
bool isAttributeDestructor() const
 
bool isexecutableblock(const std::string &file, const std::string &token) const
 
bool isexportedsuffix(const std::string &prefix, const std::string &token) const
 
bool isexporter(const std::string &prefix) const
 
const std::string & blockstart(const std::string &file) const
 
bool isentrypoint(const std::string &func) const
 
const std::string & blockend(const std::string &file) const
 
bool isreflection(const std::string &token) const
 
bool iskeyword(const std::string &file, const std::string &keyword) const
 
bool markupFile(const std::string &path) const
 
bool isimporter(const std::string &file, const std::string &importer) const
 
bool isexportedprefix(const std::string &prefix, const std::string &token) const
 
int blockstartoffset(const std::string &file) const
 
int reflectionArgument(const std::string &token) const
 
Function * function
function info for this function
 
This is just a container for general settings so that we don't need to pass individual values to func...
 
std::vector< const Scope * > functionScopes
Fast access to function scopes.
 
const std::string & file(const Token *tok) const
get filename for given token
 
const std::vector< std::string > & getFiles() const
Get filenames (the sourcefile + the files it include).
 
The token list that the TokenList generates is a linked-list of this class.
 
static bool Match(const Token *tok, const char pattern[], nonneg int varid=0)
Match given token (or list of tokens) to a pattern list.
 
const Token * tokAt(int index) const
 
void scope(const Scope *s)
Associate this token with given scope.
 
void link(Token *linkToToken)
Create link to given token.
 
const Token * linkAt(int index) const
 
nonneg int linenr() const
 
bool isStandardType() const
 
static bool simpleMatch(const Token *tok, const char(&pattern)[count])
Match given token (or list of tokens) to a pattern list.
 
nonneg int fileIndex() const
 
The main purpose is to tokenize the source code.
 
const Token * tokens() const
 
TokenList list
Token list: stores all tokens.
 
const SymbolDatabase * getSymbolDatabase() const
 
static const std::string emptyString
 
@ error
Programming error.