11 #include "clang/AST/ASTContext.h" 12 #include "clang/ASTMatchers/ASTMatchFinder.h" 13 #include "clang/Lex/Lexer.h" 19 namespace readability {
21 RedundantDeclarationCheck::RedundantDeclarationCheck(StringRef
Name,
24 IgnoreMacros(Options.getLocalOrGlobal(
"IgnoreMacros", true)) {}
28 namedDecl(anyOf(varDecl(unless(isDefinition())),
29 functionDecl(unless(anyOf(isDefinition(), isDefaulted(),
30 hasParent(friendDecl()))))))
36 const auto *D = Result.Nodes.getNodeAs<NamedDecl>(
"Decl");
37 const auto *Prev = D->getPreviousDecl();
40 if (!Prev->getLocation().isValid())
42 if (Prev->getLocation() == D->getLocation())
45 (D->getLocation().isMacroID() || Prev->getLocation().isMacroID()))
48 for (
const auto &Parent : Result.Context->getParents(*Prev))
49 if (Parent.get<FriendDecl>())
52 const SourceManager &SM = *Result.SourceManager;
54 const bool DifferentHeaders =
55 !SM.isInMainFile(D->getLocation()) &&
56 !SM.isWrittenInSameFile(Prev->getLocation(), D->getLocation());
58 bool MultiVar =
false;
59 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
61 for (
const auto Other : VD->getDeclContext()->decls()) {
62 if (Other != D && Other->getLocStart() == VD->getLocStart()) {
69 SourceLocation EndLoc = Lexer::getLocForEndOfToken(
70 D->getSourceRange().getEnd(), 0, SM, Result.Context->getLangOpts());
72 auto Diag =
diag(D->getLocation(),
"redundant %0 declaration") << D;
73 if (!MultiVar && !DifferentHeaders)
74 Diag << FixItHint::CreateRemoval(
75 SourceRange(D->getSourceRange().getBegin(), EndLoc));
77 diag(Prev->getLocation(),
"previously declared here", DiagnosticIDs::Note);
Base class for all clang-tidy checks.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.