Skip to content

Commit 6ab7149

Browse files
committed
impl
1 parent 6fa8f7e commit 6ab7149

File tree

7 files changed

+181
-0
lines changed

7 files changed

+181
-0
lines changed

clang-tools-extra/clang-tidy/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ add_subdirectory(bugprone)
5858
add_subdirectory(cert)
5959
add_subdirectory(concurrency)
6060
add_subdirectory(cppcoreguidelines)
61+
add_subdirectory(custom)
6162
add_subdirectory(darwin)
6263
add_subdirectory(fuchsia)
6364
add_subdirectory(google)
@@ -85,6 +86,7 @@ set(ALL_CLANG_TIDY_CHECKS
8586
clangTidyCERTModule
8687
clangTidyConcurrencyModule
8788
clangTidyCppCoreGuidelinesModule
89+
clangTidyCustomModule
8890
clangTidyDarwinModule
8991
clangTidyFuchsiaModule
9092
clangTidyGoogleModule

clang-tools-extra/clang-tidy/ClangTidy.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ LLVM_INSTANTIATE_REGISTRY(clang::tidy::ClangTidyModuleRegistry)
5757

5858
namespace clang::tidy {
5959

60+
namespace custom {
61+
extern void setOptions(ClangTidyOptions const &O);
62+
} // namespace custom
63+
6064
namespace {
6165
#if CLANG_TIDY_ENABLE_STATIC_ANALYZER
6266
static const char *AnalyzerCheckNamePrefix = "clang-analyzer-";
@@ -346,6 +350,7 @@ ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory(
346350
IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS)
347351
: Context(Context), OverlayFS(std::move(OverlayFS)),
348352
CheckFactories(new ClangTidyCheckFactories) {
353+
custom::setOptions(Context.getOptions());
349354
for (ClangTidyModuleRegistry::entry E : ClangTidyModuleRegistry::entries()) {
350355
std::unique_ptr<ClangTidyModule> Module = E.instantiate();
351356
Module->addCheckFactories(*CheckFactories);
@@ -659,6 +664,7 @@ getAllChecksAndOptions(bool AllowEnablingAnalyzerAlphaCheckers) {
659664
std::make_unique<DefaultOptionsProvider>(ClangTidyGlobalOptions(), Opts),
660665
AllowEnablingAnalyzerAlphaCheckers);
661666
ClangTidyCheckFactories Factories;
667+
custom::setOptions(Context.getOptions());
662668
for (const ClangTidyModuleRegistry::entry &Module :
663669
ClangTidyModuleRegistry::entries()) {
664670
Module.instantiate()->addCheckFactories(Factories);

clang-tools-extra/clang-tidy/ClangTidyForceLinker.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ extern volatile int CppCoreGuidelinesModuleAnchorSource;
5454
static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination =
5555
CppCoreGuidelinesModuleAnchorSource;
5656

57+
// This anchor is used to force the linker to link the CustomModule.
58+
extern volatile int CustomModuleAnchorSource;
59+
static int LLVM_ATTRIBUTE_UNUSED CustomModuleAnchorDestination =
60+
CustomModuleAnchorSource;
61+
5762
// This anchor is used to force the linker to link the DarwinModule.
5863
extern volatile int DarwinModuleAnchorSource;
5964
static int LLVM_ATTRIBUTE_UNUSED DarwinModuleAnchorDestination =
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
set(LLVM_LINK_COMPONENTS
2+
support
3+
)
4+
5+
add_clang_library(clangTidyCustomModule STATIC
6+
CustomTidyModule.cpp
7+
QueryCheck.cpp
8+
9+
LINK_LIBS
10+
clangTidy
11+
clangTidyUtils
12+
13+
DEPENDS
14+
ClangDriverOptions
15+
)
16+
17+
clang_target_link_libraries(clangTidyCustomModule
18+
PRIVATE
19+
clangQuery
20+
)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include "../ClangTidy.h"
2+
#include "../ClangTidyModule.h"
3+
#include "../ClangTidyModuleRegistry.h"
4+
#include "../ClangTidyOptions.h"
5+
#include "QueryCheck.h"
6+
#include <memory>
7+
8+
namespace clang::tidy {
9+
namespace custom {
10+
11+
// FIXME: could be clearer to add parameter of addCheckFactories to pass
12+
// Options?
13+
static ClangTidyOptions const *Options = nullptr;
14+
extern void setOptions(ClangTidyOptions const &O) { Options = &O; }
15+
16+
class CustomModule : public ClangTidyModule {
17+
public:
18+
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
19+
if (Options == nullptr || !Options->CustomChecks.has_value() ||
20+
Options->CustomChecks->empty())
21+
return;
22+
for (const ClangTidyOptions::CustomCheckValue &V :
23+
Options->CustomChecks.value()) {
24+
CheckFactories.registerCheckFactory(
25+
"custom-" + V.Name,
26+
[&V](llvm::StringRef Name, ClangTidyContext *Context) {
27+
return std::make_unique<custom::QueryCheck>(Name, V, Context);
28+
});
29+
}
30+
}
31+
};
32+
33+
} // namespace custom
34+
35+
// Register the AlteraTidyModule using this statically initialized variable.
36+
static ClangTidyModuleRegistry::Add<custom::CustomModule>
37+
X("custom-module", "Adds custom query lint checks.");
38+
39+
// This anchor is used to force the linker to link in the generated object file
40+
// and thus register the AlteraModule.
41+
volatile int CustomModuleAnchorSource = 0;
42+
43+
} // namespace clang::tidy
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===--- QueryCheck.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+
9+
#include "QueryCheck.h"
10+
#include "../../clang-query/Query.h"
11+
#include "../../clang-query/QueryParser.h"
12+
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
13+
#include "llvm/ADT/StringRef.h"
14+
15+
using namespace clang::ast_matchers;
16+
17+
namespace clang::tidy::custom {
18+
19+
QueryCheck::QueryCheck(llvm::StringRef Name,
20+
const ClangTidyOptions::CustomCheckValue &V,
21+
ClangTidyContext *Context)
22+
: ClangTidyCheck(Name, Context), Matchers{} {
23+
clang::query::QuerySession QS({});
24+
llvm::StringRef QueryStringRef{V.Query};
25+
while (!QueryStringRef.empty()) {
26+
query::QueryRef Q = query::QueryParser::parse(QueryStringRef, QS);
27+
switch (Q->Kind) {
28+
case query::QK_Match: {
29+
const auto &MatchQuerry = llvm::cast<query::MatchQuery>(*Q);
30+
Matchers.push_back(MatchQuerry.Matcher);
31+
break;
32+
}
33+
case query::QK_Let: {
34+
const auto &LetQuerry = llvm::cast<query::LetQuery>(*Q);
35+
LetQuerry.run(llvm::errs(), QS);
36+
break;
37+
}
38+
case query::QK_Invalid: {
39+
const auto &InvalidQuerry = llvm::cast<query::InvalidQuery>(*Q);
40+
Context->configurationDiag(InvalidQuerry.ErrStr);
41+
break;
42+
}
43+
// FIXME: TODO
44+
case query::QK_File:
45+
case query::QK_DisableOutputKind:
46+
case query::QK_EnableOutputKind:
47+
case query::QK_SetOutputKind:
48+
case query::QK_SetTraversalKind:
49+
case query::QK_Help:
50+
case query::QK_NoOp:
51+
case query::QK_Quit:
52+
case query::QK_SetBool: {
53+
Context->configurationDiag("unsupported querry kind");
54+
}
55+
}
56+
QueryStringRef = Q->RemainingContent;
57+
}
58+
}
59+
60+
void QueryCheck::registerMatchers(MatchFinder *Finder) {
61+
for (const ast_matchers::dynamic::DynTypedMatcher &M : Matchers)
62+
Finder->addDynamicMatcher(M, this);
63+
}
64+
65+
void QueryCheck::check(const MatchFinder::MatchResult &Result) {
66+
for (auto &[Name, Node] : Result.Nodes.getMap())
67+
diag(Node.getSourceRange().getBegin(), Name) << Node.getSourceRange();
68+
}
69+
70+
} // namespace clang::tidy::custom
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===--- QueryCheck.h - clang-tidy ------------------------------*- C++ -*-===//
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+
9+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CUSTOM_QUERYCHECK_H
10+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CUSTOM_QUERYCHECK_H
11+
12+
#include "../ClangTidyCheck.h"
13+
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
14+
#include "llvm/ADT/SmallVector.h"
15+
16+
namespace clang::tidy::custom {
17+
18+
/// FIXME: Write a short description.
19+
///
20+
/// For the user-facing documentation see:
21+
/// http://clang.llvm.org/extra/clang-tidy/checks/custom/query.html
22+
class QueryCheck : public ClangTidyCheck {
23+
public:
24+
QueryCheck(llvm::StringRef Name, const ClangTidyOptions::CustomCheckValue &V,
25+
ClangTidyContext *Context);
26+
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
27+
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
28+
29+
private:
30+
llvm::SmallVector<ast_matchers::dynamic::DynTypedMatcher> Matchers{};
31+
};
32+
33+
} // namespace clang::tidy::custom
34+
35+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CUSTOM_QUERYCHECK_H

0 commit comments

Comments
 (0)