https://github.com/DeinAlptraum updated https://github.com/llvm/llvm-project/pull/143264
>From be61f911f07e5c5a497f942e530bd0f86f19478f Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Sat, 7 Jun 2025 21:57:17 +0900 Subject: [PATCH 01/11] [libclang/python] Add missing enum variants Add tests to ensure that all C-enum variants are defined on Python side. --- .../python/tests/cindex/test_enums.py | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/clang/bindings/python/tests/cindex/test_enums.py b/clang/bindings/python/tests/cindex/test_enums.py index 48452fd4f82d0..f7ed2e39037c1 100644 --- a/clang/bindings/python/tests/cindex/test_enums.py +++ b/clang/bindings/python/tests/cindex/test_enums.py @@ -1,4 +1,5 @@ import unittest +from pathlib import Path from clang.cindex import ( AccessSpecifier, @@ -13,6 +14,7 @@ TemplateArgumentKind, TLSKind, TokenKind, + TranslationUnit, TypeKind, ) @@ -46,8 +48,53 @@ def test_from_id(self): def test_duplicate_ids(self): """Check that no two kinds have the same id""" - # for enum in self.enums: for enum in self.enums: num_declared_variants = len(enum._member_map_.keys()) num_unique_variants = len(list(enum)) self.assertEqual(num_declared_variants, num_unique_variants) + + def test_all_variants(self): + """Check that all libclang enum values are also defined in cindex""" + cenum_to_pythonenum = { + "CX_CXXAccessSpecifier": AccessSpecifier, + "CXAvailabilityKind": AvailabilityKind, + "CXBinaryOperatorKind": BinaryOperator, + "CXCursorKind": CursorKind, + "CXCursor_ExceptionSpecificationKind": ExceptionSpecificationKind, + "CXLinkageKind": LinkageKind, + "CXRefQualifierKind": RefQualifierKind, + "CX_StorageClass": StorageClass, + "CXTemplateArgumentKind": TemplateArgumentKind, + "CXTLSKind": TLSKind, + "CXTokenKind": TokenKind, + "CXTypeKind": TypeKind, + } + + indexheader = ( + Path(__file__).parent.parent.parent.parent.parent + / "include/clang-c/Index.h" + ) + tu = TranslationUnit.from_source(indexheader, ["-x", "c++"]) + + enum_variant_map = {} + # For all enums in self.enums, extract all enum variants defined in Index.h + for cursor in tu.cursor.walk_preorder(): + type_class = cenum_to_pythonenum.get(cursor.type.spelling) + if ( + cursor.kind == CursorKind.ENUM_CONSTANT_DECL + and type_class in self.enums + ): + if type_class not in enum_variant_map: + enum_variant_map[type_class] = [] + enum_variant_map[type_class].append(cursor.enum_value) + + for enum in self.enums: + with self.subTest(enum): + python_kinds = set([kind.value for kind in enum]) + c_kinds = set(enum_variant_map[enum]) + missing_python_kinds = c_kinds - python_kinds + self.assertEqual( + missing_python_kinds, + set(), + f"Please ensure these variants are defined inside {enum} in cindex.py.", + ) >From 78a0cbeb5119e1beb2c2b3f64bde9dc452af588a Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Sat, 7 Jun 2025 23:29:01 +0900 Subject: [PATCH 02/11] Add new variants --- clang/bindings/python/clang/cindex.py | 62 ++++++++++++++++++- .../python/tests/cindex/test_enums.py | 2 +- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index 3398823836e62..23a8b6b439ca5 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -708,7 +708,6 @@ def is_unexposed(self): """Test if this is an unexposed kind.""" return conf.lib.clang_isUnexposed(self) # type: ignore [no-any-return] - ### # Declaration Kinds @@ -835,7 +834,6 @@ def is_unexposed(self): # A C++ access specifier decl. CXX_ACCESS_SPEC_DECL = 39 - ### # Reference Kinds @@ -1436,12 +1434,60 @@ def is_unexposed(self): # OpenMP scope directive. OMP_SCOPE_DIRECTIVE = 306 + # OpenMP reverse directive. + OMPReverseDirective = 307 + + # OpenMP interchange directive. + OMPInterchangeDirective = 308 + + # OpenMP assume directive. + OMPAssumeDirective = 309 + # OpenMP stripe directive. OMP_STRIPE_DIRECTIVE = 310 # OpenACC Compute Construct. OPEN_ACC_COMPUTE_DIRECTIVE = 320 + # OpenACC Loop Construct. + OpenACCLoopConstruct = 321 + + # OpenACC Combined Constructs. + OpenACCCombinedConstruct = 322 + + # OpenACC data Construct. + OpenACCDataConstruct = 323 + + # OpenACC enter data Construct. + OpenACCEnterDataConstruct = 324 + + # OpenACC exit data Construct. + OpenACCExitDataConstruct = 325 + + # OpenACC host_data Construct. + OpenACCHostDataConstruct = 326 + + # OpenACC wait Construct. + OpenACCWaitConstruct = 327 + + # OpenACC init Construct. + OpenACCInitConstruct = 328 + + # OpenACC shutdown Construct. + OpenACCShutdownConstruct = 329 + + # OpenACC set Construct. + OpenACCSetConstruct = 330 + + # OpenACC update Construct. + OpenACCUpdateConstruct = 331 + + # OpenACC atomic Construct. + OpenACCAtomicConstruct = 332 + + # OpenACC cache Construct. + OpenACCCacheConstruct = 333 + ### # Other Kinds @@ -1560,6 +1606,7 @@ class ExceptionSpecificationKind(BaseEnumeration): UNEVALUATED = 6 UNINSTANTIATED = 7 UNPARSED = 8 + NOTHROW = 9 ### Cursors ### @@ -2492,6 +2539,13 @@ def spelling(self): FLOAT128 = 30 HALF = 31 FLOAT16 = 32 + SHORTACCUM = 33 + ACCUM = 34 + LONGACCUM = 35 + USHORTACCUM = 36 + UACCUM = 37 + ULONGACCUM = 38 + BFLOAT16 = 39 IBM128 = 40 COMPLEX = 100 POINTER = 101 @@ -2576,6 +2630,10 @@ def spelling(self): ATOMIC = 177 BTFTAGATTRIBUTED = 178 + HLSLRESOURCE = 179 + HLSLATTRIBUTEDRESOURCE = 180 + HLSLINLINESPIRV = 181 + class RefQualifierKind(BaseEnumeration): """Describes a specific ref-qualifier of a type.""" diff --git a/clang/bindings/python/tests/cindex/test_enums.py b/clang/bindings/python/tests/cindex/test_enums.py index f7ed2e39037c1..0be1b58b2d744 100644 --- a/clang/bindings/python/tests/cindex/test_enums.py +++ b/clang/bindings/python/tests/cindex/test_enums.py @@ -96,5 +96,5 @@ def test_all_variants(self): self.assertEqual( missing_python_kinds, set(), - f"Please ensure these variants are defined inside {enum} in cindex.py.", + f"Please ensure these are defined in {enum} in cindex.py.", ) >From 1fa6e5073ed29fc3befdeb24d3df2cd67f09ee91 Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Mon, 15 Sep 2025 23:02:51 +0900 Subject: [PATCH 03/11] Determine enums automatically via BaseEnumeration subclasses --- .../python/tests/cindex/test_enums.py | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/clang/bindings/python/tests/cindex/test_enums.py b/clang/bindings/python/tests/cindex/test_enums.py index 0be1b58b2d744..2215bbca04f2a 100644 --- a/clang/bindings/python/tests/cindex/test_enums.py +++ b/clang/bindings/python/tests/cindex/test_enums.py @@ -16,25 +16,13 @@ TokenKind, TranslationUnit, TypeKind, + PrintingPolicyProperty, + BaseEnumeration, ) class TestEnums(unittest.TestCase): - enums = [ - TokenKind, - CursorKind, - TemplateArgumentKind, - ExceptionSpecificationKind, - AvailabilityKind, - AccessSpecifier, - TypeKind, - RefQualifierKind, - LanguageKind, - LinkageKind, - TLSKind, - StorageClass, - BinaryOperator, - ] + enums = BaseEnumeration.__subclasses__() def test_from_id(self): """Check that kinds can be constructed from valid IDs""" @@ -61,7 +49,9 @@ def test_all_variants(self): "CXBinaryOperatorKind": BinaryOperator, "CXCursorKind": CursorKind, "CXCursor_ExceptionSpecificationKind": ExceptionSpecificationKind, + "CXLanguageKind": LanguageKind, "CXLinkageKind": LinkageKind, + "CXPrintingPolicyProperty": PrintingPolicyProperty, "CXRefQualifierKind": RefQualifierKind, "CX_StorageClass": StorageClass, "CXTemplateArgumentKind": TemplateArgumentKind, >From fbf906e51e7a41be01c132abbdeba77444fa0b5b Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Mon, 15 Sep 2025 23:06:30 +0900 Subject: [PATCH 04/11] Fix lexicographic ordering --- clang/bindings/python/tests/cindex/test_enums.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/bindings/python/tests/cindex/test_enums.py b/clang/bindings/python/tests/cindex/test_enums.py index 2215bbca04f2a..ea53aa8333f36 100644 --- a/clang/bindings/python/tests/cindex/test_enums.py +++ b/clang/bindings/python/tests/cindex/test_enums.py @@ -45,6 +45,7 @@ def test_all_variants(self): """Check that all libclang enum values are also defined in cindex""" cenum_to_pythonenum = { "CX_CXXAccessSpecifier": AccessSpecifier, + "CX_StorageClass": StorageClass, "CXAvailabilityKind": AvailabilityKind, "CXBinaryOperatorKind": BinaryOperator, "CXCursorKind": CursorKind, @@ -53,7 +54,6 @@ def test_all_variants(self): "CXLinkageKind": LinkageKind, "CXPrintingPolicyProperty": PrintingPolicyProperty, "CXRefQualifierKind": RefQualifierKind, - "CX_StorageClass": StorageClass, "CXTemplateArgumentKind": TemplateArgumentKind, "CXTLSKind": TLSKind, "CXTokenKind": TokenKind, >From ad6ab772638134cea9391d93ecf0c970c3c2d501 Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Mon, 15 Sep 2025 23:06:58 +0900 Subject: [PATCH 05/11] Fix comment --- clang/bindings/python/tests/cindex/test_enums.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/bindings/python/tests/cindex/test_enums.py b/clang/bindings/python/tests/cindex/test_enums.py index ea53aa8333f36..fd9cb418cc621 100644 --- a/clang/bindings/python/tests/cindex/test_enums.py +++ b/clang/bindings/python/tests/cindex/test_enums.py @@ -42,7 +42,7 @@ def test_duplicate_ids(self): self.assertEqual(num_declared_variants, num_unique_variants) def test_all_variants(self): - """Check that all libclang enum values are also defined in cindex""" + """Check that all libclang enum values are also defined in cindex.py""" cenum_to_pythonenum = { "CX_CXXAccessSpecifier": AccessSpecifier, "CX_StorageClass": StorageClass, >From fb04f0993f5dd926368ba394622201d4fd9b0138 Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Mon, 15 Sep 2025 23:10:18 +0900 Subject: [PATCH 06/11] Also test that cindex.py contains no superfluous variants --- clang/bindings/python/tests/cindex/test_enums.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/clang/bindings/python/tests/cindex/test_enums.py b/clang/bindings/python/tests/cindex/test_enums.py index fd9cb418cc621..4c23f4fd46353 100644 --- a/clang/bindings/python/tests/cindex/test_enums.py +++ b/clang/bindings/python/tests/cindex/test_enums.py @@ -81,10 +81,17 @@ def test_all_variants(self): for enum in self.enums: with self.subTest(enum): python_kinds = set([kind.value for kind in enum]) - c_kinds = set(enum_variant_map[enum]) + # Defined in Index.h but not in cindex.py missing_python_kinds = c_kinds - python_kinds self.assertEqual( missing_python_kinds, set(), f"Please ensure these are defined in {enum} in cindex.py.", ) + # Defined in cindex.py but not in Index.h + superfluous_python_kinds = python_kinds - c_kinds + self.assertEqual( + superfluous_python_kinds, + set(), + f"Please ensure that all {enum} kinds defined in cindex.py have an equivalent in Index.h", + ) >From c1fa85ecd99ab19fe4b9f006e28a82fe59c1afaa Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Mon, 15 Sep 2025 23:13:58 +0900 Subject: [PATCH 07/11] Rename variable --- clang/bindings/python/tests/cindex/test_enums.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/clang/bindings/python/tests/cindex/test_enums.py b/clang/bindings/python/tests/cindex/test_enums.py index 4c23f4fd46353..bdcf3b1a203ed 100644 --- a/clang/bindings/python/tests/cindex/test_enums.py +++ b/clang/bindings/python/tests/cindex/test_enums.py @@ -69,14 +69,11 @@ def test_all_variants(self): enum_variant_map = {} # For all enums in self.enums, extract all enum variants defined in Index.h for cursor in tu.cursor.walk_preorder(): - type_class = cenum_to_pythonenum.get(cursor.type.spelling) - if ( - cursor.kind == CursorKind.ENUM_CONSTANT_DECL - and type_class in self.enums - ): - if type_class not in enum_variant_map: - enum_variant_map[type_class] = [] - enum_variant_map[type_class].append(cursor.enum_value) + python_enum = cenum_to_pythonenum.get(cursor.type.spelling) + if cursor.kind == CursorKind.ENUM_CONSTANT_DECL: + if python_enum not in enum_variant_map: + enum_variant_map[python_enum] = [] + enum_variant_map[python_enum].append(cursor.enum_value) for enum in self.enums: with self.subTest(enum): >From 0cc05084ee759ef79c6270508207702c08ad21bd Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Mon, 15 Sep 2025 23:16:16 +0900 Subject: [PATCH 08/11] Report missing enum names instead of values --- clang/bindings/python/tests/cindex/test_enums.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/clang/bindings/python/tests/cindex/test_enums.py b/clang/bindings/python/tests/cindex/test_enums.py index bdcf3b1a203ed..5637b453aa231 100644 --- a/clang/bindings/python/tests/cindex/test_enums.py +++ b/clang/bindings/python/tests/cindex/test_enums.py @@ -72,23 +72,31 @@ def test_all_variants(self): python_enum = cenum_to_pythonenum.get(cursor.type.spelling) if cursor.kind == CursorKind.ENUM_CONSTANT_DECL: if python_enum not in enum_variant_map: - enum_variant_map[python_enum] = [] - enum_variant_map[python_enum].append(cursor.enum_value) + enum_variant_map[python_enum] = dict() + enum_variant_map[python_enum][cursor.enum_value] = cursor.spelling for enum in self.enums: with self.subTest(enum): python_kinds = set([kind.value for kind in enum]) + num_to_c_kind = enum_variant_map[enum] + c_kinds = set(num_to_c_kind.keys()) # Defined in Index.h but not in cindex.py missing_python_kinds = c_kinds - python_kinds + missing_names = set( + [num_to_c_kind[kind] for kind in missing_python_kinds] + ) self.assertEqual( - missing_python_kinds, + missing_names, set(), f"Please ensure these are defined in {enum} in cindex.py.", ) # Defined in cindex.py but not in Index.h superfluous_python_kinds = python_kinds - c_kinds + missing_names = set( + [enum.from_id(kind) for kind in superfluous_python_kinds] + ) self.assertEqual( - superfluous_python_kinds, + missing_names, set(), f"Please ensure that all {enum} kinds defined in cindex.py have an equivalent in Index.h", ) >From 804550a74ed91fdfa082140867e918cf7cdc554f Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Tue, 16 Sep 2025 22:29:01 +0900 Subject: [PATCH 09/11] Remove AccessSpecifier.NONE --- clang/bindings/python/clang/cindex.py | 1 - clang/docs/ReleaseNotes.rst | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index 23a8b6b439ca5..99ec75d1d5ddc 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -2491,7 +2491,6 @@ class AccessSpecifier(BaseEnumeration): PUBLIC = 1 PROTECTED = 2 PRIVATE = 3 - NONE = 4 ### Type Kinds ### diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index dbba8f5db0cef..eb84d990b4268 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -105,6 +105,7 @@ Clang Python Bindings Potentially Breaking Changes - TypeKind ``ELABORATED`` is not used anymore, per clang AST changes removing ElaboratedTypes. The value becomes unused, and all the existing users should expect the former underlying type to be reported instead. +- Remove ``AccessSpecifier.NONE`` kind. No libclang interfaces ever returned this kind. What's New in Clang |release|? ============================== >From 6a39f06e320928a43237947f239255c870dc5af4 Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Tue, 16 Sep 2025 22:30:17 +0900 Subject: [PATCH 10/11] Add TypeKind aliases from Index.h --- clang/bindings/python/clang/cindex.py | 2 ++ clang/bindings/python/tests/cindex/test_enums.py | 7 ------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index 99ec75d1d5ddc..76269805ffa77 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -2546,6 +2546,8 @@ def spelling(self): ULONGACCUM = 38 BFLOAT16 = 39 IBM128 = 40 + FIRSTBUILTIN = VOID + LASTBUILTIN = IBM128 COMPLEX = 100 POINTER = 101 BLOCKPOINTER = 102 diff --git a/clang/bindings/python/tests/cindex/test_enums.py b/clang/bindings/python/tests/cindex/test_enums.py index 5637b453aa231..98370bf6c0109 100644 --- a/clang/bindings/python/tests/cindex/test_enums.py +++ b/clang/bindings/python/tests/cindex/test_enums.py @@ -34,13 +34,6 @@ def test_from_id(self): with self.assertRaises(ValueError): enum.from_id(-1) - def test_duplicate_ids(self): - """Check that no two kinds have the same id""" - for enum in self.enums: - num_declared_variants = len(enum._member_map_.keys()) - num_unique_variants = len(list(enum)) - self.assertEqual(num_declared_variants, num_unique_variants) - def test_all_variants(self): """Check that all libclang enum values are also defined in cindex.py""" cenum_to_pythonenum = { >From 7439bc93f8638e31e318e1696b24f8440bc6f25a Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Tue, 16 Sep 2025 22:31:04 +0900 Subject: [PATCH 11/11] Add FIXME for C++ parsing of Index.h --- clang/bindings/python/tests/cindex/test_enums.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/bindings/python/tests/cindex/test_enums.py b/clang/bindings/python/tests/cindex/test_enums.py index 98370bf6c0109..1052ed881840a 100644 --- a/clang/bindings/python/tests/cindex/test_enums.py +++ b/clang/bindings/python/tests/cindex/test_enums.py @@ -57,6 +57,9 @@ def test_all_variants(self): Path(__file__).parent.parent.parent.parent.parent / "include/clang-c/Index.h" ) + # FIXME: Index.h is a C file, but we read it as a C++ file because we + # don't get ENUM_CONSTANT_DECL cursors otherwise, which we need here + # See bug report: https://github.com/llvm/llvm-project/issues/159075 tu = TranslationUnit.from_source(indexheader, ["-x", "c++"]) enum_variant_map = {} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits