blob: cf5381722987b8692ee3e3c810aaa7f735db2ca1 [file] [log] [blame]
Sean Silvabf9b4cd2012-12-13 01:10:461=============
2Clang Plugins
3=============
4
5Clang Plugins make it possible to run extra user defined actions during
6a compilation. This document will provide a basic walkthrough of how to
7write and run a Clang Plugin.
8
9Introduction
10============
11
12Clang Plugins run FrontendActions over code. See the :doc:`FrontendAction
13tutorial <RAVFrontendAction>` on how to write a FrontendAction
14using the RecursiveASTVisitor. In this tutorial, we'll demonstrate how
15to write a simple clang plugin.
16
17Writing a PluginASTAction
18=========================
19
20The main difference from writing normal FrontendActions is that you can
21handle plugin command line options. The PluginASTAction base class
22declares a ParseArgs method which you have to implement in your plugin.
23
24::
25
26 bool ParseArgs(const CompilerInstance &CI,
27 const std::vector<std::string>& args) {
28 for (unsigned i = 0, e = args.size(); i != e; ++i) {
29 if (args[i] == "-some-arg") {
30 // Handle the command line argument.
31 }
32 }
33 return true;
34 }
35
36Registering a plugin
37====================
38
39A plugin is loaded from a dynamic library at runtime by the compiler. To
40register a plugin in a library, use FrontendPluginRegistry::Add:
41
42::
43
44 static FrontendPluginRegistry::Add<MyPlugin> X("my-plugin-name", "my plugin description");
45
46Putting it all together
47=======================
48
49Let's look at an example plugin that prints top-level function names.
50This example is also checked into the clang repository; please also take
51a look at the latest `checked in version of
52PrintFunctionNames.cpp <http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/PrintFunctionNames/PrintFunctionNames.cpp?view=markup>`_.
53
54::
55
56 #include "clang/Frontend/FrontendPluginRegistry.h"
57 #include "clang/AST/ASTConsumer.h"
58 #include "clang/AST/AST.h"
59 #include "clang/Frontend/CompilerInstance.h"
60 #include "llvm/Support/raw_ostream.h"
61 using namespace clang;
62
63 namespace {
64
65 class PrintFunctionsConsumer : public ASTConsumer {
66 public:
67 virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
68 for (DeclGroupRef::iterator i = DG.begin(), e = DG.end(); i != e; ++i) {
69 const Decl *D = *i;
70 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
71 llvm::errs() << "top-level-decl: \"" << ND->getNameAsString() << "\"\n";
72 }
73
74 return true;
75 }
76 };
77
78 class PrintFunctionNamesAction : public PluginASTAction {
79 protected:
80 ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) {
81 return new PrintFunctionsConsumer();
82 }
83
84 bool ParseArgs(const CompilerInstance &CI,
85 const std::vector<std::string>& args) {
86 for (unsigned i = 0, e = args.size(); i != e; ++i) {
87 llvm::errs() << "PrintFunctionNames arg = " << args[i] << "\n";
88
89 // Example error handling.
90 if (args[i] == "-an-error") {
91 DiagnosticsEngine &D = CI.getDiagnostics();
92 unsigned DiagID = D.getCustomDiagID(
93 DiagnosticsEngine::Error, "invalid argument '" + args[i] + "'");
94 D.Report(DiagID);
95 return false;
96 }
97 }
98 if (args.size() && args[0] == "help")
99 PrintHelp(llvm::errs());
100
101 return true;
102 }
103 void PrintHelp(llvm::raw_ostream& ros) {
104 ros << "Help for PrintFunctionNames plugin goes here\n";
105 }
106
107 };
108
109 }
110
111 static FrontendPluginRegistry::Add<PrintFunctionNamesAction>
112 X("print-fns", "print function names");
113
114Running the plugin
115==================
116
117To run a plugin, the dynamic library containing the plugin registry must
118be loaded via the -load command line option. This will load all plugins
119that are registered, and you can select the plugins to run by specifying
120the -plugin option. Additional parameters for the plugins can be passed
121with -plugin-arg-<plugin-name>.
122
123Note that those options must reach clang's cc1 process. There are two
124ways to do so:
125
126- Directly call the parsing process by using the -cc1 option; this has
127 the downside of not configuring the default header search paths, so
128 you'll need to specify the full system path configuration on the
129 command line.
130- Use clang as usual, but prefix all arguments to the cc1 process with
131 -Xclang.
132
133For example, to run the print-function-names plugin over a source file
134in clang, first build the plugin, and then call clang with the plugin
135from the source tree:
136
137::
138
139 $ export BD=/path/to/build/directory
140 $ (cd $BD && make PrintFunctionNames )
141 $ clang++ -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS \
142 -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE \
143 -I$BD/tools/clang/include -Itools/clang/include -I$BD/include -Iinclude \
144 tools/clang/tools/clang-check/ClangCheck.cpp -fsyntax-only \
145 -Xclang -load -Xclang $BD/lib/PrintFunctionNames.so -Xclang \
146 -plugin -Xclang print-fns
147
148Also see the print-function-name plugin example's
149`README <http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/PrintFunctionNames/README.txt?view=markup>`_