From 724dea85cd9da744f0b479fa7578350facb98fd5 Mon Sep 17 00:00:00 2001 From: Michka Popoff Date: Tue, 7 Jun 2016 23:11:36 +0200 Subject: [PATCH 1/4] Extend the map test for gcc (see #55) Calling create_decl_string on the _M_clone_node calldef is failing with gcc > 4.9 and -std=c++11 This test should is currently failing, it is only there to have a way to demonstrate the error and to fix it. --- unittests/test_map_gcc5.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/unittests/test_map_gcc5.py b/unittests/test_map_gcc5.py index 35dfe44d..62b8665f 100644 --- a/unittests/test_map_gcc5.py +++ b/unittests/test_map_gcc5.py @@ -21,7 +21,9 @@ def test_map_gcc5(self): """ The code in test_map_gcc5.hpp was breaking pygccxml. - Test that case (gcc5 + castxml + c++11). See issue #45 + Test that case (gcc5 + castxml + c++11). + + See issue #45 and #55 """ @@ -29,7 +31,16 @@ def test_map_gcc5(self): return decls = parser.parse([self.header], self.config) - self.global_ns = declarations.get_global_namespace(decls) + global_ns = declarations.get_global_namespace(decls) + + # This calldef is defined with gcc > 4.9 (maybe earlier, not tested) + # and -std=c++11. Calling create_decl_string is failing with gcc. + # With clang the calldef does not exist so the matche + # will just return an empty list, letting the test pass. + criteria = declarations.calldef_matcher(name="_M_clone_node") + free_funcs = declarations.matcher.find(criteria, global_ns) + for free_funcs in free_funcs: + print(free_funcs.create_decl_string(with_defaults=False)) def create_suite(): From 138ed87c798c02f246cdfe73bf757c704eec47e3 Mon Sep 17 00:00:00 2001 From: Michka Popoff Date: Tue, 14 Jun 2016 23:59:46 +0200 Subject: [PATCH 2/4] Fix problem with argument without names when building declaration string (#55) When passing an object without name to a templated function, pygcxxml was failing when building the declaration string of the function. This is now fixed by displaying no name in the generated declaration string. --- pygccxml/declarations/algorithm.py | 19 +++++-- unittests/data/test_argument_without_name.hpp | 18 ++++++ unittests/test_all.py | 4 +- unittests/test_argument_without_name.py | 56 +++++++++++++++++++ unittests/test_map_gcc5.py | 8 ++- 5 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 unittests/data/test_argument_without_name.hpp create mode 100644 unittests/test_argument_without_name.py diff --git a/pygccxml/declarations/algorithm.py b/pygccxml/declarations/algorithm.py index a42d7ce5..d37cfedb 100644 --- a/pygccxml/declarations/algorithm.py +++ b/pygccxml/declarations/algorithm.py @@ -124,13 +124,24 @@ def full_name(decl, with_defaults=True): raise RuntimeError("Unable to generate full name for None object!") if with_defaults: if not decl.cache.full_name: - decl.cache.full_name = full_name_from_declaration_path( - declaration_path(decl)) + path = declaration_path(decl) + if path == [""]: + # Declarations without names are allowed (for examples class + # or struct instances). In this case set an empty name.. + decl.cache.full_name = "" + else: + decl.cache.full_name = full_name_from_declaration_path(path) return decl.cache.full_name else: if not decl.cache.full_partial_name: - decl.cache.full_partial_name = full_name_from_declaration_path( - partial_declaration_path(decl)) + path = partial_declaration_path(decl) + if path == [""]: + # Declarations without names are allowed (for examples class + # or struct instances). In this case set an empty name. + decl.cache.full_partial_name = "" + else: + decl.cache.full_partial_name = \ + full_name_from_declaration_path(path) return decl.cache.full_partial_name diff --git a/unittests/data/test_argument_without_name.hpp b/unittests/data/test_argument_without_name.hpp new file mode 100644 index 00000000..ff993b3f --- /dev/null +++ b/unittests/data/test_argument_without_name.hpp @@ -0,0 +1,18 @@ +// Copyright 2014-2016 Insight Software Consortium. +// Copyright 2004-2009 Roman Yakovenko. +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Demonstrate some code where a struct without name is passed to a +// templated function. See bug #55 + +template +void +function(type &var) {}; + +int main() +{ + // Create foo, a struct with no name + struct { } foo; + function(foo); +} diff --git a/unittests/test_all.py b/unittests/test_all.py index f5472692..1e739811 100644 --- a/unittests/test_all.py +++ b/unittests/test_all.py @@ -71,6 +71,7 @@ import test_cpp_standards import unnamed_classes_tester import test_map_gcc5 +import test_argument_without_name testers = [ # , demangled_tester # failing right now @@ -134,7 +135,8 @@ test_copy_constructor, test_cpp_standards, unnamed_classes_tester, - test_map_gcc5 + test_map_gcc5, + test_argument_without_name ] if 'posix' in os.name: diff --git a/unittests/test_argument_without_name.py b/unittests/test_argument_without_name.py new file mode 100644 index 00000000..d288a47c --- /dev/null +++ b/unittests/test_argument_without_name.py @@ -0,0 +1,56 @@ +# Copyright 2014-2016 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +import unittest +import parser_test_case + +from pygccxml import parser +from pygccxml import declarations + + +class tester_t(parser_test_case.parser_test_case_t): + + def __init__(self, *args): + parser_test_case.parser_test_case_t.__init__(self, *args) + self.header = "test_argument_without_name.hpp" + self.config.cflags = "-std=c++11" + + def test_argument_without_name(self): + + """ + Test passing an object without name to a templated function. + + The test was failing when building the declaration string. + The declaration string will be 'void (*)( & )'. If the passed + object had a name the result would then be 'void (*)(Name & )'. + + See bug #55 + + """ + + if self.config.xml_generator == "gccxml": + return + + decls = parser.parse([self.header], self.config) + global_ns = declarations.get_global_namespace(decls) + + criteria = declarations.calldef_matcher(name="function") + free_funcs = declarations.matcher.find(criteria, global_ns) + for free_func in free_funcs: + decl_string = free_func.create_decl_string(with_defaults=False) + self.assertEqual(decl_string, "void (*)( & )") + + +def create_suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(tester_t)) + return suite + + +def run_suite(): + unittest.TextTestRunner(verbosity=2).run(create_suite()) + +if __name__ == "__main__": + run_suite() diff --git a/unittests/test_map_gcc5.py b/unittests/test_map_gcc5.py index 62b8665f..ba91cf13 100644 --- a/unittests/test_map_gcc5.py +++ b/unittests/test_map_gcc5.py @@ -1,4 +1,5 @@ # Copyright 2014-2016 Insight Software Consortium. +# Copyright 2004-2009 Roman Yakovenko. # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt @@ -35,12 +36,15 @@ def test_map_gcc5(self): # This calldef is defined with gcc > 4.9 (maybe earlier, not tested) # and -std=c++11. Calling create_decl_string is failing with gcc. - # With clang the calldef does not exist so the matche + # With clang the calldef does not exist so the matcher # will just return an empty list, letting the test pass. + # See the test_argument_without_name.py for an equivalent test, + # which is not depending on the presence of the _M_clone_node + # method in the stl_tree.h file. criteria = declarations.calldef_matcher(name="_M_clone_node") free_funcs = declarations.matcher.find(criteria, global_ns) for free_funcs in free_funcs: - print(free_funcs.create_decl_string(with_defaults=False)) + free_funcs.create_decl_string(with_defaults=False) def create_suite(): From b528b19286c518b15948ed15b8926ab8815ec65f Mon Sep 17 00:00:00 2001 From: Michka Popoff Date: Thu, 16 Jun 2016 23:30:17 +0200 Subject: [PATCH 3/4] Bump version number to v1.7.6 --- docs/conf.py | 6 +++--- pygccxml/__init__.py | 2 +- setup.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 871bff5f..b380fad2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -46,16 +46,16 @@ # General information about the project. project = u'pygccxml' -copyright = u'2014-2015, Insight Software Consortium' +copyright = u'2014-2016, Insight Software Consortium' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '1.7.5' +version = '1.7.6' # The full version, including alpha/beta/rc tags. -release = '1.7.5' +release = '1.7.6' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/pygccxml/__init__.py b/pygccxml/__init__.py index a0979c4f..0ff2061b 100644 --- a/pygccxml/__init__.py +++ b/pygccxml/__init__.py @@ -40,4 +40,4 @@ # TODO: # 1. Add "explicit" property for constructors -__version__ = '1.7.5' +__version__ = '1.7.6' diff --git a/setup.py b/setup.py index d8927cdf..0a95582e 100644 --- a/setup.py +++ b/setup.py @@ -7,14 +7,14 @@ from setuptools import setup setup(name="pygccxml", - version="1.7.5", + version="1.7.6", author="Roman Yakovenko", author_email="roman yakovenko at gmail com", maintainer="Michka Popoff and the Insight Software Consortium", maintainer_email="castxml@public.kitware.com", description="Python package for easy C++ declarations navigation.", url="https://github.com/gccxml/pygccxml", - download_url="https://github.com/gccxml/pygccxml/archive/v1.7.5.tar.gz", + download_url="https://github.com/gccxml/pygccxml/archive/v1.7.6.tar.gz", license="Boost", keywords="C++, declaration parser, CastXML, gccxml", packages=["pygccxml", From b1f64237f9bc1a33f4f1204a7a3aea6beee3b40e Mon Sep 17 00:00:00 2001 From: Michka Popoff Date: Thu, 16 Jun 2016 23:30:51 +0200 Subject: [PATCH 4/4] Document fix for version 1.7.6 --- docs/history.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/history.rst b/docs/history.rst index db6e1313..adf8286f 100644 --- a/docs/history.rst +++ b/docs/history.rst @@ -11,6 +11,11 @@ to python 3 (keeping it compatible with python 2). In Mai 2014, Michka Popoff and the Insight Software Consortium revived pygccxml by setting up a git repositery on github, hosted along with gccxml. +Version 1.7.6 +------------- + +1. Fix problem with argument without names when building declaration string (#55) + Version 1.7.5 -------------