Skip to content

Commit 800010f

Browse files
committed
Fix evaluation of the unsigned enumeration values
If the type of an enumeration is not native (e.g. uint8_t) but is unsigned then evaluation of the value might get wrong: for values bigger than half of type range the return value will be negative. This happens because for non-native enum types the TypeKind is ELABORATED. To get the real integer type, the conversion to canonical type is required before the enum_value() function can decide about type being signed or unsigned.
1 parent 4b27b58 commit 800010f

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

clang/bindings/python/clang/cindex.py

+2
Original file line numberDiff line numberDiff line change
@@ -1952,6 +1952,8 @@ def enum_value(self):
19521952
underlying_type = self.type
19531953
if underlying_type.kind == TypeKind.ENUM:
19541954
underlying_type = underlying_type.get_declaration().enum_type
1955+
if underlying_type.kind == TypeKind.ELABORATED:
1956+
underlying_type = underlying_type.get_canonical()
19551957
if underlying_type.kind in (
19561958
TypeKind.CHAR_U,
19571959
TypeKind.UCHAR,

clang/bindings/python/tests/cindex/test_cursor.py

+19
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,25 @@ def test_enum_values_cpp(self):
570570
self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL)
571571
self.assertEqual(ham.enum_value, 0x10000000000)
572572

573+
def test_enum_values_on_elaborated_type(self):
574+
tu = get_tu(
575+
"using myUType = unsigned char; enum TEST : myUType { SPAM = 1, HAM = 0xff;", lang="cpp"
576+
)
577+
enum = get_cursor(tu, "TEST")
578+
self.assertIsNotNone(enum)
579+
580+
self.assertEqual(enum.kind, CursorKind.ENUM_DECL)
581+
582+
enum_constants = list(enum.get_children())
583+
self.assertEqual(len(enum_constants), 2)
584+
585+
spam, ham = enum_constants
586+
587+
self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL)
588+
self.assertEqual(spam.enum_value, 1)
589+
self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL)
590+
self.assertEqual(ham.enum_value, 255)
591+
573592
def test_annotation_attribute(self):
574593
tu = get_tu(
575594
'int foo (void) __attribute__ ((annotate("here be annotation attribute")));'

0 commit comments

Comments
 (0)