TODO: bail out on unexpected data
| 457 | |
| 458 | // TODO: bail out on unexpected data |
| 459 | void CheckUnusedFunctions::analyseWholeProgram(const Settings &settings, ErrorLogger &errorLogger, const std::string &buildDir) |
| 460 | { |
| 461 | std::map<std::string, Location> decls; |
| 462 | std::set<std::string> calls; |
| 463 | |
| 464 | const auto handler = [&decls, &calls](const char* checkattr, const tinyxml2::XMLElement* e, const AnalyzerInformation::Info& filesTxtInfo) { |
| 465 | if (std::strcmp(checkattr,"CheckUnusedFunctions") != 0) |
| 466 | return; |
| 467 | for (const tinyxml2::XMLElement *e2 = e->FirstChildElement(); e2; e2 = e2->NextSiblingElement()) { |
| 468 | const char* functionName = e2->Attribute("functionName"); |
| 469 | if (functionName == nullptr) |
| 470 | continue; |
| 471 | const char* name = e2->Name(); |
| 472 | if (std::strcmp(name,"functioncall") == 0) { |
| 473 | calls.insert(functionName); |
| 474 | continue; |
| 475 | } |
| 476 | if (std::strcmp(name,"functiondecl") == 0) { |
| 477 | const char* lineNumber = e2->Attribute("lineNumber"); |
| 478 | if (lineNumber) { |
| 479 | const char* file = e2->Attribute("file"); |
| 480 | const char* column = default_if_null(e2->Attribute("column"), "0"); |
| 481 | // cppcheck-suppress templateInstantiation - TODO: fix this - see #11631 |
| 482 | decls[functionName] = Location(file ? file : filesTxtInfo.sourceFile, strToInt<int>(lineNumber), strToInt<int>(column)); |
| 483 | } |
| 484 | } |
| 485 | } |
| 486 | }; |
| 487 | |
| 488 | const std::string err = AnalyzerInformation::processFilesTxt(buildDir, handler, settings.debugainfo); |
| 489 | if (!err.empty()) { |
| 490 | const ErrorMessage errmsg({}, "", Severity::error, err, "internalError", Certainty::normal); |
| 491 | errorLogger.reportErr(errmsg); |
| 492 | return; |
| 493 | } |
| 494 | |
| 495 | for (auto decl = decls.cbegin(); decl != decls.cend(); ++decl) { |
| 496 | const std::string &functionName = stripTemplateParameters(decl->first); |
| 497 | |
| 498 | if (settings.library.isentrypoint(functionName)) |
| 499 | continue; |
| 500 | |
| 501 | if (calls.find(functionName) == calls.end() && !isOperatorFunction(functionName)) { |
| 502 | const Location &loc = decl->second; |
| 503 | unusedFunctionError(errorLogger, loc.fileName, /*fileIndex*/ 0, loc.lineNumber, loc.column, functionName); |
| 504 | } |
| 505 | } |
| 506 | } |
| 507 | |
| 508 | void CheckUnusedFunctions::updateFunctionData(const CheckUnusedFunctions& checkUnusedFunctions) |
| 509 | { |
nothing calls this directly
no test coverage detected