Sophie

Sophie

distrib > Fedora > 17 > i386 > by-pkgid > 22d19aa2887b575b22775df3fe562f02 > files > 70

gcc-python-plugin-docs-0.9-4.1.fc17.i686.rpm



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Creating custom GCC attributes &mdash; gcc-python-plugin 0.9 documentation</title>
    
    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '0.9',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="top" title="gcc-python-plugin 0.9 documentation" href="index.html" />
    <link rel="next" title="Usage example: a static analysis tool for CPython extension code" href="cpychecker.html" />
    <link rel="prev" title="Working with callbacks" href="callbacks.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="cpychecker.html" title="Usage example: a static analysis tool for CPython extension code"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="callbacks.html" title="Working with callbacks"
             accesskey="P">previous</a> |</li>
        <li><a href="index.html">gcc-python-plugin 0.9 documentation</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="creating-custom-gcc-attributes">
<h1>Creating custom GCC attributes<a class="headerlink" href="#creating-custom-gcc-attributes" title="Permalink to this headline">¶</a></h1>
<p>GNU C supports a non-standard <a class="reference external" href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html">__attribute__(()) syntax</a> for marking
declarations with additional information that may be of interest to the
optimizer, and for checking the correctness of the code.</p>
<p>The GCC Python plugin allows you to create custom attributes, which may
be of use to your scripts: you can use this to annotate C code with additional
information.  For example, you could create a custom attribute for functions
describing the interaction of a function on mutex objects:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">extern</span> <span class="kt">void</span> <span class="n">some_function</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
  <span class="n">__attribute__</span><span class="p">((</span><span class="n">claims_mutex</span><span class="p">(</span><span class="s">&quot;io&quot;</span><span class="p">)));</span>

<span class="k">extern</span> <span class="kt">void</span> <span class="n">some_other_function</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
  <span class="n">__attribute__</span><span class="p">((</span><span class="n">releases_mutex</span><span class="p">(</span><span class="s">&quot;io&quot;</span><span class="p">)));</span>
</pre></div>
</div>
<p>and use this in a custom code-checker.</p>
<p>Custom attributes can take string and integer parameters.  For example, the
above custom attributes take a single string parameter.  A custom attribute can
take more than one parameter, or none at all.</p>
<p>To create custom attributes from Python, you need to wire up a callback
response to the <a class="reference internal" href="callbacks.html#gcc.PLUGIN_ATTRIBUTES" title="gcc.PLUGIN_ATTRIBUTES"><tt class="xref py py-data docutils literal"><span class="pre">gcc.PLUGIN_ATTRIBUTES</span></tt></a> event:</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">gcc</span><span class="o">.</span><span class="n">register_callback</span><span class="p">(</span><span class="n">gcc</span><span class="o">.</span><span class="n">PLUGIN_ATTRIBUTES</span><span class="p">,</span>
                      <span class="n">register_our_attributes</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p>This callback should then call <a class="reference internal" href="#gcc.register_attribute" title="gcc.register_attribute"><tt class="xref py py-func docutils literal"><span class="pre">gcc.register_attribute()</span></tt></a> to associate
the name of the attribute with a Python callback to be called when the
attribute is encountered in C code.</p>
<dl class="function">
<dt id="gcc.register_attribute">
<tt class="descclassname">gcc.</tt><tt class="descname">register_attribute</tt><big>(</big><em>name</em>, <em>min_length</em>, <em>max_length</em>, <em>decl_required</em>, <em>type_required</em>, <em>function_type_required</em>, <em>callable</em><big>)</big><a class="headerlink" href="#gcc.register_attribute" title="Permalink to this definition">¶</a></dt>
<dd><p>Registers a new GCC attribute with the given <em>name</em> , usable in C source
code via <tt class="docutils literal"><span class="pre">__attribute__(())</span></tt>.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
<li><strong>name</strong> (<em>str</em>) &#8211; the name of the new attribute</li>
<li><strong>min_length</strong> (<em>int</em>) &#8211; the minimum number of arguments expected when the attribute is used</li>
<li><strong>max_length</strong> (<em>int</em>) &#8211; the maximum number of arguments expected when the
attribute is used (-1 for no maximum)</li>
<li><strong>decl_required</strong> &#8211; </li>
<li><strong>type_required</strong> &#8211; </li>
<li><strong>function_type_required</strong> &#8211; </li>
<li><strong>callable</strong> (<em>a callable object, such as a function</em>) &#8211; the callback to be invoked when the attribute is seen</li>
</ul>
</td>
</tr>
</tbody>
</table>
</dd></dl>

