DurationComparisonCheck.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. //===--- DurationComparisonCheck.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 "DurationComparisonCheck.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 DurationComparisonCheck::registerMatchers(MatchFinder *Finder) {
  17. auto Matcher = expr(comparisonOperatorWithCallee(functionDecl(
  18. functionDecl(DurationConversionFunction())
  19. .bind("function_decl"))))
  20. .bind("binop");
  21. Finder->addMatcher(Matcher, this);
  22. }
  23. void DurationComparisonCheck::check(const MatchFinder::MatchResult &Result) {
  24. const auto *Binop = Result.Nodes.getNodeAs<BinaryOperator>("binop");
  25. std::optional<DurationScale> Scale = getScaleForDurationInverse(
  26. Result.Nodes.getNodeAs<FunctionDecl>("function_decl")->getName());
  27. if (!Scale)
  28. return;
  29. // In most cases, we'll only need to rewrite one of the sides, but we also
  30. // want to handle the case of rewriting both sides. This is much simpler if
  31. // we unconditionally try and rewrite both, and let the rewriter determine
  32. // if nothing needs to be done.
  33. if (isInMacro(Result, Binop->getLHS()) || isInMacro(Result, Binop->getRHS()))
  34. return;
  35. std::string LhsReplacement =
  36. rewriteExprFromNumberToDuration(Result, *Scale, Binop->getLHS());
  37. std::string RhsReplacement =
  38. rewriteExprFromNumberToDuration(Result, *Scale, Binop->getRHS());
  39. diag(Binop->getBeginLoc(), "perform comparison in the duration domain")
  40. << FixItHint::CreateReplacement(Binop->getSourceRange(),
  41. (llvm::Twine(LhsReplacement) + " " +
  42. Binop->getOpcodeStr() + " " +
  43. RhsReplacement)
  44. .str());
  45. }
  46. } // namespace clang::tidy::abseil