[clang] [libclang/python] Refactor enum usage (PR #95608)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 14 14:19:56 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Jannick Kremer (DeinAlptraum)

<details>
<summary>Changes</summary>

Use Python's builtin enum class instead of writing our own.

This is preparation for passing a strict type check in PR #<!-- -->78114 , fixing 920 out of 1341 strict typing errors

---

Patch is 64.63 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/95608.diff


2 Files Affected:

- (modified) clang/bindings/python/clang/cindex.py (+765-905) 
- (modified) clang/bindings/python/tests/cindex/test_enums.py (+3-11) 


``````````diff
diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index b3d51e4d2a668..aacfc333723c4 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -68,6 +68,7 @@
 
 import collections.abc
 import os
+from enum import Enum
 
 
 # Python 3 strings are unicode, translate them to/from utf8 for C-interop.
@@ -611,51 +612,25 @@ def register(value, name):
 
 
 ### Cursor Kinds ###
-class BaseEnumeration:
+class BaseEnumeration(Enum):
     """
     Common base class for named enumerations held in sync with Index.h values.
-
-    Subclasses must define their own _kinds and _name_map members, as:
-    _kinds = []
-    _name_map = None
-    These values hold the per-subclass instances and value-to-name mappings,
-    respectively.
-
     """
 
-    def __init__(self, value):
-        if value >= len(self.__class__._kinds):
-            self.__class__._kinds += [None] * (value - len(self.__class__._kinds) + 1)
-        if self.__class__._kinds[value] is not None:
-            raise ValueError(
-                "{0} value {1} already loaded".format(str(self.__class__), value)
-            )
-        self.value = value
-        self.__class__._kinds[value] = self
-        self.__class__._name_map = None
 
     def from_param(self):
         return self.value
 
-    @property
-    def name(self):
-        """Get the enumeration name of this cursor kind."""
-        if self._name_map is None:
-            self._name_map = {}
-            for key, value in self.__class__.__dict__.items():
-                if isinstance(value, self.__class__):
-                    self._name_map[value] = key
-        return self._name_map[self]
-
     @classmethod
     def from_id(cls, id):
-        if id < 0 or id >= len(cls._kinds) or cls._kinds[id] is None:
-            raise ValueError("Unknown template argument kind %d" % id)
-        return cls._kinds[id]
+        try:
+            return cls(id)
+        except ValueError:
+            raise ValueError("Unknown %s %d" % (cls.__name__, id)) from None
 
     def __repr__(self):
         return "%s.%s" % (
-            self.__class__,
+            self.__class__.__name__,
             self.name,
         )
 
@@ -665,14 +640,10 @@ class CursorKind(BaseEnumeration):
     A CursorKind describes the kind of entity that a cursor points to.
     """
 
-    # The required BaseEnumeration declarations.
-    _kinds = []
-    _name_map = None
-
     @staticmethod
     def get_all_kinds():
         """Return all CursorKind enumeration instances."""
-        return [x for x in CursorKind._kinds if not x is None]
+        return list(CursorKind)
 
     def is_declaration(self):
         """Test if this is a declaration kind."""
@@ -710,822 +681,820 @@ def is_unexposed(self):
         """Test if this is an unexposed kind."""
         return conf.lib.clang_isUnexposed(self)
 
-    def __repr__(self):
-        return "CursorKind.%s" % (self.name,)
-
 
-###
-# Declaration Kinds
+    ###
+    # Declaration Kinds
 
-# A declaration whose specific kind is not exposed via this interface.
-#
-# Unexposed declarations have the same operations as any other kind of
-# declaration; one can extract their location information, spelling, find their
-# definitions, etc. However, the specific kind of the declaration is not
-# reported.
-CursorKind.UNEXPOSED_DECL = CursorKind(1)
+    # A declaration whose specific kind is not exposed via this interface.
+    #
+    # Unexposed declarations have the same operations as any other kind of
+    # declaration; one can extract their location information, spelling, find
+    # their definitions, etc. However, the specific kind of the declaration is
+    # not reported.
+    UNEXPOSED_DECL = 1
 
-# A C or C++ struct.
-CursorKind.STRUCT_DECL = CursorKind(2)
+    # A C or C++ struct.
+    STRUCT_DECL = 2
 
-# A C or C++ union.
-CursorKind.UNION_DECL = CursorKind(3)
+    # A C or C++ union.
+    UNION_DECL = 3
 
-# A C++ class.
-CursorKind.CLASS_DECL = CursorKind(4)
+    # A C++ class.
+    CLASS_DECL = 4
 
-# An enumeration.
-CursorKind.ENUM_DECL = CursorKind(5)
+    # An enumeration.
+    ENUM_DECL = 5
 
-# A field (in C) or non-static data member (in C++) in a struct, union, or C++
-# class.
-CursorKind.FIELD_DECL = CursorKind(6)
+    # A field (in C) or non-static data member (in C++) in a struct, union, or
+    # C++ class.
+    FIELD_DECL = 6
 
-# An enumerator constant.
-CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
+    # An enumerator constant.
+    ENUM_CONSTANT_DECL = 7
 
-# A function.
-CursorKind.FUNCTION_DECL = CursorKind(8)
+    # A function.
+    FUNCTION_DECL = 8
 
-# A variable.
-CursorKind.VAR_DECL = CursorKind(9)
+    # A variable.
+    VAR_DECL = 9
 
-# A function or method parameter.
-CursorKind.PARM_DECL = CursorKind(10)
+    # A function or method parameter.
+    PARM_DECL = 10
 
-# An Objective-C @interface.
-CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
+    # An Objective-C @interface.
+    OBJC_INTERFACE_DECL = 11
 
-# An Objective-C @interface for a category.
-CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
+    # An Objective-C @interface for a category.
+    OBJC_CATEGORY_DECL = 12
 
-# An Objective-C @protocol declaration.
-CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
+    # An Objective-C @protocol declaration.
+    OBJC_PROTOCOL_DECL = 13
 
-# An Objective-C @property declaration.
-CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
+    # An Objective-C @property declaration.
+    OBJC_PROPERTY_DECL = 14
 
-# An Objective-C instance variable.
-CursorKind.OBJC_IVAR_DECL = CursorKind(15)
+    # An Objective-C instance variable.
+    OBJC_IVAR_DECL = 15
 
-# An Objective-C instance method.
-CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16)
+    # An Objective-C instance method.
+    OBJC_INSTANCE_METHOD_DECL = 16
 
-# An Objective-C class method.
-CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17)
+    # An Objective-C class method.
+    OBJC_CLASS_METHOD_DECL = 17
 
-# An Objective-C @implementation.
-CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18)
+    # An Objective-C @implementation.
+    OBJC_IMPLEMENTATION_DECL = 18
 
-# An Objective-C @implementation for a category.
-CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19)
+    # An Objective-C @implementation for a category.
+    OBJC_CATEGORY_IMPL_DECL = 19
 
-# A typedef.
-CursorKind.TYPEDEF_DECL = CursorKind(20)
+    # A typedef.
+    TYPEDEF_DECL = 20
 
-# A C++ class method.
-CursorKind.CXX_METHOD = CursorKind(21)
+    # A C++ class method.
+    CXX_METHOD = 21
 
-# A C++ namespace.
-CursorKind.NAMESPACE = CursorKind(22)
+    # A C++ namespace.
+    NAMESPACE = 22
 
-# A linkage specification, e.g. 'extern "C"'.
-CursorKind.LINKAGE_SPEC = CursorKind(23)
+    # A linkage specification, e.g. 'extern "C"'.
+    LINKAGE_SPEC = 23
 
-# A C++ constructor.
-CursorKind.CONSTRUCTOR = CursorKind(24)
+    # A C++ constructor.
+    CONSTRUCTOR = 24
 
-# A C++ destructor.
-CursorKind.DESTRUCTOR = CursorKind(25)
+    # A C++ destructor.
+    DESTRUCTOR = 25
 
-# A C++ conversion function.
-CursorKind.CONVERSION_FUNCTION = CursorKind(26)
+    # A C++ conversion function.
+    CONVERSION_FUNCTION = 26
 
-# A C++ template type parameter
-CursorKind.TEMPLATE_TYPE_PARAMETER = CursorKind(27)
+    # A C++ template type parameter
+    TEMPLATE_TYPE_PARAMETER = 27
 
-# A C++ non-type template parameter.
-CursorKind.TEMPLATE_NON_TYPE_PARAMETER = CursorKind(28)
+    # A C++ non-type template parameter.
+    TEMPLATE_NON_TYPE_PARAMETER = 28
 
-# A C++ template template parameter.
-CursorKind.TEMPLATE_TEMPLATE_PARAMETER = CursorKind(29)
+    # A C++ template template parameter.
+    TEMPLATE_TEMPLATE_PARAMETER = 29
 
-# A C++ function template.
-CursorKind.FUNCTION_TEMPLATE = CursorKind(30)
+    # A C++ function template.
+    FUNCTION_TEMPLATE = 30
 
-# A C++ class template.
-CursorKind.CLASS_TEMPLATE = CursorKind(31)
+    # A C++ class template.
+    CLASS_TEMPLATE = 31
 
-# A C++ class template partial specialization.
-CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION = CursorKind(32)
+    # A C++ class template partial specialization.
+    CLASS_TEMPLATE_PARTIAL_SPECIALIZATION = 32
 
-# A C++ namespace alias declaration.
-CursorKind.NAMESPACE_ALIAS = CursorKind(33)
+    # A C++ namespace alias declaration.
+    NAMESPACE_ALIAS = 33
 
-# A C++ using directive
-CursorKind.USING_DIRECTIVE = CursorKind(34)
+    # A C++ using directive
+    USING_DIRECTIVE = 34
 
-# A C++ using declaration
-CursorKind.USING_DECLARATION = CursorKind(35)
+    # A C++ using declaration
+    USING_DECLARATION = 35
 
-# A Type alias decl.
-CursorKind.TYPE_ALIAS_DECL = CursorKind(36)
+    # A Type alias decl.
+    TYPE_ALIAS_DECL = 36
 
-# A Objective-C synthesize decl
-CursorKind.OBJC_SYNTHESIZE_DECL = CursorKind(37)
+    # A Objective-C synthesize decl
+    OBJC_SYNTHESIZE_DECL = 37
 
-# A Objective-C dynamic decl
-CursorKind.OBJC_DYNAMIC_DECL = CursorKind(38)
+    # A Objective-C dynamic decl
+    OBJC_DYNAMIC_DECL = 38
 
-# A C++ access specifier decl.
-CursorKind.CXX_ACCESS_SPEC_DECL = CursorKind(39)
+    # A C++ access specifier decl.
+    CXX_ACCESS_SPEC_DECL = 39
 
 
-###
-# Reference Kinds
+    ###
+    # Reference Kinds
 
-CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40)
-CursorKind.OBJC_PROTOCOL_REF = CursorKind(41)
-CursorKind.OBJC_CLASS_REF = CursorKind(42)
+    OBJC_SUPER_CLASS_REF = 40
+    OBJC_PROTOCOL_REF = 41
+    OBJC_CLASS_REF = 42
 
-# A reference to a type declaration.
-#
-# A type reference occurs anywhere where a type is named but not
-# declared. For example, given:
-#   typedef unsigned size_type;
-#   size_type size;
-#
-# The typedef is a declaration of size_type (CXCursor_TypedefDecl),
-# while the type of the variable "size" is referenced. The cursor
-# referenced by the type of size is the typedef for size_type.
-CursorKind.TYPE_REF = CursorKind(43)
-CursorKind.CXX_BASE_SPECIFIER = CursorKind(44)
+    # A reference to a type declaration.
+    #
+    # A type reference occurs anywhere where a type is named but not
+    # declared. For example, given:
+    #   typedef unsigned size_type;
+    #   size_type size;
+    #
+    # The typedef is a declaration of size_type (CXCursor_TypedefDecl),
+    # while the type of the variable "size" is referenced. The cursor
+    # referenced by the type of size is the typedef for size_type.
+    TYPE_REF = 43
+    CXX_BASE_SPECIFIER = 44
 
-# A reference to a class template, function template, template
-# template parameter, or class template partial specialization.
-CursorKind.TEMPLATE_REF = CursorKind(45)
+    # A reference to a class template, function template, template
+    # template parameter, or class template partial specialization.
+    TEMPLATE_REF = 45
 
-# A reference to a namespace or namepsace alias.
-CursorKind.NAMESPACE_REF = CursorKind(46)
+    # A reference to a namespace or namepsace alias.
+    NAMESPACE_REF = 46
 
-# A reference to a member of a struct, union, or class that occurs in
-# some non-expression context, e.g., a designated initializer.
-CursorKind.MEMBER_REF = CursorKind(47)
+    # A reference to a member of a struct, union, or class that occurs in
+    # some non-expression context, e.g., a designated initializer.
+    MEMBER_REF = 47
 
-# A reference to a labeled statement.
-CursorKind.LABEL_REF = CursorKind(48)
+    # A reference to a labeled statement.
+    LABEL_REF = 48
 
-# A reference to a set of overloaded functions or function templates
-# that has not yet been resolved to a specific function or function template.
-CursorKind.OVERLOADED_DECL_REF = CursorKind(49)
+    # A reference to a set of overloaded functions or function templates that
+    # has not yet been resolved to a specific function or function template.
+    OVERLOADED_DECL_REF = 49
 
-# A reference to a variable that occurs in some non-expression
-# context, e.g., a C++ lambda capture list.
-CursorKind.VARIABLE_REF = CursorKind(50)
+    # A reference to a variable that occurs in some non-expression
+    # context, e.g., a C++ lambda capture list.
+    VARIABLE_REF = 50
 
-###
-# Invalid/Error Kinds
+    ###
+    # Invalid/Error Kinds
 
-CursorKind.INVALID_FILE = CursorKind(70)
-CursorKind.NO_DECL_FOUND = CursorKind(71)
-CursorKind.NOT_IMPLEMENTED = CursorKind(72)
-CursorKind.INVALID_CODE = CursorKind(73)
+    INVALID_FILE = 70
+    NO_DECL_FOUND = 71
+    NOT_IMPLEMENTED = 72
+    INVALID_CODE = 73
 
-###
-# Expression Kinds
+    ###
+    # Expression Kinds
 
-# An expression whose specific kind is not exposed via this interface.
-#
-# Unexposed expressions have the same operations as any other kind of
-# expression; one can extract their location information, spelling, children,
-# etc. However, the specific kind of the expression is not reported.
-CursorKind.UNEXPOSED_EXPR = CursorKind(100)
+    # An expression whose specific kind is not exposed via this interface.
+    #
+    # Unexposed expressions have the same operations as any other kind of
+    # expression; one can extract their location information, spelling,
+    # children, etc.
+    # However, the specific kind of the expression is not reported.
+    UNEXPOSED_EXPR = 100
 
-# An expression that refers to some value declaration, such as a function,
-# variable, or enumerator.
-CursorKind.DECL_REF_EXPR = CursorKind(101)
+    # An expression that refers to some value declaration, such as a function,
+    # variable, or enumerator.
+    DECL_REF_EXPR = 101
 
-# An expression that refers to a member of a struct, union, class, Objective-C
-# class, etc.
-CursorKind.MEMBER_REF_EXPR = CursorKind(102)
+    # An expression that refers to a member of a struct, union, class,
+    # Objective-C class, etc.
+    MEMBER_REF_EXPR = 102
 
-# An expression that calls a function.
-CursorKind.CALL_EXPR = CursorKind(103)
+    # An expression that calls a function.
+    CALL_EXPR = 103
 
-# An expression that sends a message to an Objective-C object or class.
-CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104)
+    # An expression that sends a message to an Objective-C object or class.
+    OBJC_MESSAGE_EXPR = 104
 
-# An expression that represents a block literal.
-CursorKind.BLOCK_EXPR = CursorKind(105)
+    # An expression that represents a block literal.
+    BLOCK_EXPR = 105
 
-# An integer literal.
-CursorKind.INTEGER_LITERAL = CursorKind(106)
+    # An integer literal.
+    INTEGER_LITERAL = 106
 
-# A floating point number literal.
-CursorKind.FLOATING_LITERAL = CursorKind(107)
+    # A floating point number literal.
+    FLOATING_LITERAL = 107
 
-# An imaginary number literal.
-CursorKind.IMAGINARY_LITERAL = CursorKind(108)
+    # An imaginary number literal.
+    IMAGINARY_LITERAL = 108
 
-# A string literal.
-CursorKind.STRING_LITERAL = CursorKind(109)
+    # A string literal.
+    STRING_LITERAL = 109
 
-# A character literal.
-CursorKind.CHARACTER_LITERAL = CursorKind(110)
+    # A character literal.
+    CHARACTER_LITERAL = 110
 
-# A parenthesized expression, e.g. "(1)".
-#
-# This AST node is only formed if full location information is requested.
-CursorKind.PAREN_EXPR = CursorKind(111)
+    # A parenthesized expression, e.g. "(1)".
+    #
+    # This AST node is only formed if full location information is requested.
+    PAREN_EXPR = 111
 
-# This represents the unary-expression's (except sizeof and
-# alignof).
-CursorKind.UNARY_OPERATOR = CursorKind(112)
+    # This represents the unary-expression's (except sizeof and
+    # alignof).
+    UNARY_OPERATOR = 112
 
-# [C99 6.5.2.1] Array Subscripting.
-CursorKind.ARRAY_SUBSCRIPT_EXPR = CursorKind(113)
+    # [C99 6.5.2.1] Array Subscripting.
+    ARRAY_SUBSCRIPT_EXPR = 113
 
-# A builtin binary operation expression such as "x + y" or
-# "x <= y".
-CursorKind.BINARY_OPERATOR = CursorKind(114)
+    # A builtin binary operation expression such as "x + y" or "x <= y".
+    BINARY_OPERATOR = 114
 
-# Compound assignment such as "+=".
-CursorKind.COMPOUND_ASSIGNMENT_OPERATOR = CursorKind(115)
+    # Compound assignment such as "+=".
+    COMPOUND_ASSIGNMENT_OPERATOR = 115
 
-# The ?: ternary operator.
-CursorKind.CONDITIONAL_OPERATOR = CursorKind(116)
+    # The ?: ternary operator.
+    CONDITIONAL_OPERATOR = 116
 
-# An explicit cast in C (C99 6.5.4) or a C-style cast in C++
-# (C++ [expr.cast]), which uses the syntax (Type)expr.
-#
-# For example: (int)f.
-CursorKind.CSTYLE_CAST_EXPR = CursorKind(117)
+    # An explicit cast in C (C99 6.5.4) or a C-style cast in C++
+    # (C++ [expr.cast]), which uses the syntax (Type)expr.
+    #
+    # For example: (int)f.
+    CSTYLE_CAST_EXPR = 117
 
-# [C99 6.5.2.5]
-CursorKind.COMPOUND_LITERAL_EXPR = CursorKind(118)
+    # [C99 6.5.2.5]
+    COMPOUND_LITERAL_EXPR = 118
 
-# Describes an C or C++ initializer list.
-CursorKind.INIT_LIST_EXPR = CursorKind(119)
+    # Describes an C or C++ initializer list.
+    INIT_LIST_EXPR = 119
 
-# The GNU address of label extension, representing &&label.
-CursorKind.ADDR_LABEL_EXPR = CursorKind(120)
+    # The GNU address of label extension, representing &&label.
+    ADDR_LABEL_EXPR = 120
 
-# This is the GNU Statement Expression extension: ({int X=4; X;})
-CursorKind.StmtExpr = CursorKind(121)
+    # This is the GNU Statement Expression extension: ({int X=4; X;})
+    StmtExpr = 121
 
-# Represents a C11 generic selection.
-CursorKind.GENERIC_SELECTION_EXPR = CursorKind(122)
+    # Represents a C11 generic selection.
+    GENERIC_SELECTION_EXPR = 122
 
-# Implements the GNU __null extension, which is a name for a null
-# pointer constant that has integral type (e.g., int or long) and is the same
-# size and alignment as a pointer.
-#
-# The __null extension is typically only used by system headers, which define
-# NULL as __null in C++ rather than using 0 (which is an integer that may not
-# match the size of a pointer).
-CursorKind.GNU_NULL_EXPR = CursorKind(123)
+    # Implements the GNU __null extension, which is a name for a null
+    # pointer constant that has integral type (e.g., int or long) and is the
+    # same size and alignment as a pointer.
+    #
+    # The __null extension is typically only used by system headers, which
+    # define NULL as __null in C++ rather than using 0 (which is an integer that
+    # may not match the size of a pointer).
+    GNU_NULL_EXPR = 123
 
-# C++'s static_cast<> expression.
-CursorKind.CXX_STATIC_CAST_EXPR = CursorKind(124)
+    # C++'s static_cast<> expression.
+    CXX_STATIC_CAST_EXPR = 124
 
-# C++'s dynamic_cast<> expression.
-CursorKind.CXX_DYNAMIC_CAST_EXPR = CursorKind(125)
+    # C++'s dynamic_cast<> expression.
+    CXX_DYNAMIC_CAST_EXPR = 125
 
-# C++'s reinterpret_cast<> expression.
-CursorKind.CXX_REINTERPRET_CAST_EXPR = CursorKind(126)
+    # C++'s reinterpret_cast<> expression.
+    CXX_REINTERPRET_CAST_EXPR = 126
 
-# C++'s const_cast<> expression.
-CursorKind.CXX_CONST_CAST_EXPR = CursorKind(127)
+    # C++'s const_cast<> expression.
+    CXX_CONST_CAST_EXPR = 127
 
-# Represents an explicit C++ type conversion that uses "functional"
-# notion (C++ [expr.type.conv]).
-#
-# Example:
-# \code
-#   x = int(0.5);
-# \endcode
-CursorKind.CXX_FUNCTIONAL_CAST_EXPR = CursorKind(128)
+    # Represents an explicit C++ type conversion that uses "functional"
+    # notion (C++ [expr.type.conv]).
+    #
+    # Example:
+    # \code
+    #   x = int(0.5);
+    # \endcode
+    CXX_FUNCTIONAL_CAST_EXPR = 128
 
-# A C++ typeid expression (C++ [expr.typeid]).
-CursorKind.CXX_TYPEID_EXPR = CursorKind(129)
+    # A C++ typeid expression (C++ [expr.typeid]).
+    CXX_TYPEID_EXPR = 129
 
-# [C++ 2.13.5] C++ Boolean Literal.
-CursorKind.CXX_BOOL_LITERAL_EXPR = CursorKind(130)
+    # [C++ 2.13.5] C++ Boolean Literal.
+    CXX_BOOL_LITERAL_EXPR = 130
 
-# [C++0x 2.14.7] C++ Pointer Literal.
-CursorKind.CXX_NULL_PTR_LITERAL_EXPR = CursorKind(131)
+    # [C++0x 2.14.7] C++ Pointer Literal.
+    CXX_NULL_PTR_LITERAL_EXPR = 131
 
-# Represents the "this" expression in C++
-CursorKind.CXX_THIS_EXPR = CursorKind(132)
+    # Represents the "this" expression in C++
+    CXX_THIS_EXPR = 132
 
-# [C++ 15] C++ Throw Expression.
-#
-# This handles 'throw' and 'throw' assignment-expression. When
-# assignment-expression isn't present, Op will be null.
-CursorKind.CXX_THROW_EXPR = CursorKind(133)
+    # [C++ 15] C++ Throw Expression.
+    #
+    # This handles 'throw' and 'throw' assignment-expression. When
+    # assignment-expression isn't present, Op will be...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/95608


More information about the cfe-commits mailing list