clang-tools  14.0.0git
DurationConversionCastCheck.cpp
Go to the documentation of this file.
1 //===--- DurationConversionCastCheck.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 
10 #include "DurationRewriter.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/Tooling/FixIt.h"
14 
15 using namespace clang::ast_matchers;
16 
17 namespace clang {
18 namespace tidy {
19 namespace abseil {
20 
21 void DurationConversionCastCheck::registerMatchers(MatchFinder *Finder) {
22  auto CallMatcher = ignoringImpCasts(callExpr(
23  callee(functionDecl(DurationConversionFunction()).bind("func_decl")),
24  hasArgument(0, expr().bind("arg"))));
25 
26  Finder->addMatcher(
27  expr(anyOf(
28  cxxStaticCastExpr(hasSourceExpression(CallMatcher)).bind("cast_expr"),
29  cStyleCastExpr(hasSourceExpression(CallMatcher)).bind("cast_expr"),
30  cxxFunctionalCastExpr(hasSourceExpression(CallMatcher))
31  .bind("cast_expr"))),
32  this);
33 }
34 
36  const MatchFinder::MatchResult &Result) {
37  const auto *MatchedCast =
38  Result.Nodes.getNodeAs<ExplicitCastExpr>("cast_expr");
39 
40  if (isInMacro(Result, MatchedCast))
41  return;
42 
43  const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>("func_decl");
44  const auto *Arg = Result.Nodes.getNodeAs<Expr>("arg");
45  StringRef ConversionFuncName = FuncDecl->getName();
46 
47  llvm::Optional<DurationScale> Scale =
48  getScaleForDurationInverse(ConversionFuncName);
49  if (!Scale)
50  return;
51 
52  // Casting a double to an integer.
53  if (MatchedCast->getTypeAsWritten()->isIntegerType() &&
54  ConversionFuncName.contains("Double")) {
55  llvm::StringRef NewFuncName = getDurationInverseForScale(*Scale).second;
56 
57  diag(MatchedCast->getBeginLoc(),
58  "duration should be converted directly to an integer rather than "
59  "through a type cast")
60  << FixItHint::CreateReplacement(
61  MatchedCast->getSourceRange(),
62  (llvm::Twine(NewFuncName.substr(2)) + "(" +
63  tooling::fixit::getText(*Arg, *Result.Context) + ")")
64  .str());
65  }
66 
67  // Casting an integer to a double.
68  if (MatchedCast->getTypeAsWritten()->isRealFloatingType() &&
69  ConversionFuncName.contains("Int64")) {
70  llvm::StringRef NewFuncName = getDurationInverseForScale(*Scale).first;
71 
72  diag(MatchedCast->getBeginLoc(), "duration should be converted directly to "
73  "a floating-point number rather than "
74  "through a type cast")
75  << FixItHint::CreateReplacement(
76  MatchedCast->getSourceRange(),
77  (llvm::Twine(NewFuncName.substr(2)) + "(" +
78  tooling::fixit::getText(*Arg, *Result.Context) + ")")
79  .str());
80  }
81 }
82 
83 } // namespace abseil
84 } // namespace tidy
85 } // namespace clang
clang::tidy::abseil::getScaleForDurationInverse
llvm::Optional< DurationScale > getScaleForDurationInverse(llvm::StringRef Name)
Given the name of an inverse Duration function (e.g., ToDoubleSeconds), return its DurationScale,...
Definition: DurationRewriter.cpp:231
clang::tidy::abseil::isInMacro
bool isInMacro(const MatchFinder::MatchResult &Result, const Expr *E)
Definition: DurationRewriter.cpp:305
clang::tidy::modernize::getText
static StringRef getText(const Token &Tok, const SourceManager &Sources)
Definition: UseOverrideCheck.cpp:78
clang::ast_matchers
Definition: AbseilMatcher.h:14
clang::tidy::abseil::getDurationInverseForScale
const std::pair< llvm::StringRef, llvm::StringRef > & getDurationInverseForScale(DurationScale Scale)
Given a Scale return the fully qualified inverse functions for it.
Definition: DurationRewriter.cpp:40
DurationRewriter.h
clang::clangd::check
bool check(llvm::StringRef File, llvm::function_ref< bool(const Position &)> ShouldCheckLine, const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts, bool EnableCodeCompletion)
Definition: Check.cpp:258
DurationConversionCastCheck.h
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27