RedundantMemberInitCheck.cpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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. #include "RedundantMemberInitCheck.h"
  9. #include "../utils/Matchers.h"
  10. #include "clang/AST/ASTContext.h"
  11. #include "clang/ASTMatchers/ASTMatchFinder.h"
  12. #include "clang/Lex/Lexer.h"
  13. #include <algorithm>
  14. using namespace clang::ast_matchers;
  15. using namespace clang::tidy::matchers;
  16. namespace clang::tidy::readability {
  17. void RedundantMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  18. Options.store(Opts, "IgnoreBaseInCopyConstructors",
  19. IgnoreBaseInCopyConstructors);
  20. }
  21. void RedundantMemberInitCheck::registerMatchers(MatchFinder *Finder) {
  22. Finder->addMatcher(
  23. cxxConstructorDecl(
  24. unless(isDelegatingConstructor()), ofClass(unless(isUnion())),
  25. forEachConstructorInitializer(
  26. cxxCtorInitializer(
  27. withInitializer(
  28. cxxConstructExpr(
  29. hasDeclaration(
  30. cxxConstructorDecl(ofClass(cxxRecordDecl(
  31. unless(isTriviallyDefaultConstructible()))))))
  32. .bind("construct")),
  33. unless(forField(hasType(isConstQualified()))),
  34. unless(forField(hasParent(recordDecl(isUnion())))))
  35. .bind("init")))
  36. .bind("constructor"),
  37. this);
  38. }
  39. void RedundantMemberInitCheck::check(const MatchFinder::MatchResult &Result) {
  40. const auto *Init = Result.Nodes.getNodeAs<CXXCtorInitializer>("init");
  41. const auto *Construct = Result.Nodes.getNodeAs<CXXConstructExpr>("construct");
  42. const auto *ConstructorDecl =
  43. Result.Nodes.getNodeAs<CXXConstructorDecl>("constructor");
  44. if (IgnoreBaseInCopyConstructors && ConstructorDecl->isCopyConstructor() &&
  45. Init->isBaseInitializer())
  46. return;
  47. if (Construct->getNumArgs() == 0 ||
  48. Construct->getArg(0)->isDefaultArgument()) {
  49. if (Init->isAnyMemberInitializer()) {
  50. diag(Init->getSourceLocation(), "initializer for member %0 is redundant")
  51. << Init->getAnyMember()
  52. << FixItHint::CreateRemoval(Init->getSourceRange());
  53. } else {
  54. diag(Init->getSourceLocation(),
  55. "initializer for base class %0 is redundant")
  56. << Construct->getType()
  57. << FixItHint::CreateRemoval(Init->getSourceRange());
  58. }
  59. }
  60. }
  61. } // namespace clang::tidy::readability