o
    C2h                     @   s@  d Z ddlZddlZddlZddlmZ ddlmZmZmZ ddl	m
Z
mZmZ eeeejeeeejB eeedB ZedZdd	d
ddddZi fddZdd Zdd ZG dd deZG dd deZG dd deZe ZG dd de
eeeZG dd deZG dd  d e
eeZ G d!d" d"e Z!G d#d$ d$e
eeZ"G d%d& d&eZ#G d'd( d(e Z$G d)d* d*Z%G d+d, d,e Z&G d-d. d.e eeZ'G d/d0 d0e'Z(G d1d2 d2e)Z*G d3d4 d4e*Z+G d5d6 d6e'Z,G d7d8 d8e*Z-G d9d: d:e Z.G d;d< d<e.Z/G d=d> d>e.Z0G d?d@ d@e Z1G dAdB dBeZ2dS )Cz_
Classes that are LLVM values: Value, Constant...
Instructions are in the instructions module.
    N)MappingProxyType)valuestypes_utils)_StrCaching_StringReferenceCaching_HasMetadataz !#$%&'()*+,-./:;<=>?@[]^_`{|}~z[-a-zA-Z$._][-a-zA-Z$._0-9]*$gtlteqnegele)><==!=z>=z<=c                    st   t | tr	|  } t | ttfsJ  s,tdD ]}|tv r%t| |< qd|  |< q fdd| D }d|S )z
    Escape the given bytestring for safe use as a LLVM array constant.
    Any unicode string input is first encoded with utf8 into bytes.
       z\%02xc                    s   g | ]} | qS  r   ).0ch_mapr   f/var/www/html/alexa/alex_system/speach-to-text/venv/lib/python3.10/site-packages/llvmlite/ir/values.py
<listcomp>/   s    z"_escape_string.<locals>.<listcomp> )	
isinstancestrencodebytes	bytearrayrange_VALID_CHARSchrjoin)textr   r   bufr   r   r   _escape_string   s   

r'   c                        fdd}|S )Nc                    s   t |  fdd}|S )Nc                    sJ   | j |j krtd| j |j f d | j |  |j | }t| j |S )N,Operands must be the same type, got (%s, %s)z{0} ({1} {2}, {3} {4}))type
ValueErrorformatget_referenceFormattedConstant)lhsrhsfmtopnamer   r   wrapped5   s   


z%_binop.<locals>.wrap.<locals>.wrapped	functoolswrapsfnr4   r2   r   r   wrap4   s   
z_binop.<locals>.wrapr   r3   r:   r   r2   r   _binop3   s   r<   c                    r(   )Nc                    s   t   fdd}|S )Nc                    s8    | | || j kr| S d| j |  |}t||S )Nz{0} ({1} {2} to {3}))r*   r,   r-   r.   )selftypop)r9   r3   r   r   r4   F   s   



z&_castop.<locals>.wrap.<locals>.wrappedr5   r8   r2   )r9   r   r:   E   s   	z_castop.<locals>.wrapr   r;   r   r2   r   _castopD   s   r@   c                   @   s8  e Zd ZdZeddd Zeddd Zedd	d
 Zeddd Zeddd Z	eddd Z
