54 lines
2.2 KiB
C++
54 lines
2.2 KiB
C++
|
//===--- DurationDivisionCheck.cpp - clang-tidy----------------------------===//
|
||
|
//
|
||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#include "DurationDivisionCheck.h"
|
||
|
#include "clang/AST/ASTContext.h"
|
||
|
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||
|
#include "clang/Lex/Lexer.h"
|
||
|
|
||
|
namespace clang::tidy::abseil {
|
||
|
|
||
|
using namespace clang::ast_matchers;
|
||
|
|
||
|
void DurationDivisionCheck::registerMatchers(MatchFinder *Finder) {
|
||
|
const auto DurationExpr =
|
||
|
expr(hasType(cxxRecordDecl(hasName("::absl::Duration"))));
|
||
|
Finder->addMatcher(
|
||
|
traverse(TK_AsIs,
|
||
|
implicitCastExpr(
|
||
|
hasSourceExpression(ignoringParenCasts(
|
||
|
cxxOperatorCallExpr(hasOverloadedOperatorName("/"),
|
||
|
hasArgument(0, DurationExpr),
|
||
|
hasArgument(1, DurationExpr))
|
||
|
.bind("OpCall"))),
|
||
|
hasImplicitDestinationType(qualType(unless(isInteger()))),
|
||
|
unless(hasParent(cxxStaticCastExpr())),
|
||
|
unless(hasParent(cStyleCastExpr())),
|
||
|
unless(isInTemplateInstantiation()))),
|
||
|
this);
|
||
|
}
|
||
|
|
||
|
void DurationDivisionCheck::check(const MatchFinder::MatchResult &Result) {
|
||
|
const auto *OpCall = Result.Nodes.getNodeAs<CXXOperatorCallExpr>("OpCall");
|
||
|
diag(OpCall->getOperatorLoc(),
|
||
|
"operator/ on absl::Duration objects performs integer division; "
|
||
|
"did you mean to use FDivDuration()?")
|
||
|
<< FixItHint::CreateInsertion(OpCall->getBeginLoc(),
|
||
|
"absl::FDivDuration(")
|
||
|
<< FixItHint::CreateReplacement(
|
||
|
SourceRange(OpCall->getOperatorLoc(), OpCall->getOperatorLoc()),
|
||
|
", ")
|
||
|
<< FixItHint::CreateInsertion(
|
||
|
Lexer::getLocForEndOfToken(
|
||
|
Result.SourceManager->getSpellingLoc(OpCall->getEndLoc()), 0,
|
||
|
*Result.SourceManager, Result.Context->getLangOpts()),
|
||
|
")");
|
||
|
}
|
||
|
|
||
|
} // namespace clang::tidy::abseil
|