Skip to content

[libclang/python] Add missing enum variants #143264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 60 additions & 2 deletions clang/bindings/python/clang/cindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,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

Expand Down Expand Up @@ -834,7 +833,6 @@ def is_unexposed(self):
# A C++ access specifier decl.
CXX_ACCESS_SPEC_DECL = 39


###
# Reference Kinds

Expand Down Expand Up @@ -1435,12 +1433,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

Expand Down Expand Up @@ -1559,6 +1605,7 @@ class ExceptionSpecificationKind(BaseEnumeration):
UNEVALUATED = 6
UNINSTANTIATED = 7
UNPARSED = 8
NOTHROW = 9

### Cursors ###

Expand Down Expand Up @@ -2482,6 +2529,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
Expand Down Expand Up @@ -2566,6 +2620,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."""

Expand Down
49 changes: 48 additions & 1 deletion clang/bindings/python/tests/cindex/test_enums.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import unittest
from pathlib import Path

from clang.cindex import (
AccessSpecifier,
Expand All @@ -12,6 +13,7 @@
TemplateArgumentKind,
TLSKind,
TokenKind,
TranslationUnit,
TypeKind,
)

Expand Down Expand Up @@ -44,8 +46,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 are defined in {enum} in cindex.py.",
)