eddd Zeddd Zeddd Zeddd Zed d!d" Zed#d$d% Zed&d'd( Zed)d*d+ Zed,d-d. Zed/d0d1 Zed2d3d4 Zed5d6d7 Zd8d9 Zd:d; Zd<d= Zd>d? Zd@dA ZdBdC ZdDdE ZdFdG ZedHdIdJ Z edKdLdM Z!edNdOdP Z"edQdRdS Z#edTdUdV Z$edWdXdY Z%edZd[d\ Z&ed]d^d_ Z'ed`dadb Z(edcddde Z)edfdgdh Z*edidjdk Z+dldm Z,dnS )o_ConstOpMixinzQ
    A mixin defining constant operations, for use in constant-like classes.
    shlc                 C      dS )z<
        Left integer shift:
            lhs << rhs
        Nr   r=   otherr   r   r   rB   ]       z_ConstOpMixin.shllshrc                 C   rC   )zP
        Logical (unsigned) right integer shift:
            lhs >> rhs
        Nr   rD   r   r   r   rG   d   rF   z_ConstOpMixin.lshrashrc                 C   rC   )zQ
        Arithmetic (signed) right integer shift:
            lhs >> rhs
        Nr   rD   r   r   r   rH   k   rF   z_ConstOpMixin.ashraddc                 C   rC   )z9
        Integer addition:
            lhs + rhs
        Nr   rD   r   r   r   rI   r   rF   z_ConstOpMixin.addfaddc                 C   rC   )z@
        Floating-point addition:
            lhs + rhs
        Nr   rD   r   r   r   rJ   y   rF   z_ConstOpMixin.faddsubc                 C   rC   )z<
        Integer subtraction:
            lhs - rhs
        Nr   rD   r   r   r   rK      rF   z_ConstOpMixin.subfsubc                 C   rC   )zC
        Floating-point subtraction:
            lhs - rhs
        Nr   rD   r   r   r   rL      rF   z_ConstOpMixin.fsubmulc                 C   rC   )z?
        Integer multiplication:
            lhs * rhs
        Nr   rD   r   r   r   rM      rF   z_ConstOpMixin.mulfmulc                 C   rC   )zF
        Floating-point multiplication:
            lhs * rhs
        Nr   rD   r   r   r   rN      rF   z_ConstOpMixin.fmuludivc                 C   rC   )zB
        Unsigned integer division:
            lhs / rhs
        Nr   rD   r   r   r   rO      rF   z_ConstOpMixin.udivsdivc                 C   rC   )z@
        Signed integer division:
            lhs / rhs
        Nr   rD   r   r   r   rP      rF   z_ConstOpMixin.sdivfdivc                 C   rC   )z@
        Floating-point division:
            lhs / rhs
        Nr   rD   r   r   r   rQ      rF   z_ConstOpMixin.fdivuremc                 C   rC   )zC
        Unsigned integer remainder:
            lhs % rhs
        Nr   rD   r   r   r   rR      rF   z_ConstOpMixin.uremsremc                 C   rC   )zA
        Signed integer remainder:
            lhs % rhs
        Nr   rD   r   r   r   rS      rF   z_ConstOpMixin.sremfremc                 C   rC   )zA
        Floating-point remainder:
            lhs % rhs
        Nr   rD   r   r   r   rT      rF   z_ConstOpMixin.fremorc                 C   rC   )z;
        Bitwise integer OR:
            lhs | rhs
        Nr   rD   r   r   r   or_   rF   z_ConstOpMixin.or_andc                 C   rC   )z<
        Bitwise integer AND:
            lhs & rhs
        Nr   rD   r   r   r   and_   rF   z_ConstOpMixin.and_xorc                 C   rC   )z<
        Bitwise integer XOR:
            lhs ^ rhs
        Nr   rD   r   r   r   rY      rF   z_ConstOpMixin.xorc              	   C   s   |d }zt | }W n ty   td||f w |dkr"|dv s&|| }| j|jkr6td| j|jf d||| j|  |j| }ttd|S )Ncmpzinvalid comparison %r for %si)r   r   r)   z{0} {1} ({2} {3}, {4} {5})   )	_CMP_MAPKeyErrorr+   r*   r,   r-   r.   r   IntType)r=   prefixsigncmpoprE   insr?   r1   r   r   r   _cmp   s$   


z_ConstOpMixin._cmpc                 C      |  dd||S )z
        Signed integer comparison:
            lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>='
        r[   srd   r=   rb   rE   r   r   r   icmp_signed      z_ConstOpMixin.icmp_signedc                 C   re   )z
        Unsigned integer (or pointer) comparison:
            lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>='
        r[   urg   rh   r   r   r   icmp_unsigned   rj   z_ConstOpMixin.icmp_unsignedc                 C   re   )z
        Floating-point ordered comparison:
            lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>=', 'ord', 'uno'
        forg   rh   r   r   r   fcmp_ordered  rj   z_ConstOpMixin.fcmp_orderedc                 C   re   )z
        Floating-point unordered comparison:
            lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>=', 'ord', 'uno'
        rm   rk   rg   rh   r   r   r   fcmp_unordered  rj   z_ConstOpMixin.fcmp_unorderedc                 C   s>   t | jtjrt| jd| jj }nt| jd}| |S )z@
        Bitwise integer complement:
            ~value
        )rq   )r   r*   r   
VectorTyper   ConstantcountrY   )r=   r0   r   r   r   not_  s   
z_ConstOpMixin.not_c                 C   s   t | jd}|| S )z6
        Integer negative:
            -value
        r   )r   rs   r*   rK   )r=   zeror   r   r   neg$  s   
