blob: 561dc82d1fe2f9d22ccf771e1cd042853091e272 [file] [log] [blame]
Benjamin Kramer8f5eb562016-03-03 08:58:12 +00001//===- ClangTidyPlugin.cpp - clang-tidy as a clang plugin -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "../ClangTidy.h"
Ivan Donchevskii37512e52018-12-14 07:29:06 +000011#include "../ClangTidyForceLinker.h"
Benjamin Kramer8f5eb562016-03-03 08:58:12 +000012#include "../ClangTidyModule.h"
13#include "clang/Frontend/CompilerInstance.h"
14#include "clang/Frontend/FrontendPluginRegistry.h"
15#include "clang/Frontend/MultiplexConsumer.h"
16
17namespace clang {
18namespace tidy {
19
20/// The core clang tidy plugin action. This just provides the AST consumer and
21/// command line flag parsing for using clang-tidy as a clang plugin.
22class ClangTidyPluginAction : public PluginASTAction {
23 /// Wrapper to grant the context the same lifetime as the action. We use
24 /// MultiplexConsumer to avoid writing out all the forwarding methods.
25 class WrapConsumer : public MultiplexConsumer {
26 std::unique_ptr<ClangTidyContext> Context;
27
28 public:
29 WrapConsumer(std::unique_ptr<ClangTidyContext> Context,
30 std::vector<std::unique_ptr<ASTConsumer>> Consumer)
31 : MultiplexConsumer(std::move(Consumer)), Context(std::move(Context)) {}
32 };
33
34public:
35 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
36 StringRef File) override {
37 // Insert the current diagnostics engine.
Sam McCall3c1f4902018-11-08 17:42:16 +000038 Context->setDiagnosticsEngine(&Compiler.getDiagnostics());
Benjamin Kramer8f5eb562016-03-03 08:58:12 +000039
40 // Create the AST consumer.
41 ClangTidyASTConsumerFactory Factory(*Context);
42 std::vector<std::unique_ptr<ASTConsumer>> Vec;
43 Vec.push_back(Factory.CreateASTConsumer(Compiler, File));
44
45 return llvm::make_unique<WrapConsumer>(std::move(Context), std::move(Vec));
46 }
47
48 bool ParseArgs(const CompilerInstance &,
49 const std::vector<std::string> &Args) override {
50 ClangTidyGlobalOptions GlobalOptions;
51 ClangTidyOptions DefaultOptions;
52 ClangTidyOptions OverrideOptions;
53
54 // Parse the extra command line args.
55 // FIXME: This is very limited at the moment.
56 for (StringRef Arg : Args)
57 if (Arg.startswith("-checks="))
58 OverrideOptions.Checks = Arg.substr(strlen("-checks="));
59
60 auto Options = llvm::make_unique<FileOptionsProvider>(
61 GlobalOptions, DefaultOptions, OverrideOptions);
62 Context = llvm::make_unique<ClangTidyContext>(std::move(Options));
63 return true;
64 }
65
66private:
67 std::unique_ptr<ClangTidyContext> Context;
68};
69} // namespace tidy
70} // namespace clang
71
72// This anchor is used to force the linker to link in the generated object file
73// and thus register the clang-tidy plugin.
74volatile int ClangTidyPluginAnchorSource = 0;
75
76static clang::FrontendPluginRegistry::Add<clang::tidy::ClangTidyPluginAction>
77 X("clang-tidy", "clang-tidy");