void FunctionArgsByRef::processFunction()

in src/checks/level2/function-args-by-ref.cpp [97:153]


void FunctionArgsByRef::processFunction(FunctionDecl *func)
{
    if (!func || !func->isThisDeclarationADefinition() || func->isDeleted() || shouldIgnoreOperator(func)) {
        return;
    }

    if (m_context->isQtDeveloper() && shouldIgnoreFunction(func)) {
        return;
    }

    Stmt *body = func->getBody();

    auto funcParams = Utils::functionParameters(func);
    for (unsigned int i = 0; i < funcParams.size(); ++i) {
        ParmVarDecl *param = funcParams[i];
        const QualType paramQt = clazy::unrefQualType(param->getType());
        const Type *paramType = paramQt.getTypePtrOrNull();
        if (!paramType || paramType->isIncompleteType() || paramType->isDependentType()) {
            continue;
        }

        if (shouldIgnoreClass(paramType->getAsCXXRecordDecl())) {
            continue;
        }

        clazy::QualTypeClassification classif;
        bool success = clazy::classifyQualType(m_context, param->getType(), param, classif, body);
        if (!success) {
            continue;
        }

        std::vector<CXXCtorInitializer *> ctorInits = Utils::ctorInitializer(dyn_cast<CXXConstructorDecl>(func), param);
        if (Utils::ctorInitializerContainsMove(ctorInits)) {
            continue;
        }

        if (classif.passBigTypeByConstRef || classif.passNonTriviallyCopyableByConstRef) {
            std::string error;
            std::vector<FixItHint> fixits;

            std::string paramStr = param->getType().getAsString(lo());
            const std::string funcName = func->getQualifiedNameAsString();

            if (const std::string paramName = param->getNameAsString(); !paramName.empty())
                paramStr.append(" " + paramName);

            if (classif.passNonTriviallyCopyableByConstRef) { // Prefer this warning, because we might otherwise annoy user with specific size of Qt classes
                error = funcName + ": Missing reference on non-trivial type (" + paramStr + ')';
            } else if (classif.passBigTypeByConstRef) {
                error = warningMsgForSmallType(classif.size_of_T, paramStr);
            }

            addFixits(fixits, func, i);
            emitWarning(param->getBeginLoc(), error, fixits);
        }
    }
}