54 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "DurationDivisionCheck.h"10#include "clang/AST/ASTContext.h"11#include "clang/ASTMatchers/ASTMatchFinder.h"12#include "clang/Lex/Lexer.h"13 14namespace clang::tidy::abseil {15 16using namespace clang::ast_matchers;17 18void DurationDivisionCheck::registerMatchers(MatchFinder *Finder) {19 const auto DurationExpr =20 expr(hasType(cxxRecordDecl(hasName("::absl::Duration"))));21 Finder->addMatcher(22 traverse(TK_AsIs,23 implicitCastExpr(24 hasSourceExpression(ignoringParenCasts(25 cxxOperatorCallExpr(hasOverloadedOperatorName("/"),26 hasArgument(0, DurationExpr),27 hasArgument(1, DurationExpr))28 .bind("OpCall"))),29 hasImplicitDestinationType(qualType(unless(isInteger()))),30 unless(hasParent(cxxStaticCastExpr())),31 unless(hasParent(cStyleCastExpr())),32 unless(isInTemplateInstantiation()))),33 this);34}35 36void DurationDivisionCheck::check(const MatchFinder::MatchResult &Result) {37 const auto *OpCall = Result.Nodes.getNodeAs<CXXOperatorCallExpr>("OpCall");38 diag(OpCall->getOperatorLoc(),39 "operator/ on absl::Duration objects performs integer division; "40 "did you mean to use FDivDuration()?")41 << FixItHint::CreateInsertion(OpCall->getBeginLoc(),42 "absl::FDivDuration(")43 << FixItHint::CreateReplacement(44 SourceRange(OpCall->getOperatorLoc(), OpCall->getOperatorLoc()),45 ", ")46 << FixItHint::CreateInsertion(47 Lexer::getLocForEndOfToken(48 Result.SourceManager->getSpellingLoc(OpCall->getEndLoc()), 0,49 *Result.SourceManager, Result.Context->getLangOpts()),50 ")");51}52 53} // namespace clang::tidy::abseil54