| 1363 | } |
| 1364 | |
| 1365 | void CheckClassImpl::privateFunctions() |
| 1366 | { |
| 1367 | if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("unusedPrivateFunction")) |
| 1368 | return; |
| 1369 | |
| 1370 | logChecker("CheckClass::privateFunctions"); // style |
| 1371 | |
| 1372 | for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { |
| 1373 | |
| 1374 | // do not check borland classes with properties.. |
| 1375 | if (Token::findsimplematch(scope->bodyStart, "; __property ;", scope->bodyEnd)) |
| 1376 | continue; |
| 1377 | |
| 1378 | std::list<const Function*> privateFuncs; |
| 1379 | for (const Function &func : scope->functionList) { |
| 1380 | // Get private functions.. |
| 1381 | if (func.type == FunctionType::eFunction && func.access == AccessControl::Private && !func.isOperator()) // TODO: There are smarter ways to check private operator usage |
| 1382 | privateFuncs.push_back(&func); |
| 1383 | } |
| 1384 | |
| 1385 | // Bailout for overridden virtual functions of base classes |
| 1386 | if (!scope->definedType->derivedFrom.empty()) { |
| 1387 | // Check virtual functions |
| 1388 | for (auto it = privateFuncs.cbegin(); it != privateFuncs.cend();) { |
| 1389 | if ((*it)->isImplicitlyVirtual(true)) // Give true as default value to be returned if we don't see all base classes |
| 1390 | it = privateFuncs.erase(it); |
| 1391 | else |
| 1392 | ++it; |
| 1393 | } |
| 1394 | } |
| 1395 | |
| 1396 | while (!privateFuncs.empty()) { |
| 1397 | const auto& pf = privateFuncs.front(); |
| 1398 | if (pf->token->isAttributeMaybeUnused() || pf->token->isAttributeUnused()) { |
| 1399 | privateFuncs.pop_front(); |
| 1400 | continue; |
| 1401 | } |
| 1402 | if (pf->tokenDef && (pf->tokenDef->isAttributeMaybeUnused() || pf->tokenDef->isAttributeUnused())) { |
| 1403 | privateFuncs.pop_front(); |
| 1404 | continue; |
| 1405 | } |
| 1406 | // Check that all private functions are used |
| 1407 | bool used = checkFunctionUsage(pf, scope); // Usage in this class |
| 1408 | // Check in friend classes |
| 1409 | const std::vector<Type::FriendInfo>& friendList = scope->definedType->friendList; |
| 1410 | for (std::size_t i = 0; i < friendList.size() && !used; i++) { |
| 1411 | if (friendList[i].type) |
| 1412 | used = checkFunctionUsage(pf, friendList[i].type->classScope); |
| 1413 | else |
| 1414 | used = true; // Assume, it is used if we do not see friend class |
| 1415 | } |
| 1416 | |
| 1417 | if (!used) |
| 1418 | unusedPrivateFunctionError(pf->token, pf->tokenDef, scope->className, pf->name()); |
| 1419 | |
| 1420 | privateFuncs.pop_front(); |
| 1421 | } |
| 1422 | } |