brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.4 KiB · ac56f5d Raw
69 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 "ExplicitMakePairCheck.h"10#include "clang/AST/ASTContext.h"11#include "clang/ASTMatchers/ASTMatchFinder.h"12#include "clang/ASTMatchers/ASTMatchers.h"13 14using namespace clang::ast_matchers;15 16namespace clang {17namespace {18AST_MATCHER(DeclRefExpr, hasExplicitTemplateArgs) {19  return Node.hasExplicitTemplateArgs();20}21} // namespace22 23namespace tidy::google::build {24 25void ExplicitMakePairCheck::registerMatchers(26    ast_matchers::MatchFinder *Finder) {27  // Look for std::make_pair with explicit template args. Ignore calls in28  // templates.29  Finder->addMatcher(30      callExpr(unless(isInTemplateInstantiation()),31               callee(expr(ignoringParenImpCasts(32                   declRefExpr(hasExplicitTemplateArgs(),33                               to(functionDecl(hasName("::std::make_pair"))))34                       .bind("declref")))))35          .bind("call"),36      this);37}38 39void ExplicitMakePairCheck::check(const MatchFinder::MatchResult &Result) {40  const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call");41  const auto *DeclRef = Result.Nodes.getNodeAs<DeclRefExpr>("declref");42 43  // Sanity check: The use might have overriden ::std::make_pair.44  if (Call->getNumArgs() != 2)45    return;46 47  const Expr *Arg0 = Call->getArg(0)->IgnoreParenImpCasts();48  const Expr *Arg1 = Call->getArg(1)->IgnoreParenImpCasts();49 50  // If types don't match, we suggest replacing with std::pair and explicit51  // template arguments. Otherwise just remove the template arguments from52  // make_pair.53  if (Arg0->getType() != Call->getArg(0)->getType() ||54      Arg1->getType() != Call->getArg(1)->getType()) {55    diag(Call->getBeginLoc(), "for C++11-compatibility, use pair directly")56        << FixItHint::CreateReplacement(57               SourceRange(DeclRef->getBeginLoc(), DeclRef->getLAngleLoc()),58               "std::pair<");59  } else {60    diag(Call->getBeginLoc(),61         "for C++11-compatibility, omit template arguments from make_pair")62        << FixItHint::CreateRemoval(63               SourceRange(DeclRef->getLAngleLoc(), DeclRef->getRAngleLoc()));64  }65}66 67} // namespace tidy::google::build68} // namespace clang69