1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- //===--- ExplicitMakePairCheck.cpp - clang-tidy -----------------*- C++ -*-===//
- //
- // 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 "ExplicitMakePairCheck.h"
- #include "clang/AST/ASTContext.h"
- #include "clang/ASTMatchers/ASTMatchFinder.h"
- #include "clang/ASTMatchers/ASTMatchers.h"
- using namespace clang::ast_matchers;
- namespace clang {
- namespace {
- AST_MATCHER(DeclRefExpr, hasExplicitTemplateArgs) {
- return Node.hasExplicitTemplateArgs();
- }
- } // namespace
- namespace tidy::google::build {
- void ExplicitMakePairCheck::registerMatchers(
- ast_matchers::MatchFinder *Finder) {
- // Look for std::make_pair with explicit template args. Ignore calls in
- // templates.
- Finder->addMatcher(
- callExpr(unless(isInTemplateInstantiation()),
- callee(expr(ignoringParenImpCasts(
- declRefExpr(hasExplicitTemplateArgs(),
- to(functionDecl(hasName("::std::make_pair"))))
- .bind("declref")))))
- .bind("call"),
- this);
- }
- void ExplicitMakePairCheck::check(const MatchFinder::MatchResult &Result) {
- const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call");
- const auto *DeclRef = Result.Nodes.getNodeAs<DeclRefExpr>("declref");
- // Sanity check: The use might have overriden ::std::make_pair.
- if (Call->getNumArgs() != 2)
- return;
- const Expr *Arg0 = Call->getArg(0)->IgnoreParenImpCasts();
- const Expr *Arg1 = Call->getArg(1)->IgnoreParenImpCasts();
- // If types don't match, we suggest replacing with std::pair and explicit
- // template arguments. Otherwise just remove the template arguments from
- // make_pair.
- if (Arg0->getType() != Call->getArg(0)->getType() ||
- Arg1->getType() != Call->getArg(1)->getType()) {
- diag(Call->getBeginLoc(), "for C++11-compatibility, use pair directly")
- << FixItHint::CreateReplacement(
- SourceRange(DeclRef->getBeginLoc(), DeclRef->getLAngleLoc()),
- "std::pair<");
- } else {
- diag(Call->getBeginLoc(),
- "for C++11-compatibility, omit template arguments from make_pair")
- << FixItHint::CreateRemoval(
- SourceRange(DeclRef->getLAngleLoc(), DeclRef->getRAngleLoc()));
- }
- }
- } // namespace tidy::google::build
- } // namespace clang
|