"""
This type stub file was generated by pyright.
"""

import enum

from llvmlite.binding import ffi

class Linkage(enum.IntEnum):
    external = ...
    available_externally = ...
    linkonce_any = ...
    linkonce_odr = ...
    linkonce_odr_autohide = ...
    weak_any = ...
    weak_odr = ...
    appending = ...
    internal = ...
    private = ...
    dllimport = ...
    dllexport = ...
    external_weak = ...
    ghost = ...
    common = ...
    linker_private = ...
    linker_private_weak = ...

class Visibility(enum.IntEnum):
    default = ...
    hidden = ...
    protected = ...

class StorageClass(enum.IntEnum):
    default = ...
    dllimport = ...
    dllexport = ...

class ValueKind(enum.IntEnum):
    argument = ...
    basic_block = ...
    memory_use = ...
    memory_def = ...
    memory_phi = ...
    function = ...
    global_alias = ...
    global_ifunc = ...
    global_variable = ...
    block_address = ...
    constant_expr = ...
    constant_array = ...
    constant_struct = ...
    constant_vector = ...
    undef_value = ...
    constant_aggregate_zero = ...
    constant_data_array = ...
    constant_data_vector = ...
    constant_int = ...
    constant_fp = ...
    constant_pointer_null = ...
    constant_token_none = ...
    metadata_as_value = ...
    inline_asm = ...
    instruction = ...
    poison_value = ...

class ValueRef(ffi.ObjectRef):
    """A weak reference to a LLVM value."""
    def __init__(self, ptr, kind, parents) -> None: ...
    @property
    def module(self):
        """
        The module this function or global variable value was obtained from.
        """
        ...

    @property
    def function(self):
        """
        The function this argument or basic block value was obtained from.
        """
        ...

    @property
    def block(self):
        """
        The block this instruction value was obtained from.
        """
        ...

    @property
    def instruction(self):
        """
        The instruction this operand value was obtained from.
        """
        ...

    @property
    def is_global(self): ...
    @property
    def is_function(self): ...
    @property
    def is_block(self): ...
    @property
    def is_argument(self): ...
    @property
    def is_instruction(self): ...
    @property
    def is_operand(self): ...
    @property
    def is_constant(self):  # -> bool:
        ...
    @property
    def value_kind(self):  # -> ValueKind:
        ...
    @property
    def name(self): ...
    @name.setter
    def name(self, val):  # -> None:
        ...
    @property
    def linkage(self):  # -> Linkage:
        ...
    @linkage.setter
    def linkage(self, value):  # -> None:
        ...
    @property
    def visibility(self):  # -> Visibility:
        ...
    @visibility.setter
    def visibility(self, value):  # -> None:
        ...
    @property
    def storage_class(self):  # -> StorageClass:
        ...
    @storage_class.setter
    def storage_class(self, value):  # -> None:
        ...
    def add_function_attribute(self, attr):  # -> None:
        """Only works on function value

        Parameters
        -----------
        attr : str
            attribute name
        """
        ...

    @property
    def type(self):  # -> TypeRef:
        """
        This value's LLVM type.
        """
        ...

    @property
    def global_value_type(self):  # -> TypeRef:
        """
        Uses ``LLVMGlobalGetValueType()``.
        Needed for opaque pointers in globals.
        > For globals, use getValueType().
        See https://llvm.org/docs/OpaquePointers.html#migration-instructions
        """
        ...

    @property
    def is_declaration(self):
        """
        Whether this value (presumably global) is defined in the current
        module.
        """
        ...

    @property
    def attributes(
        self,
    ):  # -> _AttributeListIterator | Iterator[Never] | _AttributeSetIterator:
        """
        Return an iterator over this value's attributes.
        The iterator will yield a string for each attribute.
        """
        ...

    @property
    def blocks(self):  # -> _BlocksIterator:
        """
        Return an iterator over this function's blocks.
        The iterator will yield a ValueRef for each block.
        """
        ...

    @property
    def arguments(self):  # -> _ArgumentsIterator:
        """
        Return an iterator over this function's arguments.
        The iterator will yield a ValueRef for each argument.
        """
        ...

    @property
    def instructions(self):  # -> _InstructionsIterator:
        """
        Return an iterator over this block's instructions.
        The iterator will yield a ValueRef for each instruction.
        """
        ...

    @property
    def operands(self):  # -> _OperandsIterator:
        """
        Return an iterator over this instruction's operands.
        The iterator will yield a ValueRef for each operand.
        """
        ...

    @property
    def opcode(self):  # -> str | None:
        ...
    @property
    def incoming_blocks(self):  # -> _IncomingBlocksIterator:
        """
        Return an iterator over this phi instruction's incoming blocks.
        The iterator will yield a ValueRef for each block.
        """
        ...

    def get_constant_value(self, signed_int=..., round_fp=...):  # -> int | str:
        """
        Return the constant value, either as a literal (when supported)
        or as a string.

        Parameters
        -----------
        signed_int : bool
            if True and the constant is an integer, returns a signed version
        round_fp : bool
            if True and the constant is a floating point value, rounds the
            result upon accuracy loss (e.g., when querying an fp128 value).
            By default, raises an exception on accuracy loss
        """
        ...

class _ValueIterator(ffi.ObjectRef):
    kind = ...
    def __init__(self, ptr, parents) -> None: ...
    def __next__(self):  # -> ValueRef:
        ...

    next = ...
    def __iter__(self):  # -> Self:
        ...

class _AttributeIterator(ffi.ObjectRef):
    def __next__(self): ...

    next = ...
    def __iter__(self):  # -> Self:
        ...

class _AttributeListIterator(_AttributeIterator): ...
class _AttributeSetIterator(_AttributeIterator): ...

class _BlocksIterator(_ValueIterator):
    kind = ...

class _ArgumentsIterator(_ValueIterator):
    kind = ...

class _InstructionsIterator(_ValueIterator):
    kind = ...

class _OperandsIterator(_ValueIterator):
    kind = ...

class _IncomingBlocksIterator(_ValueIterator):
    kind = ...
