Skip to content

Commit 718dcb2

Browse files
praetorian20iMichka
authored andcommitted
"is_union" type trait and unit tests
Change-Id: I9f92881bce2afbe2db7160a3acefb21a0fbdd925 Cherry-picked from the develop branch
1 parent 8c6a8e0 commit 718dcb2

File tree

5 files changed

+89
-7
lines changed

5 files changed

+89
-7
lines changed

pygccxml/declarations/type_traits.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,15 @@ def is_fundamental(type):
365365
(cpptypes.volatile_t, cpptypes.const_t))
366366

367367

368-
class declaration_xxx_traits(object):
368+
def is_union(type_):
369+
"""returns True if type represents a C++ union"""
370+
if not is_class(type_):
371+
return False
372+
decl = class_traits.get_declaration(type_)
373+
return decl.class_type == class_declaration.CLASS_TYPES.UNION
369374

375+
376+
class declaration_xxx_traits(object):
370377
"""this class implements the functionality needed for convenient work with
371378
declaration classes
372379

unittests/data/unnamed_classes.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct S1{
2525
unsigned int raw;
2626
} flags;
2727

28-
union FileAttribs{
28+
union /*FileAttribs*/{
2929
struct{
3030
unsigned int isReadOnly : 1;
3131
unsigned int isHidden : 1;
@@ -45,6 +45,16 @@ struct S1{
4545
unsigned int raw;
4646
} fileattribs; // in GetFileAttributes() format
4747
} header;
48+
49+
struct S3{
50+
union
51+
{
52+
char anon_mem_c;
53+
int anon_mem_i;
54+
};
55+
long s3_mem;
56+
S2 s2;
57+
};
4858
};
4959

5060
} // namespace

unittests/parser_test_case.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,11 @@ def _test_calldef_exceptions(self, calldef, exceptions):
8989
lambda parser, a1, a2, *args: parser.assertTrue(a1 in a2, args)
9090
parser_test_case_t.assertNotIn = \
9191
lambda parser, a1, a2, *args: parser.assertFalse(a1 in a2, args)
92+
parser_test_case_t.assertIs = \
93+
lambda parser, a1, a2, *args: parser.assertTrue(a1 is a2, args)
94+
parser_test_case_t.assertIsNot = \
95+
lambda parser, a1, a2, *args: parser.assertFalse(a1 is a2, args)
96+
parser_test_case_t.assertIsNone = \
97+
lambda parser, a1, *args: parser.assertTrue(a1 is None, args)
98+
parser_test_case_t.assertIsNotNone = \
99+
lambda parser, a1, *args: parser.assertFalse(a1 is None, args)

unittests/test_all.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
import test_va_list_tag_removal
7070
import test_copy_constructor
7171
import test_cpp_standards
72+
import unnamed_classes_tester
7273

7374
testers = [
7475
# , demangled_tester # failing right now
@@ -130,7 +131,8 @@
130131
test_utils,
131132
test_va_list_tag_removal,
132133
test_copy_constructor,
133-
test_cpp_standards
134+
test_cpp_standards,
135+
unnamed_classes_tester
134136
]
135137

136138
if 'posix' in os.name:

unittests/unnamed_classes_tester.py

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from pygccxml import parser
1010
from pygccxml import declarations
11+
from pygccxml.declarations import type_traits
1112

1213

1314
class tester_t(parser_test_case.parser_test_case_t):
@@ -23,10 +24,64 @@ def setUp(self):
2324
self.global_ns = declarations.get_global_namespace(decls)
2425
self.global_ns.init_optimizer()
2526

26-
def test(self):
27-
# bf_x = self.global_ns.variable( 'x' )
28-
# self.assertTrue( bf_x.bits == 1 )
29-
pass
27+
def validate_bitfields(self, parent, bitfields):
28+
for key in bitfields:
29+
var = parent.variable(key)
30+
self.assertEqual(var.bits, bitfields[key])
31+
32+
def do_union_test(self, union_name, bitfields):
33+
s2 = self.global_ns.class_('S2')
34+
self.assertFalse(type_traits.is_union(s2))
35+
self.assertEqual(s2.parent.name, 'S1')
36+
self.assertFalse(type_traits.is_union(s2.parent))
37+
38+
union = s2.variable(union_name)
39+
self.assertTrue(type_traits.is_union(union.type))
40+
41+
union_type = type_traits.remove_declarated(union.type)
42+
self.validate_bitfields(union_type, bitfields)
43+
self.assertIsNotNone(union_type.variable('raw'))
44+
45+
def test_union_Flags(self):
46+
flags_bitfields = {
47+
'hasItemIdList': 1,
48+
'pointsToFileOrDir': 1,
49+
'hasDescription': 1,
50+
'hasRelativePath': 1,
51+
'hasWorkingDir': 1,
52+
'hasCmdLineArgs': 1,
53+
'hasCustomIcon': 1,
54+
'useWorkingDir': 1,
55+
'unused': 24,
56+
}
57+
self.do_union_test('flags', flags_bitfields)
58+
59+
def test_unnamed_unions(self):
60+
fileattribs_bitfields = {
61+
'isReadOnly': 1,
62+
'isHidden': 1,
63+
'isSystem': 1,
64+
'isVolumeLabel': 1,
65+
'isDir': 1,
66+
'isModified': 1,
67+
'isEncrypted': 1,
68+
'isNormal': 1,
69+
'isTemporary': 1,
70+
'isSparse': 1,
71+
'hasReparsePoint': 1,
72+
'isCompressed': 1,
73+
'isOffline': 1,
74+
'unused': 19,
75+
}
76+
self.do_union_test('fileattribs', fileattribs_bitfields)
77+
78+
def test_anonymous_unions(self):
79+
s3 = self.global_ns.class_('S3')
80+
self.assertEqual(s3.parent.name, 'S1')
81+
82+
s3_vars = ['anon_mem_c', 'anon_mem_i', 's3_mem', 's2']
83+
for var in s3_vars:
84+
self.assertFalse(type_traits.is_union(s3.variable(var).type))
3085

3186

3287
def create_suite():

0 commit comments

Comments
 (0)