hc
2023-11-06 15ade055295d13f95d49e3d99b09f3bbfb4a43e7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- Copyright (C) 1988-2016 Free Software Foundation, Inc.
 
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with the
Invariant Sections being "Funding Free Software", the Front-Cover
Texts being (a) (see below), and with the Back-Cover Texts being (b)
(see below).  A copy of the license is included in the section entitled
"GNU Free Documentation License".
 
(a) The FSF's Front-Cover Text is:
 
A GNU Manual
 
(b) The FSF's Back-Cover Text is:
 
You have freedom to copy and modify this GNU Manual, like GNU
     software.  Copies published by the Free Software Foundation raise
     funds for GNU development. -->
<!-- Created by GNU Texinfo 5.2, http://www.gnu.org/software/texinfo/ -->
<head>
<title>GNU Compiler Collection (GCC) Internals: Plugin API</title>
 
<meta name="description" content="GNU Compiler Collection (GCC) Internals: Plugin API">
<meta name="keywords" content="GNU Compiler Collection (GCC) Internals: Plugin API">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="index.html#Top" rel="start" title="Top">
<link href="Option-Index.html#Option-Index" rel="index" title="Option Index">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Plugins.html#Plugins" rel="up" title="Plugins">
<link href="Plugins-pass.html#Plugins-pass" rel="next" title="Plugins pass">
<link href="Plugins-loading.html#Plugins-loading" rel="prev" title="Plugins loading">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
blockquote.smallquotation {font-size: smaller}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
div.indentedblock {margin-left: 3.2em}
div.lisp {margin-left: 3.2em}
div.smalldisplay {margin-left: 3.2em}
div.smallexample {margin-left: 3.2em}
div.smallindentedblock {margin-left: 3.2em; font-size: smaller}
div.smalllisp {margin-left: 3.2em}
kbd {font-style:oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: inherit; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: inherit; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.nocodebreak {white-space:nowrap}
span.nolinebreak {white-space:nowrap}
span.roman {font-family:serif; font-weight:normal}
span.sansserif {font-family:sans-serif; font-weight:normal}
ul.no-bullet {list-style: none}
-->
</style>
 
 
</head>
 
<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
<a name="Plugin-API"></a>
<div class="header">
<p>
Next: <a href="Plugins-pass.html#Plugins-pass" accesskey="n" rel="next">Plugins pass</a>, Previous: <a href="Plugins-loading.html#Plugins-loading" accesskey="p" rel="prev">Plugins loading</a>, Up: <a href="Plugins.html#Plugins" accesskey="u" rel="up">Plugins</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<a name="Plugin-API-1"></a>
<h3 class="section">23.2 Plugin API</h3>
 
<p>Plugins are activated by the compiler at specific events as defined in
<samp>gcc-plugin.h</samp>.  For each event of interest, the plugin should
call <code>register_callback</code> specifying the name of the event and
address of the callback function that will handle that event.
</p>
<p>The header <samp>gcc-plugin.h</samp> must be the first gcc header to be included.
</p>
<a name="Plugin-license-check"></a>
<h4 class="subsection">23.2.1 Plugin license check</h4>
 
<p>Every plugin should define the global symbol <code>plugin_is_GPL_compatible</code>
to assert that it has been licensed under a GPL-compatible license.
If this symbol does not exist, the compiler will emit a fatal error
and exit with the error message:
</p>
<div class="smallexample">
<pre class="smallexample">fatal error: plugin <var>name</var> is not licensed under a GPL-compatible license
<var>name</var>: undefined symbol: plugin_is_GPL_compatible
compilation terminated
</pre></div>
 
<p>The declared type of the symbol should be int, to match a forward declaration
in <samp>gcc-plugin.h</samp> that suppresses C++ mangling.  It does not need to be in
any allocated section, though.  The compiler merely asserts that
the symbol exists in the global scope.  Something like this is enough:
</p>
<div class="smallexample">
<pre class="smallexample">int plugin_is_GPL_compatible;
</pre></div>
 
<a name="Plugin-initialization"></a>
<h4 class="subsection">23.2.2 Plugin initialization</h4>
 
<p>Every plugin should export a function called <code>plugin_init</code> that
is called right after the plugin is loaded. This function is
responsible for registering all the callbacks required by the plugin
and do any other required initialization.
</p>
<p>This function is called from <code>compile_file</code> right before invoking
the parser.  The arguments to <code>plugin_init</code> are:
</p>
<ul>
<li> <code>plugin_info</code>: Plugin invocation information.
</li><li> <code>version</code>: GCC version.
</li></ul>
 
<p>The <code>plugin_info</code> struct is defined as follows:
</p>
<div class="smallexample">
<pre class="smallexample">struct plugin_name_args
{
  char *base_name;              /* Short name of the plugin
                                   (filename without .so suffix). */
  const char *full_name;        /* Path to the plugin as specified with
                                   -fplugin=. */
  int argc;                     /* Number of arguments specified with
                                   -fplugin-arg-.... */
  struct plugin_argument *argv; /* Array of ARGC key-value pairs. */
  const char *version;          /* Version string provided by plugin. */
  const char *help;             /* Help string provided by plugin. */
}
</pre></div>
 
<p>If initialization fails, <code>plugin_init</code> must return a non-zero
value.  Otherwise, it should return 0.
</p>
<p>The version of the GCC compiler loading the plugin is described by the
following structure:
</p>
<div class="smallexample">
<pre class="smallexample">struct plugin_gcc_version
{
  const char *basever;
  const char *datestamp;
  const char *devphase;
  const char *revision;
  const char *configuration_arguments;
};
</pre></div>
 
<p>The function <code>plugin_default_version_check</code> takes two pointers to
such structure and compare them field by field. It can be used by the
plugin&rsquo;s <code>plugin_init</code> function.
</p>
<p>The version of GCC used to compile the plugin can be found in the symbol
<code>gcc_version</code> defined in the header <samp>plugin-version.h</samp>. The
recommended version check to perform looks like
</p>
<div class="smallexample">
<pre class="smallexample">#include &quot;plugin-version.h&quot;
...
 
int
plugin_init (struct plugin_name_args *plugin_info,
             struct plugin_gcc_version *version)
{
  if (!plugin_default_version_check (version, &amp;gcc_version))
    return 1;
 
}
</pre></div>
 
<p>but you can also check the individual fields if you want a less strict check.
</p>
<a name="Plugin-callbacks"></a>
<h4 class="subsection">23.2.3 Plugin callbacks</h4>
 
<p>Callback functions have the following prototype:
</p>
<div class="smallexample">
<pre class="smallexample">/* The prototype for a plugin callback function.
     gcc_data  - event-specific data provided by GCC
     user_data - plugin-specific data provided by the plug-in.  */
typedef void (*plugin_callback_func)(void *gcc_data, void *user_data);
</pre></div>
 
<p>Callbacks can be invoked at the following pre-determined events:
</p>
 
<div class="smallexample">
<pre class="smallexample">enum plugin_event
{
  PLUGIN_START_PARSE_FUNCTION,  /* Called before parsing the body of a function. */
  PLUGIN_FINISH_PARSE_FUNCTION, /* After finishing parsing a function. */
  PLUGIN_PASS_MANAGER_SETUP,    /* To hook into pass manager.  */
  PLUGIN_FINISH_TYPE,           /* After finishing parsing a type.  */
  PLUGIN_FINISH_DECL,           /* After finishing parsing a declaration. */
  PLUGIN_FINISH_UNIT,           /* Useful for summary processing.  */
  PLUGIN_PRE_GENERICIZE,        /* Allows to see low level AST in C and C++ frontends.  */
  PLUGIN_FINISH,                /* Called before GCC exits.  */
  PLUGIN_INFO,                  /* Information about the plugin. */
  PLUGIN_GGC_START,             /* Called at start of GCC Garbage Collection. */
  PLUGIN_GGC_MARKING,           /* Extend the GGC marking. */
  PLUGIN_GGC_END,               /* Called at end of GGC. */
  PLUGIN_REGISTER_GGC_ROOTS,    /* Register an extra GGC root table. */
  PLUGIN_ATTRIBUTES,            /* Called during attribute registration */
  PLUGIN_START_UNIT,            /* Called before processing a translation unit.  */
  PLUGIN_PRAGMAS,               /* Called during pragma registration. */
  /* Called before first pass from all_passes.  */
  PLUGIN_ALL_PASSES_START,
  /* Called after last pass from all_passes.  */
  PLUGIN_ALL_PASSES_END,
  /* Called before first ipa pass.  */
  PLUGIN_ALL_IPA_PASSES_START,
  /* Called after last ipa pass.  */
  PLUGIN_ALL_IPA_PASSES_END,
  /* Allows to override pass gate decision for current_pass.  */
  PLUGIN_OVERRIDE_GATE,
  /* Called before executing a pass.  */
  PLUGIN_PASS_EXECUTION,
  /* Called before executing subpasses of a GIMPLE_PASS in
     execute_ipa_pass_list.  */
  PLUGIN_EARLY_GIMPLE_PASSES_START,
  /* Called after executing subpasses of a GIMPLE_PASS in
     execute_ipa_pass_list.  */
  PLUGIN_EARLY_GIMPLE_PASSES_END,
  /* Called when a pass is first instantiated.  */
  PLUGIN_NEW_PASS,
/* Called when a file is #include-d or given via the #line directive.
   This could happen many times.  The event data is the included file path,
   as a const char* pointer.  */
  PLUGIN_INCLUDE_FILE,
 
  PLUGIN_EVENT_FIRST_DYNAMIC    /* Dummy event used for indexing callback
                                   array.  */
};
</pre></div>
 
<p>In addition, plugins can also look up the enumerator of a named event,
and / or generate new events dynamically, by calling the function
<code>get_named_event_id</code>.
</p>
<p>To register a callback, the plugin calls <code>register_callback</code> with
the arguments:
</p>
<ul>
<li> <code>char *name</code>: Plugin name.
</li><li> <code>int event</code>: The event code.
</li><li> <code>plugin_callback_func callback</code>: The function that handles <code>event</code>.
</li><li> <code>void *user_data</code>: Pointer to plugin-specific data.
</li></ul>
 
<p>For the <i>PLUGIN_PASS_MANAGER_SETUP</i>, <i>PLUGIN_INFO</i>, and
<i>PLUGIN_REGISTER_GGC_ROOTS</i> pseudo-events the <code>callback</code> should be null,
and the <code>user_data</code> is specific.
</p>
<p>When the <i>PLUGIN_PRAGMAS</i> event is triggered (with a null pointer as
data from GCC), plugins may register their own pragmas.  Notice that
pragmas are not available from <samp>lto1</samp>, so plugins used with
<code>-flto</code> option to GCC during link-time optimization cannot use
pragmas and do not even see functions like <code>c_register_pragma</code> or
<code>pragma_lex</code>.
</p>
<p>The <i>PLUGIN_INCLUDE_FILE</i> event, with a <code>const char*</code> file path as
GCC data, is triggered for processing of <code>#include</code> or
<code>#line</code> directives.
</p>
<p>The <i>PLUGIN_FINISH</i> event is the last time that plugins can call GCC
functions, notably emit diagnostics with <code>warning</code>, <code>error</code>
etc.
</p>
 
<hr>
<div class="header">
<p>
Next: <a href="Plugins-pass.html#Plugins-pass" accesskey="n" rel="next">Plugins pass</a>, Previous: <a href="Plugins-loading.html#Plugins-loading" accesskey="p" rel="prev">Plugins loading</a>, Up: <a href="Plugins.html#Plugins" accesskey="u" rel="up">Plugins</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
</div>
 
 
 
</body>
</html>