diff options
author | thegeorg <thegeorg@yandex-team.com> | 2024-03-13 13:58:24 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2024-03-13 14:11:53 +0300 |
commit | 11a895b7e15d1c5a1f52706396b82e3f9db953cb (patch) | |
tree | fabc6d883b0f946151f61ae7865cee9f529a1fdd /contrib/libs/clang16/tools/extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp | |
parent | 9685917341315774aad5733b1793b1e533a88bbb (diff) | |
download | ydb-11a895b7e15d1c5a1f52706396b82e3f9db953cb.tar.gz |
Export clang-format16 via ydblib project
6e6be3a95868fde888d801b7590af4044049563f
Diffstat (limited to 'contrib/libs/clang16/tools/extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp')
-rw-r--r-- | contrib/libs/clang16/tools/extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/contrib/libs/clang16/tools/extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp b/contrib/libs/clang16/tools/extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp new file mode 100644 index 0000000000..adfedb4e84 --- /dev/null +++ b/contrib/libs/clang16/tools/extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp @@ -0,0 +1,75 @@ +//===--- TriviallyDestructibleCheck.cpp - clang-tidy ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "TriviallyDestructibleCheck.h" +#include "../utils/LexerUtils.h" +#include "../utils/Matchers.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; +using namespace clang::ast_matchers::internal; +using namespace clang::tidy::matchers; + +namespace clang::tidy::performance { + +namespace { + +AST_MATCHER(Decl, isFirstDecl) { return Node.isFirstDecl(); } + +AST_MATCHER_P(CXXRecordDecl, hasBase, Matcher<QualType>, InnerMatcher) { + for (const CXXBaseSpecifier &BaseSpec : Node.bases()) { + QualType BaseType = BaseSpec.getType(); + if (InnerMatcher.matches(BaseType, Finder, Builder)) + return true; + } + return false; +} + +} // namespace + +void TriviallyDestructibleCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxDestructorDecl( + isDefaulted(), + unless(anyOf(isFirstDecl(), isVirtual(), + ofClass(cxxRecordDecl( + anyOf(hasBase(unless(isTriviallyDestructible())), + has(fieldDecl(unless( + hasType(isTriviallyDestructible())))))))))) + .bind("decl"), + this); +} + +void TriviallyDestructibleCheck::check(const MatchFinder::MatchResult &Result) { + const auto *MatchedDecl = Result.Nodes.getNodeAs<CXXDestructorDecl>("decl"); + + // Get locations of both first and out-of-line declarations. + SourceManager &SM = *Result.SourceManager; + const auto *FirstDecl = cast<CXXMethodDecl>(MatchedDecl->getFirstDecl()); + const SourceLocation FirstDeclEnd = utils::lexer::findNextTerminator( + FirstDecl->getEndLoc(), SM, getLangOpts()); + const CharSourceRange SecondDeclRange = CharSourceRange::getTokenRange( + MatchedDecl->getBeginLoc(), + utils::lexer::findNextTerminator(MatchedDecl->getEndLoc(), SM, + getLangOpts())); + if (FirstDeclEnd.isInvalid() || SecondDeclRange.isInvalid()) + return; + + // Report diagnostic. + diag(FirstDecl->getLocation(), + "class %0 can be made trivially destructible by defaulting the " + "destructor on its first declaration") + << FirstDecl->getParent() + << FixItHint::CreateInsertion(FirstDeclEnd, " = default") + << FixItHint::CreateRemoval(SecondDeclRange); + diag(MatchedDecl->getLocation(), "destructor definition is here", + DiagnosticIDs::Note); +} + +} // namespace clang::tidy::performance |