z_ConstOpMixin.negc                 C   s   d | j|  }t| j|S )z=
        Floating-point negative:
            -value
        zfneg ({0} {1}))r,   r*   r-   r.   )r=   r1   r   r   r   fneg,  s   z_ConstOpMixin.fnegtruncc                 C   rC   )z@
        Truncating integer downcast to a smaller type.
        Nr   r=   r>   r   r   r   ry   8  rF   z_ConstOpMixin.trunczextc                 C   rC   )z@
        Zero-extending integer upcast to a larger type
        Nr   rz   r   r   r   r{   >  rF   z_ConstOpMixin.zextsextc                 C   rC   )zA
        Sign-extending integer upcast to a larger type.
        Nr   rz   r   r   r   r|   D  rF   z_ConstOpMixin.sextfptruncc                 C   rC   )zA
        Floating-point downcast to a less precise type.
        Nr   rz   r   r   r   r}   J  rF   z_ConstOpMixin.fptruncfpextc                 C   rC   )z?
        Floating-point upcast to a more precise type.
        Nr   rz   r   r   r   r~   P  rF   z_ConstOpMixin.fpextbitcastc                 C   rC   )z;
        Pointer cast to a different pointer type.
        Nr   rz   r   r   r   r   V  rF   z_ConstOpMixin.bitcastfptouic                 C   rC   )z=
        Convert floating-point to unsigned integer.
        Nr   rz   r   r   r   r   \  rF   z_ConstOpMixin.fptouiuitofpc                 C   rC   )z=
        Convert unsigned integer to floating-point.
        Nr   rz   r   r   r   r   b  rF   z_ConstOpMixin.uitofpfptosic                 C   rC   )z;
        Convert floating-point to signed integer.
        Nr   rz   r   r   r   r   h  rF   z_ConstOpMixin.fptosisitofpc                 C   rC   )z;
        Convert signed integer to floating-point.
        Nr   rz   r   r   r   r   n  rF   z_ConstOpMixin.sitofpptrtointc                 C   @   t | jtjsd}t|| jf t |tjstd|f dS )z*
        Cast pointer to integer.
        z2can only call ptrtoint() on pointer type, not '%s'z-can only ptrtoint() to integer type, not '%s'N)r   r*   r   PointerType	TypeErrorr_   r=   r>   msgr   r   r   r   t     z_ConstOpMixin.ptrtointinttoptrc                 C   r   )z*
        Cast integer to pointer.
        z7can only call inttoptr() on integer constants, not '%s'z-can only inttoptr() to pointer type, not '%s'N)r   r*   r   r_   r   r   r   r   r   r   r     r   z_ConstOpMixin.inttoptrc                 C   sx   t | jtjstd| jf | j}|D ]}||}qdd |D }d| jj| j|  d	|}t
|| j|S )z>
        Call getelementptr on this pointer constant.
        z2can only call gep() on pointer constants, not '%s'c                 S   s   g | ]}d  |j| qS ){0} {1}r,   r*   r-   )r   idxr   r   r   r     s    z%_ConstOpMixin.gep.<locals>.<listcomp>z!getelementptr ({0}, {1} {2}, {3}), )r   r*   r   r   r   gepr,   pointeer-   r$   r.   
as_pointer	addrspace)r=   indicesouttyper[   
strindicesr?   r   r   r   r     s   
z_ConstOpMixin.gepN)-__name__
__module____qualname____doc__r<   rB   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rV   rX   rY   rd   ri   rl   ro   rp   ru   rw   rx   r@   ry   r{   r|   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   rA   T   s    

















			











rA   c                   @      e Zd ZdZdd ZdS )Valuez(
    The base class for all values.
    c                 C   s   d| j j| jf S )Nz<ir.%s type='%s' ...>)	__class__r   r*   r=   r   r   r   __repr__     zValue.__repr__N)r   r   r   r   r   r   r   r   r   r         r   c                   @   r   )
_Undefinedz0
    'undef': a value for undefined values.
    c                 C   s$   zt W S  ty   tt Y S w N)	Undefined	NameErrorobject__new__r   )clsr   r   r   r     s
   z_Undefined.__new__N)r   r   r   r   r   r   r   r   r   r     s    r   c                   @   sn   e Zd ZdZdd Zdd Zdd Zedd	 ZedddZ	e
dd Zdd Zdd Zdd Zdd ZdS )rs   z 
    A constant LLVM value.
    c                 C   s:   t |tjsJ t |tjrJ || _||}|| _d S r   )r   r   TypeVoidTyper*   wrap_constant_valueconstantr=   r>   r   r   r   r   __init__  s
   

zConstant.__init__c                 C      d | j|  S Nr   r   r   r   r   r   
_to_string  r   zConstant._to_stringc                 C   sZ   | j d u r| jj}|S | j tu rd}|S t| j tr$dt| j }|S | j| j }|S )Nundefzc"{0}")	r   r*   nullr   r   r    r,   r'   format_constantr=   valr   r   r   _get_reference  s   

