
# Autogenerated by mlir-tblgen; don't manually edit.

from ._ods_common import _cext as _ods_cext
from ._ods_common import (
    equally_sized_accessor as _ods_equally_sized_accessor,
    get_default_loc_context as _ods_get_default_loc_context,
    get_op_results_or_values as _get_op_results_or_values,
    segmented_accessor as _ods_segmented_accessor,
)
_ods_ir = _ods_cext.ir
_ods_cext.globals.register_traceback_file_exclusion(__file__)

import builtins
from typing import Any as _Any, Sequence as _Sequence, Union as _Union, Optional as _Optional
import sys as _sys
if _sys.version_info >= (3, 12):
  from collections.abc import Buffer as _Buffer  # pytype: disable=not-supported-yet
else:
  try:
    from typing_extensions import Buffer as _Buffer
  except ImportError:
    _Buffer = _Any


@_ods_cext.register_dialect
class _Dialect(_ods_ir.Dialect):
  DIALECT_NAMESPACE = "emitc"

@_ods_cext.register_operation(_Dialect)
class AddOp(_ods_ir.OpView):
  r"""
  With the `emitc.add` operation the arithmetic operator + (addition) can
  be applied.
  
  Example:
  
  ```mlir
  // Custom form of the addition operation.
  %0 = emitc.add %arg0, %arg1 : (i32, i32) -> i32
  %1 = emitc.add %arg2, %arg3 : (!emitc.ptr<f32>, i32) -> !emitc.ptr<f32>
  ```
  ```c++
  // Code emitted for the operations above.
  int32_t v5 = v1 + v2;
  float* v6 = v3 + v4;
  ```
  """

  OPERATION_NAME = "emitc.add"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(lhs)
    operands.append(rhs)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operation.operands[1]

@_ods_cext.register_op_adaptor(AddOp)
class AddOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.add"

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operands[1]

