clang-tools  11.0.0
RedundantMemberInitCheck.cpp
Go to the documentation of this file.
1 //===--- RedundantMemberInitCheck.cpp - clang-tidy-------------------------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "../utils/Matchers.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/Lex/Lexer.h"
14 #include <algorithm>
15 
16 using namespace clang::ast_matchers;
17 using namespace clang::tidy::matchers;
18 
19 namespace clang {
20 namespace tidy {
21 namespace readability {
22 
23 void RedundantMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
24  Options.store(Opts, "IgnoreBaseInCopyConstructors",
25  IgnoreBaseInCopyConstructors);
26 }
27 
28 void RedundantMemberInitCheck::registerMatchers(MatchFinder *Finder) {
29  auto Construct =
30  cxxConstructExpr(
31  hasDeclaration(cxxConstructorDecl(hasParent(
32  cxxRecordDecl(unless(isTriviallyDefaultConstructible()))))))
33  .bind("construct");
34 
35  Finder->addMatcher(
36  traverse(
37  ast_type_traits::TK_AsIs,
38  cxxConstructorDecl(
39  unless(isDelegatingConstructor()),
40  ofClass(unless(
41  anyOf(isUnion(), ast_matchers::isTemplateInstantiation()))),
42  forEachConstructorInitializer(
43  cxxCtorInitializer(
44  isWritten(), withInitializer(ignoringImplicit(Construct)),
45  unless(forField(hasType(isConstQualified()))),
46  unless(forField(hasParent(recordDecl(isUnion())))))
47  .bind("init")))
48  .bind("constructor")),
49  this);
50 }
51 
52 void RedundantMemberInitCheck::check(const MatchFinder::MatchResult &Result) {
53  const auto *Init = Result.Nodes.getNodeAs<CXXCtorInitializer>("init");
54  const auto *Construct = Result.Nodes.getNodeAs<CXXConstructExpr>("construct");
55  const auto *ConstructorDecl =
56  Result.Nodes.getNodeAs<CXXConstructorDecl>("constructor");
57 
58  if (IgnoreBaseInCopyConstructors && ConstructorDecl->isCopyConstructor() &&
59  Init->isBaseInitializer())
60  return;
61 
62  if (Construct->getNumArgs() == 0 ||
63  Construct->getArg(0)->isDefaultArgument()) {
64  if (Init->isAnyMemberInitializer()) {
65  diag(Init->getSourceLocation(), "initializer for member %0 is redundant")
66  << Init->getAnyMember()
67  << FixItHint::CreateRemoval(Init->getSourceRange());
68  } else {
69  diag(Init->getSourceLocation(),
70  "initializer for base class %0 is redundant")
71  << Construct->getType()
72  << FixItHint::CreateRemoval(Init->getSourceRange());
73  }
74  }
75 }
76 
77 } // namespace readability
78 } // namespace tidy
79 } // namespace clang
clang::tidy::matchers
Definition: clang-tidy/utils/Matchers.h:17
clang::tidy::utils::type_traits::isTriviallyDefaultConstructible
bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context)
Returns true if Type is trivially default constructible.
Definition: TypeTraits.cpp:92
clang::ast_matchers
Definition: AbseilMatcher.h:14
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
RedundantMemberInitCheck.h
clang::tidy::ClangTidyOptions::OptionMap
std::map< std::string, ClangTidyValue > OptionMap
Definition: ClangTidyOptions.h:111