[cfe-commits] [PATCH] Implement a better plugin API for clang

Nico Weber thakis at chromium.org
Thu Jun 21 07:17:47 PDT 2012


On Thu, Jun 21, 2012 at 5:17 AM, Tobias Grosser <tobias at grosser.es> wrote:
> On 06/20/2012 11:58 PM, Joshua Cranmer wrote:
>> diff --git a/docs/ClangPlugins.html b/docs/ClangPlugins.html
>> --- a/docs/ClangPlugins.html
>> +++ b/docs/ClangPlugins.html
>
> Hi Joshua,
>
> I am not a regular contributor to clang, but I am following the plugin
> infrastructure development and I must say I like the general direction.
> My use case are no frontend plugins, but a plugin to drive the Polly
> optimizer. What I would like clang to support is:
>
> - Allow the insertion of linker flags such as '-lgmp' from a plugin
> - Allow the insertion of '-mllvm -flag' style parameters to change the
> LLVM default behaviour.
> - Shorter plugin parameters in the style of -<plugin-name>-<argument>.
> E.g. '-polly-vectorize'.
>
> I know this is not the goal of this patch, but this gives the context
> from which I look at it. Now to the actual patch
>
>
>> @@ -16,65 +16,79 @@
>>   <p>Clang Plugins make it possible to run extra user defined actions during
>>   a compilation. This document will provide a basic walkthrough of how to write
>>   and run a Clang Plugin.</p>
>>
>>   <!-- ======================================================================= -->
>>   <h2 id="intro">Introduction</h2>
>>   <!-- ======================================================================= -->
>>
>> -<p>Clang Plugins run FrontendActions over code. See the
>> -<a href="RAVFrontendAction.html">FrontendAction tutorial</a>  on how to write a
>> -FrontendAction using the RecursiveASTVisitor. In this tutorial, we'll
>> +<p>Clang Plugins run a set of callbacks over code. These callbacks are functions
>> +that the plugin exports that the compiler uses over the course of compiling
>> +code. These functions need not be implemented (except for clang_plugin_init). By
>> +use of these hooks, compilers can affect or observer the course of compilation
>> +by using several callbacks. The most important callback is the ASTConsumer
>> +callback, which allows plugins to interact with the abstract syntax tree of
>> +code. See the
>
> This is still very frontend specific, but definitely an improvement.
>
>>   <!-- ======================================================================= -->
>> -<h2 id="pluginactions">Writing a PluginASTAction</h2>
>> +<h2 id="init">Arguments and initialization</h2>
>>   <!-- ======================================================================= -->
>>
>> -<p>The main difference from writing normal FrontendActions is that you can
>> -handle plugin command line options. The
>> -PluginASTAction base class declares a ParseArgs method which you have to
>> -implement in your plugin.
>> -</p>
>> +<p>The first function called when a plugin is loaded is clang_plugin_init. This
>> +function returns a boolean indicating whether or not the plugin can run on the
>> +code. As arguments, this function is given the arguments of the plugin as well
>> +as the version of clang being run. An example looks like this:</p>
>>   <pre>
>> -  bool ParseArgs(const CompilerInstance&CI,
>> -                 const std::vector<std::string>& args) {
>> -    for (unsigned i = 0, e = args.size(); i != e; ++i) {
>> -      if (args[i] == "-some-arg") {
>> -        // Handle the command line argument.
>> +  bool clang_plugin_init(int argc, plugin::PluginArg *argv,
>> +      plugin::Version *version) {
>> +    // Check the version of clang
>> +    if (version->major != CLANG_VERSION_MAJOR ||
>> +        version->minor != CLANG_VERSION_MINOR)
>> +      return false;
>> +
>> +    for (int i = 0; i< argc; ++i) {
>> +      if (!strcmp(argv[i].name, "-some-arg")) {
>> +        // Handle the command line argument
>>         }
>
> Like the runtime check for the plugin version. It is definitely a step
> forward. However, do you know what happens if some function names in
> clang changed and the plugin still references old function names? I
> suppose this will still give a linker error when loading the plugin. So
> even so this is going in the right direction, it may be nice to reason
> in future patches about a solution that gives a clear error message in
> that case.
>
>>   <!-- ======================================================================= -->
>> -<h2 id="registerplugin">Registering a plugin</h2>
>> +<h2 id="callbacks">Setting callbacks</h2>
>>   <!-- ======================================================================= -->
>>
>> -<p>A plugin is loaded from a dynamic library at runtime by the compiler. To register
>> -a plugin in a library, use FrontendPluginRegistry::Add:</p>
>> +<p>The most important plugin hook is the one that is called before each file is
>> +compiled: clang_plugin_begin_file. This allows plugins to add their own custom
>> +ASTConsumer (among other compiler hooks).</p>

Is this ASTConsumer run in addition to codegen, instead of codegen, or
is there an option to choose? I'd like to be able to have a plugin
that runs in addition to codegen, which only provides additional
diagnostics.

>>   <pre>
>> -  static FrontendPluginRegistry::Add<MyPlugin>  X("my-plugin-name", "my plugin description");
>> +  void clang_plugin_begin_file(llvm::StringRef fileName,
>> +      const CompilerInstance&CI, plugin::PluginFileCallbacks *callbacks) {
>> +    callbacks->astConsumer = new PrintFunctionsConsumer();
>> +  }
>>   </pre>
>
> Sounds good. Do you think at it will be possible in later patches to add
> hooks to change the linker flags or the -mllvm flags?
>
>>   <!-- ======================================================================= -->
>>   <h2 id="running">Running the plugin</h2>
>>   <!-- ======================================================================= -->
>>
>> -<p>To run a plugin, the dynamic library containing the plugin registry must be
>> -loaded via the -load command line option. This will load all plugins that are
>> -registered, and you can select the plugins to run by specifying the -plugin
>> -option. Additional parameters for the plugins can be passed with -plugin-arg-<plugin-name>.</p>
>> +<p>To run a plugin, you merely need to specify the plugin to be loaded using the
>> +-fplugin command line options. Additional parameters for the plugins can be passed with -fplugin-arg-<plugin-name>-<arg>=<value>  or
>> +-fplugin-arg<plugin-name>-<arg>. These options work the same when both run
>> +with the normal driver and the cc1 process.</p>
>
> Nice to see plugin arguments now also work with the normal driver!
>
> That's it from me. Thanks Joshua for working on this!
>
> Tobi
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list