clang-tools  14.0.0git
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  Finder->addMatcher(
30  cxxConstructorDecl(
31  unless(isDelegatingConstructor()), ofClass(unless(isUnion())),
32  forEachConstructorInitializer(
33  cxxCtorInitializer(
34  withInitializer(
35  cxxConstructExpr(
36  hasDeclaration(
37  cxxConstructorDecl(ofClass(cxxRecordDecl(
38  unless(isTriviallyDefaultConstructible()))))))
39  .bind("construct")),
40  unless(forField(hasType(isConstQualified()))),
41  unless(forField(hasParent(recordDecl(isUnion())))))
42  .bind("init")))
43  .bind("constructor"),
44  this);
45 }
46 
47 void RedundantMemberInitCheck::check(const MatchFinder::MatchResult &Result) {
48  const auto *Init = Result.Nodes.getNodeAs<CXXCtorInitializer>("init");
49  const auto *Construct = Result.Nodes.getNodeAs<CXXConstructExpr>("construct");
50  const auto *ConstructorDecl =
51  Result.Nodes.getNodeAs<CXXConstructorDecl>("constructor");
52 
53  if (IgnoreBaseInCopyConstructors && ConstructorDecl->isCopyConstructor() &&
54  Init->isBaseInitializer())
55  return;
56 
57  if (Construct->getNumArgs() == 0 ||
58  Construct->getArg(0)->isDefaultArgument()) {
59  if (Init->isAnyMemberInitializer()) {
60  diag(Init->getSourceLocation(), "initializer for member %0 is redundant")
61  << Init->getAnyMember()
62  << FixItHint::CreateRemoval(Init->getSourceRange());
63  } else {
64  diag(Init->getSourceLocation(),
65  "initializer for base class %0 is redundant")
66  << Construct->getType()
67  << FixItHint::CreateRemoval(Init->getSourceRange());
68  }
69  }
70 }
71 
72 } // namespace readability
73 } // namespace tidy
74 } // namespace clang
clang::tidy::ClangTidyOptions::OptionMap
llvm::StringMap< ClangTidyValue > OptionMap
Definition: ClangTidyOptions.h:115
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::clangd::check
bool check(llvm::StringRef File, llvm::function_ref< bool(const Position &)> ShouldCheckLine, const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts, bool EnableCodeCompletion)
Definition: Check.cpp:258
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
RedundantMemberInitCheck.h