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;
}