================ @@ -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:
```cpp // Remove everything before call. Diagnostic << FixItHint::CreateRemoval(CharSourceRange::getCharRange( ComparisonExpr->getBeginLoc(), FindExpr->getBeginLoc())); // Rename function. Diagnostic << FixItHint::CreateReplacement(FindExpr->getExprLoc(), ReplacementFunction->getName()); // Replace everything after the opening parenthesis with search expression. const auto SearchExprText = Lexer::getSourceText( CharSourceRange::getTokenRange(SearchExpr->getSourceRange()), *Result.SourceManager, Result.Context->getLangOpts()); Diagnostic << FixItHint::CreateReplacement( CharSourceRange::getTokenRange(FindExpr->getArg(0)->getBeginLoc(), ComparisonExpr->getEndLoc()), (SearchExprText + ")").str()); // Add possible negation '!'. if (Neg) Diagnostic << FixItHint::CreateInsertion(FindExpr->getBeginLoc(), "!"); ``` I think this strategy might work, bit of a mix of both methods. Let me know what you think. 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