void UnnecessaryValueParamCheck::registerMatchers(MatchFinder *Finder) {
  const auto ExpensiveValueParamDecl =
      parmVarDecl(hasType(hasCanonicalType(allOf(matchers::isExpensiveToCopy(),
                                                 unless(referenceType())))),
                  decl().bind("param"));
  Finder->addMatcher(
      functionDecl(isDefinition(), unless(cxxMethodDecl(isOverride())),
                   unless(isInstantiated()),
                   has(typeLoc(forEach(ExpensiveValueParamDecl))),
                   decl().bind("functionDecl")),
      this);
}
void DeprecatedIosBaseAliasesCheck::registerMatchers(MatchFinder *Finder) {
  // Only register the matchers for C++; the functionality currently does not
  // provide any benefit to other languages, despite being benign.
  if (!getLangOpts().CPlusPlus)
    return;

  auto IoStateDecl = typedefDecl(hasAnyName(DeprecatedTypes)).bind("TypeDecl");
  auto IoStateType =
      qualType(hasDeclaration(IoStateDecl), unless(elaboratedType()));

  Finder->addMatcher(typeLoc(loc(IoStateType)).bind("TypeLoc"), this);
}
void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
  // Only register the matchers for C++; the functionality currently does not
  // provide any benefit to other languages, despite being benign.
  if (!getLangOpts().CPlusPlus)
    return;

  auto AutoPtrDecl = recordDecl(hasName("auto_ptr"), isFromStdNamespace());
  auto AutoPtrType = qualType(hasDeclaration(AutoPtrDecl));

  //   std::auto_ptr<int> a;
  //        ^~~~~~~~~~~~~
  //
  //   typedef std::auto_ptr<int> int_ptr_t;
  //                ^~~~~~~~~~~~~
  //
  //   std::auto_ptr<int> fn(std::auto_ptr<int>);
  //        ^~~~~~~~~~~~~         ^~~~~~~~~~~~~
  Finder->addMatcher(typeLoc(loc(qualType(AutoPtrType,
                                          // Skip elaboratedType() as the named
                                          // type will match soon thereafter.
                                          unless(elaboratedType()))))
                         .bind(AutoPtrTokenId),
                     this);

  //   using std::auto_ptr;
  //   ^~~~~~~~~~~~~~~~~~~
  Finder->addMatcher(usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(allOf(
                                   hasName("auto_ptr"), isFromStdNamespace()))))
                         .bind(AutoPtrTokenId),
                     this);

  // Find ownership transfers via copy construction and assignment.
  // AutoPtrOwnershipTransferId is bound to the the part that has to be wrapped
  // into std::move().
  //   std::auto_ptr<int> i, j;
  //   i = j;
  //   ~~~~^
  auto MovableArgumentMatcher =
      expr(isLValue(), hasType(AutoPtrType)).bind(AutoPtrOwnershipTransferId);

  Finder->addMatcher(
      cxxOperatorCallExpr(hasOverloadedOperatorName("="),
                          callee(cxxMethodDecl(ofClass(AutoPtrDecl))),
                          hasArgument(1, MovableArgumentMatcher)),
      this);
  Finder->addMatcher(cxxConstructExpr(hasType(AutoPtrType), argumentCountIs(1),
                                      hasArgument(0, MovableArgumentMatcher)),
                     this);
}
void IntegerTypesCheck::registerMatchers(MatchFinder *Finder) {
  // Find all TypeLocs. The relevant Style Guide rule only applies to C++.
  if (!getLangOpts().CPlusPlus)
    return;
  // Match any integer types, unless they are passed to a printf-based API:
  //
  // http://google.github.io/styleguide/cppguide.html#64-bit_Portability
  // "Where possible, avoid passing arguments of types specified by
  // bitwidth typedefs to printf-based APIs."
  Finder->addMatcher(typeLoc(loc(isInteger()),
                             unless(hasAncestor(callExpr(
                                 callee(functionDecl(hasAttr(attr::Format)))))))
                         .bind("tl"),
                     this);
  IdentTable = llvm::make_unique<IdentifierTable>(getLangOpts());
}
void AvoidConstParamsInDecls::registerMatchers(MatchFinder *Finder) {
  const auto ConstParamDecl =
      parmVarDecl(hasType(qualType(isConstQualified()))).bind("param");
  Finder->addMatcher(
      functionDecl(unless(isDefinition()),
                   // Lambdas are always their own definition, but they
                   // generate a non-definition FunctionDecl too. Ignore those.
                   // Class template instantiations have a non-definition
                   // CXXMethodDecl for methods that aren't used in this
                   // translation unit. Ignore those, as the template will have
                   // already been checked.
                   unless(cxxMethodDecl(ofClass(cxxRecordDecl(anyOf(
                       isLambda(), ast_matchers::isTemplateInstantiation()))))),
                   has(typeLoc(forEach(ConstParamDecl))))
          .bind("func"),
      this);
}
TEST(DynTypedNode, TypeLocSourceRange) {
  RangeVerifier<DynTypedNode> Verifier;
  Verifier.expectRange(1, 1, 1, 8);
  EXPECT_TRUE(Verifier.match("void f() {}", typeLoc(loc(functionType()))));
}
/// \brief Creates a matcher that finds the locations of types referring to the
/// \c std::auto_ptr() type.
///
/// \code
///   std::auto_ptr<int> a;
///        ^~~~~~~~~~~~~
///
///   typedef std::auto_ptr<int> int_ptr_t;
///                ^~~~~~~~~~~~~
///
///   std::auto_ptr<int> fn(std::auto_ptr<int>);
///        ^~~~~~~~~~~~~         ^~~~~~~~~~~~~
///
///   <etc...>
/// \endcode
TypeLocMatcher makeAutoPtrTypeLocMatcher() {
  // Skip elaboratedType() as the named type will match soon thereafter.
  return typeLoc(loc(qualType(AutoPtrType, unless(elaboratedType()))))
      .bind(AutoPtrTokenId);
}