zConstant._get_referencec                 C   sZ   dd |D }t |dkrtd|d }|D ]
}||kr!tdq| t|t ||S )zO
        Construct a literal array constant made of the given members.
        c                 S      g | ]}|j qS r   r*   r   elr   r   r   r         z*Constant.literal_array.<locals>.<listcomp>r   zneed at least one elementz$all elements must have the same type)lenr+   r   r   	ArrayType)r   elemstystyrE   r   r   r   literal_array  s   zConstant.literal_arrayFc                 C   s    dd |D }| t |||S )zS
        Construct a literal structure constant made of the given members.
        c                 S   r   r   r   r   r   r   r   r     r   z+Constant.literal_struct.<locals>.<listcomp>)r   LiteralStructType)r   r   packedr   r   r   r   literal_struct  s   zConstant.literal_structc                 C   s   t | jtjstd| jjS )Nz)Only pointer constant have address spaces)r   r*   r   r   r   r   r   r   r   r   r     s   zConstant.addrspacec                 C   s   t |trt| t|kS dS NF)r   rs   r   rD   r   r   r   __eq__  s   
zConstant.__eq__c                 C      |  | S r   r   rD   r   r   r   __ne__     zConstant.__ne__c                 C   s   t t| S r   )hashr   r   r   r   r   __hash__  r   zConstant.__hash__c                 C   s   d| j | jf S )Nz <ir.Constant type='%s' value=%r>)r*   r   r   r   r   r   r        zConstant.__repr__N)F)r   r   r   r   r   r   r   classmethodr   r   propertyr   r   r   r   r   r   r   r   r   rs     s    

rs   c                   @   (   e Zd ZdZdd Zdd Zdd ZdS )	r.   zA
    A constant with an already formatted IR representation.
    c                 C   s    t |tsJ t| || d S r   )r   r   rs   r   r   r   r   r   r     s   zFormattedConstant.__init__c                 C      | j S r   r   r   r   r   r   r        zFormattedConstant._to_stringc                 C   r   r   r   r   r   r   r   r     r   z FormattedConstant._get_referenceN)r   r   r   r   r   r   r   r   r   r   r   r.     s
    r.   c                   @   sf   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dd Z
ee	e
Zdd Zdd Zedd ZdS )
NamedValuez*
    The base class for named values.
    %Tc                 C   s6   |d usJ t |tjsJ || _|| _| | d S r   )r   r   r   parentr*   	_set_name)r=   r   r*   namer   r   r   r     s
   zNamedValue.__init__c                 C   s>   g }t | jtjs|d|   | | d|	 S )Nz{0} = r   )
r   r*   r   r   appendr,   r-   descrr$   rstripr=   r&   r   r   r   r      s
   
zNamedValue._to_stringc                 C   s   t r   )NotImplementedErrorr   r   r   r   r   '     zNamedValue.descrc                 C   r   r   )_namer   r   r   r   	_get_name*  r   zNamedValue._get_namec                 C   s   | j jj|| jd}|| _d S )N)deduplicate)r   scoperegisterdeduplicate_namer   r=   r   r   r   r   r   -  s   

zNamedValue._set_namec                 C   s8   | j }d|v sd|v r|dddd}d| j|S )N\"\5c\22z{0}"{1}")r   replacer,   name_prefixr   r   r   r   r   4  s   zNamedValue._get_referencec                 C      d| j j| j| jf S )Nz<ir.%s %r of type '%s'>r   r   r   r*   r   r   r   r   r   ;  s   zNamedValue.__repr__c                 C   s:   | j }t|tjr| j j}t|tjr|S td| j )NzNot a function: {0})r*   r   r   r   r   FunctionTyper   r,   )r=   r   r   r   r   function_type?  s   zNamedValue.function_typeN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s    
r   c                       sL   e Zd ZdZ fddZdd Zdd ZeZdd	 Zd
d Z	dd Z
  ZS )MetaDataStringz[
    A metadata string, i.e. a constant string used as a value in a metadata
    node.
    c                    s$   t t| j|t dd || _d S )Nr   r   )superr   r   r   MetaDataTypestring)r=   r   r   r   r   r   r   P  s
   
zMetaDataString.__init__c                 C   s   ||   df7 }d S )N
)r-   r   r   r   r   r   V     zMetaDataString.descrc                 C   s   d t| jS )Nz!"{0}")r,   r'   r   r   r   r   r   r   Y  r   zMetaDataString._get_referencec                 C      t |tr| j|jkS dS r   )r   r   r   rD   r   r   r   r   ^     
zMetaDataString.__eq__c                 C   r   r   r   rD   r   r   r   r   d  r   zMetaDataString.__ne__c                 C   
   t | jS r   )r   r   r   r   r   r   r   g     
