1//===--- DurationFactoryFloatCheck.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
9#include "DurationFactoryFloatCheck.h"
10#include "DurationRewriter.h"
11#include "clang/AST/ASTContext.h"
12#include "clang/ASTMatchers/ASTMatchFinder.h"
13#include "clang/Lex/Lexer.h"
14#include <optional>
15
16using namespace clang::ast_matchers;
17
18namespace clang::tidy::abseil {
19
20// Returns `true` if `Range` is inside a macro definition.
21static bool insideMacroDefinition(const MatchFinder::MatchResult &Result,
22 SourceRange Range) {
23 return !clang::Lexer::makeFileCharRange(
24 Range: clang::CharSourceRange::getCharRange(R: Range),
25 SM: *Result.SourceManager, LangOpts: Result.Context->getLangOpts())
26 .isValid();
27}
28
29void DurationFactoryFloatCheck::registerMatchers(MatchFinder *Finder) {
30 Finder->addMatcher(
31 NodeMatch: callExpr(callee(InnerMatcher: functionDecl(DurationFactoryFunction())),
32 hasArgument(N: 0, InnerMatcher: anyOf(cxxStaticCastExpr(hasDestinationType(
33 InnerMatcher: realFloatingPointType())),
34 cStyleCastExpr(hasDestinationType(
35 InnerMatcher: realFloatingPointType())),
36 cxxFunctionalCastExpr(hasDestinationType(
37 InnerMatcher: realFloatingPointType())),
38 floatLiteral())))
39 .bind(ID: "call"),
40 Action: this);
41}
42
43void DurationFactoryFloatCheck::check(const MatchFinder::MatchResult &Result) {
44 const auto *MatchedCall = Result.Nodes.getNodeAs<CallExpr>(ID: "call");
45
46 // Don't try and replace things inside of macro definitions.
47 if (insideMacroDefinition(Result, MatchedCall->getSourceRange()))
48 return;
49
50 const Expr *Arg = MatchedCall->getArg(Arg: 0)->IgnoreImpCasts();
51 // Arguments which are macros are ignored.
52 if (Arg->getBeginLoc().isMacroID())
53 return;
54
55 std::optional<std::string> SimpleArg = stripFloatCast(Result, Node: *Arg);
56 if (!SimpleArg)
57 SimpleArg = stripFloatLiteralFraction(Result, Node: *Arg);
58
59 if (SimpleArg) {
60 diag(Loc: MatchedCall->getBeginLoc(), Description: "use the integer version of absl::%0")
61 << MatchedCall->getDirectCallee()->getName()
62 << FixItHint::CreateReplacement(Arg->getSourceRange(), *SimpleArg);
63 }
64}
65
66} // namespace clang::tidy::abseil
67

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp