Skip to content

Commit 7c3f60f

Browse files
committed
Fix bug in remove_pointer function when used on a function pointer (#61)
1 parent d9aaa34 commit 7c3f60f

File tree

5 files changed

+94
-3
lines changed

5 files changed

+94
-3
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ Version 1.8.0 (not yet released)
1717
specifically when containing parentheses:
1818
myClass<std::vector<char>(const std::string &, const std::string &)> obj;
1919

20+
* When using the ```remove_pointer``` function on a function pointer, the
21+
```remove_pointer``` function now correctly returns a ```calldef_type_t```.
22+
2023
* ```declarations.is_string```, ```declarations.is_std_wstring```,
2124
```declarations.is_std_ostream``` and ```declarations.is_std_wostream``` now
2225
correctly work when a the type is also a reference.

pygccxml/declarations/type_traits.py

-2
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,6 @@ def remove_pointer(type_):
249249
return (
250250
cpptypes.volatile_t(cpptypes.const_t(nake_type.base.base.base))
251251
)
252-
elif isinstance(nake_type.base, cpptypes.calldef_type_t):
253-
return type_
254252
else:
255253
return nake_type.base
256254

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright 2014-2016 Insight Software Consortium.
2+
// Copyright 2004-2009 Roman Yakovenko.
3+
// Distributed under the Boost Software License, Version 1.0.
4+
// See http://www.boost.org/LICENSE_1_0.txt
5+
6+
// func1 is a function pointer
7+
// In this case, func1 is the declaration of a function which has two arguments
8+
// (on the right) and returns nothing (void on the left)
9+
void (*func1)(int, double);
10+
11+
// Another pointer, but not a function pointer
12+
int const volatile* myPointer;

unittests/test_all.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import test_argument_without_name
7474
import test_smart_pointer
7575
import test_pattern_parser
76+
import test_function_pointer
7677

7778
testers = [
7879
# , demangled_tester # failing right now
@@ -138,7 +139,8 @@
138139
test_map_gcc5,
139140
test_argument_without_name,
140141
test_smart_pointer,
141-
test_pattern_parser
142+
test_pattern_parser,
143+
test_function_pointer
142144
]
143145

144146
if 'posix' in os.name:

unittests/test_function_pointer.py

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Copyright 2014-2016 Insight Software Consortium.
2+
# Copyright 2004-2009 Roman Yakovenko.
3+
# Distributed under the Boost Software License, Version 1.0.
4+
# See http://www.boost.org/LICENSE_1_0.txt
5+
6+
import unittest
7+
import parser_test_case
8+
9+
from pygccxml import parser
10+
from pygccxml import declarations
11+
12+
13+
class Test(parser_test_case.parser_test_case_t):
14+
15+
def __init__(self, *args):
16+
parser_test_case.parser_test_case_t.__init__(self, *args)
17+
self.header = "test_function_pointer.hpp"
18+
19+
def test_function_pointer(self):
20+
"""
21+
Test working with pointers and function pointers.
22+
23+
"""
24+
25+
decls = parser.parse([self.header], self.config)
26+
global_ns = declarations.get_global_namespace(decls)
27+
28+
# Test on a function pointer
29+
criteria = declarations.variable_matcher(name="func1")
30+
variables = declarations.matcher.find(criteria, global_ns)
31+
32+
self.assertTrue(variables[0].name == "func1")
33+
self.assertTrue(
34+
isinstance(variables[0].decl_type, declarations.pointer_t))
35+
self.assertTrue(
36+
str(variables[0].decl_type) == "void (*)( int,double ) *")
37+
self.assertTrue(
38+
declarations.is_calldef_pointer(variables[0].decl_type))
39+
self.assertTrue(
40+
isinstance(declarations.remove_pointer(variables[0].decl_type),
41+
declarations.free_function_type_t))
42+
43+
# Get the function (free_function_type_t) and test the return and
44+
# argument types
45+
function = variables[0].decl_type.base
46+
self.assertTrue(isinstance(function.return_type, declarations.void_t))
47+
self.assertTrue(
48+
isinstance(function.arguments_types[0], declarations.int_t))
49+
self.assertTrue(
50+
isinstance(function.arguments_types[1], declarations.double_t))
51+
52+
# Test on a normal pointer
53+
criteria = declarations.variable_matcher(name="myPointer")
54+
variables = declarations.matcher.find(criteria, global_ns)
55+
56+
self.assertTrue(variables[0].name == "myPointer")
57+
self.assertTrue(
58+
isinstance(variables[0].decl_type, declarations.pointer_t))
59+
self.assertFalse(
60+
declarations.is_calldef_pointer(variables[0].decl_type))
61+
self.assertTrue(
62+
isinstance(declarations.remove_pointer(variables[0].decl_type),
63+
declarations.volatile_t))
64+
65+
66+
def create_suite():
67+
suite = unittest.TestSuite()
68+
suite.addTest(unittest.makeSuite(Test))
69+
return suite
70+
71+
72+
def run_suite():
73+
unittest.TextTestRunner(verbosity=2).run(create_suite())
74+
75+
if __name__ == "__main__":
76+
run_suite()

0 commit comments

Comments
 (0)