Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:18

0001 //===--- DurationRewriter.h - clang-tidy ------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONREWRITER_H
0010 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONREWRITER_H
0011 
0012 #include "clang/ASTMatchers/ASTMatchFinder.h"
0013 #include "clang/ASTMatchers/ASTMatchers.h"
0014 #include <cinttypes>
0015 #include <optional>
0016 
0017 namespace clang::tidy::abseil {
0018 
0019 /// Duration factory and conversion scales
0020 enum class DurationScale : std::uint8_t {
0021   Hours = 0,
0022   Minutes,
0023   Seconds,
0024   Milliseconds,
0025   Microseconds,
0026   Nanoseconds,
0027 };
0028 
0029 /// Given a `Scale`, return the appropriate factory function call for
0030 /// constructing a `Duration` for that scale.
0031 llvm::StringRef getDurationFactoryForScale(DurationScale Scale);
0032 
0033 /// Given a 'Scale', return the appropriate factory function call for
0034 /// constructing a `Time` for that scale.
0035 llvm::StringRef getTimeFactoryForScale(DurationScale Scale);
0036 
0037 // Determine if `Node` represents a literal floating point or integral zero.
0038 bool isLiteralZero(const ast_matchers::MatchFinder::MatchResult &Result,
0039                    const Expr &Node);
0040 
0041 /// Possibly strip a floating point cast expression.
0042 ///
0043 /// If `Node` represents an explicit cast to a floating point type, return
0044 /// the textual context of the cast argument, otherwise `std::nullopt`.
0045 std::optional<std::string>
0046 stripFloatCast(const ast_matchers::MatchFinder::MatchResult &Result,
0047                const Expr &Node);
0048 
0049 /// Possibly remove the fractional part of a floating point literal.
0050 ///
0051 /// If `Node` represents a floating point literal with a zero fractional part,
0052 /// return the textual context of the integral part, otherwise `std::nullopt`.
0053 std::optional<std::string>
0054 stripFloatLiteralFraction(const ast_matchers::MatchFinder::MatchResult &Result,
0055                           const Expr &Node);
0056 
0057 /// Possibly further simplify a duration factory function's argument, without
0058 /// changing the scale of the factory function. Return that simplification or
0059 /// the text of the argument if no simplification is possible.
0060 std::string
0061 simplifyDurationFactoryArg(const ast_matchers::MatchFinder::MatchResult &Result,
0062                            const Expr &Node);
0063 
0064 /// Given the name of an inverse Duration function (e.g., `ToDoubleSeconds`),
0065 /// return its `DurationScale`, or `std::nullopt` if a match is not found.
0066 std::optional<DurationScale> getScaleForDurationInverse(llvm::StringRef Name);
0067 
0068 /// Given the name of an inverse Time function (e.g., `ToUnixSeconds`),
0069 /// return its `DurationScale`, or `std::nullopt` if a match is not found.
0070 std::optional<DurationScale> getScaleForTimeInverse(llvm::StringRef Name);
0071 
0072 /// Given a `Scale` return the fully qualified inverse functions for it.
0073 /// The first returned value is the inverse for `double`, and the second
0074 /// returned value is the inverse for `int64`.
0075 const std::pair<llvm::StringRef, llvm::StringRef> &
0076 getDurationInverseForScale(DurationScale Scale);
0077 
0078 /// Returns the Time inverse function name for a given `Scale`.
0079 llvm::StringRef getTimeInverseForScale(DurationScale Scale);
0080 
0081 /// Assuming `Node` has type `double` or `int` representing a time interval of
0082 /// `Scale`, return the expression to make it a suitable `Duration`.
0083 std::string rewriteExprFromNumberToDuration(
0084     const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale,
0085     const Expr *Node);
0086 
0087 /// Assuming `Node` has a type `int` representing a time instant of `Scale`
0088 /// since The Epoch, return the expression to make it a suitable `Time`.
0089 std::string rewriteExprFromNumberToTime(
0090     const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale,
0091     const Expr *Node);
0092 
0093 /// Return `false` if `E` is a either: not a macro at all; or an argument to
0094 /// one.  In the both cases, we often want to do the transformation.
0095 bool isInMacro(const ast_matchers::MatchFinder::MatchResult &Result,
0096                const Expr *E);
0097 
0098 AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher<FunctionDecl>,
0099                      DurationConversionFunction) {
0100   using namespace clang::ast_matchers;
0101   return functionDecl(
0102       hasAnyName("::absl::ToDoubleHours", "::absl::ToDoubleMinutes",
0103                  "::absl::ToDoubleSeconds", "::absl::ToDoubleMilliseconds",
0104                  "::absl::ToDoubleMicroseconds", "::absl::ToDoubleNanoseconds",
0105                  "::absl::ToInt64Hours", "::absl::ToInt64Minutes",
0106                  "::absl::ToInt64Seconds", "::absl::ToInt64Milliseconds",
0107                  "::absl::ToInt64Microseconds", "::absl::ToInt64Nanoseconds"));
0108 }
0109 
0110 AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher<FunctionDecl>,
0111                      DurationFactoryFunction) {
0112   using namespace clang::ast_matchers;
0113   return functionDecl(hasAnyName("::absl::Nanoseconds", "::absl::Microseconds",
0114                                  "::absl::Milliseconds", "::absl::Seconds",
0115                                  "::absl::Minutes", "::absl::Hours"));
0116 }
0117 
0118 AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher<FunctionDecl>,
0119                      TimeConversionFunction) {
0120   using namespace clang::ast_matchers;
0121   return functionDecl(hasAnyName(
0122       "::absl::ToUnixHours", "::absl::ToUnixMinutes", "::absl::ToUnixSeconds",
0123       "::absl::ToUnixMillis", "::absl::ToUnixMicros", "::absl::ToUnixNanos"));
0124 }
0125 
0126 AST_MATCHER_FUNCTION_P(ast_matchers::internal::Matcher<Stmt>,
0127                        comparisonOperatorWithCallee,
0128                        ast_matchers::internal::Matcher<Decl>, funcDecl) {
0129   using namespace clang::ast_matchers;
0130   return binaryOperator(
0131       anyOf(hasOperatorName(">"), hasOperatorName(">="), hasOperatorName("=="),
0132             hasOperatorName("<="), hasOperatorName("<")),
0133       hasEitherOperand(ignoringImpCasts(callExpr(callee(funcDecl)))));
0134 }
0135 
0136 } // namespace clang::tidy::abseil
0137 
0138 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONREWRITER_H