[gcc-python-plugin] Fix issue with PyArg_ParseTuple("K") seen compiling gdb
by David Hugh Malcolm
commit a2adc26842032518eefee972fc92c4125eb7b07b
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Fri Jun 24 15:45:24 2011 -0400
Fix issue with PyArg_ParseTuple("K") seen compiling gdb
libcpychecker/PyArg_ParseTuple.py | 26 ++++++++--
tests/cpychecker/PyArg_ParseTuple/typedefs/input.c | 52 ++++++++++++++++++++
.../cpychecker/PyArg_ParseTuple/typedefs/script.py | 19 +++++++
3 files changed, 92 insertions(+), 5 deletions(-)
---
diff --git a/libcpychecker/PyArg_ParseTuple.py b/libcpychecker/PyArg_ParseTuple.py
index 453f0e0..7ccf30e 100644
--- a/libcpychecker/PyArg_ParseTuple.py
+++ b/libcpychecker/PyArg_ParseTuple.py
@@ -364,7 +364,7 @@ class MismatchingType(ParsedFormatStringError):
return ('Mismatching type in call to %s with format code "%s"'
% (self.funcname, self.fmt.fmt_string))
-def type_equality(exp_type, actual_type):
+def compatible_type(exp_type, actual_type):
log('comparing exp_type: %s (%r) with actual_type: %s (%r)' % (exp_type, exp_type, actual_type, actual_type))
log('type(exp_type): %r %s' % (type(exp_type), type(exp_type)))
@@ -382,16 +382,32 @@ def type_equality(exp_type, actual_type):
# was expected, rather than:
# struct PyObject * *
if isinstance(exp_type, gcc.TypeDecl):
- if type_equality(exp_type.type, actual_type):
+ if compatible_type(exp_type.type, actual_type):
return True
if isinstance(actual_type, gcc.TypeDecl):
- if type_equality(exp_type, actual_type.type):
+ if compatible_type(exp_type, actual_type.type):
return True
# Dereference for pointers (and ptrs to ptrs etc):
if isinstance(actual_type, gcc.PointerType) and isinstance(exp_type, gcc.PointerType):
- if type_equality(actual_type.dereference, exp_type.dereference):
+ if compatible_type(actual_type.dereference, exp_type.dereference):
+ return True
+
+ # Don't be too fussy about typedefs to integer types
+ # For instance:
+ # typedef unsigned PY_LONG_LONG gdb_py_ulongest;
+ # gives a different IntegerType instance to that of
+ # gcc.Type.long_long().unsigned_equivalent
+ # As long as the size, signedness etc are the same, let it go
+ if isinstance(actual_type, gcc.IntegerType) and isinstance(exp_type, gcc.IntegerType):
+ def compare_int_types():
+ for attr in ('precision', 'unsigned',
+ 'const', 'volatile', 'restrict'):
+ if getattr(actual_type, attr) != getattr(exp_type, attr):
+ return False
+ return True
+ if compare_int_types():
return True
return False
@@ -451,7 +467,7 @@ def check_pyargs(fun):
return
for index, ((exp_arg, exp_type), vararg) in enumerate(zip(exp_types, varargs)):
- if not type_equality(exp_type, vararg.type):
+ if not compatible_type(exp_type, vararg.type):
err = MismatchingType(funcname, fmt,
index + varargs_idx + 1,
exp_arg.code, exp_type, vararg)
diff --git a/tests/cpychecker/PyArg_ParseTuple/typedefs/input.c b/tests/cpychecker/PyArg_ParseTuple/typedefs/input.c
new file mode 100644
index 0000000..822a0fc
--- /dev/null
+++ b/tests/cpychecker/PyArg_ParseTuple/typedefs/input.c
@@ -0,0 +1,52 @@
+/*
+ Copyright 2011 David Malcolm <dmalcolm(a)redhat.com>
+ Copyright 2011 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/>.
+*/
+
+/*
+ Verify that the checker can cope with typedefs of another type
+ c.f. error reported here:
+ https://fedorahosted.org/pipermail/gcc-python-plugin/2011-June/000006.html
+*/
+
+#include <Python.h>
+
+/* as seen in gdb source code: */
+typedef unsigned PY_LONG_LONG gdb_py_ulongest;
+
+static PyObject *
+parse_to_a_typedef(PyObject *self, PyObject *args)
+{
+ gdb_py_ulongest val;
+
+ /*
+ "K" expects "unsigned PY_LONG_LONG", which "val" is, via a typedef
+ */
+ if (!PyArg_ParseTuple(args, "K", &val)) {
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+/*
+ PEP-7
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/
diff --git a/tests/cpychecker/PyArg_ParseTuple/typedefs/script.py b/tests/cpychecker/PyArg_ParseTuple/typedefs/script.py
new file mode 100644
index 0000000..e120c53
--- /dev/null
+++ b/tests/cpychecker/PyArg_ParseTuple/typedefs/script.py
@@ -0,0 +1,19 @@
+# Copyright 2011 David Malcolm <dmalcolm(a)redhat.com>
+# Copyright 2011 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/>.
+
+from libcpychecker import main
+main()
12 years, 11 months
[gcc-python-plugin] Remove stray import
by David Hugh Malcolm
commit 86971e046541ec653640585edcc183091a8215c7
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Fri Jun 24 14:37:00 2011 -0400
Remove stray import
libcpychecker/PyArg_ParseTuple.py | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
---
diff --git a/libcpychecker/PyArg_ParseTuple.py b/libcpychecker/PyArg_ParseTuple.py
index 2eff8e1..453f0e0 100644
--- a/libcpychecker/PyArg_ParseTuple.py
+++ b/libcpychecker/PyArg_ParseTuple.py
@@ -464,7 +464,6 @@ def check_pyargs(fun):
if isinstance(bb.gimple, list):
for stmt in bb.gimple:
if isinstance(stmt, gcc.GimpleCall):
- from gccutils import pprint
if stmt.fndecl:
if stmt.fndecl.name == 'PyArg_ParseTuple':
check_callsite(stmt, 'PyArg_ParseTuple', 1, 2)
12 years, 11 months
[gcc-python-plugin] Cope with calls to function pointers in the arg checker
by David Hugh Malcolm
commit 896b4c8fd8bfe54cea34f87cf534d470f8a0dfcc
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Fri Jun 24 14:01:20 2011 -0400
Cope with calls to function pointers in the arg checker
libcpychecker/PyArg_ParseTuple.py | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
---
diff --git a/libcpychecker/PyArg_ParseTuple.py b/libcpychecker/PyArg_ParseTuple.py
index 13efbf1..2eff8e1 100644
--- a/libcpychecker/PyArg_ParseTuple.py
+++ b/libcpychecker/PyArg_ParseTuple.py
@@ -464,10 +464,10 @@ def check_pyargs(fun):
if isinstance(bb.gimple, list):
for stmt in bb.gimple:
if isinstance(stmt, gcc.GimpleCall):
- #log('stmt.fn: %s %r' % (stmt.fn, stmt.fn))
- #log('stmt.fndecl: %s %r' % (stmt.fndecl, stmt.fndecl))
- if stmt.fndecl.name == 'PyArg_ParseTuple':
- check_callsite(stmt, 'PyArg_ParseTuple', 1, 2)
- elif stmt.fndecl.name == 'PyArg_ParseTupleAndKeywords':
- check_callsite(stmt, 'PyArg_ParseTupleAndKeywords', 2, 4)
+ from gccutils import pprint
+ if stmt.fndecl:
+ if stmt.fndecl.name == 'PyArg_ParseTuple':
+ check_callsite(stmt, 'PyArg_ParseTuple', 1, 2)
+ elif stmt.fndecl.name == 'PyArg_ParseTupleAndKeywords':
+ check_callsite(stmt, 'PyArg_ParseTupleAndKeywords', 2, 4)
12 years, 11 months
[gcc-python-plugin] Set up various things in sys, including sys.path
by David Hugh Malcolm
commit 48229eaa23c0092825d1d078a27dad2e435efc5b
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Fri Jun 24 13:48:41 2011 -0400
Set up various things in sys, including sys.path
Add the plugin's directory to sys.path, to allow it to find gccutils.py
and libcpychecker without needing to set PYTHONPATH all over the place
Makefile | 8 +++---
README.rst | 9 ++++---
docs/basics.rst | 9 ++++---
gcc-python.c | 58 ++++++++++++++++++++++++++++++++++++++++++++
gcc-with-python | 2 +-
run-test-suite.py | 1 -
tests/plugin/sys/input.c | 18 +++++++++++++
tests/plugin/sys/script.py | 30 ++++++++++++++++++++++
8 files changed, 121 insertions(+), 14 deletions(-)
---
diff --git a/Makefile b/Makefile
index a88f409..39d5a61 100644
--- a/Makefile
+++ b/Makefile
@@ -104,11 +104,11 @@ TEST_CFLAGS= \
# A catch-all test for quick experimentation with the API:
test: plugin
- PYTHONPATH=$(shell pwd) gcc -v $(TEST_CFLAGS) $(shell pwd)/test.c
+ gcc -v $(TEST_CFLAGS) $(shell pwd)/test.c
# Selftest for the cpychecker.py code:
testcpychecker: plugin
- PYTHONPATH=$(shell pwd) python testcpychecker.py -v
+ python testcpychecker.py -v
# Selftest for the cpybuilder code:
testcpybuilder:
@@ -118,11 +118,11 @@ dump_gimple:
gcc -fdump-tree-gimple $(shell pwd)/test.c
debug: plugin
- PYTHONPATH=$(shell pwd) gcc -v $(TEST_CFLAGS) $(shell pwd)/test.c
+ gcc -v $(TEST_CFLAGS) $(shell pwd)/test.c
# A simple demo, to make it easy to demonstrate the cpychecker:
demo: plugin
- PYTHONPATH=$(shell pwd) gcc -fplugin=$(shell pwd)/python.so -fplugin-arg-python-script=cpychecker.py $(shell python-config --cflags) $(shell pwd)/demo.c
+ gcc -fplugin=$(shell pwd)/python.so -fplugin-arg-python-script=cpychecker.py $(shell python-config --cflags) $(shell pwd)/demo.c
test-suite: plugin
python run-test-suite.py
diff --git a/README.rst b/README.rst
index c6686a2..ecdc2b4 100644
--- a/README.rst
+++ b/README.rst
@@ -63,10 +63,11 @@ arguments to the gcc invocation::
gcc -fplugin=python.so -fplugin-arg-python-script=PATH_TO_SCRIPT.py OTHER_ARGS
-and have it run your script as the plugin starts up. However at the moment
-you have to supply absolute paths to the plugin, and to the script. (There's
-also a gccutil.py, and you have to set PYTHONPATH for the plugin to be able to
-find it).
+and have it run your script as the plugin starts up.
+
+The plugin automatically adds the absolute path to its own directory to the
+end of its `sys.path`, so that it can find support modules, such as gccutils.py
+and `libcpychecker`.
The exact API is still in flux; you can currently connect to events by
registering callbacks e.g. to be called for each function in the source at
diff --git a/docs/basics.rst b/docs/basics.rst
index 5e62016..0bb53fd 100644
--- a/docs/basics.rst
+++ b/docs/basics.rst
@@ -53,10 +53,11 @@ Once you've built the plugin, you can invoke a Python script like this:
gcc -fplugin=python.so -fplugin-arg-python-script=PATH_TO_SCRIPT.py OTHER_ARGS
-and have it run your script as the plugin starts up. However at the moment
-you have to supply absolute paths to the plugin, and to the script. (There's
-also a gccutil.py, and you have to set PYTHONPATH for the plugin to be able to
-find it).
+and have it run your script as the plugin starts up.
+
+The plugin automatically adds the absolute path to its own directory to the
+end of its `sys.path`, so that it can find support modules, such as gccutils.py
+and `libcpychecker`.
There is also a helper script, `gcc-with-python`, which expects a python script
as its first argument, then regular gcc arguments:
diff --git a/gcc-python.c b/gcc-python.c
index f382e18..af4e62b 100644
--- a/gcc-python.c
+++ b/gcc-python.c
@@ -527,7 +527,61 @@ static void gcc_python_run_any_script(void)
}
}
+int
+setup_sys(struct plugin_name_args *plugin_info)
+{
+ /*
+
+ * Sets up "sys.plugin_full_name" as plugin_info->full_name. This is the
+ path to the plugin (as specified with -fplugin=)
+
+ * Sets up "sys.plugin_base_name" as plugin_info->base_name. This is the
+ short name, of the plugin (filename without .so suffix)
+
+ * Add the directory containing the plugin to "sys.path", so that it can
+ find modules relative to itself without needing PYTHONPATH to be set up.
+ (sys.path has already been initialized by the call to Py_Initialize)
+ */
+ int result = 0; /* failure */
+ PyObject *full_name = NULL;
+ PyObject *base_name = NULL;
+ const char *program =
+ "import sys;\n"
+ "import os;\n"
+ "sys.path.append(os.path.abspath(os.path.dirname(sys.plugin_full_name)))\n";
+
+ /* Setup "sys.plugin_full_name" */
+ full_name = PyString_FromString(plugin_info->full_name);
+ if (!full_name) {
+ goto error;
+ }
+ if (-1 == PySys_SetObject("plugin_full_name", full_name)) {
+ goto error;
+ }
+
+ /* Setup "sys.plugin_base_name" */
+ base_name = PyString_FromString(plugin_info->base_name);
+ if (!base_name) {
+ goto error;
+ }
+ if (-1 == PySys_SetObject("plugin_base_name", base_name)) {
+ goto error;
+ }
+
+ /* Add the plugin's path to sys.path */
+ if (-1 == PyRun_SimpleString(program)) {
+ goto error;
+ }
+
+ /* Success: */
+ result = 1;
+
+ error:
+ Py_XDECREF(full_name);
+ Py_XDECREF(base_name);
+ return result;
+}
int
plugin_init (struct plugin_name_args *plugin_info,
@@ -551,6 +605,10 @@ plugin_init (struct plugin_name_args *plugin_info,
return 1;
}
+ if (!setup_sys(plugin_info)) {
+ return 1;
+ }
+
/* Init other modules */
/* FIXME: properly integrate them within the module hierarchy */
diff --git a/gcc-with-python b/gcc-with-python
index 5987b48..f68c918 100755
--- a/gcc-with-python
+++ b/gcc-with-python
@@ -16,4 +16,4 @@
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
-PYTHONPATH=$(pwd) gcc -fplugin=$(pwd)/python.so -fplugin-arg-python-script=$@
+gcc -fplugin=$(pwd)/python.so -fplugin-arg-python-script=$@
diff --git a/run-test-suite.py b/run-test-suite.py
index f0c5182..1674912 100644
--- a/run-test-suite.py
+++ b/run-test-suite.py
@@ -101,7 +101,6 @@ def run_test(testdir):
err = TestStream(os.path.join(testdir, 'stderr.txt'))
env = dict(os.environ)
- env['PYTHONPATH'] = os.getcwd()
args = ['gcc']
args += ['-c']
diff --git a/tests/plugin/sys/input.c b/tests/plugin/sys/input.c
new file mode 100644
index 0000000..c7ec480
--- /dev/null
+++ b/tests/plugin/sys/input.c
@@ -0,0 +1,18 @@
+/*
+ Copyright 2011 David Malcolm <dmalcolm(a)redhat.com>
+ Copyright 2011 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/>.
+*/
diff --git a/tests/plugin/sys/script.py b/tests/plugin/sys/script.py
new file mode 100644
index 0000000..b11fbf4
--- /dev/null
+++ b/tests/plugin/sys/script.py
@@ -0,0 +1,30 @@
+# Copyright 2011 David Malcolm <dmalcolm(a)redhat.com>
+# Copyright 2011 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/>.
+
+# Verify the things the plugin exposes within the sys module
+import sys
+import os
+
+assert hasattr(sys, 'plugin_full_name')
+assert os.path.exists(sys.plugin_full_name)
+
+assert hasattr(sys, 'plugin_base_name')
+assert sys.plugin_base_name == 'python' # for now
+
+# Verify that the plugin's directory is in sys.path, as an absolute path:
+plugin_dir = os.path.abspath(os.path.dirname(sys.plugin_full_name))
+assert plugin_dir in sys.path
12 years, 11 months
[gcc-python-plugin] Automatically supply the correct header search directory for selftests that #include <Python.h>
by David Hugh Malcolm
commit df0d37e0f1f796f03ab0de0f9f2717d02904632d
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Thu Jun 23 19:48:58 2011 -0400
Automatically supply the correct header search directory for selftests that #include <Python.h>
run-test-suite.py | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
---
diff --git a/run-test-suite.py b/run-test-suite.py
index e36fc43..f0c5182 100644
--- a/run-test-suite.py
+++ b/run-test-suite.py
@@ -33,6 +33,7 @@
import glob
import os
import sys
+from distutils.sysconfig import get_python_inc
from subprocess import Popen, PIPE
from cpybuilder import CommandError
@@ -108,6 +109,12 @@ def run_test(testdir):
args += ['-fplugin=%s' % os.path.abspath('python.so'),
'-fplugin-arg-python-script=%s' % script_py]
+ # Special-case: add the python include dir (for this runtime) if the C code
+ # uses Python.h:
+ code = open(c_input, 'r').read()
+ if '#include <Python.h>' in code:
+ args += ['-I' + get_python_inc()]
+
getopts_py = os.path.join(testdir, 'getopts.py')
if os.path.exists(getopts_py):
p = Popen([sys.executable, getopts_py], stdout=PIPE, stderr=PIPE)
12 years, 11 months
[gcc-python-plugin] Move the debugging information to be more prominent, and reword
by David Hugh Malcolm
commit 9dcda10a26980d2674b737468dbf3135d15762f1
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Thu Jun 23 10:32:49 2011 -0400
Move the debugging information to be more prominent, and reword
docs/basics.rst | 29 +++++++++++++++--------------
1 files changed, 15 insertions(+), 14 deletions(-)
---
diff --git a/docs/basics.rst b/docs/basics.rst
index 0c205ee..5e62016 100644
--- a/docs/basics.rst
+++ b/docs/basics.rst
@@ -96,6 +96,21 @@ of the code; we may have to change things as GCC changes in future releases
also).
+Debugging your script
+---------------------
+
+You can place a forced breakpoint in your script using this standard Python
+one-liner::
+
+ import pdb; pdb.set_trace()
+
+If Python reaches this location it will interrupt the compile and put you
+within the `pdb` interactive debugger, from where you can investigate.
+
+See http://docs.python.org/library/pdb.html#debugger-commands for more
+information.
+
+
Accessing parameters
--------------------
@@ -434,17 +449,3 @@ Working with source code
.. py:attribute:: column
(int) Column number within source file (starting at 1, not 0)
-
-Debugging
-=========
-
-You can place a forced breakpoint in your script using this standard Python
-one-liner::
-
- import pdb; pdb.set_trace()
-
-This will interrupt the compile and put you in pdb's interactive debugger,
-from which you can examine data.
-
-See http://docs.python.org/library/pdb.html#debugger-commands for more
-information
12 years, 11 months
[gcc-python-plugin] Add note about debugging
by David Hugh Malcolm
commit 83f5fdfbdbb4a3b336bb0894d15bb6b77e9c4625
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Thu Jun 23 03:37:06 2011 -0400
Add note about debugging
docs/basics.rst | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
---
diff --git a/docs/basics.rst b/docs/basics.rst
index 64d0629..0c205ee 100644
--- a/docs/basics.rst
+++ b/docs/basics.rst
@@ -435,3 +435,16 @@ Working with source code
(int) Column number within source file (starting at 1, not 0)
+Debugging
+=========
+
+You can place a forced breakpoint in your script using this standard Python
+one-liner::
+
+ import pdb; pdb.set_trace()
+
+This will interrupt the compile and put you in pdb's interactive debugger,
+from which you can examine data.
+
+See http://docs.python.org/library/pdb.html#debugger-commands for more
+information
12 years, 11 months
[gcc-python-plugin] Fix a mismatch between gccutils.pformat() and the API docs
by David Hugh Malcolm
commit 70a1824411f8c49c714750432032c6f135de25f1
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Wed Jun 22 21:06:47 2011 -0400
Fix a mismatch between gccutils.pformat() and the API docs
gccutils.py | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
---
diff --git a/gccutils.py b/gccutils.py
index 96e0ef5..f42d6a0 100644
--- a/gccutils.py
+++ b/gccutils.py
@@ -99,12 +99,12 @@ class TextualPrettyPrinter(PrettyPrinter):
def pprint(self, obj):
import sys
- sys.stdout.write(self.pformat(obj, 0))
+ sys.stdout.write(self.pformat(obj))
def make_indent(self, indent):
return indent * ' '
- def pformat(self, obj, indent):
+ def pformat(self, obj):
return self._recursive_format_obj(obj, set(), 0)
def indent(self, prefix, txt):
12 years, 11 months
[gcc-python-plugin] Document the 'basic_blocks' attribute of gcc.Cfg
by David Hugh Malcolm
commit 59f6941c5f3b2280f854022d5ab5620080f29a29
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Wed Jun 22 21:05:34 2011 -0400
Document the 'basic_blocks' attribute of gcc.Cfg
docs/cfg.rst | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
---
diff --git a/docs/cfg.rst b/docs/cfg.rst
index 3e2bd07..b5deaf5 100644
--- a/docs/cfg.rst
+++ b/docs/cfg.rst
@@ -44,8 +44,18 @@ You can get at the control flow graph of a :py:class:`gcc.Function` via its
A ``gcc.Cfg`` is a wrapper around GCC's `struct control_flow_graph`.
- It has attributes ``entry`` and ``exit``, both of which are instances of
- :py:class:`gcc.BasicBlock`.
+ .. py:attribute:: basic_blocks
+
+ List of :py:class:`gcc.BasicBlock`, giving all of the basic blocks within
+ this CFG
+
+ .. py:attribute:: entry
+
+ Instance of :py:class:`gcc.BasicBlock`: the entrypoint for this CFG
+
+ .. py:attribute:: exit
+
+ Instance of :py:class:`gcc.BasicBlock`: the final one within this CFG
You can use ``gccutils.cfg_to_dot`` to render a gcc.Cfg as a graphviz
diagram. It will render the diagram, showing each basic block, with
12 years, 11 months
[gcc-python-plugin] Introduce a compatibility header file
by David Hugh Malcolm
commit 4fa48ee5b6faf9ed588ada22b0aba8ac52facb91
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Wed Jun 22 21:03:24 2011 -0400
Introduce a compatibility header file
Initially this is merely as a staging area for declarations that I wish
GCC's plugin interface exposed.
gcc-python-compat.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++
gcc-python-gimple.c | 7 +-----
gcc-python-tree.c | 8 +-----
3 files changed, 64 insertions(+), 13 deletions(-)
---
diff --git a/gcc-python-compat.h b/gcc-python-compat.h
new file mode 100644
index 0000000..3d31a66
--- /dev/null
+++ b/gcc-python-compat.h
@@ -0,0 +1,62 @@
+/*
+ Copyright 2011 David Malcolm <dmalcolm(a)redhat.com>
+ Copyright 2011 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/>.
+*/
+
+#ifndef INCLUDED__GCC_PYTHON_COMPAT_H
+#define INCLUDED__GCC_PYTHON_COMPAT_H
+
+#include "gimple.h"
+#include "tree.h"
+
+/*
+ There are a few GCC symbols that don't seem to be exposed in the plugin
+ headers, but I wish were.
+
+ We manually repeated the necessary declarations here.
+
+ This is wrong, but at least it's all captured here in one place. Hopefully
+ these will eventually become officially exposed to plugins, but for now its
+ all here.
+*/
+
+/*
+ This is declared in gcc/gimple-pretty-print.c, but not exposed in any of
+ the plugin headers AFAIK:
+*/
+extern void
+dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags);
+
+
+/*
+ This is declated in gcc/tree-pretty-print.c (around line 580); it doesn't
+ seem to be declared in any of the plugin headers:
+ */
+extern int
+dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
+ bool is_stmt);
+
+
+/*
+ PEP-7
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/
+
+#endif /* INCLUDED__GCC_PYTHON_COMPAT_H */
diff --git a/gcc-python-gimple.c b/gcc-python-gimple.c
index 0054c00..41d23c9 100644
--- a/gcc-python-gimple.c
+++ b/gcc-python-gimple.c
@@ -20,6 +20,7 @@
#include <Python.h>
#include "gcc-python.h"
#include "gcc-python-wrappers.h"
+#include "gcc-python-compat.h"
#include "gimple.h"
#include "tree-flow.h"
#include "tree-flow-inline.h"
@@ -30,12 +31,6 @@ gcc_Gimple_repr(struct PyGccGimple * self)
return gcc_python_string_from_format("%s()", Py_TYPE(self)->tp_name);
}
-/* FIXME:
- This is declared in gimple-pretty-print.c, but not exposed in any of the plugin headers AFAIK:
-*/
-void
-dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags);
-
PyObject *
gcc_Gimple_str(struct PyGccGimple * self)
{
diff --git a/gcc-python-tree.c b/gcc-python-tree.c
index 40c4666..ec460ad 100644
--- a/gcc-python-tree.c
+++ b/gcc-python-tree.c
@@ -20,6 +20,7 @@
#include <Python.h>
#include "gcc-python.h"
#include "gcc-python-wrappers.h"
+#include "gcc-python-compat.h"
#include "gimple.h"
//#include "rtl.h"
@@ -39,13 +40,6 @@
Code for various tree types
*/
-/* FIXME:
- This doesn't seem to be declared in any of the plugin headers:
- */
-int
-dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
- bool is_stmt);
-
PyObject *
gcc_Tree_str(struct PyGccTree * self)
{
12 years, 11 months