Notes on writing a GCC plugin¶
Here are notes on some of my discoveries while working on a plugin for GCC.
Callback arguments¶
I have been toying around with a plugin to GCC to generate a Fortran
module source with the appropriate bind(c)
settings from a C header
file. According to the GCC internals manual, the basic structure
is:
void callback(void * gcc_data, void * user_data)
{
...
};
int plugin_init(...)
{
struct PACKAGE_NAME_data data;
...
register_callback(..., callback, &data)
};
However, all of the tutorials online punt on how to actually pass
arguments through the user_data
by using NULL
. This is not helpful
if the plugin will be run in concurrent processes. Initially, I could
not get the casting correct. After a bit of playing, I finally stumbled
on the proper casting:
void callback(void * gcc_data, void * user_data)
{
struct PACKAGE_NAME_data * data;
data = reinterpret_cast<struct PACKAGE_NAME_data *>(user_data);
...
};
int plugin_init(...)
{
static struct PACKAGE_NAME_data data;
...
register_callback(..., callback, &data)
};
(You could just use C style casting, but this is C++ so you shouldn’t)
When to walk the AST¶
All the tutorials I could find online worked at the gate pass or at the
final stage. I want to walk the tree immediately after the parsing is
done and the AST has been assembled. I originally thought I wanted the
PLUGIN_PRE_GENERICIZE
, but that is not appropriate for C/C++ parsing
(the manual says this in the section on GENERIC). It looks like the
GIMPLE pass is where we get the full tree before push down. The
PLUGIN_OVERRIDE_GATE
appears to run too soon, but I’m still working on
that.
Working with autotools¶
We need to undefine the macros set by autotools because the plugin framework defines them before we can. This simply suppresses the warnings about that.
#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
I just put it in a header ‘package-config.h’ with the appropriate
#include
to use in additional files.
Edit 2020-03-29¶
The original purpose for writing a plugin was to concoct a way to generate the Fortran 2003 interface module given a C header. It sort of worked, but not well enough to put it out in the world. I came back to it (again) the other night to take another stab. But then I was googling a different problem and came across this article. It looks like they beat me to the punch. Oh well. But at least I have a new project to keep an eye on!