parameters: (operand_kind, capability_mapping)
return_statement: return kind_name, case_defs + '\n\n' + enum_attr
docstring: Generates the TableGen EnumAttr definition for the given operand kind.
  
    Returns:
      - The operand kind's name
      - A string containing the TableGen EnumAttr definition
docstring_summary: Generates the TableGen EnumAttr definition for the given operand kind.
docstring_tokens: Generates the TableGen EnumAttr definition for the given operand kind .
function: def gen_operand_kind_enum_attr(operand_kind, capability_mapping):
    """Generates the TableGen EnumAttr definition for the given operand kind.
  
    Returns:
      - The operand kind's name
      - A string containing the TableGen EnumAttr definition
    """
    if 'enumerants' not in operand_kind:
      return '', ''
  
    # Returns a symbol for the given case in the given kind. This function
    # handles Dim specially to avoid having numbers as the start of symbols,
    # which does not play well with C++ and the MLIR parser.
    def get_case_symbol(kind_name, case_name):
      if kind_name == 'Dim':
        if case_name == '1D' or case_name == '2D' or case_name == '3D':
          return 'Dim{}'.format(case_name)
      return case_name
  
    kind_name = operand_kind['kind']
    is_bit_enum = operand_kind['category'] == 'BitEnum'
    kind_category = 'Bit' if is_bit_enum else 'I32'
    kind_acronym = ''.join([c for c in kind_name if c >= 'A' and c <= 'Z'])
  
    name_to_case_dict = {}
    for case in operand_kind['enumerants']:
      name_to_case_dict[case['enumerant']] = case
  
    if kind_name == 'Capability':
      # Special treatment for capability cases: we need to sort them topologically
      # because a capability can refer to another via the 'implies' field.
      kind_cases = toposort_capabilities(operand_kind['enumerants'],
                                         capability_mapping)
    else:
      kind_cases = [(case['enumerant'], case['value'])
                    for case in operand_kind['enumerants']]
      kind_cases, _ = uniquify_enum_cases(kind_cases)
    max_len = max([len(symbol) for (symbol, _) in kind_cases])
  
    # Generate the definition for each enum case
    fmt_str = 'def SPV_{acronym}_{case} {colon:>{offset}} '\
              '{category}EnumAttrCase<"{symbol}", {value}>{avail}'
    case_defs = []
    for case in kind_cases:
      avail = get_availability_spec(name_to_case_dict[case[0]],
                                    capability_mapping,
                                    False, kind_name == 'Capability')
      case_def = fmt_str.format(
          category=kind_category,
          acronym=kind_acronym,
          case=case[0],
          symbol=get_case_symbol(kind_name, case[0]),
          value=case[1],
          avail=' {{\n  {}\n}}'.format(avail) if avail else ';',
          colon=':',
          offset=(max_len + 1 - len(case[0])))
      case_defs.append(case_def)
    case_defs = '\n'.join(case_defs)
  
    # Generate the list of enum case names
    fmt_str = 'SPV_{acronym}_{symbol}';
    case_names = [fmt_str.format(acronym=kind_acronym,symbol=case[0])
                  for case in kind_cases]
  
    # Split them into sublists and concatenate into multiple lines
    case_names = split_list_into_sublists(case_names)
    case_names = ['{:6}'.format('') + ', '.join(sublist)
                  for sublist in case_names]
    case_names = ',\n'.join(case_names)
  
    # Generate the enum attribute definition
    enum_attr = '''def SPV_{name}Attr :
      SPV_{category}EnumAttr<"{name}", "valid SPIR-V {name}", [
  {cases}
      ]>;'''.format(
            name=kind_name, category=kind_category, cases=case_names)
    return kind_name, case_defs + '\n\n' + enum_attr
function_tokens: def gen_operand_kind_enum_attr ( operand_kind , capability_mapping ) : if 'enumerants' not in operand_kind : return '' , '' # Returns a symbol for the given case in the given kind. This function # handles Dim specially to avoid having numbers as the start of symbols, # which does not play well with C++ and the MLIR parser. def get_case_symbol ( kind_name , case_name ) : if kind_name == 'Dim' : if case_name == '1D' or case_name == '2D' or case_name == '3D' : return 'Dim{}' . format ( case_name ) return case_name kind_name = operand_kind [ 'kind' ] is_bit_enum = operand_kind [ 'category' ] == 'BitEnum' kind_category = 'Bit' if is_bit_enum else 'I32' kind_acronym = '' . join ( [ c for c in kind_name if c >= 'A' and c <= 'Z' ] ) name_to_case_dict = { } for case in operand_kind [ 'enumerants' ] : name_to_case_dict [ case [ 'enumerant' ] ] = case if kind_name == 'Capability' : # Special treatment for capability cases: we need to sort them topologically # because a capability can refer to another via the 'implies' field. kind_cases = toposort_capabilities ( operand_kind [ 'enumerants' ] , capability_mapping ) else : kind_cases = [ ( case [ 'enumerant' ] , case [ 'value' ] ) for case in operand_kind [ 'enumerants' ] ] kind_cases , _ = uniquify_enum_cases ( kind_cases ) max_len = max ( [ len ( symbol ) for ( symbol , _ ) in kind_cases ] ) # Generate the definition for each enum case fmt_str = 'def SPV_{acronym}_{case} {colon:>{offset}} ' '{category}EnumAttrCase<"{symbol}", {value}>{avail}' case_defs = [ ] for case in kind_cases : avail = get_availability_spec ( name_to_case_dict [ case [ 0 ] ] , capability_mapping , False , kind_name == 'Capability' ) case_def = fmt_str . format ( category = kind_category , acronym = kind_acronym , case = case [ 0 ] , symbol = get_case_symbol ( kind_name , case [ 0 ] ) , value = case [ 1 ] , avail = ' {{\n  {}\n}}' . format ( avail ) if avail else ';' , colon = ':' , offset = ( max_len + 1 - len ( case [ 0 ] ) ) ) case_defs . append ( case_def ) case_defs = '\n' . join ( case_defs ) # Generate the list of enum case names fmt_str = 'SPV_{acronym}_{symbol}' case_names = [ fmt_str . format ( acronym = kind_acronym , symbol = case [ 0 ] ) for case in kind_cases ] # Split them into sublists and concatenate into multiple lines case_names = split_list_into_sublists ( case_names ) case_names = [ '{:6}' . format ( '' ) + ', ' . join ( sublist ) for sublist in case_names ] case_names = ',\n' . join ( case_names ) # Generate the enum attribute definition enum_attr = '''def SPV_{name}Attr :
      SPV_{category}EnumAttr<"{name}", "valid SPIR-V {name}", [
  {cases}
      ]>;''' . format ( name = kind_name , category = kind_category , cases = case_names ) return kind_name , case_defs + '\n\n' + enum_attr