================ @@ -189,7 +203,54 @@ void UseStartsEndsWithCheck::check(const MatchFinder::MatchResult &Result) { if (ComparisonExpr->getBeginLoc().isMacroID()) return; - const bool Neg = ComparisonExpr->getOpcode() == BO_NE; + bool Neg; + if (const auto *BO = llvm::dyn_cast<BinaryOperator>(ComparisonExpr)) { + Neg = BO->getOpcode() == BO_NE; + } else { + assert(llvm::isa<CXXOperatorCallExpr>(ComparisonExpr)); + Neg = llvm::cast<CXXOperatorCallExpr>(ComparisonExpr)->getOperator() == + OO_ExclaimEqual; + } + + // Check if this is a substr case + bool IsSubstr = FindFun->getName() == "substr"; + + if (IsSubstr) { + const auto *SubstrCall = cast<CXXMemberCallExpr>(FindExpr); + const Expr *Object = SubstrCall->getImplicitObjectArgument(); + + std::string ObjectStr; + std::string SearchStr; + bool Invalid = false; + + auto &SM = *Result.SourceManager; + + CharSourceRange ObjectRange = CharSourceRange::getTokenRange( + Object->getBeginLoc(), Object->getEndLoc()); + ObjectStr = Lexer::getSourceText(ObjectRange, SM, getLangOpts(), &Invalid).str(); + if (Invalid) + return; + + CharSourceRange SearchRange = CharSourceRange::getTokenRange( + SearchExpr->getBeginLoc(), SearchExpr->getEndLoc()); + SearchStr = Lexer::getSourceText(SearchRange, SM, getLangOpts(), &Invalid).str(); + if (Invalid) + return; + + // Build the new expression: [!]Object.starts_with(SearchExpr) + std::string NewExpr = + (llvm::Twine(Neg ? "!" : "") + ObjectStr + "." + + ReplacementFunction->getName() + "(" + SearchStr + ")").str(); + // Replace the entire comparison expression + auto Diag = diag(ComparisonExpr->getBeginLoc(), + "use %0 instead of substr() %select{==|!=}1") + << ReplacementFunction->getName() << Neg; + Diag << FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(ComparisonExpr->getSourceRange()), + NewExpr); + return; + } + ---------------- nicovank wrote:
Hmm, I now see why some changes here are necessary beyond the existing logic, this is for cases e.g. `v = str.subtr(0, v.size())`, because now we need to move `v` into the parenthesis. If possible, I think this and the other existing cases should be consolidated into a single replacement strategy for every case. I'll take a quick stab at it later today, these range replacements/insertions/removals are finicky. https://github.com/llvm/llvm-project/pull/116033 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits