| 66 | } |
| 67 | |
| 68 | void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Settings &settings) |
| 69 | { |
| 70 | const char * const FileName = tokenizer.list.getFiles().front().c_str(); |
| 71 | |
| 72 | const bool doMarkup = settings.library.markupFile(FileName); |
| 73 | |
| 74 | // Function declarations.. |
| 75 | if (!doMarkup) { |
| 76 | const SymbolDatabase* symbolDatabase = tokenizer.getSymbolDatabase(); |
| 77 | for (const Scope* scope : symbolDatabase->functionScopes) { |
| 78 | const Function* func = scope->function; |
| 79 | if (!func || !func->token) |
| 80 | continue; |
| 81 | |
| 82 | // Don't warn about functions that are marked by __attribute__((constructor)) or __attribute__((destructor)) |
| 83 | if (func->isAttributeConstructor() || func->isAttributeDestructor() || func->type != FunctionType::eFunction || func->isOperator()) |
| 84 | continue; |
| 85 | |
| 86 | if (func->isAttributeUnused() || func->isAttributeMaybeUnused()) |
| 87 | continue; |
| 88 | |
| 89 | if (func->isExtern()) |
| 90 | continue; |
| 91 | |
| 92 | bool foundAllBaseClasses{}; |
| 93 | if (const Function* ofunc = func->getOverriddenFunction(&foundAllBaseClasses)) { |
| 94 | if (!foundAllBaseClasses || ofunc->isPure()) |
| 95 | continue; |
| 96 | } |
| 97 | else if (func->isImplicitlyVirtual()) { |
| 98 | continue; |
| 99 | } |
| 100 | |
| 101 | mFunctionDecl.emplace_back(func); |
| 102 | |
| 103 | FunctionUsage &usage = mFunctions[stripTemplateParameters(func->name())]; |
| 104 | |
| 105 | if (func->retDef && (func->retDef->isAttributeUnused() || func->retDef->isAttributeMaybeUnused())) { |
| 106 | usage.usedOtherFile = true; |
| 107 | } |
| 108 | |
| 109 | if (!usage.lineNumber) { |
| 110 | usage.lineNumber = func->token->linenr(); |
| 111 | usage.column = func->token->column(); |
| 112 | } |
| 113 | usage.isC = func->token->isC(); |
| 114 | usage.isStatic = func->isStatic(); |
| 115 | |
| 116 | // TODO: why always overwrite this but not the filename and line? |
| 117 | usage.fileIndex = func->token->fileIndex(); |
| 118 | const std::string& fileName = tokenizer.list.file(func->token); |
| 119 | |
| 120 | // No filename set yet.. |
| 121 | if (usage.filename.empty()) { |
| 122 | usage.filename = fileName; |
| 123 | } |
| 124 | // Multiple files => filename = "+" |
| 125 | else if (usage.filename != fileName) { |