97 while (Multiplier != 1.0) {
98 std::optional<std::tuple<DurationScale, double>> Result =
102 if (std::get<1>(*Result) == 1.0)
103 return std::get<0>(*Result);
104 Multiplier = std::get<1>(*Result);
105 OldScale = std::get<0>(*Result);
114 callee(functionDecl(durationFactoryFunction()).bind(
"call_decl")),
117 ignoringImpCasts(anyOf(
118 cxxFunctionalCastExpr(
120 anyOf(isInteger(), realFloatingPointType())),
121 hasSourceExpression(initListExpr())),
122 integerLiteral(equals(0)), floatLiteral(equals(0.0)),
123 binaryOperator(hasOperatorName(
"*"),
124 hasEitherOperand(ignoringImpCasts(
125 anyOf(integerLiteral(), floatLiteral()))))
127 binaryOperator(hasOperatorName(
"/"), hasRHS(floatLiteral()))
128 .bind(
"div_binop")))))
134 const auto *Call = Result.Nodes.getNodeAs<CallExpr>(
"call");
137 if (Call->getExprLoc().isMacroID())
140 const Expr *Arg = Call->getArg(0)->IgnoreParenImpCasts();
142 if (Arg->getBeginLoc().isMacroID())
147 diag(Call->getBeginLoc(),
148 "use ZeroDuration() for zero-length time intervals")
149 << FixItHint::CreateReplacement(Call->getSourceRange(),
150 "absl::ZeroDuration()");
154 const auto *CallDecl = Result.Nodes.getNodeAs<FunctionDecl>(
"call_decl");
155 std::optional<DurationScale> MaybeScale =
161 const Expr *Remainder =
nullptr;
162 std::optional<DurationScale> NewScale;
165 if (
const auto *MultBinOp =
166 Result.Nodes.getNodeAs<BinaryOperator>(
"mult_binop")) {
171 const auto *IntLit = dyn_cast<IntegerLiteral>(MultBinOp->getLHS());
172 const auto *FloatLit = dyn_cast<FloatingLiteral>(MultBinOp->getLHS());
173 if (IntLit || FloatLit) {
176 Remainder = MultBinOp->getRHS();
181 IntLit = dyn_cast<IntegerLiteral>(MultBinOp->getRHS());
182 FloatLit = dyn_cast<FloatingLiteral>(MultBinOp->getRHS());
183 if (IntLit || FloatLit) {
186 Remainder = MultBinOp->getLHS();
189 }
else if (
const auto *DivBinOp =
190 Result.Nodes.getNodeAs<BinaryOperator>(
"div_binop")) {
193 const auto *FloatLit = cast<FloatingLiteral>(DivBinOp->getRHS());
195 std::optional<DurationScale> NewScale =
196 getNewScale(Scale, 1.0 / FloatLit->getValueAsApproximateDouble());
198 const Expr *Remainder = DivBinOp->getLHS();
202 diag(Call->getBeginLoc(),
"internal duration scaling can be removed")
203 << FixItHint::CreateReplacement(
204 Call->getSourceRange(),
206 tooling::fixit::getText(*Remainder, *Result.Context) +
")")
212 assert(Remainder &&
"No remainder found");
215 diag(Call->getBeginLoc(),
"internal duration scaling can be removed")
216 << FixItHint::CreateReplacement(
217 Call->getSourceRange(),
219 tooling::fixit::getText(*Remainder, *Result.Context) +
")")