<p>In this example, we can simply print when the attribute is seen, to verify that
the callback mechanism is working:</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">attribute_callback_for_claims_mutex</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
    <span class="k">print</span><span class="p">(</span><span class="s">&#39;attribute_callback_for_claims_mutex called: args: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="p">))</span>

<span class="k">def</span> <span class="nf">attribute_callback_for_releases_mutex</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
    <span class="k">print</span><span class="p">(</span><span class="s">&#39;attribute_callback_for_releases_mutex called: args: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="p">))</span>

<span class="k">def</span> <span class="nf">register_our_attributes</span><span class="p">():</span>
    <span class="n">gcc</span><span class="o">.</span><span class="n">register_attribute</span><span class="p">(</span><span class="s">&#39;claims_mutex&#39;</span><span class="p">,</span>
                           <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span>
                           <span class="bp">False</span><span class="p">,</span> <span class="bp">False</span><span class="p">,</span> <span class="bp">False</span><span class="p">,</span>
                           <span class="n">attribute_callback_for_claims_mutex</span><span class="p">)</span>
    <span class="n">gcc</span><span class="o">.</span><span class="n">register_attribute</span><span class="p">(</span><span class="s">&#39;releases_mutex&#39;</span><span class="p">,</span>
                           <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span>
                           <span class="bp">False</span><span class="p">,</span> <span class="bp">False</span><span class="p">,</span> <span class="bp">False</span><span class="p">,</span>
                           <span class="n">attribute_callback_for_releases_mutex</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p>Putting it all together, here is an example Python script for the plugin:</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">gcc</span>

<span class="c"># Verify that we can register custom attributes:</span>

<span class="k">def</span> <span class="nf">attribute_callback_for_claims_mutex</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
    <span class="k">print</span><span class="p">(</span><span class="s">&#39;attribute_callback_for_claims_mutex called: args: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="p">))</span>

<span class="k">def</span> <span class="nf">attribute_callback_for_releases_mutex</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
    <span class="k">print</span><span class="p">(</span><span class="s">&#39;attribute_callback_for_releases_mutex called: args: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="p">))</span>

<span class="k">def</span> <span class="nf">register_our_attributes</span><span class="p">():</span>
    <span class="n">gcc</span><span class="o">.</span><span class="n">register_attribute</span><span class="p">(</span><span class="s">&#39;claims_mutex&#39;</span><span class="p">,</span>
                           <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span>
                           <span class="bp">False</span><span class="p">,</span> <span class="bp">False</span><span class="p">,</span> <span class="bp">False</span><span class="p">,</span>
                           <span class="n">attribute_callback_for_claims_mutex</span><span class="p">)</span>
    <span class="n">gcc</span><span class="o">.</span><span class="n">register_attribute</span><span class="p">(</span><span class="s">&#39;releases_mutex&#39;</span><span class="p">,</span>
                           <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span>
                           <span class="bp">False</span><span class="p">,</span> <span class="bp">False</span><span class="p">,</span> <span class="bp">False</span><span class="p">,</span>
                           <span class="n">attribute_callback_for_releases_mutex</span><span class="p">)</span>

<span class="c"># Wire up our callback:</span>
<span class="n">gcc</span><span class="o">.</span><span class="n">register_callback</span><span class="p">(</span><span class="n">gcc</span><span class="o">.</span><span class="n">PLUGIN_ATTRIBUTES</span><span class="p">,</span>
                      <span class="n">register_our_attributes</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p>Compiling this test C source file:</p>
<blockquote>
<div><div class="highlight-c"><div class="highlight"><pre><span class="cm">/* Function declarations with custom attributes: */</span>
<span class="k">extern</span> <span class="n">some_function</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="n">__attribute__</span><span class="p">((</span><span class="n">claims_mutex</span><span class="p">(</span><span class="s">&quot;io&quot;</span><span class="p">)));</span>

<span class="k">extern</span> <span class="n">some_other_function</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="n">__attribute__</span><span class="p">((</span><span class="n">releases_mutex</span><span class="p">(</span><span class="s">&quot;io&quot;</span><span class="p">)));</span>

<span class="k">extern</span> <span class="n">yet_another_function</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="n">__attribute__</span><span class="p">((</span><span class="n">claims_mutex</span><span class="p">(</span><span class="s">&quot;db&quot;</span><span class="p">),</span>
                                                 <span class="n">claims_mutex</span><span class="p">(</span><span class="s">&quot;io&quot;</span><span class="p">),</span>
                                                 <span class="n">releases_mutex</span><span class="p">(</span><span class="s">&quot;io&quot;</span><span class="p">)));</span>
</pre></div>
</div>
</div></blockquote>
<p>leads to this output from the script:</p>
<blockquote>
<div><div class="highlight-bash"><div class="highlight"><pre>attribute_callback_for_claims_mutex called: args: <span class="o">(</span>gcc.FunctionDecl<span class="o">(</span><span class="s1">&#39;some_function&#39;</span><span class="o">)</span>, gcc.StringCst<span class="o">(</span><span class="s1">&#39;io&#39;</span><span class="o">))</span>
attribute_callback_for_releases_mutex called: args: <span class="o">(</span>gcc.FunctionDecl<span class="o">(</span><span class="s1">&#39;some_other_function&#39;</span><span class="o">)</span>, gcc.StringCst<span class="o">(</span><span class="s1">&#39;io&#39;</span><span class="o">))</span>
attribute_callback_for_claims_mutex called: args: <span class="o">(</span>gcc.FunctionDecl<span class="o">(</span><span class="s1">&#39;yet_another_function&#39;</span><span class="o">)</span>, gcc.StringCst<span class="o">(</span><span class="s1">&#39;db&#39;</span><span class="o">))</span>
attribute_callback_for_claims_mutex called: args: <span class="o">(</span>gcc.FunctionDecl<span class="o">(</span><span class="s1">&#39;yet_another_function&#39;</span><span class="o">)</span>, gcc.StringCst<span class="o">(</span><span class="s1">&#39;io&#39;</span><span class="o">))</span>
attribute_callback_for_releases_mutex called: args: <span class="o">(</span>gcc.FunctionDecl<span class="o">(</span><span class="s1">&#39;yet_another_function&#39;</span><span class="o">)</span>, gcc.StringCst<span class="o">(</span><span class="s1">&#39;io&#39;</span><span class="o">))</span>
</pre></div>
</div>
</div></blockquote>
<div class="section" id="using-the-preprocessor-to-guard-attribute-usage">
<h2>Using the preprocessor to guard attribute usage<a class="headerlink" href="#using-the-preprocessor-to-guard-attribute-usage" title="Permalink to this headline">¶</a></h2>
<p>Unfortunately, the above C code will only work when it is compiled with the
Python script that adds the custom attributes.</p>
<p>You can avoid this by using <a class="reference internal" href="preprocessor.html#gcc.define_macro" title="gcc.define_macro"><tt class="xref py py-func docutils literal"><span class="pre">gcc.define_macro()</span></tt></a> to pre-define a
preprocessor name (e.g. &#8220;WITH_ATTRIBUTE_CLAIMS_MUTEX&#8221;) at the same time as when
you define the attribute:</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">gcc</span>

<span class="k">def</span> <span class="nf">attribute_callback_for_claims_mutex</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
    <span class="k">print</span><span class="p">(</span><span class="s">&#39;attribute_callback_for_claims_mutex called: args: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="p">))</span>

<span class="k">def</span> <span class="nf">attribute_callback_for_releases_mutex</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
    <span class="k">print</span><span class="p">(</span><span class="s">&#39;attribute_callback_for_releases_mutex called: args: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="p">))</span>

<span class="k">def</span> <span class="nf">register_our_attributes</span><span class="p">():</span>
    <span class="n">gcc</span><span class="o">.</span><span class="n">register_attribute</span><span class="p">(</span><span class="s">&#39;claims_mutex&#39;</span><span class="p">,</span>
                           <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span>
                           <span class="bp">False</span><span class="p">,</span> <span class="bp">False</span><span class="p">,</span> <span class="bp">False</span><span class="p">,</span>
                           <span class="n">attribute_callback_for_claims_mutex</span><span class="p">)</span>
    <span class="n">gcc</span><span class="o">.</span><span class="n">define_macro</span><span class="p">(</span><span class="s">&#39;WITH_ATTRIBUTE_CLAIMS_MUTEX&#39;</span><span class="p">)</span>

    <span class="n">gcc</span><span class="o">.</span><span class="n">register_attribute</span><span class="p">(</span><span class="s">&#39;releases_mutex&#39;</span><span class="p">,</span>
                           <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span>
                           <span class="bp">False</span><span class="p">,</span> <span class="bp">False</span><span class="p">,</span> <span class="bp">False</span><span class="p">,</span>
                           <span class="n">attribute_callback_for_releases_mutex</span><span class="p">)</span>
    <span class="n">gcc</span><span class="o">.</span><span class="n">define_macro</span><span class="p">(</span><span class="s">&#39;WITH_ATTRIBUTE_RELEASES_MUTEX&#39;</span><span class="p">)</span>

<span class="c"># Wire up our callback:</span>
<span class="n">gcc</span><span class="o">.</span><span class="n">register_callback</span><span class="p">(</span><span class="n">gcc</span><span class="o">.</span><span class="n">PLUGIN_ATTRIBUTES</span><span class="p">,</span>
                      <span class="n">register_our_attributes</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p>This way the user can write this C code instead, and have it work both with
and without the Python script:</p>
<blockquote>
<div><div class="highlight-c"><div class="highlight"><pre><span class="cp">#if defined(WITH_ATTRIBUTE_CLAIMS_MUTEX)</span>
<span class="cp"> #define CLAIMS_MUTEX(x) __attribute__((claims_mutex(x)))</span>
<span class="cp">#else</span>
<span class="cp"> #define CLAIMS_MUTEX(x)</span>
<span class="cp">#endif</span>

<span class="cp">#if defined(WITH_ATTRIBUTE_RELEASES_MUTEX)</span>
<span class="cp"> #define RELEASES_MUTEX(x) __attribute__((releases_mutex(x)))</span>
<span class="cp">#else</span>
<span class="cp"> #define RELEASES_MUTEX(x)</span>
<span class="cp">#endif</span>


<span class="cm">/* Function declarations with custom attributes: */</span>
<span class="k">extern</span> <span class="kt">void</span> <span class="n">some_function</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
    <span class="n">CLAIMS_MUTEX</span><span class="p">(</span><span class="s">&quot;io&quot;</span><span class="p">);</span>

<span class="k">extern</span> <span class="kt">void</span> <span class="n">some_other_function</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
    <span class="n">RELEASES_MUTEX</span><span class="p">(</span><span class="s">&quot;io&quot;</span><span class="p">);</span>

<span class="k">extern</span> <span class="kt">void</span> <span class="n">yet_another_function</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
    <span class="n">CLAIMS_MUTEX</span><span class="p">(</span><span class="s">&quot;db&quot;</span><span class="p">)</span>
    <span class="n">CLAIMS_MUTEX</span><span class="p">(</span><span class="s">&quot;io&quot;</span><span class="p">)</span>
    <span class="n">RELEASES_MUTEX</span><span class="p">(</span><span class="s">&quot;io&quot;</span><span class="p">);</span>
</pre></div>
</div>
</div></blockquote>
<p>giving this output from the script:</p>
<blockquote>
<div><div class="highlight-bash"><div class="highlight"><pre>attribute_callback_for_claims_mutex called: args: <span class="o">(</span>gcc.FunctionDecl<span class="o">(</span><span class="s1">&#39;some_function&#39;</span><span class="o">)</span>, gcc.StringCst<span class="o">(</span><span class="s1">&#39;io&#39;</span><span class="o">))</span>
attribute_callback_for_releases_mutex called: args: <span class="o">(</span>gcc.FunctionDecl<span class="o">(</span><span class="s1">&#39;some_other_function&#39;</span><span class="o">)</span>, gcc.StringCst<span class="o">(</span><span class="s1">&#39;io&#39;</span><span class="o">))</span>
attribute_callback_for_claims_mutex called: args: <span class="o">(</span>gcc.FunctionDecl<span class="o">(</span><span class="s1">&#39;yet_another_function&#39;</span><span class="o">)</span>, gcc.StringCst<span class="o">(</span><span class="s1">&#39;db&#39;</span><span class="o">))</span>
attribute_callback_for_claims_mutex called: args: <span class="o">(</span>gcc.FunctionDecl<span class="o">(</span><span class="s1">&#39;yet_another_function&#39;</span><span class="o">)</span>, gcc.StringCst<span class="o">(</span><span class="s1">&#39;io&#39;</span><span class="o">))</span>
attribute_callback_for_releases_mutex called: args: <span class="o">(</span>gcc.FunctionDecl<span class="o">(</span><span class="s1">&#39;yet_another_function&#39;</span><span class="o">)</span>, gcc.StringCst<span class="o">(</span><span class="s1">&#39;io&#39;</span><span class="o">))</span>
</pre></div>
</div>
</div></blockquote>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
  <h3><a href="index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Creating custom GCC attributes</a><ul>
<li><a class="reference internal" href="#using-the-preprocessor-to-guard-attribute-usage">Using the preprocessor to guard attribute usage</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="callbacks.html"
                        title="previous chapter">Working with callbacks</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="cpychecker.html"
                        title="next chapter">Usage example: a static analysis tool for CPython extension code</a></p>
  <h3>This Page</h3>
  <ul class="this-page-menu">
    <li><a href="_sources/attributes.txt"
           rel="nofollow">Show Source</a></li>
  </ul>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="cpychecker.html" title="Usage example: a static analysis tool for CPython extension code"
             >next</a> |</li>
        <li class="right" >
          <a href="callbacks.html" title="Working with callbacks"
             >previous</a> |</li>
        <li><a href="index.html">gcc-python-plugin 0.9 documentation</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
        &copy; Copyright 2011, David Malcolm.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
    </div>
  </body>
</html>