1 //===- 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" 11 #include "../ClangTidyModule.h" 12 #include "clang/Frontend/CompilerInstance.h" 13 #include "clang/Frontend/FrontendPluginRegistry.h" 14 #include "clang/Frontend/MultiplexConsumer.h" 15 16 namespace clang { 17 namespace tidy { 18 19 /// The core clang tidy plugin action. This just provides the AST consumer and 20 /// command line flag parsing for using clang-tidy as a clang plugin. 21 class ClangTidyPluginAction : public PluginASTAction { 22 /// Wrapper to grant the context the same lifetime as the action. We use 23 /// MultiplexConsumer to avoid writing out all the forwarding methods. 24 class WrapConsumer : public MultiplexConsumer { 25 std::unique_ptr<ClangTidyContext> Context; 26 27 public: 28 WrapConsumer(std::unique_ptr<ClangTidyContext> Context, 29 std::vector<std::unique_ptr<ASTConsumer>> Consumer) 30 : MultiplexConsumer(std::move(Consumer)), Context(std::move(Context)) {} 31 }; 32 33 public: 34 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler, 35 StringRef File) override { 36 // Insert the current diagnostics engine. 37 Context->setDiagnosticsEngine(&Compiler.getDiagnostics()); 38 39 // Create the AST consumer. 40 ClangTidyASTConsumerFactory Factory(*Context); 41 std::vector<std::unique_ptr<ASTConsumer>> Vec; 42 Vec.push_back(Factory.CreateASTConsumer(Compiler, File)); 43 44 return llvm::make_unique<WrapConsumer>(std::move(Context), std::move(Vec)); 45 } 46 47 bool ParseArgs(const CompilerInstance &, 48 const std::vector<std::string> &Args) override { 49 ClangTidyGlobalOptions GlobalOptions; 50 ClangTidyOptions DefaultOptions; 51 ClangTidyOptions OverrideOptions; 52 53 // Parse the extra command line args. 54 // FIXME: This is very limited at the moment. 55 for (StringRef Arg : Args) 56 if (Arg.startswith("-checks=")) 57 OverrideOptions.Checks = Arg.substr(strlen("-checks=")); 58 59 auto Options = llvm::make_unique<FileOptionsProvider>( 60 GlobalOptions, DefaultOptions, OverrideOptions); 61 Context = llvm::make_unique<ClangTidyContext>(std::move(Options)); 62 return true; 63 } 64 65 private: 66 std::unique_ptr<ClangTidyContext> Context; 67 }; 68 } // namespace tidy 69 } // namespace clang 70 71 // This anchor is used to force the linker to link in the generated object file 72 // and thus register the clang-tidy plugin. 73 volatile int ClangTidyPluginAnchorSource = 0; 74 75 static clang::FrontendPluginRegistry::Add<clang::tidy::ClangTidyPluginAction> 76 X("clang-tidy", "clang-tidy"); 77 78 namespace clang { 79 namespace tidy { 80 81 // This anchor is used to force the linker to link the CERTModule. 82 extern volatile int CERTModuleAnchorSource; 83 static int LLVM_ATTRIBUTE_UNUSED CERTModuleAnchorDestination = 84 CERTModuleAnchorSource; 85 86 // This anchor is used to force the linker to link the LLVMModule. 87 extern volatile int LLVMModuleAnchorSource; 88 static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination = 89 LLVMModuleAnchorSource; 90 91 // This anchor is used to force the linker to link the CppCoreGuidelinesModule. 92 extern volatile int CppCoreGuidelinesModuleAnchorSource; 93 static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination = 94 CppCoreGuidelinesModuleAnchorSource; 95 96 // This anchor is used to force the linker to link the GoogleModule. 97 extern volatile int GoogleModuleAnchorSource; 98 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination = 99 GoogleModuleAnchorSource; 100 101 // This anchor is used to force the linker to link the MiscModule. 102 extern volatile int MiscModuleAnchorSource; 103 static int LLVM_ATTRIBUTE_UNUSED MiscModuleAnchorDestination = 104 MiscModuleAnchorSource; 105 106 // This anchor is used to force the linker to link the ModernizeModule. 107 extern volatile int ModernizeModuleAnchorSource; 108 static int LLVM_ATTRIBUTE_UNUSED ModernizeModuleAnchorDestination = 109 ModernizeModuleAnchorSource; 110 111 // This anchor is used to force the linker to link the MPIModule. 112 extern volatile int MPIModuleAnchorSource; 113 static int LLVM_ATTRIBUTE_UNUSED MPIModuleAnchorDestination = 114 MPIModuleAnchorSource; 115 116 // This anchor is used to force the linker to link the PerformanceModule. 117 extern volatile int PerformanceModuleAnchorSource; 118 static int LLVM_ATTRIBUTE_UNUSED PerformanceModuleAnchorDestination = 119 PerformanceModuleAnchorSource; 120 121 // This anchor is used to force the linker to link the ReadabilityModule. 122 extern volatile int ReadabilityModuleAnchorSource; 123 static int LLVM_ATTRIBUTE_UNUSED ReadabilityModuleAnchorDestination = 124 ReadabilityModuleAnchorSource; 125 126 // This anchor is used to force the linker to link the ObjCModule. 127 extern volatile int ObjCModuleAnchorSource; 128 static int LLVM_ATTRIBUTE_UNUSED ObjCModuleAnchorDestination = 129 ObjCModuleAnchorSource; 130 131 } // namespace tidy 132 } // namespace clang 133