11 #include "clang/Tooling/FixIt.h" 12 #include "llvm/ADT/IndexedMap.h" 23 return static_cast<unsigned>(Scale);
28 static llvm::Optional<llvm::APSInt>
30 double Value = FloatLiteral.getValueAsApproximateDouble();
31 if (std::fmod(Value, 1) == 0) {
32 if (Value >= static_cast<double>(1u << 31))
35 return llvm::APSInt::get(static_cast<int64_t>(Value));
40 const std::pair<llvm::StringRef, llvm::StringRef> &
42 static const llvm::IndexedMap<std::pair<llvm::StringRef, llvm::StringRef>,
47 llvm::IndexedMap<std::pair<llvm::StringRef, llvm::StringRef>,
51 InverseMap[DurationScale::Hours] =
52 std::make_pair(
"::absl::ToDoubleHours",
"::absl::ToInt64Hours");
53 InverseMap[DurationScale::Minutes] =
54 std::make_pair(
"::absl::ToDoubleMinutes",
"::absl::ToInt64Minutes");
55 InverseMap[DurationScale::Seconds] =
56 std::make_pair(
"::absl::ToDoubleSeconds",
"::absl::ToInt64Seconds");
57 InverseMap[DurationScale::Milliseconds] = std::make_pair(
58 "::absl::ToDoubleMilliseconds",
"::absl::ToInt64Milliseconds");
59 InverseMap[DurationScale::Microseconds] = std::make_pair(
60 "::absl::ToDoubleMicroseconds",
"::absl::ToInt64Microseconds");
61 InverseMap[DurationScale::Nanoseconds] = std::make_pair(
62 "::absl::ToDoubleNanoseconds",
"::absl::ToInt64Nanoseconds");
66 return InverseMap[Scale];
71 static llvm::Optional<std::string>
74 const std::pair<llvm::StringRef, llvm::StringRef> &InverseFunctions =
76 if (
const auto *MaybeCallArg = selectFirst<const Expr>(
78 match(callExpr(callee(functionDecl(hasAnyName(
79 InverseFunctions.first, InverseFunctions.second))),
80 hasArgument(0, expr().bind(
"e"))),
81 Node, *Result.Context))) {
82 return tooling::fixit::getText(*MaybeCallArg, *Result.Context).str();
91 case DurationScale::Hours:
93 case DurationScale::Minutes:
94 return "absl::Minutes";
95 case DurationScale::Seconds:
96 return "absl::Seconds";
97 case DurationScale::Milliseconds:
98 return "absl::Milliseconds";
99 case DurationScale::Microseconds:
100 return "absl::Microseconds";
101 case DurationScale::Nanoseconds:
102 return "absl::Nanoseconds";
104 llvm_unreachable(
"unknown scaling factor");
110 anyOf(integerLiteral(equals(0)), floatLiteral(equals(0.0)));
113 if (selectFirst<const clang::Expr>(
114 "val", match(expr(ignoringImpCasts(ZeroMatcher)).bind(
"val"), Node,
115 *Result.Context)) !=
nullptr)
120 if (selectFirst<const clang::Expr>(
121 "val", match(cxxFunctionalCastExpr(
123 anyOf(isInteger(), realFloatingPointType())),
124 hasSourceExpression(initListExpr(
125 hasInit(0, ignoringParenImpCasts(ZeroMatcher)))))
127 Node, *Result.Context)) !=
nullptr)
133 llvm::Optional<std::string>
136 if (
const Expr *MaybeCastArg = selectFirst<const Expr>(
138 match(expr(anyOf(cxxStaticCastExpr(
139 hasDestinationType(realFloatingPointType()),
140 hasSourceExpression(expr().bind(
"cast_arg"))),
142 hasDestinationType(realFloatingPointType()),
143 hasSourceExpression(expr().bind(
"cast_arg"))),
144 cxxFunctionalCastExpr(
145 hasDestinationType(realFloatingPointType()),
146 hasSourceExpression(expr().bind(
"cast_arg"))))),
147 Node, *Result.Context)))
148 return tooling::fixit::getText(*MaybeCastArg, *Result.Context).str();
153 llvm::Optional<std::string>
156 if (
const auto *LitFloat = llvm::dyn_cast<FloatingLiteral>(&Node))
159 return IntValue->toString(10);
167 if (llvm::Optional<std::string> MaybeArg =
stripFloatCast(Result, Node))
171 if (llvm::Optional<std::string> MaybeArg =
176 return tooling::fixit::getText(Node, *Result.Context).str();
180 static const llvm::StringMap<DurationScale> ScaleMap(
181 {{
"ToDoubleHours", DurationScale::Hours},
182 {
"ToInt64Hours", DurationScale::Hours},
183 {
"ToDoubleMinutes", DurationScale::Minutes},
184 {
"ToInt64Minutes", DurationScale::Minutes},
185 {
"ToDoubleSeconds", DurationScale::Seconds},
186 {
"ToInt64Seconds", DurationScale::Seconds},
187 {
"ToDoubleMilliseconds", DurationScale::Milliseconds},
188 {
"ToInt64Milliseconds", DurationScale::Milliseconds},
189 {
"ToDoubleMicroseconds", DurationScale::Microseconds},
190 {
"ToInt64Microseconds", DurationScale::Microseconds},
191 {
"ToDoubleNanoseconds", DurationScale::Nanoseconds},
192 {
"ToInt64Nanoseconds", DurationScale::Nanoseconds}});
194 auto ScaleIter = ScaleMap.find(std::string(Name));
195 if (ScaleIter == ScaleMap.end())
198 return ScaleIter->second;
204 const Expr &RootNode = *Node->IgnoreParenImpCasts();
207 if (llvm::Optional<std::string> MaybeRewrite =
209 return *MaybeRewrite;
212 return std::string(
"absl::ZeroDuration()");
std::string rewriteExprFromNumberToDuration(const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale, const Expr *Node)
Assuming Node has type double or int representing a time interval of Scale, return the expression to ...
static llvm::Optional< std::string > rewriteInverseDurationCall(const MatchFinder::MatchResult &Result, DurationScale Scale, const Expr &Node)
If Node is a call to the inverse of Scale, return that inverse's argument, otherwise None...
llvm::StringRef getFactoryForScale(DurationScale Scale)
Returns the factory function name for a given Scale.
unsigned operator()(DurationScale Scale) const
static constexpr llvm::StringLiteral Name
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
std::string simplifyDurationFactoryArg(const MatchFinder::MatchResult &Result, const Expr &Node)
llvm::Optional< DurationScale > getScaleForInverse(llvm::StringRef Name)
Given the name of an inverse Duration function (e.g., ToDoubleSeconds), return its DurationScale...
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static llvm::Optional< llvm::APSInt > truncateIfIntegral(const FloatingLiteral &FloatLiteral)
Returns an integer if the fractional part of a FloatingLiteral is 0.
llvm::Optional< std::string > stripFloatCast(const ast_matchers::MatchFinder::MatchResult &Result, const Expr &Node)
Possibly strip a floating point cast expression.
llvm::Optional< std::string > stripFloatLiteralFraction(const MatchFinder::MatchResult &Result, const Expr &Node)
bool IsLiteralZero(const MatchFinder::MatchResult &Result, const Expr &Node)
Returns true if Node is a value which evaluates to a literal 0.
const std::pair< llvm::StringRef, llvm::StringRef > & getInverseForScale(DurationScale Scale)
Given a Scale return the fully qualified inverse functions for it.
DurationScale
Duration factory and conversion scales.