Skip to content

Commit c14b512

Browse files
committed
Fixes for type traits handling of cv-qualified array types
cv-qualified arrays were not being handled correctly by type traits manipulations functions. For instance, 'int const[N]' would not be detected as 'const'. Similar problems existed for volatile qualified arrays too. Change-Id: If5deaecf4cc9ab38cb8b8ac90befa9c62ebd0106
1 parent 13089ae commit c14b512

File tree

3 files changed

+130
-8
lines changed

3 files changed

+130
-8
lines changed

pygccxml/declarations/type_traits.py

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,13 @@ def remove_reference(type):
284284
def is_const(type):
285285
"""returns True, if type represents C++ const type, False otherwise"""
286286
nake_type = remove_alias(type)
287-
return isinstance(nake_type, cpptypes.const_t)
287+
if isinstance(nake_type, cpptypes.const_t):
288+
return True
289+
elif isinstance(nake_type, cpptypes.volatile_t):
290+
return is_const(nake_type.base)
291+
elif isinstance(nake_type, cpptypes.array_t):
292+
return is_const(nake_type.base)
293+
return False
288294

289295

290296
def remove_const(type):
@@ -297,6 +303,16 @@ def remove_const(type):
297303
if not is_const(nake_type):
298304
return type
299305
else:
306+
if isinstance(nake_type, cpptypes.array_t):
307+
is_v = is_volatile(nake_type)
308+
if is_v:
309+
base_type = nake_type.base.base.base
310+
else:
311+
base_type = nake_type.base.base
312+
result_type = base_type
313+
if is_v:
314+
result_type = cpptypes.volatile_t(result_type)
315+
return cpptypes.array_t(result_type, nake_type.size)
300316
return nake_type.base
301317

302318

@@ -322,7 +338,13 @@ def is_same(type1, type2):
322338
def is_volatile(type):
323339
"""returns True, if type represents C++ volatile type, False otherwise"""
324340
nake_type = remove_alias(type)
325-
return isinstance(nake_type, cpptypes.volatile_t)
341+
if isinstance(nake_type, cpptypes.volatile_t):
342+
return True
343+
elif isinstance(nake_type, cpptypes.const_t):
344+
return is_volatile(nake_type.base)
345+
elif isinstance(nake_type, cpptypes.array_t):
346+
return is_volatile(nake_type.base)
347+
return False
326348

327349

328350
def remove_volatile(type):
@@ -334,6 +356,16 @@ def remove_volatile(type):
334356
if not is_volatile(nake_type):
335357
return type
336358
else:
359+
if isinstance(nake_type, cpptypes.array_t):
360+
is_c = is_const(nake_type)
361+
if is_c:
362+
base_type = nake_type.base.base.base
363+
else:
364+
base_type = nake_type.base.base
365+
result_type = base_type
366+
if is_c:
367+
result_type = cpptypes.const_t(result_type)
368+
return cpptypes.array_t(result_type, nake_type.size)
337369
return nake_type.base
338370

339371

@@ -344,12 +376,12 @@ def remove_cv(type):
344376
if not is_const(nake_type) and not is_volatile(nake_type):
345377
return type
346378
result = nake_type
347-
if is_const(nake_type):
348-
result = nake_type.base
379+
if is_const(result):
380+
result = remove_const(result)
349381
if is_volatile(result):
350-
result = result.base
382+
result = remove_volatile(result)
351383
if is_const(result):
352-
result = result.base
384+
result = remove_const(result)
353385
return result
354386

355387

unittests/array_bug_tester.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,50 @@ def test4(self):
5555
'::xyz[2][3]' == aaaa_type.decl_string,
5656
aaaa_type.decl_string)
5757

58+
def test5(self):
59+
code = 'char const arr[4] = {};'
60+
src_reader = parser.source_reader_t(self.config)
61+
global_ns = declarations.get_global_namespace(
62+
src_reader.read_string(code))
63+
arr_type = global_ns.variable('arr').type
64+
self.assertTrue(
65+
'char const[4]' == arr_type.decl_string,
66+
arr_type.decl_string)
67+
self.assertTrue(
68+
declarations.is_array(arr_type))
69+
self.assertTrue(
70+
declarations.is_const(arr_type))
71+
72+
def test6(self):
73+
code = 'char volatile arr[4] = {};'
74+
src_reader = parser.source_reader_t(self.config)
75+
global_ns = declarations.get_global_namespace(
76+
src_reader.read_string(code))
77+
arr_type = global_ns.variable('arr').type
78+
self.assertTrue(
79+
'char volatile[4]' == arr_type.decl_string,
80+
arr_type.decl_string)
81+
self.assertTrue(
82+
declarations.is_array(arr_type))
83+
self.assertTrue(
84+
declarations.is_volatile(arr_type))
85+
86+
def test7(self):
87+
code = 'char const volatile arr[4] = {};'
88+
src_reader = parser.source_reader_t(self.config)
89+
global_ns = declarations.get_global_namespace(
90+
src_reader.read_string(code))
91+
arr_type = global_ns.variable('arr').type
92+
self.assertTrue(
93+
'char const volatile[4]' == arr_type.decl_string,
94+
arr_type.decl_string)
95+
self.assertTrue(
96+
declarations.is_array(arr_type))
97+
self.assertTrue(
98+
declarations.is_const(arr_type))
99+
self.assertTrue(
100+
declarations.is_volatile(arr_type))
101+
58102

59103
def create_suite():
60104
suite = unittest.TestSuite()

unittests/data/type_traits_castxml.hpp

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ namespace no{
195195
typedef std::set< std::string > string_set_type;
196196
typedef std::multimap< std::string, std::string > s2s_multimap_type;
197197
typedef detail::vertex vertex_type;
198-
typedef detail::const_item const_item_t;
199-
typedef detail::const_container const_container_t;
198+
// typedef detail::const_item const_item_t;
199+
// typedef detail::const_container const_container_t;
200200
}
201201
}
202202

@@ -408,6 +408,8 @@ namespace yes{
408408
typedef const void const_void_t;
409409
typedef const incomplete_type const_incomplete_type_t;
410410
typedef int* const int_const_t;
411+
typedef int* volatile const int_volatile_const_t;
412+
typedef int* const volatile int_const_volatile_t;
411413
//TODO typedef const int& const_int_ref_t;
412414
}
413415

@@ -429,23 +431,40 @@ namespace before{
429431
typedef const incomplete_type x2;
430432
typedef int* const x3;
431433
typedef int* volatile x4;
434+
typedef void const * x5;
435+
436+
typedef char arr_42[42];
437+
typedef char const arr_c_42[42];
438+
typedef char volatile arr_v_42[42];
439+
typedef char const volatile arr_cv_42[42];
440+
typedef char volatile const arr_vc_42[42];
432441
}
433442

434443
namespace after{
435444
typedef void x1;
436445
typedef incomplete_type x2;
437446
typedef int* x3;
438447
typedef int* volatile x4;
448+
typedef void const * x5;
449+
450+
typedef char arr_42[42];
451+
typedef char arr_c_42[42];
452+
typedef char volatile arr_v_42[42];
453+
typedef char volatile arr_cv_42[42];
454+
typedef char volatile arr_vc_42[42];
439455
} }
440456

441457
namespace is_volatile{
442458
namespace yes{
443459

444460
typedef void * volatile vvoid_ptr_t;
445461
typedef volatile int volatile_int_t;
462+
typedef int* volatile const int_volatile_const_t;
463+
typedef int* const volatile int_const_volatile_t;
446464
}
447465

448466
namespace no{
467+
typedef void volatile * void_ptr_to_v_t;
449468
typedef int* int_ptr_t;
450469
typedef const int* const_int_ptr_t;
451470
typedef int* volatile_int_ptr_t;
@@ -462,12 +481,26 @@ namespace before{
462481
typedef void * volatile x1;
463482
typedef volatile int x2;
464483
typedef int* x3;
484+
typedef void volatile * x4;
485+
486+
typedef char arr_42[42];
487+
typedef char const arr_c_42[42];
488+
typedef char volatile arr_v_42[42];
489+
typedef char const volatile arr_cv_42[42];
490+
typedef char volatile const arr_vc_42[42];
465491
}
466492

467493
namespace after{
468494
typedef void * x1;
469495
typedef int x2;
470496
typedef int* x3;
497+
typedef void volatile * x4;
498+
499+
typedef char arr_42[42];
500+
typedef char const arr_c_42[42];
501+
typedef char arr_v_42[42];
502+
typedef char const arr_cv_42[42];
503+
typedef char const arr_vc_42[42];
471504
} }
472505

473506

@@ -487,6 +520,12 @@ namespace before{
487520
typedef int* const x32;
488521

489522
typedef void(*x40)();
523+
524+
typedef char arr_42[42];
525+
typedef char const arr_c_42[42];
526+
typedef char volatile arr_v_42[42];
527+
typedef char const volatile arr_cv_42[42];
528+
typedef char volatile const arr_vc_42[42];
490529
}
491530

492531
namespace after{
@@ -503,6 +542,12 @@ namespace after{
503542
typedef int* x32;
504543

505544
typedef void(*x40)();
545+
546+
typedef char arr_42[42];
547+
typedef char arr_c_42[42];
548+
typedef char arr_v_42[42];
549+
typedef char arr_cv_42[42];
550+
typedef char arr_vc_42[42];
506551
} }
507552

508553

@@ -661,6 +706,7 @@ namespace yes{
661706
const int yes2[2] = {0};
662707
const volatile int yes3[2] = {0};
663708
int yes4[2][3];
709+
int const yes5[2] = {0};
664710
}
665711

666712
namespace no{

0 commit comments

Comments
 (0)