zMetaDataString.__hash__)r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   r   r   r   J  s    r   c                   @   s$   e Zd ZdZdd Zdd ZeZdS )MetaDataArgumentz
    An argument value to a function taking metadata arguments.
    This can wrap any other kind of LLVM value.

    Do not instantiate directly, Builder.call() will create these
    automatically.
    c                 C   s4   t |tsJ t |jtjrJ t | _|| _d S r   )r   r   r*   r   r   wrapped_valuer=   valuer   r   r   r   t  s   

zMetaDataArgument.__init__c                 C   s   d | jj| j S r   )r,   r   r*   r-   r   r   r   r   r   z  s   
zMetaDataArgument._get_referenceN)r   r   r   r   r   r   r   r   r   r   r   r   k  s
    r   c                   @   s    e Zd ZdZdd Zdd ZdS )NamedMetaDatazk
    A named metadata node.

    Do not instantiate directly, use Module.add_named_metadata() instead.
    c                 C   s   || _ g | _d S r   )r   operands)r=   r   r   r   r   r     s   
zNamedMetaData.__init__c                 C      | j | d S r   )r  r   )r=   mdr   r   r   rI     r   zNamedMetaData.addN)r   r   r   r   r   rI   r   r   r   r   r    s    r  c                       L   e Zd ZdZdZ fddZdd Zdd Zd	d
 Zdd Z	dd Z
  ZS )MDValuez
    A metadata node's value, consisting of a sequence of elements ("operands").

    Do not instantiate directly, use Module.add_metadata() instead.
    !c                    s4   t t| j|t |d t|| _|j|  d S Nr   )	r   r  r   r   r   tupler  metadatar   )r=   r   r   r   r   r   r   r     s   
zMDValue.__init__c                 C   s   g }| j D ]-}t|jtjr&t|tr|jd u r|d q||  q|d	|j|  qd
|}|d	|df7 }d S )Nr   r   r   z
!{{ {0} }}r   )r  r   r*   r   r   rs   r   r   r-   r,   r$   )r=   r&   r  r?   r   r   r   r     s   

zMDValue.descrc                 C      | j t| j S r   r   r   r   r   r   r   r   r     r   zMDValue._get_referencec                 C   r   r   )r   r  r  rD   r   r   r   r     r   zMDValue.__eq__c                 C   r   r   r   rD   r   r   r   r     r   zMDValue.__ne__c                 C   r   r   )r   r  r   r   r   r   r     r   zMDValue.__hash__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    s    r  c                   @   r   )DITokenz
    A debug information enumeration value that should appear bare in
    the emitted metadata.

    Use this to wrap known constants, e.g. the DW_* enumerations.
    c                 C   s
   || _ d S r   )r  r   r   r   r   r     r   zDIToken.__init__N)r   r   r   r   r   r   r   r   r   r    s    r  c                       r  )DIValuez
    A debug information descriptor, containing key-value pairs.

    Do not instantiate directly, use Module.add_debug_info() instead.
    r  c                    s@   t t| j|t |d || _|| _t|| _|j	
|  d S r	  )r   r  r   r   r   is_distinctkindr
  r  r  r   )r=   r   r  r  r  r   r   r   r   r     s   
zDIValue.__init__c                 C   s   | j r|d7 }g }| jD ]S\}}|d u rd}n?|du rd}n8|du r%d}n1t|tr.|j}n(t|tr;dt|}nt|trEt|}nt|t	rO|
 }ntd|f |d	|| qd
|}|d| jd|df7 }d S )N)z	distinct r   TtrueFfalsez"{}"z'invalid operand type for debug info: %rz{0}: {1}r   r  (z)
)r  r  r   r  r  r   r,   r'   intr   r-   r   r   r$   r  )r=   r&   r  keyr  strvaluer   r   r   r     s0   






zDIValue.descrc                 C   r  r   r  r   r   r   r   r     r   zDIValue._get_referencec                 C   s2   t |tr| j|jko| j|jko| j|jkS dS r   )r   r  r  r  r  rD   r   r   r   r     s   


zDIValue.__eq__c                 C   r   r   r   rD   r   r   r   r     r   zDIValue.__ne__c                 C   s   t | j| j| jfS r   )r   r  r  r  r   r   r   r   r     r   zDIValue.__hash__r  r   r   r   r   r    s    	r  c                       s(   e Zd ZdZdZdZ fddZ  ZS )GlobalValuez
    A global value.
    @Fc                    s2   t t| j|i | d| _d| _d| _i | _d S Nr   )r   r  r   linkagestorage_classsectionr  )r=   argskwargsr   r   r   r     s
   
