11 #include "clang/AST/ASTContext.h" 12 #include "clang/ASTMatchers/ASTMatchFinder.h" 13 #include "clang/Tooling/FixIt.h" 24 return !clang::Lexer::makeFileCharRange(
25 clang::CharSourceRange::getCharRange(Range),
26 *Result.SourceManager, Result.Context->getLangOpts())
36 return selectFirst<const Expr>(
39 callExpr(hasParent(materializeTemporaryExpr(hasParent(
40 cxxConstructExpr(hasParent(exprWithCleanups(
41 hasParent(varDecl()))))))))
43 callExpr(hasParent(varDecl())).bind(
"e"))),
44 *Node, *Result.Context)) !=
nullptr;
51 return selectFirst<const Expr>(
55 expr(hasParent(materializeTemporaryExpr(
56 hasParent(cxxConstructExpr(
57 hasParent(callExpr()),
58 unless(hasParent(cxxOperatorCallExpr())))))))
60 expr(hasParent(callExpr()),
61 unless(hasParent(cxxOperatorCallExpr())))
63 *Node, *Result.Context)) !=
nullptr;
66 static bool isReturn(
const MatchFinder::MatchResult &
Result,
const Expr *Node) {
69 return selectFirst<const Expr>(
72 expr(hasParent(materializeTemporaryExpr(hasParent(
73 cxxConstructExpr(hasParent(exprWithCleanups(
74 hasParent(returnStmt()))))))))
76 expr(hasParent(returnStmt())).bind(
"e"))),
77 *Node, *Result.Context)) !=
nullptr;
89 llvm::StringRef Replacement) {
90 diag(Node->getBeginLoc(),
"perform subtraction in the time domain")
91 << FixItHint::CreateReplacement(Node->getSourceRange(), Replacement);
94 void TimeSubtractionCheck::registerMatchers(MatchFinder *Finder) {
96 {
"Hours",
"Minutes",
"Seconds",
"Millis",
"Micros",
"Nanos"}) {
97 std::string TimeInverse = (llvm::Twine(
"ToUnix") + ScaleName).str();
99 assert(Scale &&
"Unknow scale encountered");
101 auto TimeInverseMatcher = callExpr(callee(
102 functionDecl(hasName((llvm::Twine(
"::absl::") + TimeInverse).str()))
103 .bind(
"func_decl")));
113 hasArgument(0, binaryOperator(hasOperatorName(
"-"),
114 hasLHS(TimeInverseMatcher))
117 Finder->addMatcher(CallMatcher,
this);
122 auto OperandMatcher =
123 binaryOperator(hasOperatorName(
"-"), hasRHS(TimeInverseMatcher))
125 Finder->addMatcher(OperandMatcher,
this);
129 void TimeSubtractionCheck::check(
const MatchFinder::MatchResult &
Result) {
130 const auto *BinOp = Result.Nodes.getNodeAs<BinaryOperator>(
"binop");
131 std::string InverseName =
140 const auto *OuterCall = Result.Nodes.getNodeAs<CallExpr>(
"outer_call");
152 (llvm::Twine(NeedParens ?
"(" :
"") +
155 (NeedParens ?
")" :
""))
161 const auto *MaybeCallArg = selectFirst<const CallExpr>(
162 "arg",
match(expr(hasAncestor(
163 callExpr(callee(functionDecl(hasName(
166 *BinOp, *Result.Context));
167 if (MaybeCallArg && MaybeCallArg->getArg(0)->IgnoreImpCasts() == BinOp &&
177 (llvm::Twine(NeedParens ?
"(" :
"") +
181 (NeedParens ?
")" :
""))
static bool isArgument(const MatchFinder::MatchResult &Result, const Expr *Node)
std::vector< std::string > match(const SymbolIndex &I, const FuzzyFindRequest &Req, bool *Incomplete)
static std::string getNameAsString(const NamedDecl *Decl)
const std::pair< llvm::StringRef, llvm::StringRef > & getDurationInverseForScale(DurationScale Scale)
Given a Scale return the fully qualified inverse functions for it.
static bool isConstructorAssignment(const MatchFinder::MatchResult &Result, const Expr *Node)
static bool parensRequired(const MatchFinder::MatchResult &Result, const Expr *Node)
static bool isReturn(const MatchFinder::MatchResult &Result, const Expr *Node)
static bool InsideMacroDefinition(const MatchFinder::MatchResult &Result, SourceRange Range)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
llvm::Optional< DurationScale > getScaleForTimeInverse(llvm::StringRef Name)
Given the name of an inverse Time function (e.g., ToUnixSeconds), return its DurationScale, or None if a match is not found.
CharSourceRange Range
SourceRange for the file name.
std::string rewriteExprFromNumberToTime(const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale, const Expr *Node)
Assuming Node has a type int representing a time instant of Scale since The Epoch, return the expression to make it a suitable Time.
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
llvm::StringRef getDurationFactoryForScale(DurationScale Scale)
Returns the factory function name for a given Scale.
static void emitDiagnostic(const Expr *MovingCall, const DeclRefExpr *MoveArg, const UseAfterMove &Use, ClangTidyCheck *Check, ASTContext *Context)