def add(result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return AddOp(result=result, lhs=lhs, rhs=rhs, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class AddressOfOp(_ods_ir.OpView):
  r"""
  This operation models the C & (address of) operator for a single operand,
  which must be an emitc.lvalue, and returns an emitc pointer to its location.
  
  Example:
  
  ```mlir
  // Custom form of applying the & operator.
  %0 = emitc.address_of %arg0 : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
  ```
  """

  OPERATION_NAME = "emitc.address_of"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, reference: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(reference)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def reference(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(AddressOfOp)
class AddressOfOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.address_of"

  @builtins.property
  def reference(self) -> _ods_ir.Value:
    return self.operands[0]

def address_of(result: _ods_ir.Type, reference: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return AddressOfOp(result=result, reference=reference, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class ApplyOp(_ods_ir.OpView):
  r"""
  With the `emitc.apply` operation the operators & (address of) and * (contents of)
  can be applied to a single operand.
  
  Example:
  
  ```mlir
  // Custom form of applying the & operator.
  %0 = emitc.apply "&"(%arg0) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
  
  // Generic form of the same operation.
  %0 = "emitc.apply"(%arg0) {applicableOperator = "&"}
      : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
  
  ```
  """

  OPERATION_NAME = "emitc.apply"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, applicableOperator: _Union[str, _ods_ir.StringAttr], operand: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(operand)
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["applicableOperator"] = (applicableOperator if (
    isinstance(applicableOperator, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('StrAttr')) else
      _ods_ir.AttrBuilder.get('StrAttr')(applicableOperator, context=_ods_context))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def operand(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def applicableOperator(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["applicableOperator"]

  @applicableOperator.setter
  def applicableOperator(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["applicableOperator"] = value

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(ApplyOp)
class ApplyOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.apply"

  @builtins.property
  def operand(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def applicableOperator(self) -> _ods_ir.StringAttr:
    return self.attributes["applicableOperator"]

def apply(result: _ods_ir.Type, applicable_operator: _Union[str, _ods_ir.StringAttr], operand: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return ApplyOp(result=result, applicableOperator=applicable_operator, operand=operand, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class AssignOp(_ods_ir.OpView):
  r"""
  The `emitc.assign` operation stores an SSA value to the location designated by an
  EmitC variable. This operation doesn't return any value. The assigned value
  must be of the same type as the variable being assigned. The operation is
  emitted as a C/C++ '=' operator.
  
  Example:
  
  ```mlir
  // Integer variable
  %0 = "emitc.variable"(){value = 42 : i32} : () -> !emitc.lvalue<i32>
  %1 = emitc.call_opaque "foo"() : () -> (i32)
  
  // Assign emitted as `... = ...;`
  "emitc.assign"(%0, %1) : (!emitc.lvalue<i32>, i32) -> ()
  ```
  """

  OPERATION_NAME = "emitc.assign"

  _ODS_REGIONS = (0, True)

  def __init__(self, var: _ods_ir.Value, value: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(var)
    operands.append(value)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def var(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def value(self) -> _ods_ir.Value:
    return self.operation.operands[1]

@_ods_cext.register_op_adaptor(AssignOp)
class AssignOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.assign"

  @builtins.property
  def var(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def value(self) -> _ods_ir.Value:
    return self.operands[1]

def assign(var: _ods_ir.Value, value: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> AssignOp:
  return AssignOp(var=var, value=value, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class BitwiseAndOp(_ods_ir.OpView):
  r"""
  With the `emitc.bitwise_and` operation the bitwise operator & (and) can
  be applied.
  
  Example:
  
  ```mlir
  %0 = emitc.bitwise_and %arg0, %arg1 : (i32, i32) -> i32
  ```
  ```c++
  // Code emitted for the operation above.
  int32_t v3 = v1 & v2;
  ```
  """

  OPERATION_NAME = "emitc.bitwise_and"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(lhs)
    operands.append(rhs)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operation.operands[1]

@_ods_cext.register_op_adaptor(BitwiseAndOp)
class BitwiseAndOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.bitwise_and"

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operands[1]

def bitwise_and(result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return BitwiseAndOp(result=result, lhs=lhs, rhs=rhs, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class BitwiseLeftShiftOp(_ods_ir.OpView):
  r"""
  With the `emitc.bitwise_left_shift` operation the bitwise operator <<
  (left shift) can be applied.
  
  Example:
  
  ```mlir
  %0 = emitc.bitwise_left_shift %arg0, %arg1 : (i32, i32) -> i32
  ```
  ```c++
  // Code emitted for the operation above.
  int32_t v3 = v1 << v2;
  ```
  """

  OPERATION_NAME = "emitc.bitwise_left_shift"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(lhs)
    operands.append(rhs)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operation.operands[1]

@_ods_cext.register_op_adaptor(BitwiseLeftShiftOp)
class BitwiseLeftShiftOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.bitwise_left_shift"

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operands[1]

def bitwise_left_shift(result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return BitwiseLeftShiftOp(result=result, lhs=lhs, rhs=rhs, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class BitwiseNotOp(_ods_ir.OpView):
  r"""
  With the `emitc.bitwise_not` operation the bitwise operator ~ (not) can
  be applied.
  
  Example:
  
  ```mlir
  %0 = emitc.bitwise_not %arg0 : (i32) -> i32
  ```
  ```c++
  // Code emitted for the operation above.
  int32_t v2 = ~v1;
  ```
  """

  OPERATION_NAME = "emitc.bitwise_not"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(_gen_arg_0)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

@_ods_cext.register_op_adaptor(BitwiseNotOp)
class BitwiseNotOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.bitwise_not"

def bitwise_not(result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return BitwiseNotOp(result=result, _gen_arg_0=_gen_arg_0, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class BitwiseOrOp(_ods_ir.OpView):
  r"""
  With the `emitc.bitwise_or` operation the bitwise operator | (or)
  can be applied.
  
  Example:
  
  ```mlir
  %0 = emitc.bitwise_or %arg0, %arg1 : (i32, i32) -> i32
  ```
  ```c++
  // Code emitted for the operation above.
  int32_t v3 = v1 | v2;
  ```
  """

  OPERATION_NAME = "emitc.bitwise_or"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(lhs)
    operands.append(rhs)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operation.operands[1]

@_ods_cext.register_op_adaptor(BitwiseOrOp)
class BitwiseOrOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.bitwise_or"

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operands[1]

def bitwise_or(result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return BitwiseOrOp(result=result, lhs=lhs, rhs=rhs, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class BitwiseRightShiftOp(_ods_ir.OpView):
  r"""
  With the `emitc.bitwise_right_shift` operation the bitwise operator >>
  (right shift) can be applied.
  
  Example:
  
  ```mlir
  %0 = emitc.bitwise_right_shift %arg0, %arg1 : (i32, i32) -> i32
  ```
  ```c++
  // Code emitted for the operation above.
  int32_t v3 = v1 >> v2;
  ```
  """

  OPERATION_NAME = "emitc.bitwise_right_shift"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(lhs)
    operands.append(rhs)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operation.operands[1]

@_ods_cext.register_op_adaptor(BitwiseRightShiftOp)
class BitwiseRightShiftOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.bitwise_right_shift"

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operands[1]

def bitwise_right_shift(result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return BitwiseRightShiftOp(result=result, lhs=lhs, rhs=rhs, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class BitwiseXorOp(_ods_ir.OpView):
  r"""
  With the `emitc.bitwise_xor` operation the bitwise operator ^ (xor)
  can be applied.
  
  Example:
  
  ```mlir
  %0 = emitc.bitwise_xor %arg0, %arg1 : (i32, i32) -> i32
  ```
  ```c++
  // Code emitted for the operation above.
  int32_t v3 = v1 ^ v2;
  ```
  """

  OPERATION_NAME = "emitc.bitwise_xor"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(lhs)
    operands.append(rhs)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operation.operands[1]

@_ods_cext.register_op_adaptor(BitwiseXorOp)
class BitwiseXorOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.bitwise_xor"

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operands[1]

def bitwise_xor(result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return BitwiseXorOp(result=result, lhs=lhs, rhs=rhs, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class CallOp(_ods_ir.OpView):
  r"""
  The `emitc.call` operation represents a direct call to an `emitc.func`
  that is within the same symbol scope as the call. The operands and result type
  of the call must match the specified function type. The callee is encoded as a
  symbol reference attribute named "callee".
  
  Example:
  
  ```mlir
  %2 = emitc.call @my_add(%0, %1) : (f32, f32) -> f32
  ```
  """

  OPERATION_NAME = "emitc.call"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _Sequence[_ods_ir.Type], callee: _Union[str, _ods_ir.FlatSymbolRefAttr], operands_: _Sequence[_ods_ir.Value], *, arg_attrs: _Optional[_Union[_Any, _ods_ir.ArrayAttr]] = None, res_attrs: _Optional[_Union[_Any, _ods_ir.ArrayAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.extend(_get_op_results_or_values(operands_))
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["callee"] = (callee if (
    isinstance(callee, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('FlatSymbolRefAttr')) else
      _ods_ir.AttrBuilder.get('FlatSymbolRefAttr')(callee, context=_ods_context))
    if arg_attrs is not None: attributes["arg_attrs"] = (arg_attrs if (
        isinstance(arg_attrs, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('DictArrayAttr')) else
          _ods_ir.AttrBuilder.get('DictArrayAttr')(arg_attrs, context=_ods_context))
    if res_attrs is not None: attributes["res_attrs"] = (res_attrs if (
        isinstance(res_attrs, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('DictArrayAttr')) else
          _ods_ir.AttrBuilder.get('DictArrayAttr')(res_attrs, context=_ods_context))
    results = []
    results.extend(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def operands_(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operation.operands) - 1 + 1
    return self.operation.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def callee(self) -> _ods_ir.FlatSymbolRefAttr:
    return self.operation.attributes["callee"]

  @callee.setter
  def callee(self, value: _ods_ir.FlatSymbolRefAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["callee"] = value

  @builtins.property
  def arg_attrs(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "arg_attrs" not in self.operation.attributes:
      return None
    return self.operation.attributes["arg_attrs"]

  @arg_attrs.setter
  def arg_attrs(self, value: _Optional[_ods_ir.ArrayAttr]):
    if value is not None:
      self.operation.attributes["arg_attrs"] = value
    elif "arg_attrs" in self.operation.attributes:
      del self.operation.attributes["arg_attrs"]

  @arg_attrs.deleter
  def arg_attrs(self):
    del self.operation.attributes["arg_attrs"]

  @builtins.property
  def res_attrs(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "res_attrs" not in self.operation.attributes:
      return None
    return self.operation.attributes["res_attrs"]

  @res_attrs.setter
  def res_attrs(self, value: _Optional[_ods_ir.ArrayAttr]):
    if value is not None:
      self.operation.attributes["res_attrs"] = value
    elif "res_attrs" in self.operation.attributes:
      del self.operation.attributes["res_attrs"]

  @res_attrs.deleter
  def res_attrs(self):
    del self.operation.attributes["res_attrs"]

@_ods_cext.register_op_adaptor(CallOp)
class CallOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.call"

  @builtins.property
  def operands_(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operands) - 1 + 1
    return self.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def callee(self) -> _ods_ir.FlatSymbolRefAttr:
    return self.attributes["callee"]

  @builtins.property
  def arg_attrs(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "arg_attrs" not in self.attributes:
      return None
    return self.attributes["arg_attrs"]

  @builtins.property
  def res_attrs(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "res_attrs" not in self.attributes:
      return None
    return self.attributes["res_attrs"]

def call(result: _Sequence[_ods_ir.Type], callee: _Union[str, _ods_ir.FlatSymbolRefAttr], operands_: _Sequence[_ods_ir.Value], *, arg_attrs: _Optional[_Union[_Any, _ods_ir.ArrayAttr]] = None, res_attrs: _Optional[_Union[_Any, _ods_ir.ArrayAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _Union[_ods_ir.OpResult, _ods_ir.OpResultList, CallOp]:
  op = CallOp(result=result, callee=callee, operands_=operands_, arg_attrs=arg_attrs, res_attrs=res_attrs, loc=loc, ip=ip); results = op.results
  return results if len(results) > 1 else (results[0] if len(results) == 1 else op)

@_ods_cext.register_operation(_Dialect)
class CallOpaqueOp(_ods_ir.OpView):
  r"""
  The `emitc.call_opaque` operation represents a C++ function call. The callee
  can be an arbitrary non-empty string. The call allows specifying order
  of operands and attributes in the call as follows:
  
  - integer value of index type refers to an operand;
  - attribute which will get lowered to constant value in call;
  
  Example:
  
  ```mlir
  // Custom form defining a call to `foo()`.
  %0 = emitc.call_opaque "foo" () : () -> i32
  
  // Generic form of the same operation.
  %0 = "emitc.call_opaque"() {callee = "foo"} : () -> i32
  ```
  """

  OPERATION_NAME = "emitc.call_opaque"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _Sequence[_ods_ir.Type], callee: _Union[str, _ods_ir.StringAttr], operands_: _Sequence[_ods_ir.Value], *, args: _Optional[_Union[_Sequence[_ods_ir.Attribute], _ods_ir.ArrayAttr]] = None, template_args: _Optional[_Union[_Sequence[_ods_ir.Attribute], _ods_ir.ArrayAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.extend(_get_op_results_or_values(operands_))
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["callee"] = (callee if (
    isinstance(callee, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('StrAttr')) else
      _ods_ir.AttrBuilder.get('StrAttr')(callee, context=_ods_context))
    if args is not None: attributes["args"] = (args if (
        isinstance(args, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('ArrayAttr')) else
          _ods_ir.AttrBuilder.get('ArrayAttr')(args, context=_ods_context))
    if template_args is not None: attributes["template_args"] = (template_args if (
        isinstance(template_args, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('ArrayAttr')) else
          _ods_ir.AttrBuilder.get('ArrayAttr')(template_args, context=_ods_context))
    results = []
    results.extend(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def operands_(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operation.operands) - 1 + 1
    return self.operation.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def callee(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["callee"]

  @callee.setter
  def callee(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["callee"] = value

  @builtins.property
  def args(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "args" not in self.operation.attributes:
      return None
    return self.operation.attributes["args"]

  @args.setter
  def args(self, value: _Optional[_ods_ir.ArrayAttr]):
    if value is not None:
      self.operation.attributes["args"] = value
    elif "args" in self.operation.attributes:
      del self.operation.attributes["args"]

  @args.deleter
  def args(self):
    del self.operation.attributes["args"]

  @builtins.property
  def template_args(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "template_args" not in self.operation.attributes:
      return None
    return self.operation.attributes["template_args"]

  @template_args.setter
  def template_args(self, value: _Optional[_ods_ir.ArrayAttr]):
    if value is not None:
      self.operation.attributes["template_args"] = value
    elif "template_args" in self.operation.attributes:
      del self.operation.attributes["template_args"]

  @template_args.deleter
  def template_args(self):
    del self.operation.attributes["template_args"]

@_ods_cext.register_op_adaptor(CallOpaqueOp)
class CallOpaqueOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.call_opaque"

  @builtins.property
  def operands_(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operands) - 1 + 1
    return self.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def callee(self) -> _ods_ir.StringAttr:
    return self.attributes["callee"]

  @builtins.property
  def args(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "args" not in self.attributes:
      return None
    return self.attributes["args"]

  @builtins.property
  def template_args(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "template_args" not in self.attributes:
      return None
    return self.attributes["template_args"]

def call_opaque(result: _Sequence[_ods_ir.Type], callee: _Union[str, _ods_ir.StringAttr], operands_: _Sequence[_ods_ir.Value], *, args: _Optional[_Union[_Sequence[_ods_ir.Attribute], _ods_ir.ArrayAttr]] = None, template_args: _Optional[_Union[_Sequence[_ods_ir.Attribute], _ods_ir.ArrayAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _Union[_ods_ir.OpResult, _ods_ir.OpResultList, CallOpaqueOp]:
  op = CallOpaqueOp(result=result, callee=callee, operands_=operands_, args=args, template_args=template_args, loc=loc, ip=ip); results = op.results
  return results if len(results) > 1 else (results[0] if len(results) == 1 else op)

@_ods_cext.register_operation(_Dialect)
class CastOp(_ods_ir.OpView):
  r"""
  The `emitc.cast` operation performs an explicit type conversion and is emitted
  as a C-style cast expression. It can be applied to integer, float, index
  and EmitC types.
  
  Example:
  
  ```mlir
  // Cast from `int32_t` to `float`
  %0 = emitc.cast %arg0: i32 to f32
  
  // Cast from `void` to `int32_t` pointer
  %1 = emitc.cast %arg1 :
      !emitc.ptr<!emitc.opaque<"void">> to !emitc.ptr<i32>
  ```
  """

  OPERATION_NAME = "emitc.cast"

  _ODS_REGIONS = (0, True)

  def __init__(self, dest: _ods_ir.Type, source: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(source)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(dest)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def source(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def dest(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(CastOp)
class CastOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.cast"

  @builtins.property
  def source(self) -> _ods_ir.Value:
    return self.operands[0]

def cast(dest: _ods_ir.Type, source: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return CastOp(dest=dest, source=source, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class ClassOp(_ods_ir.OpView):
  r"""
  The `emitc.class` operation defines a C++ class, acting as a container
  for its data fields (`emitc.field`) and methods (`emitc.func`).
  It creates a distinct scope, isolating its contents from the surrounding
  MLIR region, similar to how C++ classes encapsulate their internals.
  
  Example:
  
  ```mlir
  emitc.class @modelClass {
    emitc.field @fieldName0 : !emitc.array<1xf32> = {emitc.opaque = "input_tensor"}
    emitc.func @execute() {
      %0 = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t
      %1 = get_field @fieldName0 : !emitc.array<1xf32>
      %2 = subscript %1[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
      return
    }
  }
  // Class with a final specifer
  emitc.class final @modelClass {
    emitc.field @fieldName0 : !emitc.array<1xf32> = {emitc.opaque = "input_tensor"}
    emitc.func @execute() {
      %0 = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t
      %1 = get_field @fieldName0 : !emitc.array<1xf32>
      %2 = subscript %1[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
      return
    }
  }
  ```
  """

  OPERATION_NAME = "emitc.class"

  _ODS_REGIONS = (1, True)

  def __init__(self, sym_name: _Union[str, _ods_ir.StringAttr], *, final_specifier: _Optional[bool] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["sym_name"] = (sym_name if (
    isinstance(sym_name, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('SymbolNameAttr')) else
      _ods_ir.AttrBuilder.get('SymbolNameAttr')(sym_name, context=_ods_context))
    if bool(final_specifier): attributes["final_specifier"] = _ods_ir.UnitAttr.get(
      _ods_get_default_loc_context(loc))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def sym_name(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["sym_name"]

  @sym_name.setter
  def sym_name(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["sym_name"] = value

  @builtins.property
  def final_specifier(self) -> bool:
    return "final_specifier" in self.operation.attributes

  @final_specifier.setter
  def final_specifier(self, value):
    if bool(value):
      self.operation.attributes["final_specifier"] = _ods_ir.UnitAttr.get()
    elif "final_specifier" in self.operation.attributes:
      del self.operation.attributes["final_specifier"]

  @final_specifier.deleter
  def final_specifier(self):
    del self.operation.attributes["final_specifier"]

  @builtins.property
  def body(self) -> _ods_ir.Region:
    return self.regions[0]

@_ods_cext.register_op_adaptor(ClassOp)
class ClassOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.class"

  @builtins.property
  def sym_name(self) -> _ods_ir.StringAttr:
    return self.attributes["sym_name"]

  @builtins.property
  def final_specifier(self) -> bool:
    return "final_specifier" in self.attributes

def class_(sym_name: _Union[str, _ods_ir.StringAttr], *, final_specifier: _Optional[bool] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> ClassOp:
  return ClassOp(sym_name=sym_name, final_specifier=final_specifier, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class CmpOp(_ods_ir.OpView):
  r"""
  With the `emitc.cmp` operation the comparison operators ==, !=, <, <=, >, >=, <=> 
  can be applied.
  
  Its first argument is an attribute that defines the comparison operator:
  
  - equal to (mnemonic: `"eq"`; integer value: `0`)
  - not equal to (mnemonic: `"ne"`; integer value: `1`)
  - less than (mnemonic: `"lt"`; integer value: `2`)
  - less than or equal to (mnemonic: `"le"`; integer value: `3`)
  - greater than (mnemonic: `"gt"`; integer value: `4`)
  - greater than or equal to (mnemonic: `"ge"`; integer value: `5`)
  - three-way-comparison (mnemonic: `"three_way"`; integer value: `6`)
  
  Example:
  ```mlir
  // Custom form of the cmp operation.
  %0 = emitc.cmp eq, %arg0, %arg1 : (i32, i32) -> i1
  %1 = emitc.cmp lt, %arg2, %arg3 : 
      (
        !emitc.opaque<"std::valarray<float>">,
        !emitc.opaque<"std::valarray<float>">
      ) -> !emitc.opaque<"std::valarray<bool>">
  ```
  ```c++
  // Code emitted for the operations above.
  bool v5 = v1 == v2;
  std::valarray<bool> v6 = v3 < v4;
  ```
  """

  OPERATION_NAME = "emitc.cmp"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, predicate: _Union[_Any, _ods_ir.Attribute], lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(lhs)
    operands.append(rhs)
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["predicate"] = (predicate if (
    isinstance(predicate, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('EmitC_CmpPredicateAttr')) else
      _ods_ir.AttrBuilder.get('EmitC_CmpPredicateAttr')(predicate, context=_ods_context))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operation.operands[1]

  @builtins.property
  def predicate(self) -> _ods_ir.Attribute:
    return self.operation.attributes["predicate"]

  @predicate.setter
  def predicate(self, value: _ods_ir.Attribute):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["predicate"] = value

@_ods_cext.register_op_adaptor(CmpOp)
class CmpOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.cmp"

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operands[1]

  @builtins.property
  def predicate(self) -> _ods_ir.Attribute:
    return self.attributes["predicate"]

def cmp(result: _ods_ir.Type, predicate: _Union[_Any, _ods_ir.Attribute], lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return CmpOp(result=result, predicate=predicate, lhs=lhs, rhs=rhs, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class ConditionalOp(_ods_ir.OpView):
  r"""
  With the `emitc.conditional` operation the ternary conditional operator can
  be applied.
  
  Example:
  
  ```mlir
  %0 = emitc.cmp gt, %arg0, %arg1 : (i32, i32) -> i1
  
  %c0 = "emitc.constant"() {value = 10 : i32} : () -> i32
  %c1 = "emitc.constant"() {value = 11 : i32} : () -> i32
  
  %1 = emitc.conditional %0, %c0, %c1 : i32
  ```
  ```c++
  // Code emitted for the operations above.
  bool v3 = v1 > v2;
  int32_t v4 = 10;
  int32_t v5 = 11;
  int32_t v6 = v3 ? v4 : v5;
  ```
  """

  OPERATION_NAME = "emitc.conditional"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, condition: _ods_ir.Value[_ods_ir.IntegerType], true_value: _ods_ir.Value, false_value: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(condition)
    operands.append(true_value)
    operands.append(false_value)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def condition(self) -> _ods_ir.Value[_ods_ir.IntegerType]:
    return self.operation.operands[0]

  @builtins.property
  def true_value(self) -> _ods_ir.Value:
    return self.operation.operands[1]

  @builtins.property
  def false_value(self) -> _ods_ir.Value:
    return self.operation.operands[2]

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(ConditionalOp)
class ConditionalOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.conditional"

  @builtins.property
  def condition(self) -> _ods_ir.Value[_ods_ir.IntegerType]:
    return self.operands[0]

  @builtins.property
  def true_value(self) -> _ods_ir.Value:
    return self.operands[1]

  @builtins.property
  def false_value(self) -> _ods_ir.Value:
    return self.operands[2]

def conditional(result: _ods_ir.Type, condition: _ods_ir.Value[_ods_ir.IntegerType], true_value: _ods_ir.Value, false_value: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return ConditionalOp(result=result, condition=condition, true_value=true_value, false_value=false_value, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class ConstantOp(_ods_ir.OpView):
  r"""
  The `emitc.constant` operation produces an SSA value equal to some constant
  specified by an attribute. This can be used to form simple integer and
  floating point constants, as well as more exotic things like tensor
  constants. The `emitc.constant` operation also supports the EmitC opaque
  attribute and the EmitC opaque type. Since folding is supported,
  it should not be used with pointers.
  
  Example:
  
  ```mlir
  // Integer constant
  %0 = "emitc.constant"(){value = 42 : i32} : () -> i32
  
  // Constant emitted as `char = CHAR_MIN;`
  %1 = "emitc.constant"() {value = #emitc.opaque<"CHAR_MIN">}
    : () -> !emitc.opaque<"char">
  ```
  """

  OPERATION_NAME = "emitc.constant"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, value: _Union[_Any, _ods_ir.Attribute], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["value"] = (value if (
    isinstance(value, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('EmitC_OpaqueOrTypedAttr')) else
      _ods_ir.AttrBuilder.get('EmitC_OpaqueOrTypedAttr')(value, context=_ods_context))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def value(self) -> _ods_ir.Attribute:
    return self.operation.attributes["value"]

  @value.setter
  def value(self, value: _ods_ir.Attribute):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["value"] = value

@_ods_cext.register_op_adaptor(ConstantOp)
class ConstantOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.constant"

  @builtins.property
  def value(self) -> _ods_ir.Attribute:
    return self.attributes["value"]

def constant(result: _ods_ir.Type, value: _Union[_Any, _ods_ir.Attribute], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return ConstantOp(result=result, value=value, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class DeclareFuncOp(_ods_ir.OpView):
  r"""
  The `emitc.declare_func` operation allows to insert a function declaration for an
  `emitc.func` at a specific position. The operation only requires the "callee"
  of the `emitc.func` to be specified as an attribute.
  
  Example:
  
  ```mlir
  emitc.declare_func @bar
  emitc.func @foo(%arg0: i32) -> i32 {
    %0 = emitc.call @bar(%arg0) : (i32) -> (i32)
    emitc.return %0 : i32
  }
  
  emitc.func @bar(%arg0: i32) -> i32 {
    emitc.return %arg0 : i32
  }
  ```
  
  ```c++
  // Code emitted for the operations above.
  int32_t bar(int32_t v1);
  int32_t foo(int32_t v1) {
    int32_t v2 = bar(v1);
    return v2;
  }
  
  int32_t bar(int32_t v1) {
    return v1;
  }
  ```
  """

  OPERATION_NAME = "emitc.declare_func"

  _ODS_REGIONS = (0, True)

  def __init__(self, sym_name: _Union[str, _ods_ir.FlatSymbolRefAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["sym_name"] = (sym_name if (
    isinstance(sym_name, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('FlatSymbolRefAttr')) else
      _ods_ir.AttrBuilder.get('FlatSymbolRefAttr')(sym_name, context=_ods_context))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def sym_name(self) -> _ods_ir.FlatSymbolRefAttr:
    return self.operation.attributes["sym_name"]

  @sym_name.setter
  def sym_name(self, value: _ods_ir.FlatSymbolRefAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["sym_name"] = value

@_ods_cext.register_op_adaptor(DeclareFuncOp)
class DeclareFuncOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.declare_func"

  @builtins.property
  def sym_name(self) -> _ods_ir.FlatSymbolRefAttr:
    return self.attributes["sym_name"]

def declare_func(sym_name: _Union[str, _ods_ir.FlatSymbolRefAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> DeclareFuncOp:
  return DeclareFuncOp(sym_name=sym_name, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class DereferenceOp(_ods_ir.OpView):
  r"""
  This operation models the C * (dereference) operator, which must be of
  !emitc.ptr<> type, returning an !emitc.lvalue<> the value pointed to by the
  pointer.
  
  Example:
  
  ```mlir
  // Custom form of the dereference operator.
  %0 = emitc.dereference %arg0 : (!emitc.ptr<i32>) -> !emitc.lvalue<i32>
  ```
  """

  OPERATION_NAME = "emitc.dereference"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, pointer: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(pointer)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def pointer(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(DereferenceOp)
class DereferenceOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.dereference"

  @builtins.property
  def pointer(self) -> _ods_ir.Value:
    return self.operands[0]

def dereference(result: _ods_ir.Type, pointer: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return DereferenceOp(result=result, pointer=pointer, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class DivOp(_ods_ir.OpView):
  r"""
  With the `emitc.div` operation the arithmetic operator / (division) can
  be applied.
  
  Example:
  
  ```mlir
  // Custom form of the division operation.
  %0 = emitc.div %arg0, %arg1 : (i32, i32) -> i32
  %1 = emitc.div %arg2, %arg3 : (f32, f32) -> f32
  ```
  ```c++
  // Code emitted for the operations above.
  int32_t v5 = v1 / v2;
  float v6 = v3 / v4;
  ```
  """

  OPERATION_NAME = "emitc.div"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, _gen_arg_1: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(_gen_arg_0)
    operands.append(_gen_arg_1)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

@_ods_cext.register_op_adaptor(DivOp)
class DivOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.div"

def div(result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, _gen_arg_1: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return DivOp(result=result, _gen_arg_0=_gen_arg_0, _gen_arg_1=_gen_arg_1, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class DoOp(_ods_ir.OpView):
  r"""
  The `emitc.do` operation represents a C/C++ do-while loop construct that
  repeatedly executes a body region as long as a condition region evaluates to
  true. The operation has two regions:
  
  1. A body region that contains the loop body
  2. A condition region that must yield a boolean value (i1)
  
  The condition is evaluated before each iteration as follows:
  - The condition region must contain exactly one block with:
    1. An `emitc.expression` operation producing an i1 value
    2. An `emitc.yield` passing through the expression result
  - The expression's body contains the actual condition logic
  
  The body region is executed before the first evaluation of the 
  condition. Thus, there is a guarantee that the loop will be executed 
  at least once. The loop terminates when the condition yields false.
  
  The canonical structure of `emitc.do` is:
  
  ```mlir
  emitc.do {
    // Body region (no terminator required).
    // Loop body operations...
  } while {
    // Condition region (must yield i1)
    %condition = emitc.expression : () -> i1 {
      // Condition computation...
      %result = ... : i1  // Last operation must produce i1
      emitc.yield %result : i1
    }
    // Forward expression result
    emitc.yield %condition : i1  
  }
  ```
  
  Example:
  
  ```mlir
  emitc.func @do_example() {
    %counter = "emitc.variable"() <{value = 0 : i32}> : () -> !emitc.lvalue<i32>
    %end = emitc.literal "10" : i32
    %step = emitc.literal "1" : i32
  
    emitc.do {
      // Print current value
      %val = emitc.load %counter : !emitc.lvalue<i32>
      emitc.verbatim "printf(\"%d\\n\", {});" args %val : i32
  
      // Increment counter
      %new_val = emitc.add %val, %step : (i32, i32) -> i32
      "emitc.assign"(%counter, %new_val) : (!emitc.lvalue<i32>, i32) -> ()
    } while {
      %condition = emitc.expression %counter, %end : (!emitc.lvalue<i32>, i32) -> i1 {
        %current = emitc.load %counter : !emitc.lvalue<i32>
        %cmp_res = emitc.cmp lt, %current, %end : (i32, i32) -> i1
        emitc.yield %cmp_res : i1
      }
      emitc.yield %condition : i1
    }
    return
  }
  ```
  ```c++
  // Code emitted for the operation above.
  void do_example() {
    int32_t v1 = 0;
    do {
      int32_t v2 = v1;
      printf("%d\n", v2);
      int32_t v3 = v2 + 1;
      v1 = v3;
    } while (v1 < 10);
    return;
  }
  ```
  """

  OPERATION_NAME = "emitc.do"

  _ODS_REGIONS = (2, True)

  def __init__(self, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def bodyRegion(self) -> _ods_ir.Region:
    return self.regions[0]

  @builtins.property
  def conditionRegion(self) -> _ods_ir.Region:
    return self.regions[1]

@_ods_cext.register_op_adaptor(DoOp)
class DoOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.do"

def do(*, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> DoOp:
  return DoOp(loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class ExpressionOp(_ods_ir.OpView):
  r"""
  The `emitc.expression` operation returns a single SSA value which is yielded by
  its single-basic-block region. The operation takes zero or more input operands 
  that are passed as block arguments to the region.
  
  As the operation is to be emitted as a C expression, the operations within
  its body must form a single Def-Use tree, or a DAG trivially expandable to
  one, i.e. a DAG where each operation with side effects is only reachable
  once from the expression root.
  
  Input operands can be of both value types (`EmitCType`) and lvalue types
  (`EmitC_LValueType`).
  
  Example:
  ```mlir
  %r = emitc.expression %a, %b, %c : (i32, i32, i32) -> i32 {
    %0 = emitc.call_opaque "foo"(%a) : (i32) -> i32
    %1 = emitc.add %b, %c : (i32, i32) -> i32
    %2 = emitc.mul %0, %1 : (i32, i32) -> i32
    emitc.yield %2 : i32
  }
  ```
  
  May be emitted as:
  ```c++
  int32_t v4 = foo(v1) * (v2 + v3);
  ```
  
  When specified, the optional `noinline` indicates that the expression is
  to be emitted as seen above, i.e. as the rhs of an EmitC SSA value
  definition. Otherwise, the expression may be emitted inline, i.e. directly
  at its use.
  """

  OPERATION_NAME = "emitc.expression"

  _ODS_REGIONS = (1, True)

  def __init__(self, result: _ods_ir.Type, defs: _Sequence[_ods_ir.Value], *, do_not_inline: _Optional[bool] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.extend(_get_op_results_or_values(defs))
    _ods_context = _ods_get_default_loc_context(loc)
    if bool(do_not_inline): attributes["do_not_inline"] = _ods_ir.UnitAttr.get(
      _ods_get_default_loc_context(loc))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def defs(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operation.operands) - 1 + 1
    return self.operation.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def do_not_inline(self) -> bool:
    return "do_not_inline" in self.operation.attributes

  @do_not_inline.setter
  def do_not_inline(self, value):
    if bool(value):
      self.operation.attributes["do_not_inline"] = _ods_ir.UnitAttr.get()
    elif "do_not_inline" in self.operation.attributes:
      del self.operation.attributes["do_not_inline"]

  @do_not_inline.deleter
  def do_not_inline(self):
    del self.operation.attributes["do_not_inline"]

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

  @builtins.property
  def region(self) -> _ods_ir.Region:
    return self.regions[0]

@_ods_cext.register_op_adaptor(ExpressionOp)
class ExpressionOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.expression"

  @builtins.property
  def defs(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operands) - 1 + 1
    return self.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def do_not_inline(self) -> bool:
    return "do_not_inline" in self.attributes

def expression(result: _ods_ir.Type, defs: _Sequence[_ods_ir.Value], *, do_not_inline: _Optional[bool] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return ExpressionOp(result=result, defs=defs, do_not_inline=do_not_inline, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class FieldOp(_ods_ir.OpView):
  r"""
  The `emitc.field` operation declares a named field within an `emitc.class`
  operation. The field's type must be an EmitC type. 
  
  Example:
  
  ```mlir
  // Example with an attribute:
  emitc.field @fieldName0 : !emitc.array<1xf32>  {emitc.opaque = "another_feature"}
  // Example with no attribute:
  emitc.field @fieldName0 : !emitc.array<1xf32>
  // Example with an initial value:
  emitc.field @fieldName0 : !emitc.array<1xf32> = dense<0.0>
  // Example with an initial value and attributes:
  emitc.field @fieldName0 : !emitc.array<1xf32> = dense<0.0> {
    emitc.opaque = "input_tensor"}
  ```
  """

  OPERATION_NAME = "emitc.field"

  _ODS_REGIONS = (0, True)

  def __init__(self, sym_name: _Union[str, _ods_ir.StringAttr], type_: _Union[_ods_ir.Type, _ods_ir.TypeAttr], *, initial_value: _Optional[_Union[_Any, _ods_ir.Attribute]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["sym_name"] = (sym_name if (
    isinstance(sym_name, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('SymbolNameAttr')) else
      _ods_ir.AttrBuilder.get('SymbolNameAttr')(sym_name, context=_ods_context))
    attributes["type"] = (type_ if (
    isinstance(type_, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('TypeAttr')) else
      _ods_ir.AttrBuilder.get('TypeAttr')(type_, context=_ods_context))
    if initial_value is not None: attributes["initial_value"] = (initial_value if (
        isinstance(initial_value, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('EmitC_OpaqueOrTypedAttr')) else
          _ods_ir.AttrBuilder.get('EmitC_OpaqueOrTypedAttr')(initial_value, context=_ods_context))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def sym_name(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["sym_name"]

  @sym_name.setter
  def sym_name(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["sym_name"] = value

  @builtins.property
  def type_(self) -> _ods_ir.TypeAttr:
    return self.operation.attributes["type"]

  @type_.setter
  def type_(self, value: _ods_ir.TypeAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["type"] = value

  @builtins.property
  def initial_value(self) -> _Optional[_ods_ir.Attribute]:
    if "initial_value" not in self.operation.attributes:
      return None
    return self.operation.attributes["initial_value"]

  @initial_value.setter
  def initial_value(self, value: _Optional[_ods_ir.Attribute]):
    if value is not None:
      self.operation.attributes["initial_value"] = value
    elif "initial_value" in self.operation.attributes:
      del self.operation.attributes["initial_value"]

  @initial_value.deleter
  def initial_value(self):
    del self.operation.attributes["initial_value"]

@_ods_cext.register_op_adaptor(FieldOp)
class FieldOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.field"

  @builtins.property
  def sym_name(self) -> _ods_ir.StringAttr:
    return self.attributes["sym_name"]

  @builtins.property
  def type_(self) -> _ods_ir.TypeAttr:
    return self.attributes["type"]

  @builtins.property
  def initial_value(self) -> _Optional[_ods_ir.Attribute]:
    if "initial_value" not in self.attributes:
      return None
    return self.attributes["initial_value"]

def field(sym_name: _Union[str, _ods_ir.StringAttr], type_: _Union[_ods_ir.Type, _ods_ir.TypeAttr], *, initial_value: _Optional[_Union[_Any, _ods_ir.Attribute]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> FieldOp:
  return FieldOp(sym_name=sym_name, type_=type_, initial_value=initial_value, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class FileOp(_ods_ir.OpView):
  r"""
  A `file` represents a single C/C++ file.
  
  `mlir-translate` ignores the body of all `emitc.file` ops
  unless the `-file-id=id` flag is used. With that flag, all `emitc.file` ops
  with matching id are emitted.
  
  Example:
  
  ```mlir
  emitc.file "main" {
    emitc.func @func_one() {
      emitc.return
    }
  }
  ```
  """

  OPERATION_NAME = "emitc.file"

  _ODS_REGIONS = (1, True)

  def __init__(self, id: _Union[_Any, _ods_ir.StringAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["id"] = (id if (
    isinstance(id, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('Builtin_StringAttr')) else
      _ods_ir.AttrBuilder.get('Builtin_StringAttr')(id, context=_ods_context))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def id(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["id"]

  @id.setter
  def id(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["id"] = value

  @builtins.property
  def bodyRegion(self) -> _ods_ir.Region:
    return self.regions[0]

@_ods_cext.register_op_adaptor(FileOp)
class FileOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.file"

  @builtins.property
  def id(self) -> _ods_ir.StringAttr:
    return self.attributes["id"]

def file(id: _Union[_Any, _ods_ir.StringAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> FileOp:
  return FileOp(id=id, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class ForOp(_ods_ir.OpView):
  r"""
  The `emitc.for` operation represents a C loop of the following form:
  
  ```c++
  for (T i = lb; i < ub; i += step) { /* ... */ } // where T is typeof(lb)
  ```
  
  The operation takes 3 SSA values as operands that represent the lower bound,
  upper bound and step respectively, and defines an SSA value for its
  induction variable. It has one region capturing the loop body. The induction
  variable is represented as an argument of this region. This SSA value is a
  signless integer, or an index. The step is a value of same type.
  
  This operation has no result. The body region must contain exactly one block
  that terminates with `emitc.yield`. Calling ForOp::build will create such a
  region and insert the terminator implicitly if none is defined, so will the
  parsing even in cases when it is absent from the custom format. For example:
  
  ```mlir
  // Index case.
  emitc.for %iv = %lb to %ub step %step {
    ... // body
  }
  ...
  // Integer case.
  emitc.for %iv_32 = %lb_32 to %ub_32 step %step_32 : i32 {
    ... // body
  }
  ```
  """

  OPERATION_NAME = "emitc.for"

  _ODS_REGIONS = (1, True)

  def __init__(self, lowerBound: _ods_ir.Value, upperBound: _ods_ir.Value, step: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(lowerBound)
    operands.append(upperBound)
    operands.append(step)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def lowerBound(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def upperBound(self) -> _ods_ir.Value:
    return self.operation.operands[1]

  @builtins.property
  def step(self) -> _ods_ir.Value:
    return self.operation.operands[2]

  @builtins.property
  def region(self) -> _ods_ir.Region:
    return self.regions[0]

@_ods_cext.register_op_adaptor(ForOp)
class ForOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.for"

  @builtins.property
  def lowerBound(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def upperBound(self) -> _ods_ir.Value:
    return self.operands[1]

  @builtins.property
  def step(self) -> _ods_ir.Value:
    return self.operands[2]

def for_(lower_bound: _ods_ir.Value, upper_bound: _ods_ir.Value, step: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> ForOp:
  return ForOp(lowerBound=lower_bound, upperBound=upper_bound, step=step, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class FuncOp(_ods_ir.OpView):
  r"""
  Operations within the function cannot implicitly capture values defined
  outside of the function, i.e. Functions are `IsolatedFromAbove`. All
  external references must use function arguments or attributes that establish
  a symbolic connection (e.g. symbols referenced by name via a string
  attribute like SymbolRefAttr). While the MLIR textual form provides a nice
  inline syntax for function arguments, they are internally represented as
  “block arguments” to the first block in the region.
  
  Only dialect attribute names may be specified in the attribute dictionaries
  for function arguments, results, or the function itself.
  
  Example:
  
  ```mlir
  // A function with no results:
  emitc.func @foo(%arg0 : i32) {
    emitc.call_opaque "bar" (%arg0) : (i32) -> ()
    emitc.return
  }
  
  // A function with its argument as single result:
  emitc.func @foo(%arg0 : i32) -> i32 {
    emitc.return %arg0 : i32
  }
  
  // A function with specifiers attribute:
  emitc.func @example_specifiers_fn_attr() -> i32
              attributes {specifiers = ["static","inline"]} {
    %0 = emitc.call_opaque "foo" (): () -> i32
    emitc.return %0 : i32
  }
  
  // An external function definition:
  emitc.func private @extern_func(i32)
                      attributes {specifiers = ["extern"]}
  ```
  """

  OPERATION_NAME = "emitc.func"

  _ODS_REGIONS = (1, True)

  def __init__(self, sym_name: _Union[str, _ods_ir.StringAttr], function_type: _Union[_Any, _ods_ir.TypeAttr], *, specifiers: _Optional[_Union[_Sequence[str], _ods_ir.ArrayAttr]] = None, arg_attrs: _Optional[_Union[_Any, _ods_ir.ArrayAttr]] = None, res_attrs: _Optional[_Union[_Any, _ods_ir.ArrayAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["sym_name"] = (sym_name if (
    isinstance(sym_name, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('SymbolNameAttr')) else
      _ods_ir.AttrBuilder.get('SymbolNameAttr')(sym_name, context=_ods_context))
    attributes["function_type"] = (function_type if (
    isinstance(function_type, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('anonymous_561')) else
      _ods_ir.AttrBuilder.get('anonymous_561')(function_type, context=_ods_context))
    if specifiers is not None: attributes["specifiers"] = (specifiers if (
        isinstance(specifiers, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('StrArrayAttr')) else
          _ods_ir.AttrBuilder.get('StrArrayAttr')(specifiers, context=_ods_context))
    if arg_attrs is not None: attributes["arg_attrs"] = (arg_attrs if (
        isinstance(arg_attrs, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('DictArrayAttr')) else
          _ods_ir.AttrBuilder.get('DictArrayAttr')(arg_attrs, context=_ods_context))
    if res_attrs is not None: attributes["res_attrs"] = (res_attrs if (
        isinstance(res_attrs, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('DictArrayAttr')) else
          _ods_ir.AttrBuilder.get('DictArrayAttr')(res_attrs, context=_ods_context))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def sym_name(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["sym_name"]

  @sym_name.setter
  def sym_name(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["sym_name"] = value

  @builtins.property
  def function_type(self) -> _ods_ir.TypeAttr:
    return self.operation.attributes["function_type"]

  @function_type.setter
  def function_type(self, value: _ods_ir.TypeAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["function_type"] = value

  @builtins.property
  def specifiers(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "specifiers" not in self.operation.attributes:
      return None
    return self.operation.attributes["specifiers"]

  @specifiers.setter
  def specifiers(self, value: _Optional[_ods_ir.ArrayAttr]):
    if value is not None:
      self.operation.attributes["specifiers"] = value
    elif "specifiers" in self.operation.attributes:
      del self.operation.attributes["specifiers"]

  @specifiers.deleter
  def specifiers(self):
    del self.operation.attributes["specifiers"]

  @builtins.property
  def arg_attrs(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "arg_attrs" not in self.operation.attributes:
      return None
    return self.operation.attributes["arg_attrs"]

  @arg_attrs.setter
  def arg_attrs(self, value: _Optional[_ods_ir.ArrayAttr]):
    if value is not None:
      self.operation.attributes["arg_attrs"] = value
    elif "arg_attrs" in self.operation.attributes:
      del self.operation.attributes["arg_attrs"]

  @arg_attrs.deleter
  def arg_attrs(self):
    del self.operation.attributes["arg_attrs"]

  @builtins.property
  def res_attrs(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "res_attrs" not in self.operation.attributes:
      return None
    return self.operation.attributes["res_attrs"]

  @res_attrs.setter
  def res_attrs(self, value: _Optional[_ods_ir.ArrayAttr]):
    if value is not None:
      self.operation.attributes["res_attrs"] = value
    elif "res_attrs" in self.operation.attributes:
      del self.operation.attributes["res_attrs"]

  @res_attrs.deleter
  def res_attrs(self):
    del self.operation.attributes["res_attrs"]

  @builtins.property
  def body(self) -> _ods_ir.Region:
    return self.regions[0]

@_ods_cext.register_op_adaptor(FuncOp)
class FuncOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.func"

  @builtins.property
  def sym_name(self) -> _ods_ir.StringAttr:
    return self.attributes["sym_name"]

  @builtins.property
  def function_type(self) -> _ods_ir.TypeAttr:
    return self.attributes["function_type"]

  @builtins.property
  def specifiers(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "specifiers" not in self.attributes:
      return None
    return self.attributes["specifiers"]

  @builtins.property
  def arg_attrs(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "arg_attrs" not in self.attributes:
      return None
    return self.attributes["arg_attrs"]

  @builtins.property
  def res_attrs(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "res_attrs" not in self.attributes:
      return None
    return self.attributes["res_attrs"]

def func(sym_name: _Union[str, _ods_ir.StringAttr], function_type: _Union[_Any, _ods_ir.TypeAttr], *, specifiers: _Optional[_Union[_Sequence[str], _ods_ir.ArrayAttr]] = None, arg_attrs: _Optional[_Union[_Any, _ods_ir.ArrayAttr]] = None, res_attrs: _Optional[_Union[_Any, _ods_ir.ArrayAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> FuncOp:
  return FuncOp(sym_name=sym_name, function_type=function_type, specifiers=specifiers, arg_attrs=arg_attrs, res_attrs=res_attrs, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class GetFieldOp(_ods_ir.OpView):
  r"""
  The `emitc.get_field` operation retrieves the lvalue of a
  named field from a given class instance.
  
  Example:
  
  ```mlir
  %0 = get_field @fieldName0 : !emitc.array<1xf32>
  ```
  """

  OPERATION_NAME = "emitc.get_field"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, field_name: _Union[str, _ods_ir.FlatSymbolRefAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["field_name"] = (field_name if (
    isinstance(field_name, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('FlatSymbolRefAttr')) else
      _ods_ir.AttrBuilder.get('FlatSymbolRefAttr')(field_name, context=_ods_context))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def field_name(self) -> _ods_ir.FlatSymbolRefAttr:
    return self.operation.attributes["field_name"]

  @field_name.setter
  def field_name(self, value: _ods_ir.FlatSymbolRefAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["field_name"] = value

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(GetFieldOp)
class GetFieldOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.get_field"

  @builtins.property
  def field_name(self) -> _ods_ir.FlatSymbolRefAttr:
    return self.attributes["field_name"]

def get_field(result: _ods_ir.Type, field_name: _Union[str, _ods_ir.FlatSymbolRefAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return GetFieldOp(result=result, field_name=field_name, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class GetGlobalOp(_ods_ir.OpView):
  r"""
  The `emitc.get_global` operation retrieves the lvalue of a
  named global variable. If the global variable is marked constant, assigning
  to that lvalue is undefined.
  
  Example:
  
  ```mlir
  %x = emitc.get_global @foo : !emitc.array<2xf32>
  %y = emitc.get_global @bar : !emitc.lvalue<i32>
  ```
  """

  OPERATION_NAME = "emitc.get_global"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, name: _Union[str, _ods_ir.FlatSymbolRefAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["name"] = (name if (
    isinstance(name, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('FlatSymbolRefAttr')) else
      _ods_ir.AttrBuilder.get('FlatSymbolRefAttr')(name, context=_ods_context))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def name(self) -> _ods_ir.FlatSymbolRefAttr:
    return self.operation.attributes["name"]

  @name.setter
  def name(self, value: _ods_ir.FlatSymbolRefAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["name"] = value

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(GetGlobalOp)
class GetGlobalOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.get_global"

  @builtins.property
  def name(self) -> _ods_ir.FlatSymbolRefAttr:
    return self.attributes["name"]

def get_global(result: _ods_ir.Type, name: _Union[str, _ods_ir.FlatSymbolRefAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return GetGlobalOp(result=result, name=name, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class GlobalOp(_ods_ir.OpView):
  r"""
  The `emitc.global` operation declares or defines a named global variable.
  The backing memory for the variable is allocated statically and described by
  the variable's type, which must be an EmitC type.
  Optionally, an `initial_value` can be provided.
  Internal linkage can be specified using the `static_specifier` unit attribute
  and external linkage can be specified using the `extern_specifier` unit attribute.
  Note that the default linkage without those two keywords depends on whether
  the target is C or C++ and whether the global variable is `const`.
  The global variable can also be marked constant using the `const_specifier`
  unit attribute. Writing to such constant global variables is
  undefined.
  
  The global variable can be accessed by using the `emitc.get_global` to
  retrieve the value for the global variable.
  
  Example:
  
  ```mlir
  // Global variable with an initial value.
  emitc.global @x : !emitc.array<2xf32> = dense<0.0>
  // Global variable with an initial values.
  emitc.global @x : !emitc.array<3xi32> = dense<[0, 1, 2]>
  // Global variable with an opaque initial value.
  emitc.global @x : !emitc.opaque<"char"> = #emitc.opaque<"CHAR_MIN">
  // External global variable
  emitc.global extern @x : !emitc.array<2xf32>
  // Constant global variable with internal linkage
  emitc.global static const @x : i32 = 0
  ```
  """

  OPERATION_NAME = "emitc.global"

  _ODS_REGIONS = (0, True)

  def __init__(self, sym_name: _Union[str, _ods_ir.StringAttr], type_: _Union[_ods_ir.Type, _ods_ir.TypeAttr], *, initial_value: _Optional[_Union[_Any, _ods_ir.Attribute]] = None, extern_specifier: _Optional[bool] = None, static_specifier: _Optional[bool] = None, const_specifier: _Optional[bool] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["sym_name"] = (sym_name if (
    isinstance(sym_name, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('SymbolNameAttr')) else
      _ods_ir.AttrBuilder.get('SymbolNameAttr')(sym_name, context=_ods_context))
    attributes["type"] = (type_ if (
    isinstance(type_, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('TypeAttr')) else
      _ods_ir.AttrBuilder.get('TypeAttr')(type_, context=_ods_context))
    if initial_value is not None: attributes["initial_value"] = (initial_value if (
        isinstance(initial_value, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('EmitC_OpaqueOrTypedAttr')) else
          _ods_ir.AttrBuilder.get('EmitC_OpaqueOrTypedAttr')(initial_value, context=_ods_context))
    if bool(extern_specifier): attributes["extern_specifier"] = _ods_ir.UnitAttr.get(
      _ods_get_default_loc_context(loc))
    if bool(static_specifier): attributes["static_specifier"] = _ods_ir.UnitAttr.get(
      _ods_get_default_loc_context(loc))
    if bool(const_specifier): attributes["const_specifier"] = _ods_ir.UnitAttr.get(
      _ods_get_default_loc_context(loc))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def sym_name(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["sym_name"]

  @sym_name.setter
  def sym_name(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["sym_name"] = value

  @builtins.property
  def type_(self) -> _ods_ir.TypeAttr:
    return self.operation.attributes["type"]

  @type_.setter
  def type_(self, value: _ods_ir.TypeAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["type"] = value

  @builtins.property
  def initial_value(self) -> _Optional[_ods_ir.Attribute]:
    if "initial_value" not in self.operation.attributes:
      return None
    return self.operation.attributes["initial_value"]

  @initial_value.setter
  def initial_value(self, value: _Optional[_ods_ir.Attribute]):
    if value is not None:
      self.operation.attributes["initial_value"] = value
    elif "initial_value" in self.operation.attributes:
      del self.operation.attributes["initial_value"]

  @initial_value.deleter
  def initial_value(self):
    del self.operation.attributes["initial_value"]

  @builtins.property
  def extern_specifier(self) -> bool:
    return "extern_specifier" in self.operation.attributes

  @extern_specifier.setter
  def extern_specifier(self, value):
    if bool(value):
      self.operation.attributes["extern_specifier"] = _ods_ir.UnitAttr.get()
    elif "extern_specifier" in self.operation.attributes:
      del self.operation.attributes["extern_specifier"]

  @extern_specifier.deleter
  def extern_specifier(self):
    del self.operation.attributes["extern_specifier"]

  @builtins.property
  def static_specifier(self) -> bool:
    return "static_specifier" in self.operation.attributes

  @static_specifier.setter
  def static_specifier(self, value):
    if bool(value):
      self.operation.attributes["static_specifier"] = _ods_ir.UnitAttr.get()
    elif "static_specifier" in self.operation.attributes:
      del self.operation.attributes["static_specifier"]

  @static_specifier.deleter
  def static_specifier(self):
    del self.operation.attributes["static_specifier"]

  @builtins.property
  def const_specifier(self) -> bool:
    return "const_specifier" in self.operation.attributes

  @const_specifier.setter
  def const_specifier(self, value):
    if bool(value):
      self.operation.attributes["const_specifier"] = _ods_ir.UnitAttr.get()
    elif "const_specifier" in self.operation.attributes:
      del self.operation.attributes["const_specifier"]

  @const_specifier.deleter
  def const_specifier(self):
    del self.operation.attributes["const_specifier"]

@_ods_cext.register_op_adaptor(GlobalOp)
class GlobalOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.global"

  @builtins.property
  def sym_name(self) -> _ods_ir.StringAttr:
    return self.attributes["sym_name"]

  @builtins.property
  def type_(self) -> _ods_ir.TypeAttr:
    return self.attributes["type"]

  @builtins.property
  def initial_value(self) -> _Optional[_ods_ir.Attribute]:
    if "initial_value" not in self.attributes:
      return None
    return self.attributes["initial_value"]

  @builtins.property
  def extern_specifier(self) -> bool:
    return "extern_specifier" in self.attributes

  @builtins.property
  def static_specifier(self) -> bool:
    return "static_specifier" in self.attributes

  @builtins.property
  def const_specifier(self) -> bool:
    return "const_specifier" in self.attributes

def global_(sym_name: _Union[str, _ods_ir.StringAttr], type_: _Union[_ods_ir.Type, _ods_ir.TypeAttr], *, initial_value: _Optional[_Union[_Any, _ods_ir.Attribute]] = None, extern_specifier: _Optional[bool] = None, static_specifier: _Optional[bool] = None, const_specifier: _Optional[bool] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> GlobalOp:
  return GlobalOp(sym_name=sym_name, type_=type_, initial_value=initial_value, extern_specifier=extern_specifier, static_specifier=static_specifier, const_specifier=const_specifier, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class IfOp(_ods_ir.OpView):
  r"""
  The `emitc.if` operation represents an if-then-else construct for
  conditionally executing two regions of code. The operand to an if operation
  is a boolean value. For example:
  
  ```mlir
  emitc.if %b  {
    ...
  } else {
    ...
  }
  ```
  
  The "then" region has exactly 1 block. The "else" region may have 0 or 1
  blocks. The blocks are always terminated with `emitc.yield`, which can be
  left out to be inserted implicitly. This operation doesn't produce any
  results.
  """

  OPERATION_NAME = "emitc.if"

  _ODS_REGIONS = (2, True)

  def __init__(self, condition: _ods_ir.Value[_ods_ir.IntegerType], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(condition)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def condition(self) -> _ods_ir.Value[_ods_ir.IntegerType]:
    return self.operation.operands[0]

  @builtins.property
  def thenRegion(self) -> _ods_ir.Region:
    return self.regions[0]

  @builtins.property
  def elseRegion(self) -> _ods_ir.Region:
    return self.regions[1]

@_ods_cext.register_op_adaptor(IfOp)
class IfOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.if"

  @builtins.property
  def condition(self) -> _ods_ir.Value[_ods_ir.IntegerType]:
    return self.operands[0]

def if_(condition: _ods_ir.Value[_ods_ir.IntegerType], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> IfOp:
  return IfOp(condition=condition, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class IncludeOp(_ods_ir.OpView):
  r"""
  The `emitc.include` operation allows to define a source file inclusion via the
  `#include` directive.
  
  Example:
  
  ```mlir
  // Custom form defining the inclusion of `<myheader>`.
  emitc.include <"myheader.h">
  
  // Generic form of the same operation.
  "emitc.include" (){include = "myheader.h", is_standard_include} : () -> ()
  
  // Custom form defining the inclusion of `"myheader"`.
  emitc.include "myheader.h"
  
  // Generic form of the same operation.
  "emitc.include" (){include = "myheader.h"} : () -> ()
  ```
  """

  OPERATION_NAME = "emitc.include"

  _ODS_REGIONS = (0, True)

  def __init__(self, include: _Union[str, _ods_ir.StringAttr], *, is_standard_include: _Optional[bool] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["include"] = (include if (
    isinstance(include, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('StrAttr')) else
      _ods_ir.AttrBuilder.get('StrAttr')(include, context=_ods_context))
    if bool(is_standard_include): attributes["is_standard_include"] = _ods_ir.UnitAttr.get(
      _ods_get_default_loc_context(loc))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def include(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["include"]

  @include.setter
  def include(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["include"] = value

  @builtins.property
  def is_standard_include(self) -> bool:
    return "is_standard_include" in self.operation.attributes

  @is_standard_include.setter
  def is_standard_include(self, value):
    if bool(value):
      self.operation.attributes["is_standard_include"] = _ods_ir.UnitAttr.get()
    elif "is_standard_include" in self.operation.attributes:
      del self.operation.attributes["is_standard_include"]

  @is_standard_include.deleter
  def is_standard_include(self):
    del self.operation.attributes["is_standard_include"]

@_ods_cext.register_op_adaptor(IncludeOp)
class IncludeOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.include"

  @builtins.property
  def include(self) -> _ods_ir.StringAttr:
    return self.attributes["include"]

  @builtins.property
  def is_standard_include(self) -> bool:
    return "is_standard_include" in self.attributes

def include(include: _Union[str, _ods_ir.StringAttr], *, is_standard_include: _Optional[bool] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> IncludeOp:
  return IncludeOp(include=include, is_standard_include=is_standard_include, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class LiteralOp(_ods_ir.OpView):
  r"""
  The `emitc.literal` operation produces an SSA value equal to some constant
  specified by an attribute.
  
  Example:
  
  ```mlir
  %p0 = emitc.literal "M_PI" : f32
  %1 = "emitc.add" (%arg0, %p0) : (f32, f32) -> f32
  ```
  ```c++
  // Code emitted for the operation above.
  float v2 = v1 + M_PI;
  ```
  """

  OPERATION_NAME = "emitc.literal"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, value: _Union[str, _ods_ir.StringAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["value"] = (value if (
    isinstance(value, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('StrAttr')) else
      _ods_ir.AttrBuilder.get('StrAttr')(value, context=_ods_context))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def value(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["value"]

  @value.setter
  def value(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["value"] = value

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(LiteralOp)
class LiteralOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.literal"

  @builtins.property
  def value(self) -> _ods_ir.StringAttr:
    return self.attributes["value"]

def literal(result: _ods_ir.Type, value: _Union[str, _ods_ir.StringAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return LiteralOp(result=result, value=value, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class LoadOp(_ods_ir.OpView):
  r"""
  This operation loads the content of a modifiable lvalue into an SSA value. 
  Modifications of the lvalue executed after the load are not observable on 
  the produced value.
  
  Example:
  
  ```mlir
  %1 = emitc.load %0 : !emitc.lvalue<i32>
  ```
  ```c++
  // Code emitted for the operation above.
  int32_t v2 = v1;
  ```
  """

  OPERATION_NAME = "emitc.load"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, operand: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(operand)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def operand(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(LoadOp)
class LoadOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.load"

  @builtins.property
  def operand(self) -> _ods_ir.Value:
    return self.operands[0]

def load(result: _ods_ir.Type, operand: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return LoadOp(result=result, operand=operand, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class LogicalAndOp(_ods_ir.OpView):
  r"""
  With the `emitc.logical_and` operation the logical operator && (and) can
  be applied.
  
  Example:
  
  ```mlir
  %0 = emitc.logical_and %arg0, %arg1 : i32, i32
  ```
  ```c++
  // Code emitted for the operation above.
  bool v3 = v1 && v2;
  ```
  """

  OPERATION_NAME = "emitc.logical_and"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(lhs)
    operands.append(rhs)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operation.operands[1]

@_ods_cext.register_op_adaptor(LogicalAndOp)
class LogicalAndOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.logical_and"

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operands[1]

def logical_and(result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult[_ods_ir.IntegerType]:
  return LogicalAndOp(result=result, lhs=lhs, rhs=rhs, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class LogicalNotOp(_ods_ir.OpView):
  r"""
  With the `emitc.logical_not` operation the logical operator ! (negation) can
  be applied.
  
  Example:
  
  ```mlir
  %0 = emitc.logical_not %arg0 : i32
  ```
  ```c++
  // Code emitted for the operation above.
  bool v2 = !v1;
  ```
  """

  OPERATION_NAME = "emitc.logical_not"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(_gen_arg_0)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

@_ods_cext.register_op_adaptor(LogicalNotOp)
class LogicalNotOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.logical_not"

def logical_not(result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult[_ods_ir.IntegerType]:
  return LogicalNotOp(result=result, _gen_arg_0=_gen_arg_0, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class LogicalOrOp(_ods_ir.OpView):
  r"""
  With the `emitc.logical_or` operation the logical operator || (inclusive or)
  can be applied.
  
  Example:
  
  ```mlir
  %0 = emitc.logical_or %arg0, %arg1 : i32, i32
  ```
  ```c++
  // Code emitted for the operation above.
  bool v3 = v1 || v2;
  ```
  """

  OPERATION_NAME = "emitc.logical_or"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(lhs)
    operands.append(rhs)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operation.operands[1]

@_ods_cext.register_op_adaptor(LogicalOrOp)
class LogicalOrOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.logical_or"

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operands[1]

def logical_or(result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult[_ods_ir.IntegerType]:
  return LogicalOrOp(result=result, lhs=lhs, rhs=rhs, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class MemberOfPtrOp(_ods_ir.OpView):
  r"""
  With the `emitc.member_of_ptr` operation the member access operator `->`
  can be applied.
  
  Example:
  
  ```mlir
  %0 = "emitc.member_of_ptr" (%arg0) {member = "a"}
      : (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>)
      -> !emitc.lvalue<i32>
  %1 = "emitc.member_of_ptr" (%arg0) {member = "b"}
      : (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>)
      -> !emitc.array<2xi32>
  ```
  """

  OPERATION_NAME = "emitc.member_of_ptr"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, member: _Union[str, _ods_ir.StringAttr], operand: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(operand)
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["member"] = (member if (
    isinstance(member, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('StrAttr')) else
      _ods_ir.AttrBuilder.get('StrAttr')(member, context=_ods_context))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def operand(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def member(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["member"]

  @member.setter
  def member(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["member"] = value

@_ods_cext.register_op_adaptor(MemberOfPtrOp)
class MemberOfPtrOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.member_of_ptr"

  @builtins.property
  def operand(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def member(self) -> _ods_ir.StringAttr:
    return self.attributes["member"]

def member_of_ptr(result: _ods_ir.Type, member: _Union[str, _ods_ir.StringAttr], operand: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return MemberOfPtrOp(result=result, member=member, operand=operand, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class MemberOp(_ods_ir.OpView):
  r"""
  With the `emitc.member` operation the member access operator `.` can be
  applied.
  
  Example:
  
  ```mlir
  %0 = "emitc.member" (%arg0) {member = "a"}
      : (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.lvalue<i32>
  %1 = "emitc.member" (%arg0) {member = "b"}
      : (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.array<2xi32>
  ```
  """

  OPERATION_NAME = "emitc.member"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, member: _Union[str, _ods_ir.StringAttr], operand: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(operand)
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["member"] = (member if (
    isinstance(member, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('StrAttr')) else
      _ods_ir.AttrBuilder.get('StrAttr')(member, context=_ods_context))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def operand(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def member(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["member"]

  @member.setter
  def member(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["member"] = value

@_ods_cext.register_op_adaptor(MemberOp)
class MemberOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.member"

  @builtins.property
  def operand(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def member(self) -> _ods_ir.StringAttr:
    return self.attributes["member"]

def member(result: _ods_ir.Type, member: _Union[str, _ods_ir.StringAttr], operand: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return MemberOp(result=result, member=member, operand=operand, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class MulOp(_ods_ir.OpView):
  r"""
  With the `emitc.mul` operation the arithmetic operator * (multiplication) can
  be applied.
  
  Example:
  
  ```mlir
  // Custom form of the multiplication operation.
  %0 = emitc.mul %arg0, %arg1 : (i32, i32) -> i32
  %1 = emitc.mul %arg2, %arg3 : (f32, f32) -> f32
  ```
  ```c++
  // Code emitted for the operations above.
  int32_t v5 = v1 * v2;
  float v6 = v3 * v4;
  ```
  """

  OPERATION_NAME = "emitc.mul"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, _gen_arg_1: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(_gen_arg_0)
    operands.append(_gen_arg_1)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

@_ods_cext.register_op_adaptor(MulOp)
class MulOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.mul"

def mul(result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, _gen_arg_1: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return MulOp(result=result, _gen_arg_0=_gen_arg_0, _gen_arg_1=_gen_arg_1, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class RemOp(_ods_ir.OpView):
  r"""
  With the `emitc.rem` operation the arithmetic operator % (remainder) can
  be applied.
  
  Example:
  
  ```mlir
  // Custom form of the remainder operation.
  %0 = emitc.rem %arg0, %arg1 : (i32, i32) -> i32
  ```
  ```c++
  // Code emitted for the operation above.
  int32_t v5 = v1 % v2;
  ```
  """

  OPERATION_NAME = "emitc.rem"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, _gen_arg_1: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(_gen_arg_0)
    operands.append(_gen_arg_1)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

@_ods_cext.register_op_adaptor(RemOp)
class RemOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.rem"

def rem(result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, _gen_arg_1: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return RemOp(result=result, _gen_arg_0=_gen_arg_0, _gen_arg_1=_gen_arg_1, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class ReturnOp(_ods_ir.OpView):
  r"""
  The `emitc.return` operation represents a return operation within a function.
  The operation takes zero or exactly one operand and produces no results.
  The operand number and type must match the signature of the function
  that contains the operation.
  
  Example:
  
  ```mlir
  emitc.func @foo() -> (i32) {
    ...
    emitc.return %0 : i32
  }
  ```
  """

  OPERATION_NAME = "emitc.return"

  _ODS_REGIONS = (0, True)

  def __init__(self, *, operand: _Optional[_ods_ir.Value] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    if operand is not None: operands.append(operand)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def operand(self) -> _Optional[_ods_ir.Value]:
    return None if len(self.operation.operands) < 1 else self.operation.operands[0]

@_ods_cext.register_op_adaptor(ReturnOp)
class ReturnOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.return"

  @builtins.property
  def operand(self) -> _Optional[_ods_ir.Value]:
    return None if len(self.operands) < 1 else self.operands[0]

def return_(*, operand: _Optional[_ods_ir.Value] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> ReturnOp:
  return ReturnOp(operand=operand, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class SubOp(_ods_ir.OpView):
  r"""
  With the `emitc.sub` operation the arithmetic operator - (subtraction) can
  be applied.
  
  Example:
  
  ```mlir
  // Custom form of the substraction operation.
  %0 = emitc.sub %arg0, %arg1 : (i32, i32) -> i32
  %1 = emitc.sub %arg2, %arg3 : (!emitc.ptr<f32>, i32) -> !emitc.ptr<f32>
  %2 = emitc.sub %arg4, %arg5 : (!emitc.ptr<i32>, !emitc.ptr<i32>)
      -> !emitc.ptrdiff_t
  ```
  ```c++
  // Code emitted for the operations above.
  int32_t v7 = v1 - v2;
  float* v8 = v3 - v4;
  ptrdiff_t v9 = v5 - v6;
  ```
  """

  OPERATION_NAME = "emitc.sub"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(lhs)
    operands.append(rhs)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operation.operands[1]

@_ods_cext.register_op_adaptor(SubOp)
class SubOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.sub"

  @builtins.property
  def lhs(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def rhs(self) -> _ods_ir.Value:
    return self.operands[1]

def sub(result: _ods_ir.Type, lhs: _ods_ir.Value, rhs: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return SubOp(result=result, lhs=lhs, rhs=rhs, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class SubscriptOp(_ods_ir.OpView):
  r"""
  With the `emitc.subscript` operation the subscript operator `[]` can be applied
  to variables or arguments of array, pointer and opaque type.
  
  Example:
  
  ```mlir
  %i = index.constant 1
  %j = index.constant 7
  %0 = emitc.subscript %arg0[%i, %j] : (!emitc.array<4x8xf32>, index, index)
         -> !emitc.lvalue<f32>
  %1 = emitc.subscript %arg1[%i] : (!emitc.ptr<i32>, index)
         -> !emitc.lvalue<i32>
  ```
  """

  OPERATION_NAME = "emitc.subscript"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, value: _ods_ir.Value, indices: _Sequence[_ods_ir.Value], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(value)
    operands.extend(_get_op_results_or_values(indices))
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def value(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def indices(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operation.operands) - 2 + 1
    return self.operation.operands[1:1 + _ods_variadic_group_length]

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(SubscriptOp)
class SubscriptOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.subscript"

  @builtins.property
  def value(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def indices(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operands) - 2 + 1
    return self.operands[1:1 + _ods_variadic_group_length]

def subscript(result: _ods_ir.Type, value: _ods_ir.Value, indices: _Sequence[_ods_ir.Value], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return SubscriptOp(result=result, value=value, indices=indices, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class SwitchOp(_ods_ir.OpView):
  r"""
  The `emitc.switch` is a control-flow operation that branches to one of
  the given regions based on the values of the argument and the cases.
  The operand to a switch operation is a opaque, integral or pointer
  wide types.
  
  The operation always has a "default" region and any number of case regions
  denoted by integer constants. Control-flow transfers to the case region
  whose constant value equals the value of the argument. If the argument does
  not equal any of the case values, control-flow transfer to the "default"
  region.
  
  The operation does not return any value. Moreover, case regions must be
  explicitly terminated using the `emitc.yield` operation. Default region is
  yielded implicitly.
  
  Example:
  
  ```mlir
  // Example:
  emitc.switch %0 : i32
  case 2 {
    %1 = emitc.call_opaque "func_b" () : () -> i32
    emitc.yield
  }
  case 5 {
    %2 = emitc.call_opaque "func_a" () : () -> i32
    emitc.yield
  }
  default {
    %3 = "emitc.constant"(){value = 42.0 : f32} : () -> f32
    emitc.call_opaque "func2" (%3) : (f32) -> ()
  }
  ```
  ```c++
  // Code emitted for the operations above.
  switch (v1) {
  case 2: {
    int32_t v2 = func_b();
    break;
  }
  case 5: {
    int32_t v3 = func_a();
    break;
  }
  default: {
    float v4 = 4.200000000e+01f;
    func2(v4);
    break;
  }
  }
  ```
  """

  OPERATION_NAME = "emitc.switch"

  _ODS_REGIONS = (1, False)

  def __init__(self, arg: _ods_ir.Value, cases: _Union[_Sequence[int], _ods_ir.DenseI64ArrayAttr], num_caseRegions: int, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(arg)
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["cases"] = (cases if (
    isinstance(cases, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('DenseI64ArrayAttr')) else
      _ods_ir.AttrBuilder.get('DenseI64ArrayAttr')(cases, context=_ods_context))
    results = []
    _ods_successors = None
    regions = 1 + num_caseRegions
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def arg(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def cases(self) -> _ods_ir.DenseI64ArrayAttr:
    return self.operation.attributes["cases"]

  @cases.setter
  def cases(self, value: _ods_ir.DenseI64ArrayAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["cases"] = value

  @builtins.property
  def defaultRegion(self) -> _ods_ir.Region:
    return self.regions[0]

  @builtins.property
  def caseRegions(self) -> _ods_ir.RegionSequence:
    return self.regions[1:]

@_ods_cext.register_op_adaptor(SwitchOp)
class SwitchOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.switch"

  @builtins.property
  def arg(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def cases(self) -> _ods_ir.DenseI64ArrayAttr:
    return self.attributes["cases"]

def switch(arg: _ods_ir.Value, cases: _Union[_Sequence[int], _ods_ir.DenseI64ArrayAttr], num_case_regions: int, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> SwitchOp:
  return SwitchOp(arg=arg, cases=cases, num_caseRegions=num_case_regions, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class UnaryMinusOp(_ods_ir.OpView):
  r"""
  With the `emitc.unary_minus` operation the unary operator - (minus) can be
  applied.
  
  Example:
  
  ```mlir
  %0 = emitc.unary_minus %arg0 : (i32) -> i32
  ```
  ```c++
  // Code emitted for the operation above.
  int32_t v2 = -v1;
  ```
  """

  OPERATION_NAME = "emitc.unary_minus"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(_gen_arg_0)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

@_ods_cext.register_op_adaptor(UnaryMinusOp)
class UnaryMinusOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.unary_minus"

def unary_minus(result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return UnaryMinusOp(result=result, _gen_arg_0=_gen_arg_0, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class UnaryPlusOp(_ods_ir.OpView):
  r"""
  With the `emitc.unary_plus` operation the unary operator + (plus) can be
  applied.
  
  Example:
  
  ```mlir
  %0 = emitc.unary_plus %arg0 : (i32) -> i32
  ```
  ```c++
  // Code emitted for the operation above.
  int32_t v2 = +v1;
  ```
  """

  OPERATION_NAME = "emitc.unary_plus"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(_gen_arg_0)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

@_ods_cext.register_op_adaptor(UnaryPlusOp)
class UnaryPlusOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.unary_plus"

def unary_plus(result: _ods_ir.Type, _gen_arg_0: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return UnaryPlusOp(result=result, _gen_arg_0=_gen_arg_0, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class VariableOp(_ods_ir.OpView):
  r"""
  The `emitc.variable` operation produces an SSA value equal to some value
  specified by an attribute. This can be used to form simple integer and
  floating point variables, as well as more exotic things like tensor
  variables. The `emitc.variable` operation also supports the EmitC opaque
  attribute and the EmitC opaque type. If further supports the EmitC
  pointer type, whereas folding is not supported.
  The `emitc.variable` is emitted as a C/C++ local variable.
  
  Example:
  
  ```mlir
  // Integer variable
  %0 = "emitc.variable"(){value = 42 : i32} : () -> !emitc.lvalue<i32>
  
  // Variable emitted as `int32_t* = NULL;`
  %1 = "emitc.variable"() {value = #emitc.opaque<"NULL">} 
    : () -> !emitc.lvalue<!emitc.ptr<!emitc.opaque<"int32_t">>>
  ```
  
  Since folding is not supported, it can be used with pointers.
  As an example, it is valid to create pointers to `variable` operations
  by using `apply` operations and pass these to a `call` operation.
  ```mlir
  %0 = "emitc.variable"() {value = 0 : i32} : () -> !emitc.lvalue<i32>
  %1 = "emitc.variable"() {value = 0 : i32} : () -> !emitc.lvalue<i32>
  %2 = emitc.apply "&"(%0) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
  %3 = emitc.apply "&"(%1) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
  emitc.call_opaque "write"(%2, %3)
    : (!emitc.ptr<i32>, !emitc.ptr<i32>) -> ()
  ```
  """

  OPERATION_NAME = "emitc.variable"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, value: _Union[_Any, _ods_ir.Attribute], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["value"] = (value if (
    isinstance(value, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('EmitC_OpaqueOrTypedAttr')) else
      _ods_ir.AttrBuilder.get('EmitC_OpaqueOrTypedAttr')(value, context=_ods_context))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def value(self) -> _ods_ir.Attribute:
    return self.operation.attributes["value"]

  @value.setter
  def value(self, value: _ods_ir.Attribute):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["value"] = value

@_ods_cext.register_op_adaptor(VariableOp)
class VariableOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.variable"

  @builtins.property
  def value(self) -> _ods_ir.Attribute:
    return self.attributes["value"]

def variable(result: _ods_ir.Type, value: _Union[_Any, _ods_ir.Attribute], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return VariableOp(result=result, value=value, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class VerbatimOp(_ods_ir.OpView):
  r"""
  The `emitc.verbatim` operation produces no results and the value is emitted as is
  followed by a line break  ('\n' character) during translation.
  
  Note: Use with caution. This operation can have arbitrary effects on the
  semantics of the emitted code. Use semantically more meaningful operations
  whenever possible. Additionally this op is *NOT* intended to be used to
  inject large snippets of code.
  
  This operation can be used in situations where a more suitable operation is
  not yet implemented in the dialect or where preprocessor directives
  interfere with the structure of the code. One example of this is to declare
  the linkage of external symbols to make the generated code usable in both C
  and C++ contexts:
  
  ```c++
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  ...
  
  #ifdef __cplusplus
  }
  #endif
  ```
  
  If the `emitc.verbatim` op has operands, then the `value` is interpreted as
  format string, where `{}` is a placeholder for an operand in their order.
  For example, `emitc.verbatim "#pragma my src={} dst={}" %src, %dest : i32, i32`
  would be emitted as `#pragma my src=a dst=b` if `%src` became `a` and
  `%dest` became `b` in the C code.
  `{{` in the format string is interpreted as a single `{` and doesn't introduce
  a placeholder.
  
  Example:
  
  ```mlir
  emitc.verbatim "typedef float f32;"
  emitc.verbatim "#pragma my var={} property" args %arg : f32
  ```
  ```c++
  // Code emitted for the operation above.
  typedef float f32;
  #pragma my var=v1 property
  ```
  """

  OPERATION_NAME = "emitc.verbatim"

  _ODS_REGIONS = (0, True)

  def __init__(self, value: _Union[str, _ods_ir.StringAttr], fmtArgs: _Sequence[_ods_ir.Value], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.extend(_get_op_results_or_values(fmtArgs))
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["value"] = (value if (
    isinstance(value, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('StrAttr')) else
      _ods_ir.AttrBuilder.get('StrAttr')(value, context=_ods_context))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def fmtArgs(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operation.operands) - 1 + 1
    return self.operation.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def value(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["value"]

  @value.setter
  def value(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["value"] = value

@_ods_cext.register_op_adaptor(VerbatimOp)
class VerbatimOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.verbatim"

  @builtins.property
  def fmtArgs(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operands) - 1 + 1
    return self.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def value(self) -> _ods_ir.StringAttr:
    return self.attributes["value"]

def verbatim(value: _Union[str, _ods_ir.StringAttr], fmt_args: _Sequence[_ods_ir.Value], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> VerbatimOp:
  return VerbatimOp(value=value, fmtArgs=fmt_args, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class YieldOp(_ods_ir.OpView):
  r"""
  The `emitc.yield` terminates its parent EmitC op's region, optionally yielding
  an SSA value. The semantics of how the values are yielded is defined by the
  parent operation.
  If `emitc.yield` has an operand, the operand must match the parent operation's
  result. If the parent operation defines no values, then the `emitc.yield`
  may be left out in the custom syntax and the builders will insert one
  implicitly. Otherwise, it has to be present in the syntax to indicate which
  value is yielded.
  """

  OPERATION_NAME = "emitc.yield"

  _ODS_REGIONS = (0, True)

  def __init__(self, *, result: _Optional[_ods_ir.Value] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    if result is not None: operands.append(result)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def result(self) -> _Optional[_ods_ir.Value]:
    return None if len(self.operation.operands) < 1 else self.operation.operands[0]

@_ods_cext.register_op_adaptor(YieldOp)
class YieldOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "emitc.yield"

  @builtins.property
  def result(self) -> _Optional[_ods_ir.Value]:
    return None if len(self.operands) < 1 else self.operands[0]

def yield_(*, result: _Optional[_ods_ir.Value] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> YieldOp:
  return YieldOp(result=result, loc=loc, ip=ip)