zGlobalValue.__init__)r   r   r   r   r   r   r   r   r   r   r   r   r    s
    r  c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )GlobalVariablez
    A global variable.
    r   c                    s`   t |tjsJ tt| j||||d || _d | _d| _	d| _
|| _d | _| j|  d S )Nr   F)r   r   r   r   r!  r   r   
value_typeinitializerunnamed_addrglobal_constantr   alignr   
add_global)r=   moduler>   r   r   r   r   r   r     s   zGlobalVariable.__init__c                 C   sX  | j rd}nd}| js| jd u rdnd}n| j}|r!||d  | jr,|| jd  | jr4|d | jdkrB|d| j |d	j|| jd
 | jd uro| jj	| jkrdt
d| jj	| jf |d| j   n|dvr|d| t   | jr|d| jf  | jd ur|d| jf  | jr|| jdd |d d S )Nr   globalexternalr    zunnamed_addr r   zaddrspace({0:d}) z{kind} {type})r  r*   z3got initializer of type %s for global value type %s)r*  extern_weakz, section "%s"z
, align %dT)leading_commar   )r%  r  r#  r   r  r$  r   r,   r"  r*   r   r-   r   r  r&  r  _stringify_metadata)r=   r&   r  r  r   r   r   r   &  s<   



zGlobalVariable.descr)r   )r   r   r   r   r   r   r   r   r   r   r   r!    s    r!  c                       sB   e Zd ZdZdZd fdd	Zdd Z fddZd	d
 Z  Z	S )AttributeSetzxA set of string attribute.
    Only accept items listed in *_known*.

    Properties:
    * Iterate in sorted order
    r   c                    s2   t    t|tr|g}|D ]}| | qd S r   )r   r   r   r   rI   )r=   r  r   r   r   r   r   \  s   

zAttributeSet.__init__c                 C   s   |S r   r   )r=   r   r>   r   r   r   _expandc  r   zAttributeSet._expandc                    s*   || j vrtd|| tt| |S )Nzunknown attr {!r} for {})_knownr+   r,   r   r/  rI   r   r   r   r   rI   f  s   
zAttributeSet.addc                    s    fddt  D S )Nc                    s   g | ]}  |qS r   )r0  )r   r[   rz   r   r   r   l  s    z)AttributeSet._to_list.<locals>.<listcomp>)sortedrz   r   rz   r   _to_listk  s   zAttributeSet._to_listr   )
r   r   r   r   r1  r   r0  rI   r3  r   r   r   r   r   r/  S  s    r/  c                       sv   e Zd Zeg dZd fdd	Z fddZedd Zej	d	d Zed
d Z
e
j	dd Z
 fddZ  ZS )FunctionAttributes) 
argmemonlyalwaysinlinebuiltincold
convergentinaccessiblememonlyinaccessiblemem_or_argmemonly
inlinehint	jumptableminsizenaked	nobuiltinnoduplicatenoimplicitfloatnoinlinenonlazybind	norecurse	noredzonenoreturnnounwindoptnoneoptsizereadnonereadonlyreturns_twicesanitize_addresssanitize_memorysanitize_threadsspsspreg	sspstronguwtabler   c                    s    d| _ d | _tt| | d S Nr   )_alignstack_personalityr   r5  r   r=   r  r   r   r   r   z  s   zFunctionAttributes.__init__c                    s8   |dkrd| v s|dkrd| v rt dt | d S )Nr7  rD  z$Can't have alwaysinline and noinline)r+   r   rI   r   r   r   r   rI     s   zFunctionAttributes.addc                 C   r   r   rW  r   r   r   r   
alignstack     zFunctionAttributes.alignstackc                 C   s   |dksJ || _ d S rV  rZ  r   r   r   r   r[    s   
c                 C   r   r   )rX  r   r   r   r   personality  r\  zFunctionAttributes.personalityc                 C   s    |d u st |tsJ || _d S r   )r   r  rX  r   r   r   r   r]       
c                    sL   t  |}| jr|d| j | jr$|dj| jj| j d |S )Nzalignstack({0:d})zpersonality {persty} {persfn})perstypersfn)r   r3  r[  r   r,   r]  r*   r-   )r=   ret_typeattrsr   r   r   r3    s   zFunctionAttributes._to_listr4  )r   r   r   	frozensetr1  r   rI   r   r[  setterr]  r3  r   r   r   r   r   r5  o  s    




r5  c                       s   e Zd ZdZ fddZedd Zedd Zedd	 ZdddZ	dddZ
dd Zdd Zdd Zdd Zedd Z  ZS )FunctionzRepresent a LLVM Function but does uses a Module as parent.
    Global Values are stored as a set of dependencies (attribute `depends`).
    c                    s   t |tjsJ tt j|| |d | _t	  _
g  _t  _t fdd|jD  _t |j _ j  d _d S )Nr   c                    s   g | ]}t  |qS r   )Argument)r   tr   r   r   r     s    z%Function.__init__.<locals>.<listcomp>r   )r   r   r   r   re  r   r   ftyper   	NameScoper   blocksr5  
attributesr
  r  ReturnValuereturn_typereturn_valuer   r'  calling_convention)r=   r(  rh  r   r   r   r   r     s   


zFunction.__init__c                 C   r   r   r   r   r   r   r   r(    r\  zFunction.modulec                 C   s
   | j d S rV  rj  r   r   r   r   entry_basic_block     
zFunction.entry_basic_blockc                 C   r   r   rq  r   r   r   r   basic_blocks  r\  zFunction.basic_blocksr   c                 C   s   t | |d}| j| |S )Nr   r   )Blockrj  r   )r=   r   blkr   r   r   append_basic_block  s   zFunction.append_basic_blockc                 C   s   t | |d}| j|| |S )zInsert block before
        ru  )rv  rj  insert)r=   beforer   rw  r   r   r   insert_basic_block  s   zFunction.insert_basic_blockc              	   C   s  | j rdnd}| j}ddd | jD }|  }| jr)dd| j| jj nd}t	| jr9| jj
r6dnd}n| jj
r?d	nd}| j}| j}	dd
d |||	|fD }
|  }|r`d|nd}| jrkd| jnd}d}|j|
||||||d}|| dS )zB
        Describe the prototype ("head") of the function.
        definedeclarer   c                 s   s    | ]}t |V  qd S r   r   )r   ar   r   r   	<genexpr>  s    z+Function.descr_prototype.<locals>.<genexpr>r+  r   z, ...z...c                 s   s    | ]	}|rt |V  qd S r   r~  )r   xr   r   r   r    s    z {}z section "{}"z:{prefix} {name}({args}{vararg}){attrs}{section}{metadata}
)r`   r   r  varargrb  r  r  N)rj  rn  r$   r  r-   rk  r3  rh  rm  anyvar_argr  ro  r.  r,   r  r   )r=   r&   stateretr  r   rb  r  r  cconvr`   r  r  pt_str	prototyper   r   r   descr_prototype  s2   

