예제 #1
0
    def element_count(self):
        """Number of elements in the array.

        If the array is multidimensional, a tuple consisting of element counts
        for each dimension is returned. For example, for ``int [10]``, it
        returns ``10``, and for ``int [10][20][30]``, it returns ``(10, 20,
        30)``.

        If the array is incomplete (e.g. ``int []``), it returns ``1`` because
        Clang behaves this way and there is no way of distinguishing e.g. ``int
        []`` from ``int [1]``.

        Returns ``None`` if the number of elements cannot be obtained.
        """
        type = self._type
        count_list = []

        while is_array_kind(type):
            try:
                # Type.element_count raises Exception when the element count
                # cannot be obtained.
                count_list.append(type.element_count)
            except Exception:
                count_list.append(None)
            type = type.element_type

        if len(count_list) == 1:
            return count_list[0]
        else:
            return tuple(count_list)
예제 #2
0
    def element_type(self):
        """Type of elements in the array.

        For example, for ``int [10]``, it returns an instance of
        :class:`.IntType`.
        """
        type = self._type.element_type

        while is_array_kind(type):
            type = type.element_type

        return Type._from_clang_type(type)
예제 #3
0
    def dimension(self):
        """Dimension of the array.

        For example, for ``int [10][10][10]``, it returns 3.
        """
        dimension = 1
        type = self._type.element_type

        while is_array_kind(type):
            type = type.element_type
            dimension += 1

        return dimension
    def _from_clang_type(type):
        """Creates a new type from the given clang type.

        :param clang.cindex.Type type: Internal type.

        :raises AssertionError: If the internal type is not supported.
        """
        # Basic types.
        if type.kind == cindex.TypeKind.VOID:
            return VoidType(type)
        elif is_char_kind(type):
            return CharType(type)
        elif type.kind in [cindex.TypeKind.INT, cindex.TypeKind.UINT]:
            return IntType(type)
        elif type.kind == cindex.TypeKind.FLOAT:
            return FloatType(type)
        elif type.kind in [cindex.TypeKind.DOUBLE, cindex.TypeKind.LONGDOUBLE]:
            return DoubleType(type)
        elif type.kind == cindex.TypeKind.POINTER:
            return PointerType(type)
        elif type.kind == cindex.TypeKind.BOOL:
            return BoolType(type)
        # If function pointer is a parameter of a function, it's type is not UNEXPOSED
        elif type.kind in [
                cindex.TypeKind.FUNCTIONPROTO, cindex.TypeKind.FUNCTIONNOPROTO
        ]:
            return FunctionType(type)
        elif is_array_kind(type):
            return ArrayType(type)

        # Unexposed or elaborated types. Elaborated types represent types that
        # were referred to using an elaborated type keyword, e.g. `struct S`
        # (http://clang.llvm.org/doxygen/classclang_1_1ElaboratedType.html).
        if type.kind in [
                cindex.TypeKind.UNEXPOSED, cindex.TypeKind.ELABORATED
        ]:
            canonical_type = type.get_canonical()
            # Structure (a record in Clang terms).
            if canonical_type.kind == cindex.TypeKind.RECORD:
                if canonical_type.spelling.partition(' ')[0] == 'union':
                    return UnionType(canonical_type)
                else:
                    return StructType(canonical_type)
            # Function
            elif canonical_type.kind in [
                    cindex.TypeKind.FUNCTIONPROTO,
                    cindex.TypeKind.FUNCTIONNOPROTO
            ]:
                return FunctionType(type)

        # Typedefs.
        if type.kind == cindex.TypeKind.TYPEDEF:
            # Standard typedefs.
            m = re.fullmatch(r'u?int(\d+)_t', type.spelling)
            if m is not None:
                return IntType(type, int(m.group(1)))

            # Our custom typedefs.
            m = re.fullmatch(r'float(\d+)_t', type.spelling)
            if m is not None:
                size = int(m.group(1))
                canonical_type = type.get_canonical()
                if canonical_type.kind == cindex.TypeKind.FLOAT:
                    return FloatType(type, size)
                elif canonical_type.kind == cindex.TypeKind.DOUBLE:
                    return DoubleType(type, size)

        raise AssertionError('unsupported type of kind {}'.format(type.kind))
 def _is_uninitialized_array_with_set_size(self, node):
     """Is the variable declared to be an array with size and not initialized?"""
     return (is_array_kind(self._node.type)
             and node.kind == cindex.CursorKind.INTEGER_LITERAL)