summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2012-01-09 22:43:17 (GMT)
committerDavid Malcolm <dmalcolm@redhat.com>2012-01-09 22:44:36 (GMT)
commit424d96fc059000259916712bafd0488ea96cc23d (patch)
tree5e5ffb101c9bd8ba8b8617bfeafe2de6b78f411d
parent0d9d7e66437056c0e8232ca27b12043ac2963a0d (diff)
downloadgcc-python-plugin-424d96fc059000259916712bafd0488ea96cc23d.zip
gcc-python-plugin-424d96fc059000259916712bafd0488ea96cc23d.tar.gz
gcc-python-plugin-424d96fc059000259916712bafd0488ea96cc23d.tar.xz
add get_symbol() classmethod to various tree subclasses
Wrap op_symbol_code, adding a get_symbol() classmethod to those mid-level classes which satisfy IS_EXPR_CODE_CLASS() [gcc.Reference, gcc.Comparison, gcc.Unary, gcc.Binary, gcc.Statement, gcc.VlExp, gcc.Expression] This requires adding an association from our PyTypeObjects back to enum tree_code. For now we do this using a simple autogenerated linear search. Add a selftest, and a table of the get_symbol() results from this to the documentation in a new "Appendices" section. Also, move the table of passes to be an appendix. This will allow us to print e.g. "+" rather than gcc.PlusExpr in error messages from cpychecker (similar to the issue described in https://fedorahosted.org/gcc-python-plugin/ticket/12 )
-rw-r--r--docs/appendices.rst27
-rw-r--r--docs/index.rst1
-rw-r--r--docs/misc.rst5
-rw-r--r--docs/operators.rst30
-rw-r--r--docs/tree.rst42
-rw-r--r--gcc-python-tree.c17
-rw-r--r--gcc-python-wrappers.h10
-rw-r--r--generate-tree-c.py31
-rw-r--r--tests/plugin/expressions/get_symbol/input.c28
-rw-r--r--tests/plugin/expressions/get_symbol/script.py43
-rw-r--r--tests/plugin/expressions/get_symbol/stdout.txt63
11 files changed, 281 insertions, 16 deletions
diff --git a/docs/appendices.rst b/docs/appendices.rst
new file mode 100644
index 0000000..412fcb2
--- /dev/null
+++ b/docs/appendices.rst
@@ -0,0 +1,27 @@
+.. Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+ Copyright 2012 Red Hat, Inc.
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+Appendices
+==========
+
+The following contain tables of reference material that may be useful
+when writing scripts.
+
+.. toctree::
+
+ tables-of-passes.rst
+ operators.rst
diff --git a/docs/index.rst b/docs/index.rst
index affa112..ad34079 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -41,6 +41,7 @@ Contents:
success.rst
misc.rst
release-notes.rst
+ appendices.rst
This document describes the Python plugin I've written for GCC. In theory the
plugin allows you to write Python scripts that can run inside GCC as it
diff --git a/docs/misc.rst b/docs/misc.rst
index 75c1322..717e3be 100644
--- a/docs/misc.rst
+++ b/docs/misc.rst
@@ -1,5 +1,5 @@
-.. Copyright 2011 David Malcolm <dmalcolm@redhat.com>
- Copyright 2011 Red Hat, Inc.
+.. Copyright 2011, 2012 David Malcolm <dmalcolm@redhat.com>
+ Copyright 2011, 2012 Red Hat, Inc.
This is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
@@ -29,5 +29,4 @@ scripts.
parameters.rst
preprocessor.rst
versions.rst
- tables-of-passes.rst
rtl.rst
diff --git a/docs/operators.rst b/docs/operators.rst
new file mode 100644
index 0000000..734c3a7
--- /dev/null
+++ b/docs/operators.rst
@@ -0,0 +1,30 @@
+.. Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+ Copyright 2012 Red Hat, Inc.
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+
+:py:class:`gcc.Tree` operators by symbol
+----------------------------------------
+
+.. _get_symbols:
+
+The following shows the symbol used for each expression subclass in debug
+dumps, as returned by the various `get_symbol()` class methods.
+
+There are some duplicates (e.g. `-` is used for both :py:class:`gcc.MinusExpr`
+as an infix binary operator, and by :py:class:`gcc.NegateExpr` as a prefixed
+unary operator).
+
+.. include:: ../tests/plugin/expressions/get_symbol/stdout.txt
diff --git a/docs/tree.rst b/docs/tree.rst
index 7cb2ef2..316d8c4 100644
--- a/docs/tree.rst
+++ b/docs/tree.rst
@@ -602,6 +602,12 @@ Binary Expressions
The :py:class:`gcc.Location` for this binary expression
+ .. py:classmethod:: get_symbol()
+
+ Get the symbol used in debug dumps for this :py:class:`gcc.Binary`
+ subclass, if any, as a `str`. A table showing these strings can be
+ seen :ref:`here <get_symbols>`.
+
Has subclasses for the various kinds of binary expression. These
include:
@@ -742,6 +748,12 @@ Unary Expressions
The :py:class:`gcc.Location` for this unary expression
+ .. py:classmethod:: get_symbol()
+
+ Get the symbol used in debug dumps for this :py:class:`gcc.Unary`
+ subclass, if any, as a `str`. A table showing these strings can be
+ seen :ref:`here <get_symbols>`.
+
Subclasses include:
====================================== ==================================================
@@ -786,18 +798,24 @@ Comparisons
The :py:class:`gcc.Location` for this comparison
+ .. py:classmethod:: get_symbol()
+
+ Get the symbol used in debug dumps for this :py:class:`gcc.Comparison`
+ subclass, if any, as a `str`. A table showing these strings can be
+ seen :ref:`here <get_symbols>`.
+
Subclasses include:
===================================== ======================
Subclass C/C++ operators
===================================== ======================
- .. py:class:: EqExpr
- .. py:class:: GeExpr
- .. py:class:: GtExpr
- .. py:class:: LeExpr
- .. py:class:: LtExpr
+ .. py:class:: EqExpr `==`
+ .. py:class:: GeExpr `>=`
+ .. py:class:: GtExpr `>`
+ .. py:class:: LeExpr `<=`
+ .. py:class:: LtExpr `<`
.. py:class:: LtgtExpr
- .. py:class:: NeExpr
+ .. py:class:: NeExpr `!=`
.. py:class:: OrderedExpr
.. py:class:: UneqExpr
.. py:class:: UngeExpr
@@ -823,6 +841,12 @@ References to storage
The :py:class:`gcc.Location` for this storage reference
+ .. py:classmethod:: get_symbol()
+
+ Get the symbol used in debug dumps for this :py:class:`gcc.Reference`
+ subclass, if any, as a `str`. A table showing these strings can be
+ seen :ref:`here <get_symbols>`.
+
.. py:class:: gcc.ArrayRef
A subclass of :py:class:`gcc.Reference` for expressions involving an array
@@ -926,6 +950,12 @@ Other expression subclasses
The :py:class:`gcc.Location` for this expression
+ .. py:classmethod:: get_symbol()
+
+ Get the symbol used in debug dumps for this :py:class:`gcc.Expression`
+ subclass, if any, as a `str`. A table showing these strings can be
+ seen :ref:`here <get_symbols>`.
+
Subclasses include:
===================================== ======================
diff --git a/gcc-python-tree.c b/gcc-python-tree.c
index c7ba3a0..b08e921 100644
--- a/gcc-python-tree.c
+++ b/gcc-python-tree.c
@@ -25,6 +25,9 @@
#include "cp/cp-tree.h" /* for TFF_* for use by gcc_FunctionDecl_get_fullname */
+#include "tree-flow.h" /* for op_symbol_code */
+
+
/*
Unfortunately, decl_as_string() is only available from the C++
frontend: cc1plus (it's defined in gcc/cp/error.c).
@@ -140,6 +143,20 @@ gcc_Tree_get_str_no_uid(struct PyGccTree *self, void *closure)
}
PyObject *
+gcc_Tree_get_symbol(PyObject *cls, PyObject *args)
+{
+ enum tree_code code;
+
+ if (-1 == gcc_python_tree_type_object_as_tree_code(cls, &code)) {
+ PyErr_SetString(PyExc_TypeError,
+ "no symbol associated with this type");
+ return NULL;
+ }
+
+ return gcc_python_string_from_string(op_symbol_code(code));
+}
+
+PyObject *
gcc_Declaration_repr(struct PyGccTree * self)
{
PyObject *name = NULL;
diff --git a/gcc-python-wrappers.h b/gcc-python-wrappers.h
index bb5a669..e421af1 100644
--- a/gcc-python-wrappers.h
+++ b/gcc-python-wrappers.h
@@ -105,6 +105,13 @@ gcc_Cfg_get_basic_blocks(PyGccCfg *self, void *closure);
PyObject *
gcc_Cfg_get_block_for_label(PyObject *self, PyObject *args);
+/* autogenerated-tree.c: */
+
+/* return -1 if there isn't an enum tree_code associated with this type */
+int
+gcc_python_tree_type_object_as_tree_code(PyObject *cls,
+ enum tree_code *out);
+
/* gcc-python-tree.c: */
PyObject *
gcc_Tree_str(struct PyGccTree * self);
@@ -119,6 +126,9 @@ PyObject *
gcc_Tree_get_str_no_uid(struct PyGccTree *self, void *closure);
PyObject *
+gcc_Tree_get_symbol(PyObject *cls, PyObject *args);
+
+PyObject *
gcc_Function_repr(struct PyGccFunction * self);
PyObject *
diff --git a/generate-tree-c.py b/generate-tree-c.py
index 2829b9e..46be894 100644
--- a/generate-tree-c.py
+++ b/generate-tree-c.py
@@ -136,13 +136,17 @@ def generate_intermediate_tree_classes():
getsettable = PyGetSetDefTable('gcc_%s_getset_table' % localname, [])
+ methods = PyMethodTable('gcc_%s_methods' % localname, [])
+
pytype = PyTypeObject(identifier = code_type,
localname = localname,
tp_name = 'gcc.%s' % localname,
struct_name = 'struct PyGccTree',
tp_new = 'PyType_GenericNew',
tp_base = '&gcc_TreeType',
- tp_getset = getsettable.identifier)
+ tp_getset = getsettable.identifier,
+ tp_methods = methods.identifier)
+
if localname == 'Declaration':
cu.add_defn("""
PyObject *
@@ -196,9 +200,6 @@ gcc_Declaration_get_location(struct PyGccTree *self, void *closure)
None,
'sizeof() this type, as a gcc.IntegerCst')
- methods = PyMethodTable('gcc_Type_methods', [])
-
-
def add_type(c_expr_for_node, typename):
# Expose the given global type node within the gcc.Tree API
#
@@ -264,9 +265,6 @@ PyObject*
name = ti[3:-5].lower()
add_type('global_trees[%s]' % ti, name)
- pytype.tp_methods = methods.identifier
- cu.add_defn(methods.c_defn())
-
if localname == 'Unary':
add_simple_getter('operand',
'gcc_python_make_wrapper_tree(TREE_OPERAND (self->t, 0))',
@@ -281,6 +279,12 @@ PyObject*
'gcc_python_make_wrapper_location(EXPR_LOCATION(self->t))',
"The source location of this expression")
+ methods.add_method('get_symbol',
+ 'gcc_Tree_get_symbol', # they all share the implementation
+ 'METH_CLASS|METH_NOARGS',
+ "FIXME")
+
+ cu.add_defn(methods.c_defn())
cu.add_defn(getsettable.c_defn())
cu.add_defn(pytype.c_defn())
modinit_preinit += pytype.c_invoke_type_ready()
@@ -556,6 +560,19 @@ def generate_tree_code_classes():
cu.add_defn(' &gcc_%sType, /* %s */\n' % (tree_type.camel_cased_string(), tree_type.SYM))
cu.add_defn('};\n\n')
+ cu.add_defn('\n/* Map from PyTypeObject* to GCC tree codes*/\n')
+ cu.add_defn('int \n')
+ cu.add_defn('gcc_python_tree_type_object_as_tree_code(PyObject *cls, enum tree_code *out)\n')
+ cu.add_defn('{\n')
+ for tree_type in tree_types:
+ cu.add_defn(' if (cls == (PyObject*)&gcc_%sType) {\n'
+ ' *out = %s; return 0;\n'
+ ' }\n'
+ % (tree_type.camel_cased_string(),
+ tree_type.SYM))
+ cu.add_defn(' return -1;\n')
+ cu.add_defn('}\n')
+
cu.add_defn("""
PyTypeObject*
gcc_python_autogenerated_tree_type_for_tree_code(enum tree_code code, int borrow_ref)
diff --git a/tests/plugin/expressions/get_symbol/input.c b/tests/plugin/expressions/get_symbol/input.c
new file mode 100644
index 0000000..8a8142d
--- /dev/null
+++ b/tests/plugin/expressions/get_symbol/input.c
@@ -0,0 +1,28 @@
+/*
+ Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+ Copyright 2012 Red Hat, Inc.
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/* empty */
+
+/*
+ PEP-7
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/
diff --git a/tests/plugin/expressions/get_symbol/script.py b/tests/plugin/expressions/get_symbol/script.py
new file mode 100644
index 0000000..5a53b36
--- /dev/null
+++ b/tests/plugin/expressions/get_symbol/script.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+# Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+# Copyright 2012 Red Hat, Inc.
+#
+# This is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+import gcc
+
+from gccutils import Table
+
+t = Table(['Class', 'get_symbol()'],
+ sepchar='=')
+
+for name in sorted(dir(gcc)):
+ obj = getattr(gcc, name)
+ if hasattr(obj, 'get_symbol'):
+ try:
+ sym = obj.get_symbol()
+ except TypeError:
+ continue
+ if sym != '<<< ??? >>>':
+ t.add_row((':py:class:`gcc.%s`' % name,
+ '`%s`' % sym.strip()))
+
+from StringIO import StringIO
+s = StringIO()
+t.write(s)
+
+for line in s.getvalue().splitlines():
+ print(' ' + line.rstrip())
+print('\n')
diff --git a/tests/plugin/expressions/get_symbol/stdout.txt b/tests/plugin/expressions/get_symbol/stdout.txt
new file mode 100644
index 0000000..24844e1
--- /dev/null
+++ b/tests/plugin/expressions/get_symbol/stdout.txt
@@ -0,0 +1,63 @@
+ ================================= ============
+ Class get_symbol()
+ ================================= ============
+ :py:class:`gcc.AddrExpr` `&`
+ :py:class:`gcc.BitAndExpr` `&`
+ :py:class:`gcc.BitIorExpr` `|`
+ :py:class:`gcc.BitNotExpr` `~`
+ :py:class:`gcc.BitXorExpr` `^`
+ :py:class:`gcc.CeilDivExpr` `/[cl]`
+ :py:class:`gcc.CeilModExpr` `%[cl]`
+ :py:class:`gcc.EqExpr` `==`
+ :py:class:`gcc.ExactDivExpr` `/[ex]`
+ :py:class:`gcc.FloorDivExpr` `/[fl]`
+ :py:class:`gcc.FloorModExpr` `%[fl]`
+ :py:class:`gcc.GeExpr` `>=`
+ :py:class:`gcc.GtExpr` `>`
+ :py:class:`gcc.IndirectRef` `*`
+ :py:class:`gcc.LeExpr` `<=`
+ :py:class:`gcc.LrotateExpr` `r<<`
+ :py:class:`gcc.LshiftExpr` `<<`
+ :py:class:`gcc.LtExpr` `<`
+ :py:class:`gcc.LtgtExpr` `<>`
+ :py:class:`gcc.MaxExpr` `max`
+ :py:class:`gcc.MinExpr` `min`
+ :py:class:`gcc.MinusExpr` `-`
+ :py:class:`gcc.ModifyExpr` `=`
+ :py:class:`gcc.MultExpr` `*`
+ :py:class:`gcc.NeExpr` `!=`
+ :py:class:`gcc.NegateExpr` `-`
+ :py:class:`gcc.OrderedExpr` `ord`
+ :py:class:`gcc.PlusExpr` `+`
+ :py:class:`gcc.PointerPlusExpr` `+`
+ :py:class:`gcc.PostdecrementExpr` `--`
+ :py:class:`gcc.PostincrementExpr` `++`
+ :py:class:`gcc.PredecrementExpr` `--`
+ :py:class:`gcc.PreincrementExpr` `++`
+ :py:class:`gcc.RdivExpr` `/`
+ :py:class:`gcc.ReducPlusExpr` `r+`
+ :py:class:`gcc.RoundDivExpr` `/[rd]`
+ :py:class:`gcc.RoundModExpr` `%[rd]`
+ :py:class:`gcc.RrotateExpr` `r>>`
+ :py:class:`gcc.RshiftExpr` `>>`
+ :py:class:`gcc.TruncDivExpr` `/`
+ :py:class:`gcc.TruncModExpr` `%`
+ :py:class:`gcc.TruthAndExpr` `&&`
+ :py:class:`gcc.TruthAndifExpr` `&&`
+ :py:class:`gcc.TruthNotExpr` `!`
+ :py:class:`gcc.TruthOrExpr` `||`
+ :py:class:`gcc.TruthOrifExpr` `||`
+ :py:class:`gcc.TruthXorExpr` `^`
+ :py:class:`gcc.UneqExpr` `u==`
+ :py:class:`gcc.UngeExpr` `u>=`
+ :py:class:`gcc.UngtExpr` `u>`
+ :py:class:`gcc.UnleExpr` `u<=`
+ :py:class:`gcc.UnltExpr` `u<`
+ :py:class:`gcc.UnorderedExpr` `unord`
+ :py:class:`gcc.VecLshiftExpr` `v<<`
+ :py:class:`gcc.VecRshiftExpr` `v>>`
+ :py:class:`gcc.WidenMultExpr` `w*`
+ :py:class:`gcc.WidenSumExpr` `w+`
+ ================================= ============
+
+