zFunction.descr_prototypec                 C   s   | j D ]}|| qdS )z7
        Describe of the body of the function.
        N)rj  r   )r=   r&   rw  r   r   r   
descr_body  s   
zFunction.descr_bodyc                 C   s6   |  | | jr|d | | |d d S d S )Nz{
z}
)r  rj  r   r  r   r   r   r   r     s   


zFunction.descrc                 C   s   g }|  | d|S r  )r   r$   r   r   r   r   __str__  s   

zFunction.__str__c                 C   s   t | jdkS rV  )r   rj  r   r   r   r   is_declaration  s   zFunction.is_declarationr   )r   r   r   r   r   r   r(  rr  rt  rx  r{  r  r  r   r  r  r   r   r   r   r   re    s"    




re  c                       s   e Zd Zei ddddddddddddd	dd
dddddddddddddddddddddddZd% fdd	Zdd Zedd Zej	dd Zedd Z
e
j	dd Z
ed d! Zej	d"d! Z fd#d$Z  ZS )&ArgumentAttributesbyrefTbyvalelementtypeimmargFinallocainregnestnoalias	nocapturenofreenonnullnoundefpreallocatedreturnedsignextsret
swiftasync)
swifterror	swiftselfzeroextr   c                    s&   d| _ d| _d| _tt| | d S rV  )_align_dereferenceable_dereferenceable_or_nullr   r  r   rY  r   r   r   r     s   zArgumentAttributes.__init__c                 C   s&   | j |}|r| d|j dS |S )Nr  ))r1  getr   )r=   r   r>   requires_typer   r   r   r0  !  s   zArgumentAttributes._expandc                 C   r   r   )r  r   r   r   r   r&  (  r\  zArgumentAttributes.alignc                 C       t |tr	|dksJ || _d S rV  )r   r  r  r   r   r   r   r&  ,  r^  c                 C   r   r   )r  r   r   r   r   dereferenceable1  r\  z"ArgumentAttributes.dereferenceablec                 C   r  rV  )r   r  r  r   r   r   r   r  5  r^  c                 C   r   r   )r  r   r   r   r   dereferenceable_or_null:  r\  z*ArgumentAttributes.dereferenceable_or_nullc                 C   r  rV  )r   r  r  r   r   r   r   r  >  r^  c                    s\   t  |}| jr|d| j | jr|d| j | jr,d}||| j |S )Nzalign {0:d}zdereferenceable({0:d})zdereferenceable_or_null({0:d}))r   r3  r&  r   r,   r  r  )r=   r>   rb  drefr   r   r   r3  C  s   zArgumentAttributes._to_listr4  )r   r   r   r   r1  r   r0  r   r&  rd  r  r  r3  r   r   r   r   r   r    sn    	







