U
    9%eÄ                     @   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$t sXtdD ]&}|tkrJt| |< q0d|  |< q0 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   Q/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/llvmlite/ir/values.py
<listcomp>/   s     z"_escape_string.<locals>.<listcomp> )

isinstancestrencodebytes	bytearrayAssertionErrorrange_VALID_CHARSchrjoin)textr   r   bufr   r   r   _escape_string   s    
r(   c                    s    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                    s    fdd}|S )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   s   dS )z<
        Left integer shift:
            lhs << rhs
        Nr   r=   otherr   r   r   rB   ]   s    z_ConstOpMixin.shllshrc                 C   s   dS )zP
        Logical (unsigned) right integer shift:
            lhs >> rhs
        Nr   rC   r   r   r   rE   d   s    z_ConstOpMixin.lshrashrc                 C   s   dS )zQ
        Arithmetic (signed) right integer shift:
            lhs >> rhs
        Nr   rC   r   r   r   rF   k   s    z_ConstOpMixin.ashraddc                 C   s   dS )z9
        Integer addition:
            lhs + rhs
        Nr   rC   r   r   r   rG   r   s    z_ConstOpMixin.addfaddc                 C   s   dS )z@
        Floating-point addition:
            lhs + rhs
        Nr   rC   r   r   r   rH   y   s    z_ConstOpMixin.faddsubc                 C   s   dS )z<
        Integer subtraction:
            lhs - rhs
        Nr   rC   r   r   r   rI      s    z_ConstOpMixin.subfsubc                 C   s   dS )zC
        Floating-point subtraction:
            lhs - rhs
        Nr   rC   r   r   r   rJ      s    z_ConstOpMixin.fsubmulc                 C   s   dS )z?
        Integer multiplication:
            lhs * rhs
        Nr   rC   r   r   r   rK      s    z_ConstOpMixin.mulfmulc                 C   s   dS )zF
        Floating-point multiplication:
            lhs * rhs
        Nr   rC   r   r   r   rL      s    z_ConstOpMixin.fmuludivc                 C   s   dS )zB
        Unsigned integer division:
            lhs / rhs
        Nr   rC   r   r   r   rM      s    z_ConstOpMixin.udivsdivc                 C   s   dS )z@
        Signed integer division:
            lhs / rhs
        Nr   rC   r   r   r   rN      s    z_ConstOpMixin.sdivfdivc                 C   s   dS )z@
        Floating-point division:
            lhs / rhs
        Nr   rC   r   r   r   rO      s    z_ConstOpMixin.fdivuremc                 C   s   dS )zC
        Unsigned integer remainder:
            lhs % rhs
        Nr   rC   r   r   r   rP      s    z_ConstOpMixin.uremsremc                 C   s   dS )zA
        Signed integer remainder:
            lhs % rhs
        Nr   rC   r   r   r   rQ      s    z_ConstOpMixin.sremfremc                 C   s   dS )zA
        Floating-point remainder:
            lhs % rhs
        Nr   rC   r   r   r   rR      s    z_ConstOpMixin.fremorc                 C   s   dS )z;
        Bitwise integer OR:
            lhs | rhs
        Nr   rC   r   r   r   or_   s    z_ConstOpMixin.or_andc                 C   s   dS )z<
        Bitwise integer AND:
            lhs & rhs
        Nr   rC   r   r   r   and_   s    z_ConstOpMixin.and_xorc                 C   s   dS )z<
        Bitwise integer XOR:
            lhs ^ rhs
        Nr   rC   r   r   r   rW      s    z_ConstOpMixin.xorc              	   C   s   |d }zt | }W n$ tk
