10 #include "../utils/Matchers.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/Lex/Lexer.h"
21 namespace readability {
24 Options.store(Opts,
"IgnoreBaseInCopyConstructors",
25 IgnoreBaseInCopyConstructors);
28 void RedundantMemberInitCheck::registerMatchers(MatchFinder *Finder) {
31 hasDeclaration(cxxConstructorDecl(hasParent(
37 ast_type_traits::TK_AsIs,
39 unless(isDelegatingConstructor()),
41 anyOf(isUnion(), ast_matchers::isTemplateInstantiation()))),
42 forEachConstructorInitializer(
44 isWritten(), withInitializer(ignoringImplicit(Construct)),
45 unless(forField(hasType(isConstQualified()))),
46 unless(forField(hasParent(recordDecl(isUnion())))))
48 .bind(
"constructor")),
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");
58 if (IgnoreBaseInCopyConstructors && ConstructorDecl->isCopyConstructor() &&
59 Init->isBaseInitializer())
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());
69 diag(Init->getSourceLocation(),
70 "initializer for base class %0 is redundant")
71 << Construct->getType()
72 << FixItHint::CreateRemoval(Init->getSourceRange());