r  c                       s.   e Zd Zd fdd	Zdd Zdd Z  ZS )	_BaseArgumentr   c                    s8   t |tjsJ tt| j|||d || _t | _d S r	  )	r   r   r   r   r  r   r   r  rk  )r=   r   r>   r   r   r   r   r   P  s   z_BaseArgument.__init__c                 C   r   )Nz<ir.%s %r of type %s>r   r   r   r   r   r   V  s   z_BaseArgument.__repr__c                 C   r  r   )rk  rI   )r=   attrr   r   r   add_attributeZ  r   z_BaseArgument.add_attributer  )r   r   r   r   r   r  r   r   r   r   r   r  O  s    r  c                   @   r   )rf  z3
    The specification of a function argument.
    c                 C   s>   | j | j}|rd| jd||  S d| j|  S )Nz{0} {1} {2}r+  r   )rk  r3  r*   r,   r$   r-   r=   rb  r   r   r   r  c  s   zArgument.__str__Nr   r   r   r   r  r   r   r   r   rf  ^  r   rf  c                   @   r   )rl  z9
    The specification of a function's return value.
    c                 C   s0   | j | j}|rdd|| jS t| jS )Nr   r+  )rk  r3  r*   r,   r$   r   r  r   r   r   r  q  s   
zReturnValue.__str__Nr  r   r   r   r   rl  l  r   rl  c                       s^   e Zd ZdZd fdd	Zedd Zedd Zed	d
 Zdd Z	dd Z
dd Z  ZS )rv  a   
    A LLVM IR basic block. A basic block is a sequence of
    instructions whose execution always goes from start to end.  That
    is, a control flow instruction (branch) can only appear as the
    last instruction, and incoming branches can only jump to the first
    instruction.
    r   c                    s2   t t| j|t |d |j| _g | _d | _d S r	  )r   rv  r   r   	LabelTyper   instructions
terminator)r=   r   r   r   r   r   r     s   
zBlock.__init__c                 C   s
   | j d uS r   )r  r   r   r   r   is_terminated  rs  zBlock.is_terminatedc                 C   r   r   rp  r   r   r   r   function  r\  zBlock.functionc                 C   s   | j jS r   )r   r(  r   r   r   r   r(    s   zBlock.modulec                 C   s,   | d|   |dd | jD 7 }d S )Nz{0}:
c                 S   s   g | ]}d  |qS )z  {0}
)r,   )r   instrr   r   r   r     s    zBlock.descr.<locals>.<listcomp>)r   r,   _format_namer  r   r   r   r   r     s   zBlock.descrc                 C   sd   |j |j kr
td| j|}| j| | j|| | jjD ]}|jD ]}||| q&q!dS )zReplace an instructionz$new instruction has a different typeN)	r*   r   r  indexremovery  r   rt  replace_usage)r=   oldnewposbbr  r   r   r   r     s   
zBlock.replacec                 C   s2   | j }t|s|dddd}d|}|S )Nr   r   r   r   z"{0}")r   _SIMPLE_IDENTIFIER_REmatchr   r,   r   r   r   r   r    s
   

zBlock._format_namer  )r   r   r   r   r   r   r  r  r(  r   r   r  r   r   r   r   r   rv  y  s    


rv  c                   @   r   )	BlockAddressz'
    The address of a basic block.
    c                 C   s<   t |tsJ t |tsJ td | _|| _|| _d S )N   )	r   re  rv  r   r_   r   r*   r  basic_block)r=   r  r  r   r   r   r     s
   
zBlockAddress.__init__c                 C   r   r   r   r   r   r   r   r    r   zBlockAddress.__str__c                 C   s   d | j | j S )Nzblockaddress({0}, {1}))r,   r  r-   r  r   r   r   r   r-     s   zBlockAddress.get_referenceN)r   r   r   r   r   r  r-   r   r   r   r   r    s
    r  )3r   r6   r   rer   r   llvmlite.irr   r   llvmlite.ir._utilsr   r   r   rc  mapordascii_lettersdigitsr"   compiler  r]   r'   r<   r@   r   rA   r   r   r   rs   r.   r   r   r   r  r  r  r  r  r!  setr/  r5  re  r  r  rf  rl  rv  r  r   r   r   r   <module>   sb    

  O	J8!,=>4\P6