r8   td||f Y nX |dkrJ|dksR|| }| j|jkrrt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cmpoprD   Zinsr?   r1   r   r   r   _cmp   s(    
   z_ConstOpMixin._cmpc                 C   s   |  dd||S )z
        Signed integer comparison:
            lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>='
        rY   sra   r=   r`   rD   r   r   r   icmp_signed   s    z_ConstOpMixin.icmp_signedc                 C   s   |  dd||S )z
        Unsigned integer (or pointer) comparison:
            lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>='
        rY   urc   rd   r   r   r   icmp_unsigned   s    z_ConstOpMixin.icmp_unsignedc                 C   s   |  dd||S )z
        Floating-point ordered comparison:
            lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>=', 'ord', 'uno'
        forc   rd   r   r   r   fcmp_ordered  s    z_ConstOpMixin.fcmp_orderedc                 C   s   |  dd||S )z
        Floating-point unordered comparison:
            lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>=', 'ord', 'uno'
        rh   rf   rc   rd   r   r   r   fcmp_unordered  s    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
        )rl   )r   r*   r   Z
VectorTyper   ConstantcountrW   )r=   r0   r   r   r   not_  s    z_ConstOpMixin.not_c                 C   s   t | jd}|| S )z6
        Integer negative:
            -value
        r   )r   rm   r*   rI   )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   s   dS )z@
        Truncating integer downcast to a smaller type.
        Nr   r=   r>   r   r   r   rs   8  s    z_ConstOpMixin.trunczextc                 C   s   dS )z@
        Zero-extending integer upcast to a larger type
        Nr   rt   r   r   r   ru   >  s    z_ConstOpMixin.zextsextc                 C   s   dS )zA
        Sign-extending integer upcast to a larger type.
        Nr   rt   r   r   r   rv   D  s    z_ConstOpMixin.sextfptruncc                 C   s   dS )zA
        Floating-point downcast to a less precise type.
        Nr   rt   r   r   r   rw   J  s    z_ConstOpMixin.fptruncfpextc                 C   s   dS )z?
        Floating-point upcast to a more precise type.
        Nr   rt   r   r   r   rx   P  s    z_ConstOpMixin.fpextbitcastc                 C   s   dS )z;
        Pointer cast to a different pointer type.
        Nr   rt   r   r   r   ry   V  s    z_ConstOpMixin.bitcastfptouic                 C   s   dS )z=
        Convert floating-point to unsigned integer.
        Nr   rt   r   r   r   rz   \  s    z_ConstOpMixin.fptouiuitofpc                 C   s   dS )z=
        Convert unsigned integer to floating-point.
        Nr   rt   r   r   r   r{   b  s    z_ConstOpMixin.uitofpfptosic                 C   s   dS )z;
        Convert floating-point to signed integer.
        Nr   rt   r   r   r   r|   h  s    z_ConstOpMixin.fptosisitofpc                 C   s   dS )z;
        Convert signed integer to floating-point.
        Nr   rt   r   r   r   r}   n  s    z_ConstOpMixin.sitofpptrtointc                 C   s@   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  s    z_ConstOpMixin.ptrtointinttoptrc                 C   s@   t | jtjs"d}t|| jf t |tjs<td|f dS )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     s    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=   indicesZouttyperY   Z
strindicesr?   r   r   r   r     s"      z_ConstOpMixin.gepN)-__name__
__module____qualname____doc__r<   rB   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rT   rV   rW   ra   re   rg   rj   rk   ro   rq   rr   r@   rs   ru   rv   rw   rx   ry   rz   r{   r|   r}   r~   r   r   r   r   r   r   rA   T   s   

















			











rA   c                   @   s   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__  s    zValue.__repr__N)r   r   r   r   r   r   r   r   r   r     s   r   c                   @   s   e Zd ZdZdd ZdS )
_Undefinedz0
    'undef': a value for undefined values.
    c                 C   s*   zt W S  tk
r$   tt Y S X d S 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                   @   sl   e Zd ZdZdd Zdd Zdd Zedd	 Zed
d Z	e
dd Zdd Zdd Zdd Zdd ZdS )rm   z 
    A constant LLVM value.
    c                 C   s:   t |tjstt |tjr t|| _||}|| _d S r   )r   r   Typer!   VoidTyper*   Zwrap_constant_valueconstantr=   r>   r   r   r   r   __init__  s
    
zConstant.__init__c                 C   s   d | j|  S Nr   r   r   r   r   r   
_to_string  s    zConstant._to_stringc                 C   sT   | j d kr| jj}n<| j tkr$d}n,t| j trBdt| j }n| j| j }|S )NZundefzc"{0}")	r   r*   nullr   r   r    r,   r(   Z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   s   g | ]
}|j qS r   r*   r   elr   r   r   r     s     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tyrD   r   r   r   literal_array  s    
zConstant.literal_arrayc                 C   s   dd |D }| t ||S )zS
        Construct a literal structure constant made of the given members.
        c                 S   s   g | ]
}|j qS r   r   r   r   r   r   r     s     z+Constant.literal_struct.<locals>.<listcomp>)r   ZLiteralStructType)r   r   r   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 d S NF)r   rm   r   rC   r   r   r   __eq__  s    
zConstant.__eq__c                 C   s   |  | S r   r   rC   r   r   r   __ne__  s    zConstant.__ne__c                 C   s   t t| S r   )hashr   r   r   r   r   __hash__  s    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     s    zConstant.__repr__N)r   r   r   r   r   r   r   classmethodr   r   propertyr   r   r   r   r   r   r   r   r   rm     s   


rm   c                   @   s(   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tt| || d S r   )r   r   r!   rm   r   r   r   r   r   r     s    zFormattedConstant.__init__c                 C   s   | j S r   r   r   r   r   r   r     s    zFormattedConstant._to_stringc                 C   s   | j S r   r   r   r   r   r   r     s    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 k	st t|tjst || _|| _| | d S r   )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 d S r   )NotImplementedErrorr   r   r   r   r   '  s    zNamedValue.descrc                 C   s   | j S r   )_namer   r   r   r   	_get_name*  s    zNamedValue._get_namec                 C   s   | j jj|| jd}|| _d S )N)Zdeduplicate)r   scoperegisterdeduplicate_namer   r=   r   r   r   r   r   -  s    
zNamedValue._set_namec                 C   s8   | j }d|ksd|k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   s   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 d S )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  s    zMetaDataString.descrc                 C   s   d t| jS )Nz!"{0}")r,   r(   r   r   r   r   r   r   Y  s    zMetaDataString._get_referencec                 C   s   t |tr| j|jkS dS d S r   )r   r   r   rC   r   r   r   r   ^  s    
zMetaDataString.__eq__c                 C   s   |  | S r   r   rC   r   r   r   r   d  s    zMetaDataString.__ne__c                 C   s
   t | jS r   )r   r   r   r   r   r   r   g  s    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tt |jtjr tt | _|| _d S r   )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   s   | j | d S r   )r   r   )r=   mdr   r   r   rG     s    zNamedMetaData.addN)r   r   r   r   r   rG   r   r   r   r   r     s   r   c                       sL   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 ]Z}t|jtjrLt|tr<|jd kr<|d qd||  q
|d	|j|  q
d
|}|d	|df7 }d S )Nr   r   r   z
!{{ {0} }}r   )r   r   r*   r   r   rm   r   r   r-   r,   r%   )r=   r'   r   r?   r   r   r   r     s    

zMDValue.descrc                 C   s   | j t| j S r   r   r   r   r   r   r   r   r     s    zMDValue._get_referencec                 C   s   t |tr| j|jkS dS d S r   )r   r   r   rC   r   r   r   r     s    
zMDValue.__eq__c                 C   s   |  | S r   r   rC   r   r   r   r     s    zMDValue.__ne__c                 C   s
   t | jS r   )r   r   r   r   r   r   r     s    zMDValue.__hash__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s   r   c                   @   s   e Zd ZdZdd ZdS )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     s    zDIToken.__init__N)r   r   r   r   r   r   r   r   r   r     s   r   c                       sL   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 )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 ]\}}|d kr.d}n~|dkr<d}np|dkrJd}nbt|tr\|j}nPt|trvdt|}n6t|trt|}n"t|t	r|
 }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   Zstrvaluer   r   r   r     s0    






zDIValue.descrc                 C   s   | j t| j S r   r   r   r   r   r   r     s    zDIValue._get_referencec                 C   s6   t |tr.| j|jko,| j|jko,| j|jkS dS d S r   )r   r   r   r   r   rC   r   r   r   r     s    


zDIValue.__eq__c                 C   s   |  | S r   r   rC   r   r   r   r     s    zDIValue.__ne__c                 C   s   t | j| j| jfS r   )r   r   r   r   r   r   r   r   r     s    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                    s.   t t| j|| 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ttt| j||||d || _d | _	d| _
d| _|| _d | _| j|  d S )Nr   F)r   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   s^  | j rd}nd}| js*| jd kr$dnd}n| j}|rB||d  | jrX|| jd  | jrh|d | jdkr|d| j |d	j|| jd
 | jd k	r| jj	| jkrt
d| jj	| jf |d| j   n |dkr|d| t   | jr|d| jf  | jd k	r6|d| jf  | jrP|| 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  Zextern_weakz, section "%s"z
, align %dT)Z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   rG   )r=   r   r   r   r   r   r   \  s
    

zAttributeSet.__init__c                 C   s   |S r   r   )r=   r   r>   r   r   r   _expandc  s    zAttributeSet._expandc                    s*   || j krtd|| tt| |S )Nzunknown attr {!r} for {})_knownr+   r,   r   r  rG   r   r   r   r   rG   f  s    
zAttributeSet.addc                    s    fddt  D S )Nc                    s   g | ]}  |qS r   )r  )r   rY   rt   r   r   r   l  s     z)AttributeSet._to_list.<locals>.<listcomp>)sortedrt   r   rt   r   _to_listk  s    zAttributeSet._to_list)r   )
r   r   r   r   r  r   r  rG   r
  r   r   r   r   r   r  S  s   r  c                        s   e Zd Ze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g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 ).FunctionAttributesZ
argmemonlyalwaysinlinebuiltinZcoldZinaccessiblememonlyZinaccessiblemem_or_argmemonlyZ
inlinehintZ	jumptableZminsizeZnakedZ	nobuiltinZnoduplicateZnoimplicitfloatnoinlineZnonlazybindZ	norecurseZ	noredzoneZnoreturnZnounwindZoptnoneZoptsizeZreadnonereadonlyZreturns_twiceZsanitize_addressZsanitize_memoryZsanitize_threadsspZsspregZ	sspstrongZuwtabler   c                    s    d| _ d | _tt| | d S Nr   )_alignstack_personalityr   r  r   r=   r   r   r   r   r   z  s    zFunctionAttributes.__init__c                    s8   |dkrd| ks |dkr(d| kr(t dt | d S )Nr  r  z$Can't have alwaysinline and noinline)r+   r   rG   r   r   r   r   rG     s    zFunctionAttributes.addc                 C   s   | j S r   )r  r   r   r   r   
alignstack  s    zFunctionAttributes.alignstackc                 C   s   |dkst || _d S r  )r!   r  r   r   r   r   r    s    c                 C   s   | j S r   )r  r   r   r   r   personality  s    zFunctionAttributes.personalityc                 C   s    |d kst |tst|| _d S r   )r   r   r!   r  r   r   r   r   r    s    c                    sL   t  |}| jr$|d| j | jrH|dj| jj| j d |S )Nzalignstack({0:d})zpersonality {persty} {persfn})ZperstyZpersfn)r   r
  r  r   r,   r  r*   r-   )r=   Zret_typeattrsr   r   r   r
    s    zFunctionAttributes._to_list)r   )r   r   r   	frozensetr  r   rG   r   r  setterr  r
  r   r   r   r   r   r  o  sX                          




r  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t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!   r   r  r   r   ftyper   Z	NameScoper   blocksr  
attributesr   r   ReturnValuereturn_typereturn_valuer   r   calling_convention)r=   r  r  r   r   r   r   r     s    

zFunction.__init__c                 C   s   | j S r   r   r   r   r   r   r    s    zFunction.modulec                 C   s
   | j d S r  r  r   r   r   r   entry_basic_block  s    zFunction.entry_basic_blockc                 C   s   | j S r   r%  r   r   r   r   basic_blocks  s    zFunction.basic_blocksr   c                 C   s   t | |d}| j| |S )Nr   r   )Blockr  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
        r(  )r)  r  insert)r=   beforer   r*  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rRdd| j| jj nd}t	| jrr| jj
rldnd}n| jj
r~d	nd}| j}| j}	dd
d |||	|fD }
|  }|rd|nd}| jrd| jnd}d}|j|
||||||d}|| dS )zB
        Describe the prototype ("head") of the function.
        ZdefineZ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   r1    s      z {}z section "{}"z:{prefix} {name}({args}{vararg}){attrs}{section}{metadata}
)r^   r   r   varargr  r   r   N)r  r"  r%   r   r-   r  r
  r  r!  anyZvar_argr   r#  r  r,   r   r   )r=   r'   stateretr   r   r  r3  r   Zcconvr^   r   r   Zpt_strZ	prototyper   r   r   descr_prototype  s6    

  zFunction.descr_prototypec                 C   s   | j D ]}|| qdS )z7
        Describe of the body of the function.
        N)r  r   )r=   r'   r*  r   r   r   
descr_body  s    
zFunction.descr_bodyc                 C   s2   |  | | jr.|d | | |d d S )Nz{
z}
)r7  r  r   r8  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 r  )r   r  r   r   r   r   is_declaration  s    zFunction.is_declaration)r   )r   )r   r   r   r   r   r   r  r&  r'  r+  r.  r7  r8  r   r9  r:  r   r   r   r   r   r    s    




r  c                       s   e Zd Ze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 )ArgumentAttributesTF)ZbyrefZbyvalZelementtypeZimmargZinallocaZinregnestZnoaliasZ	nocaptureZnofreeZnonnullZnoundefZpreallocatedreturnedZsignextZsretZ
swiftasyncZ
swifterrorZ	swiftselfZzeroextr   c                    s&   d| _ d| _d| _tt| | d S r  )_align_dereferenceable_dereferenceable_or_nullr   r;  r   r  r   r   r   r     s    zArgumentAttributes.__init__c                 C   s*   | j |}|r"| d|j dS |S d S )Nr   ))r  getr   )r=   r   r>   Zrequires_typer   r   r   r  !  s    zArgumentAttributes._expandc                 C   s   | j S r   )r>  r   r   r   r   r   (  s    zArgumentAttributes.alignc                 C   s    t |tr|dkst|| _d S r  )r   r   r!   r>  r   r   r   r   r   ,  s    c                 C   s   | j S r   )r?  r   r   r   r   dereferenceable1  s    z"ArgumentAttributes.dereferenceablec                 C   s    t |tr|dkst|| _d S r  )r   r   r!   r?  r   r   r   r   rC  5  s    c                 C   s   | j S r   )r@  r   r   r   r   dereferenceable_or_null:  s    z*ArgumentAttributes.dereferenceable_or_nullc                 C   s    t |tr|dkst|| _d S r  )r   r   r!   r@  r   r   r   r   rD  >  s    c                    s\   t  |}| jr$|d| j | jr<|d| j | jrXd}||| j |S )Nzalign {0:d}zdereferenceable({0:d})zdereferenceable_or_null({0:d}))r   r
  r   r   r,   rC  rD  )r=   r>   r  Zdrefr   r   r   r
  C  s    zArgumentAttributes._to_list)r   )r   r   r   r   r  r   r  r   r   r  rC  rD  r
  r   r   r   r   r   r;    sJ   





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ttt| j|||d || _t | _	d S r   )
r   r   r   r!   r   rE  r   r   r;  r  )r=   r   r>   r   r   r   r   r   P  s    z_BaseArgument.__init__c                 C   s   d| j j| j| jf S )Nz<ir.%s %r of type %s>r   r   r   r   r   r   V  s    z_BaseArgument.__repr__c                 C   s   | j | d S r   )r  rG   )r=   attrr   r   r   add_attributeZ  s    z_BaseArgument.add_attribute)r   )r   r   r   r   r   rG  r   r   r   r   r   rE  O  s   rE  c                   @   s   e Zd ZdZdd ZdS )r  z3
    The specification of a function argument.
    c                 C   sB   | j | j}|r,d| jd||  S d| j|  S d S )Nz{0} {1} {2}r  r   )r  r
  r*   r,   r%   r-   r=   r  r   r   r   r9  c  s    zArgument.__str__Nr   r   r   r   r9  r   r   r   r   r  ^  s   r  c                   @   s   e Zd ZdZdd ZdS )r   z9
    The specification of a function's return value.
    c                 C   s4   | j | j}|r&dd|| jS t| jS d S )Nr   r  )r  r
  r*   r,   r%   r   rH  r   r   r   r9  q  s    zReturnValue.__str__NrI  r   r   r   r   r   l  s   r   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 )r)  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   r)  r   r   Z	LabelTyper   instructions
terminator)r=   r   r   r   r   r   r     s    zBlock.__init__c                 C   s
   | j d k	S r   )rK  r   r   r   r   is_terminated  s    zBlock.is_terminatedc                 C   s   | j S r   r$  r   r   r   r   function  s    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_namerJ  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 ]}||| qLqBdS )zReplace an instructionz$new instruction has a different typeN)	r*   r   rJ  indexremover,  r   r'  Zreplace_usage)r=   oldnewposZbbrN  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   rO    s
    

zBlock._format_name)r   )r   r   r   r   r   r   rL  rM  r  r   r   rO  r   r   r   r   r   r)  y  s   


r)  c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	BlockAddressz'
    The address of a basic block.
    c                 C   s<   t |tstt |tsttd | _|| _|| _	d S )N   )
r   r  r!   r)  r   r]   r   r*   rM  basic_block)r=   rM  rY  r   r   r   r     s
    zBlockAddress.__init__c                 C   s   d | j|  S r   r   r   r   r   r   r9    s    zBlockAddress.__str__c                 C   s   d | j | j S )Nzblockaddress({0}, {1}))r,   rM  r-   rY  r   r   r   r   r-     s    zBlockAddress.get_referenceN)r   r   r   r   r   r9  r-   r   r   r   r   rW    s   rW  )3r   r6   r   rer   r   Zllvmlite.irr   r   Zllvmlite.ir._utilsr   r   r   r  mapordascii_lettersdigitsr#   compilerU  r[   r(   r<   r@   r   rA   r   r   r   rm   r.   r   r   r   r   r   r   r   r   r   setr  r  r  r;  rE  r  r   r)  rW  r   r   r   r   <module>   s`   

  O	J8!,=>4\P6