34 0, expr(hasType(cxxRecordDecl(hasName(
"::absl::Duration"))))),
35 hasArgument(1, expr().bind(
"arg")),
37 hasParent(functionTemplateDecl()),
38 unless(hasTemplateArgument(0, refersToType(builtinType()))),
39 hasAnyName(
"operator*=",
"operator/="))))
48 ofClass(cxxRecordDecl(hasName(
"::absl::Duration"))),
49 hasParent(functionTemplateDecl()),
50 unless(hasTemplateArgument(0, refersToType(builtinType()))),
51 hasAnyName(
"operator*=",
"operator/="))),
52 argumentCountIs(1), hasArgument(0, expr().bind(
"arg")))
60 callExpr(callee(functionDecl(
61 hasParent(functionTemplateDecl()),
62 unless(hasTemplateArgument(0, refersToType(builtinType()))),
63 hasAnyName(
"::absl::operator*",
"::absl::operator/"))),
65 hasArgument(0, expr(hasType(
66 cxxRecordDecl(hasName(
"::absl::Duration"))))),
67 hasArgument(1, expr().bind(
"arg")))
74 callExpr(callee(functionDecl(
75 hasParent(functionTemplateDecl()),
76 unless(hasTemplateArgument(0, refersToType(builtinType()))),
77 hasName(
"::absl::operator*"))),
78 argumentCountIs(2), hasArgument(0, expr().bind(
"arg")),
79 hasArgument(1, expr(hasType(
80 cxxRecordDecl(hasName(
"::absl::Duration"))))))
101 traverse(TK_AsIs, implicitCastExpr(
102 anyOf(hasCastKind(CK_UserDefinedConversion),
103 has(implicitCastExpr(
104 hasCastKind(CK_UserDefinedConversion)))),
107 DurationFactoryFunction(),
108 unless(hasParent(functionTemplateDecl())))),
109 hasArgument(0, expr().bind(
"arg")))))
115 const MatchFinder::MatchResult &Result) {
116 const llvm::StringRef Message =
117 "implicit conversion to 'int64_t' is deprecated in this context; use an "
118 "explicit cast instead";
120 TraversalKindScope RAII(*Result.Context, TK_AsIs);
122 const auto *ArgExpr = Result.Nodes.getNodeAs<Expr>(
"arg");
123 SourceLocation Loc = ArgExpr->getBeginLoc();
125 const auto *OuterExpr = Result.Nodes.getNodeAs<Expr>(
"OuterExpr");
127 if (!match(isInTemplateInstantiation(), *OuterExpr, *Result.Context)
129 if (!MatchedTemplateLocations.contains(Loc)) {
142 internal::Matcher<Stmt> IsInsideTemplate =
143 hasAncestor(decl(anyOf(classTemplateDecl(), functionTemplateDecl())));
144 if (!match(IsInsideTemplate, *ArgExpr, *Result.Context).empty())
145 MatchedTemplateLocations.insert(Loc);
147 DiagnosticBuilder Diag = diag(Loc, Message);
148 CharSourceRange SourceRange = Lexer::makeFileCharRange(
149 CharSourceRange::getTokenRange(ArgExpr->getSourceRange()),
150 *Result.SourceManager, Result.Context->getLangOpts());
151 if (SourceRange.isInvalid())
156 Diag << FixItHint::CreateInsertion(SourceRange.getBegin(),
157 "static_cast<int64_t>(")
158 << FixItHint::CreateInsertion(SourceRange.getEnd(),
")");