diff options
Diffstat (limited to 'clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp')
-rw-r--r-- | clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp | 64 |
1 files changed, 15 insertions, 49 deletions
diff --git a/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp index 80ecf8a812e..06765144539 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "DurationFactoryFloatCheck.h" +#include "DurationRewriter.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Tooling/FixIt.h" @@ -18,19 +19,6 @@ namespace clang { namespace tidy { namespace abseil { -// Returns an integer if the fractional part of a `FloatingLiteral` is `0`. -static llvm::Optional<llvm::APSInt> -truncateIfIntegral(const FloatingLiteral &FloatLiteral) { - double Value = FloatLiteral.getValueAsApproximateDouble(); - if (std::fmod(Value, 1) == 0) { - if (Value >= static_cast<double>(1u << 31)) - return llvm::None; - - return llvm::APSInt::get(static_cast<int64_t>(Value)); - } - return llvm::None; -} - // Returns `true` if `Range` is inside a macro definition. static bool InsideMacroDefinition(const MatchFinder::MatchResult &Result, SourceRange Range) { @@ -42,21 +30,14 @@ static bool InsideMacroDefinition(const MatchFinder::MatchResult &Result, void DurationFactoryFloatCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( - callExpr( - callee(functionDecl(hasAnyName( - "absl::Nanoseconds", "absl::Microseconds", "absl::Milliseconds", - "absl::Seconds", "absl::Minutes", "absl::Hours"))), - hasArgument(0, - anyOf(cxxStaticCastExpr( - hasDestinationType(realFloatingPointType()), - hasSourceExpression(expr().bind("cast_arg"))), - cStyleCastExpr( - hasDestinationType(realFloatingPointType()), - hasSourceExpression(expr().bind("cast_arg"))), - cxxFunctionalCastExpr( - hasDestinationType(realFloatingPointType()), - hasSourceExpression(expr().bind("cast_arg"))), - floatLiteral().bind("float_literal")))) + callExpr(callee(functionDecl(DurationFactoryFunction())), + hasArgument(0, anyOf(cxxStaticCastExpr(hasDestinationType( + realFloatingPointType())), + cStyleCastExpr(hasDestinationType( + realFloatingPointType())), + cxxFunctionalCastExpr(hasDestinationType( + realFloatingPointType())), + floatLiteral()))) .bind("call"), this); } @@ -73,31 +54,16 @@ void DurationFactoryFloatCheck::check(const MatchFinder::MatchResult &Result) { if (Arg->getBeginLoc().isMacroID()) return; - // Check for casts to `float` or `double`. - if (const auto *MaybeCastArg = Result.Nodes.getNodeAs<Expr>("cast_arg")) { + llvm::Optional<std::string> SimpleArg = stripFloatCast(Result, *Arg); + if (!SimpleArg) + SimpleArg = stripFloatLiteralFraction(Result, *Arg); + + if (SimpleArg) { diag(MatchedCall->getBeginLoc(), (llvm::Twine("use the integer version of absl::") + MatchedCall->getDirectCallee()->getName()) .str()) - << FixItHint::CreateReplacement( - Arg->getSourceRange(), - tooling::fixit::getText(*MaybeCastArg, *Result.Context)); - return; - } - - // Check for floats without fractional components. - if (const auto *LitFloat = - Result.Nodes.getNodeAs<FloatingLiteral>("float_literal")) { - // Attempt to simplify a `Duration` factory call with a literal argument. - if (llvm::Optional<llvm::APSInt> IntValue = truncateIfIntegral(*LitFloat)) { - diag(MatchedCall->getBeginLoc(), - (llvm::Twine("use the integer version of absl::") + - MatchedCall->getDirectCallee()->getName()) - .str()) - << FixItHint::CreateReplacement(LitFloat->getSourceRange(), - IntValue->toString(/*radix=*/10)); - return; - } + << FixItHint::CreateReplacement(Arg->getSourceRange(), *SimpleArg); } } |