DurationSubtractionCheck.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. //===--- DurationSubtractionCheck.cpp - clang-tidy ------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "DurationSubtractionCheck.h"
  9. #include "DurationRewriter.h"
  10. #include "clang/AST/ASTContext.h"
  11. #include "clang/ASTMatchers/ASTMatchFinder.h"
  12. #include "clang/Tooling/FixIt.h"
  13. #include <optional>
  14. using namespace clang::ast_matchers;
  15. namespace clang::tidy::abseil {
  16. void DurationSubtractionCheck::registerMatchers(MatchFinder *Finder) {
  17. Finder->addMatcher(
  18. binaryOperator(
  19. hasOperatorName("-"),
  20. hasLHS(callExpr(callee(functionDecl(DurationConversionFunction())
  21. .bind("function_decl")),
  22. hasArgument(0, expr().bind("lhs_arg")))))
  23. .bind("binop"),
  24. this);
  25. }
  26. void DurationSubtractionCheck::check(const MatchFinder::MatchResult &Result) {
  27. const auto *Binop = Result.Nodes.getNodeAs<BinaryOperator>("binop");
  28. const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>("function_decl");
  29. // Don't try to replace things inside of macro definitions.
  30. if (Binop->getExprLoc().isMacroID() || Binop->getExprLoc().isInvalid())
  31. return;
  32. std::optional<DurationScale> Scale =
  33. getScaleForDurationInverse(FuncDecl->getName());
  34. if (!Scale)
  35. return;
  36. std::string RhsReplacement =
  37. rewriteExprFromNumberToDuration(Result, *Scale, Binop->getRHS());
  38. const Expr *LhsArg = Result.Nodes.getNodeAs<Expr>("lhs_arg");
  39. diag(Binop->getBeginLoc(), "perform subtraction in the duration domain")
  40. << FixItHint::CreateReplacement(
  41. Binop->getSourceRange(),
  42. (llvm::Twine("absl::") + FuncDecl->getName() + "(" +
  43. tooling::fixit::getText(*LhsArg, *Result.Context) + " - " +
  44. RhsReplacement + ")")
  45. .str());
  46. }
  47. } // namespace clang::tidy::abseil