bool Qt6QLatin1StringCharToU::isInterestingCtorCall()

in src/checks/manuallevel/qt6-qlatin1stringchar-to-u.cpp [104:172]


bool Qt6QLatin1StringCharToU::isInterestingCtorCall(CXXConstructExpr *ctorExpr, const ClazyContext *const context, bool check_parent)
{
    CXXConstructorDecl *ctorDecl = ctorExpr->getConstructor();
    if (!isQLatin1CharDecl(ctorDecl) && !isQLatin1StringDecl(ctorDecl)) {
        return false;
    }

    Stmt *parent_stmt = clazy::parent(context->parentMap, ctorExpr);
    if (!parent_stmt) {
        return false;
    }
    bool oneFunctionalCast = false;
    // A given QLatin1Char/String call will have two ctorExpr passing the isQLatin1CharDecl/StringDecl
    // To avoid creating multiple fixit in case of nested QLatin1Char/String calls
    // it is important to only test the one right after a CXXFunctionalCastExpr with QLatin1Char/String name
    if (isa<CXXFunctionalCastExpr>(parent_stmt)) {
        auto *parent = dyn_cast<CXXFunctionalCastExpr>(parent_stmt);
        if (parent->getConversionFunction()->getNameAsString() != "QLatin1Char" && parent->getConversionFunction()->getNameAsString() != "QLatin1String") {
            return false;
        } // need to check that this call is related to a QString or a QChar
        if (check_parent) {
            m_QStringOrQChar_fix = relatedToQStringOrQChar(parent_stmt, context);
        }
        // in case of looking for left over, we don't do it here, because might go past the QLatin1Char/String we are nested in
        // and replace the one within
        // QString toto = QLatin1String ( something_not_supported ? QLatin1String("should not be corrected") : "toto" )
        // the inside one should not be corrected because the outside QLatin1String is staying.
        m_QChar = parent->getConversionFunction()->getNameAsString() == "QLatin1Char";

        oneFunctionalCast = true;
    }

    // Not checking the parent when looking for left over QLatin1String call nested in a QLatin1String whose fix is not supported
    if (!check_parent) {
        return oneFunctionalCast;
    }

    parent_stmt = context->parentMap->getParent(parent_stmt);
    // If an other CXXFunctionalCastExpr QLatin1String is found among the parents
    // the present QLatin1String call is nested in an other QLatin1String call and should be ignored.
    // The outer call will take care of it.
    // Unless the outer call is from a Macro, in which case the current call should not be ignored
    while (parent_stmt) {
        if (isa<CXXFunctionalCastExpr>(parent_stmt)) {
            auto *parent = dyn_cast<CXXFunctionalCastExpr>(parent_stmt);
            NamedDecl *ndecl = parent->getConversionFunction();
            if (ndecl) {
                if (ndecl->getNameAsString() == "QLatin1Char" || ndecl->getNameAsString() == "QLatin1String") {
                    if (parent_stmt->getBeginLoc().isMacroID()) {
                        auto parent_stmt_begin = parent_stmt->getBeginLoc();
                        auto parent_stmt_end = parent_stmt->getEndLoc();
                        auto parent_spl_begin = sm().getSpellingLoc(parent_stmt_begin);
                        auto parent_spl_end = sm().getSpellingLoc(parent_stmt_end);
                        auto ctorSpelling_loc = sm().getSpellingLoc(ctorExpr->getBeginLoc());
                        if (m_sm.isPointWithin(ctorSpelling_loc, parent_spl_begin, parent_spl_end)) {
                            return false;
                        }
                        return oneFunctionalCast;
                    }

                    return false;
                }
            }
        }
        parent_stmt = context->parentMap->getParent(parent_stmt);
    }

    return oneFunctionalCast;
}