llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-tools-extra Author: Congcong Cai (HerrCai0907) <details> <summary>Changes</summary> --- Patch is 31.84 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/131804.diff 25 Files Affected: - (modified) clang-tools-extra/clang-tidy/CMakeLists.txt (+2) - (modified) clang-tools-extra/clang-tidy/ClangTidy.cpp (+8-1) - (modified) clang-tools-extra/clang-tidy/ClangTidyForceLinker.h (+5) - (modified) clang-tools-extra/clang-tidy/ClangTidyModule.h (+2) - (modified) clang-tools-extra/clang-tidy/ClangTidyOptions.cpp (+53-3) - (modified) clang-tools-extra/clang-tidy/ClangTidyOptions.h (+15) - (added) clang-tools-extra/clang-tidy/custom/CMakeLists.txt (+20) - (added) clang-tools-extra/clang-tidy/custom/CustomTidyModule.cpp (+50) - (added) clang-tools-extra/clang-tidy/custom/QueryCheck.cpp (+102) - (added) clang-tools-extra/clang-tidy/custom/QueryCheck.h (+42) - (modified) clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp (+2) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+3) - (added) clang-tools-extra/docs/clang-tidy/QueryBasedCustomChecks.rst (+57) - (modified) clang-tools-extra/docs/clang-tidy/index.rst (+3) - (added) clang-tools-extra/test/clang-tidy/checkers/custom/Inputs/clang-tidy.yml (+22) - (added) clang-tools-extra/test/clang-tidy/checkers/custom/Inputs/incorrect-clang-tidy.yml (+10) - (added) clang-tools-extra/test/clang-tidy/checkers/custom/query-incorrect-query.cpp (+3) - (added) clang-tools-extra/test/clang-tidy/checkers/custom/query-partially-active-check.cpp (+5) - (added) clang-tools-extra/test/clang-tidy/checkers/custom/query.cpp (+7) - (added) clang-tools-extra/test/clang-tidy/infrastructure/Inputs/custom-query-check/append-clang-tidy.yml (+8) - (added) clang-tools-extra/test/clang-tidy/infrastructure/Inputs/custom-query-check/empty-clang-tidy.yml (+1) - (added) clang-tools-extra/test/clang-tidy/infrastructure/Inputs/custom-query-check/override-clang-tidy.yml (+11) - (added) clang-tools-extra/test/clang-tidy/infrastructure/Inputs/custom-query-check/root-clang-tidy.yml (+11) - (added) clang-tools-extra/test/clang-tidy/infrastructure/Inputs/custom-query-check/vfsoverlay.yaml (+44) - (added) clang-tools-extra/test/clang-tidy/infrastructure/custom-query-check.cpp (+45) ``````````diff diff --git a/clang-tools-extra/clang-tidy/CMakeLists.txt b/clang-tools-extra/clang-tidy/CMakeLists.txt index 93117cf1d6373..90efd2ef1f451 100644 --- a/clang-tools-extra/clang-tidy/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/CMakeLists.txt @@ -58,6 +58,7 @@ add_subdirectory(bugprone) add_subdirectory(cert) add_subdirectory(concurrency) add_subdirectory(cppcoreguidelines) +add_subdirectory(custom) add_subdirectory(darwin) add_subdirectory(fuchsia) add_subdirectory(google) @@ -85,6 +86,7 @@ set(ALL_CLANG_TIDY_CHECKS clangTidyCERTModule clangTidyConcurrencyModule clangTidyCppCoreGuidelinesModule + clangTidyCustomModule clangTidyDarwinModule clangTidyFuchsiaModule clangTidyGoogleModule diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp index d99847a82d168..f2a69e01a32c5 100644 --- a/clang-tools-extra/clang-tidy/ClangTidy.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp @@ -57,6 +57,11 @@ LLVM_INSTANTIATE_REGISTRY(clang::tidy::ClangTidyModuleRegistry) namespace clang::tidy { +namespace custom { +extern void registerCustomChecks(ClangTidyOptions const &O, + ClangTidyCheckFactories &Factories); +} // namespace custom + namespace { #if CLANG_TIDY_ENABLE_STATIC_ANALYZER static const char *AnalyzerCheckNamePrefix = "clang-analyzer-"; @@ -346,6 +351,7 @@ ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory( IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS) : Context(Context), OverlayFS(std::move(OverlayFS)), CheckFactories(new ClangTidyCheckFactories) { + custom::registerCustomChecks(Context.getOptions(), *CheckFactories); for (ClangTidyModuleRegistry::entry E : ClangTidyModuleRegistry::entries()) { std::unique_ptr<ClangTidyModule> Module = E.instantiate(); Module->addCheckFactories(*CheckFactories); @@ -416,7 +422,7 @@ ClangTidyASTConsumerFactory::createASTConsumer( .getCurrentWorkingDirectory(); if (WorkingDir) Context.setCurrentBuildDirectory(WorkingDir.get()); - + custom::registerCustomChecks(Context.getOptions(), *CheckFactories); std::vector<std::unique_ptr<ClangTidyCheck>> Checks = CheckFactories->createChecksForLanguage(&Context); @@ -659,6 +665,7 @@ getAllChecksAndOptions(bool AllowEnablingAnalyzerAlphaCheckers) { std::make_unique<DefaultOptionsProvider>(ClangTidyGlobalOptions(), Opts), AllowEnablingAnalyzerAlphaCheckers); ClangTidyCheckFactories Factories; + custom::registerCustomChecks(Context.getOptions(), Factories); for (const ClangTidyModuleRegistry::entry &Module : ClangTidyModuleRegistry::entries()) { Module.instantiate()->addCheckFactories(Factories); diff --git a/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h b/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h index adde9136ff1dd..50ac6e138df18 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h +++ b/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h @@ -54,6 +54,11 @@ extern volatile int CppCoreGuidelinesModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination = CppCoreGuidelinesModuleAnchorSource; +// This anchor is used to force the linker to link the CustomModule. +extern volatile int CustomModuleAnchorSource; +static int LLVM_ATTRIBUTE_UNUSED CustomModuleAnchorDestination = + CustomModuleAnchorSource; + // This anchor is used to force the linker to link the DarwinModule. extern volatile int DarwinModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED DarwinModuleAnchorDestination = diff --git a/clang-tools-extra/clang-tidy/ClangTidyModule.h b/clang-tools-extra/clang-tidy/ClangTidyModule.h index 28f54331755a7..6f0b2bf32a291 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyModule.h +++ b/clang-tools-extra/clang-tidy/ClangTidyModule.h @@ -62,6 +62,8 @@ class ClangTidyCheckFactories { }); } + void erase(llvm::StringRef CheckName) { Factories.erase(CheckName); } + /// Create instances of checks that are enabled. std::vector<std::unique_ptr<ClangTidyCheck>> createChecks(ClangTidyContext *Context) const; diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp index 8bac6f161fa05..acedbd8d41faa 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp @@ -8,12 +8,12 @@ #include "ClangTidyOptions.h" #include "ClangTidyModuleRegistry.h" +#include "clang/Basic/DiagnosticIDs.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Errc.h" #include "llvm/Support/ErrorOr.h" -#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBufferRef.h" #include "llvm/Support/Path.h" #include "llvm/Support/YAMLTraits.h" @@ -72,7 +72,8 @@ struct NOptionMap { NOptionMap(IO &, const ClangTidyOptions::OptionMap &OptionMap) { Options.reserve(OptionMap.size()); for (const auto &KeyValue : OptionMap) - Options.emplace_back(std::string(KeyValue.getKey()), KeyValue.getValue().Value); + Options.emplace_back(std::string(KeyValue.getKey()), + KeyValue.getValue().Value); } ClangTidyOptions::OptionMap denormalize(IO &) { ClangTidyOptions::OptionMap Map; @@ -126,6 +127,52 @@ void yamlize(IO &IO, ClangTidyOptions::OptionMap &Val, bool, } } +namespace { +struct MultiLineString { + std::string &S; +}; +} // namespace + +template <> struct BlockScalarTraits<MultiLineString> { + static void output(const MultiLineString &S, void *Ctxt, raw_ostream &OS) { + OS << S.S; + } + static StringRef input(StringRef Str, void *Ctxt, MultiLineString &S) { + S.S = Str; + return ""; + } +}; + +template <> struct ScalarEnumerationTraits<clang::DiagnosticIDs::Level> { + static void enumeration(IO &IO, clang::DiagnosticIDs::Level &Level) { + IO.enumCase(Level, "Error", clang::DiagnosticIDs::Level::Error); + IO.enumCase(Level, "Warning", clang::DiagnosticIDs::Level::Warning); + IO.enumCase(Level, "Note", clang::DiagnosticIDs::Level::Note); + } +}; +template <> struct SequenceElementTraits<ClangTidyOptions::CustomCheckDiag> { + static const bool flow = false; +}; +template <> struct MappingTraits<ClangTidyOptions::CustomCheckDiag> { + static void mapping(IO &IO, ClangTidyOptions::CustomCheckDiag &D) { + IO.mapRequired("BindName", D.BindName); + MultiLineString MLS{D.Message}; + IO.mapRequired("Message", MLS); + IO.mapOptional("Level", D.Level); + } +}; +template <> struct SequenceElementTraits<ClangTidyOptions::CustomCheckValue> { + static const bool flow = false; +}; +template <> struct MappingTraits<ClangTidyOptions::CustomCheckValue> { + static void mapping(IO &IO, ClangTidyOptions::CustomCheckValue &V) { + IO.mapRequired("Name", V.Name); + MultiLineString MLS{V.Query}; + IO.mapRequired("Query", MLS); + IO.mapRequired("Diagnostic", V.Diags); + } +}; + struct ChecksVariant { std::optional<std::string> AsString; std::optional<std::vector<std::string>> AsVector; @@ -181,6 +228,7 @@ template <> struct MappingTraits<ClangTidyOptions> { IO.mapOptional("InheritParentConfig", Options.InheritParentConfig); IO.mapOptional("UseColor", Options.UseColor); IO.mapOptional("SystemHeaders", Options.SystemHeaders); + IO.mapOptional("CustomChecks", Options.CustomChecks); } }; @@ -249,6 +297,8 @@ ClangTidyOptions &ClangTidyOptions::mergeWith(const ClangTidyOptions &Other, ClangTidyValue(KeyValue.getValue().Value, KeyValue.getValue().Priority + Order)); } + mergeVectors(CustomChecks, Other.CustomChecks); + return *this; } diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.h b/clang-tools-extra/clang-tidy/ClangTidyOptions.h index dd78c570d25d9..2a64ee8fdf7ea 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.h +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.h @@ -9,6 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H +#include "clang/Basic/DiagnosticIDs.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" @@ -17,6 +18,7 @@ #include "llvm/Support/MemoryBufferRef.h" #include "llvm/Support/VirtualFileSystem.h" #include <functional> +#include <map> #include <optional> #include <string> #include <system_error> @@ -129,6 +131,19 @@ struct ClangTidyOptions { /// Key-value mapping used to store check-specific options. OptionMap CheckOptions; + struct CustomCheckDiag { + std::string BindName; + std::string Message; + std::optional<DiagnosticIDs::Level> Level; + }; + struct CustomCheckValue { + std::string Name; + std::string Query; + llvm::SmallVector<CustomCheckDiag> Diags; + }; + using CustomCheckValueList = llvm::SmallVector<CustomCheckValue>; + std::optional<CustomCheckValueList> CustomChecks; + using ArgList = std::vector<std::string>; /// Add extra compilation arguments to the end of the list. diff --git a/clang-tools-extra/clang-tidy/custom/CMakeLists.txt b/clang-tools-extra/clang-tidy/custom/CMakeLists.txt new file mode 100644 index 0000000000000..40387b73b5253 --- /dev/null +++ b/clang-tools-extra/clang-tidy/custom/CMakeLists.txt @@ -0,0 +1,20 @@ +set(LLVM_LINK_COMPONENTS + support + ) + +add_clang_library(clangTidyCustomModule STATIC + CustomTidyModule.cpp + QueryCheck.cpp + + LINK_LIBS + clangTidy + clangTidyUtils + + DEPENDS + ClangDriverOptions + ) + +clang_target_link_libraries(clangTidyCustomModule + PRIVATE + clangQuery + ) diff --git a/clang-tools-extra/clang-tidy/custom/CustomTidyModule.cpp b/clang-tools-extra/clang-tidy/custom/CustomTidyModule.cpp new file mode 100644 index 0000000000000..e11a39f1a4ccf --- /dev/null +++ b/clang-tools-extra/clang-tidy/custom/CustomTidyModule.cpp @@ -0,0 +1,50 @@ +#include "../ClangTidy.h" +#include "../ClangTidyModule.h" +#include "../ClangTidyModuleRegistry.h" +#include "../ClangTidyOptions.h" +#include "QueryCheck.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" +#include <memory> + +namespace clang::tidy { +namespace custom { + +class CustomModule : public ClangTidyModule { +public: + void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {} +}; + +// FIXME: could be clearer to add parameter of addCheckFactories to pass +// Options? +extern void registerCustomChecks(ClangTidyOptions const &Options, + ClangTidyCheckFactories &Factories) { + static llvm::SmallSet<llvm::SmallString<32>, 8> CustomCheckNames{}; + if (!Options.CustomChecks.has_value() || Options.CustomChecks->empty()) + return; + for (llvm::SmallString<32> const &Name : CustomCheckNames) + Factories.erase(Name); + for (const ClangTidyOptions::CustomCheckValue &V : + Options.CustomChecks.value()) { + llvm::SmallString<32> Name = llvm::StringRef{"custom-" + V.Name}; + Factories.registerCheckFactory( + // add custom- prefix to avoid conflicts with builtin checks + Name, [&V](llvm::StringRef Name, ClangTidyContext *Context) { + return std::make_unique<custom::QueryCheck>(Name, V, Context); + }); + CustomCheckNames.insert(std::move(Name)); + } +} + +} // namespace custom + +// Register the AlteraTidyModule using this statically initialized variable. +static ClangTidyModuleRegistry::Add<custom::CustomModule> + X("custom-module", "Adds custom query lint checks."); + +// This anchor is used to force the linker to link in the generated object file +// and thus register the AlteraModule. +volatile int CustomModuleAnchorSource = 0; + +} // namespace clang::tidy diff --git a/clang-tools-extra/clang-tidy/custom/QueryCheck.cpp b/clang-tools-extra/clang-tidy/custom/QueryCheck.cpp new file mode 100644 index 0000000000000..c69e76918f7ed --- /dev/null +++ b/clang-tools-extra/clang-tidy/custom/QueryCheck.cpp @@ -0,0 +1,102 @@ +//===--- QueryCheck.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 "QueryCheck.h" +#include "../../clang-query/Query.h" +#include "../../clang-query/QueryParser.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/Dynamic/VariantValue.h" +#include "clang/Basic/DiagnosticIDs.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include <string> + +using namespace clang::ast_matchers; + +namespace clang::tidy::custom { + +QueryCheck::QueryCheck(llvm::StringRef Name, + const ClangTidyOptions::CustomCheckValue &V, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) { + for (const ClangTidyOptions::CustomCheckDiag &D : V.Diags) { + auto DiagnosticIdIt = + Diags + .try_emplace(D.Level.value_or(DiagnosticIDs::Warning), + llvm::StringMap<llvm::SmallVector<std::string>>{}) + .first; + auto DiagMessageIt = + DiagnosticIdIt->getSecond() + .try_emplace(D.BindName, llvm::SmallVector<std::string>{}) + .first; + DiagMessageIt->second.emplace_back(D.Message); + } + + clang::query::QuerySession QS({}); + llvm::StringRef QueryStringRef{V.Query}; + while (!QueryStringRef.empty()) { + query::QueryRef Q = query::QueryParser::parse(QueryStringRef, QS); + switch (Q->Kind) { + case query::QK_Match: { + const auto &MatchQuerry = llvm::cast<query::MatchQuery>(*Q); + Matchers.push_back(MatchQuerry.Matcher); + break; + } + case query::QK_Let: { + const auto &LetQuerry = llvm::cast<query::LetQuery>(*Q); + LetQuerry.run(llvm::errs(), QS); + break; + } + case query::QK_Invalid: { + const auto &InvalidQuerry = llvm::cast<query::InvalidQuery>(*Q); + Context->configurationDiag(InvalidQuerry.ErrStr); + break; + } + // FIXME: TODO + case query::QK_File: + case query::QK_DisableOutputKind: + case query::QK_EnableOutputKind: + case query::QK_SetOutputKind: + case query::QK_SetTraversalKind: + case query::QK_Help: + case query::QK_NoOp: + case query::QK_Quit: + case query::QK_SetBool: { + Context->configurationDiag("unsupported querry kind"); + } + } + QueryStringRef = Q->RemainingContent; + } +} + +void QueryCheck::registerMatchers(MatchFinder *Finder) { + for (const ast_matchers::dynamic::DynTypedMatcher &M : Matchers) + Finder->addDynamicMatcher(M, this); +} + +void QueryCheck::check(const MatchFinder::MatchResult &Result) { + auto Emit = [this](DiagMaps const &DiagMaps, std::string const &BindName, + DynTypedNode const &Node, DiagnosticIDs::Level Level) { + if (!DiagMaps.contains(Level)) + return; + auto &DiagMap = DiagMaps.at(Level); + if (!DiagMap.contains(BindName)) + return; + for (const std::string &Message : DiagMap.at(BindName)) { + diag(Node.getSourceRange().getBegin(), Message, Level); + } + }; + for (auto &[Name, Node] : Result.Nodes.getMap()) + Emit(Diags, Name, Node, DiagnosticIDs::Error); + for (auto &[Name, Node] : Result.Nodes.getMap()) + Emit(Diags, Name, Node, DiagnosticIDs::Warning); + // place Note last, otherwise it will not be emitted + for (auto &[Name, Node] : Result.Nodes.getMap()) + Emit(Diags, Name, Node, DiagnosticIDs::Note); +} +} // namespace clang::tidy::custom diff --git a/clang-tools-extra/clang-tidy/custom/QueryCheck.h b/clang-tools-extra/clang-tidy/custom/QueryCheck.h new file mode 100644 index 0000000000000..ded4cad4e3459 --- /dev/null +++ b/clang-tools-extra/clang-tidy/custom/QueryCheck.h @@ -0,0 +1,42 @@ +//===--- QueryCheck.h - clang-tidy ------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CUSTOM_QUERYCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CUSTOM_QUERYCHECK_H + +#include "../ClangTidyCheck.h" +#include "clang/ASTMatchers/Dynamic/VariantValue.h" +#include "clang/Basic/DiagnosticIDs.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" + +namespace clang::tidy::custom { + +/// FIXME: Write a short description. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/custom/query.html +class QueryCheck : public ClangTidyCheck { +public: + QueryCheck(llvm::StringRef Name, const ClangTidyOptions::CustomCheckValue &V, + ClangTidyContext *Context); + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + llvm::SmallVector<ast_matchers::dynamic::DynTypedMatcher> Matchers{}; + using DiagMaps = + llvm::DenseMap<DiagnosticIDs::Level, + llvm::StringMap<llvm::SmallVector<std::string>>>; + DiagMaps Diags; +}; + +} // namespace clang::tidy::custom + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CUSTOM_QUERYCHECK_H diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp index fa8887e4639b4..5784b05d2281d 100644 --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -60,6 +60,8 @@ Configuration files: Checks - Same as '--checks'. Additionally, the list of globs can be specified as a list instead of a string. + CustomChecks - Array of user defined checks based on + clang-query syntax. ExcludeHeaderFilterRegex - Same as '--exclude-header-filter'. ExtraArgs - Same as '--extra-arg'. ExtraArgsBefore - Same as '--extra-arg-before'. diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 2252efb498c2c..6d22f83f2248b 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -96,6 +96,9 @@ Improvements to clang-tidy `SystemHeaders` option is enabled. Note: this may lead to false negatives; downstream users may need to adjust their checks to preserve existing behavior. +- :program:`clang-tidy` now supports query based custom checks by `CustomChecks` + configuration option. + :doc:`Query Based Custom Check Document <clang-tidy/QueryBasedCustomChecks>` New checks ^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/QueryBasedCustomChecks.rst b/clang-tools-extra/docs/clang-tidy/QueryBasedCustomChecks.rst new file mode 100644 index 0000000000000..6efd8fe6797df --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/QueryBasedCustomChecks.rst @@ -0,0 +1,57 @@ +==================================== +Query Based Custom Clang-Tidy Checks +==================================== + +Introduction +============ + +This page provides examples of how to add query based custom checks for +:program:`clang-tidy`. + +Custom checks are based on clang-query syntax. Every custom checks will be +registered in `custom` module to avoid name conflict. They can be enabled or +disabled by the checks option like the builtin checks. + +Custom checks support inheritance from parent configurations like other +configuration items. + +Configuration +============= + +`CustomChecks` is a list of custom checks. Each check must contain + - Name: check name can been used in `-checks` option. + - Query: query string + - Diagnostic: list of diagnostics to be reported. + - BindName: name of the node to be bound in `Query`. + - Message: message to be reported. + - Level: severity of the diagnostic, the possible val... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/131804 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits