U
    +dJ                     @   s4  d Z ddlZddlZddl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.d/ d/e&Z'G d0d1 d1e(Z)G d2d3 d3e)Z*G d4d5 d5e&Z+G d6d7 d7e)Z,G d8d9 d9eZ-G d:d; d;e-Z.G d<d= d=e-Z/G d>d? d?eZ0G d@dA dAeZ1dS )Bz_
Classes that are LLVM values: Value, Constant...
Instructions are in the instructions module.
    N)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   6/tmp/pip-unpacked-wheel-stw2luzp/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fnr3   r1   r   r   wrap4   s    
z_binop.<locals>.wrapr   r2   r9   r   r1   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)r8   r2   r   r   r3   F   s    


 z&_castop.<locals>.wrap.<locals>.wrappedr4   r7   r1   )r8   r   r9   E   s    	z_castop.<locals>.wrapr   r:   r   r1   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   rA   ]   s    z_ConstOpMixin.shllshrc                 C   s   dS )zP
        Logical (unsigned) right integer shift:
            lhs >> rhs
        Nr   rB   r   r   r   rD   d   s    z_ConstOpMixin.lshrashrc                 C   s   dS )zQ
        Arithmetic (signed) right integer shift:
            lhs >> rhs
        Nr   rB   r   r   r   rE   k   s    z_ConstOpMixin.ashraddc                 C   s   dS )z9
        Integer addition:
            lhs + rhs
        Nr   rB   r   r   r   rF   r   s    z_ConstOpMixin.addfaddc                 C   s   dS )z@
        Floating-point addition:
            lhs + rhs
        Nr   rB   r   r   r   rG   y   s    z_ConstOpMixin.faddsubc                 C   s   dS )z<
        Integer subtraction:
            lhs - rhs
        Nr   rB   r   r   r   rH      s    z_ConstOpMixin.subfsubc                 C   s   dS )zC
        Floating-point subtraction:
            lhs - rhs
        Nr   rB   r   r   r   rI      s    z_ConstOpMixin.fsubmulc                 C   s   dS )z?
        Integer multiplication:
            lhs * rhs
        Nr   rB   r   r   r   rJ      s    z_ConstOpMixin.mulfmulc                 C   s   dS )zF
        Floating-point multiplication:
            lhs * rhs
        Nr   rB   r   r   r   rK      s    z_ConstOpMixin.fmuludivc                 C   s   dS )zB
        Unsigned integer division:
            lhs / rhs
        Nr   rB   r   r   r   rL      s    z_ConstOpMixin.udivsdivc                 C   s   dS )z@
        Signed integer division:
            lhs / rhs
        Nr   rB   r   r   r   rM      s    z_ConstOpMixin.sdivfdivc                 C   s   dS )z@
        Floating-point division:
            lhs / rhs
        Nr   rB   r   r   r   rN      s    z_ConstOpMixin.fdivuremc                 C   s   dS )zC
        Unsigned integer remainder:
            lhs % rhs
        Nr   rB   r   r   r   rO      s    z_ConstOpMixin.uremsremc                 C   s   dS )zA
        Signed integer remainder:
            lhs % rhs
        Nr   rB   r   r   r   rP      s    z_ConstOpMixin.sremfremc                 C   s   dS )zA
        Floating-point remainder:
            lhs % rhs
        Nr   rB   r   r   r   rQ      s    z_ConstOpMixin.fremorc                 C   s   dS )z;
        Bitwise integer OR:
            lhs | rhs
        Nr   rB   r   r   r   or_   s    z_ConstOpMixin.or_andc                 C   s   dS )z<
        Bitwise integer AND:
            lhs & rhs
        Nr   rB   r   r   r   and_   s    z_ConstOpMixin.and_xorc                 C   s   dS )z<
        Bitwise integer XOR:
            lhs ^ rhs
        Nr   rB   r   r   r   rV      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cmpoprC   Zinsr>   r0   r   r   r   _cmp   s(    
   z_ConstOpMixin._cmpc                 C   s   |  dd||S )z
        Signed integer comparison:
            lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>='
        rX   sr`   r<   r_   rC   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 '==', '!=', '<', '<=', '>', '>='
        rX   urb   rc   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orb   rc   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'
        rg   re   rb   rc   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
        )rk   )r   r)   r   Z
VectorTyper   ConstantcountrV   )r<   r/   r   r   r   not_  s    z_ConstOpMixin.not_c                 C   s   t | jd}|| S )z6
        Integer negative:
            -value
        r   )r   rl   r)   rH   )r<   Z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<   r0   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   rq   8  s    z_ConstOpMixin.trunczextc                 C   s   dS )z@
        Zero-extending integer upcast to a larger type
        Nr   rr   r   r   r   rs   >  s    z_ConstOpMixin.zextsextc                 C   s   dS )zA
        Sign-extending integer upcast to a larger type.
        Nr   rr   r   r   r   rt   D  s    z_ConstOpMixin.sextfptruncc                 C   s   dS )zA
        Floating-point downcast to a less precise type.
        Nr   rr   r   r   r   ru   J  s    z_ConstOpMixin.fptruncfpextc                 C   s   dS )z?
        Floating-point upcast to a more precise type.
        Nr   rr   r   r   r   rv   P  s    z_ConstOpMixin.fpextbitcastc                 C   s   dS )z;
        Pointer cast to a different pointer type.
        Nr   rr   r   r   r   rw   V  s    z_ConstOpMixin.bitcastfptouic                 C   s   dS )z=
        Convert floating-point to unsigned integer.
        Nr   rr   r   r   r   rx   \  s    z_ConstOpMixin.fptouiuitofpc                 C   s   dS )z=
        Convert unsigned integer to floating-point.
        Nr   rr   r   r   r   ry   b  s    z_ConstOpMixin.uitofpfptosic                 C   s   dS )z;
        Convert floating-point to signed integer.
        Nr   rr   r   r   r   rz   h  s    z_ConstOpMixin.fptosisitofpc                 C   s   dS )z;
        Convert signed integer to floating-point.
        Nr   rr   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outtyperX   Z
strindicesr>   r   r   r   r     s"      z_ConstOpMixin.gepN)-__name__
__module____qualname____doc__r;   rA   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rS   rU   rV   r`   rd   rf   ri   rj   rn   ro   rp   r?   rq   rs   rt   ru   rv   rw   rx   ry   rz   r{   r|   r   r   r   r   r   r   r@   T   s   

















			











r@   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 )rl   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   Z	ArrayType)r   elemstystyrC   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   rl   r   rB   r   r   r   __eq__  s    
zConstant.__eq__c                 C   s   |  | S r   r   rB   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   rl     s   


rl   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    rl   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   rB   r   r   r   r   ^  s    
zMetaDataString.__eq__c                 C   s   |  | S r   r   rB   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<   Zmdr   r   r   rF     s    zNamedMetaData.addN)r   r   r   r   r   rF   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   rl   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   rB   r   r   r   r     s    
zMDValue.__eq__c                 C   s   |  | S r   r   rB   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   rB   r   r   r   r     s    


zDIValue.__eq__c                 C   s   |  | S r   r   rB   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                       s:   e Zd ZdZdZd	ddZ fddZ fddZ  ZS )
AttributeSetzxA set of string attribute.
    Only accept items listed in *_known*.

    Properties:
    * Iterate in sorted order
    r   c                 C   s(   t |tr|g}|D ]}| | qd S r   )r   r   rF   )r<   r   r   r   r   r   r   \  s    
zAttributeSet.__init__c                    s*   || j krtd|| tt| |S )Nzunknown attr {!r} for {})_knownr*   r+   r   r  rF   r   r   r   r   rF   b  s    
zAttributeSet.addc                    s   t ttt|  S r   )itersortedr   r  __iter__r   r   r   r   r  g  s    zAttributeSet.__iter__)r   )	r   r   r   r   r  r   rF   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
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_threadZsspZsspregZ	sspstrongZuwtabler   c                    s    d| _ d | _tt| | d S Nr   )_alignstack_personalityr   r  r   r<   r   r   r   r   r   w  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   rF   r   r   r   r   rF   |  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                 C   sN   t | }| jr |d| j | jrD|dj| jj| j d d|S )Nzalignstack({0:d})zpersonality {persty} {persfn})ZperstyZpersfnr   )listr  r   r+   r  r)   r,   r$   r<   attrsr   r   r   r     s    zFunctionAttributes.__repr__)r   )r   r   r   	frozensetr  r   rF   r   r  setterr  r   r   r   r   r   r   r  l  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}|rFd|nd}t| jrf| jj	r`dnd}n| jj	rrd	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>z {}r   z, ...z...r   c                 s   s   | ]}|rt |V  qd S r   r,  )r   xr   r   r   r.    s      z section "{}"z:{prefix} {name}({args}{vararg}){attrs}{section}{metadata}
)r]   r   r   varargr  r   r   N)r  r  r$   r   r,   r  r+   anyr  Zvar_argr   r   r  r   r   )r<   r&   stateretr   r   r  r0  r   Zcconvr]   r   r   Zpt_strZ	prototyper   r   r   descr_prototype  s.    

  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}
)r4  r  r   r5  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+  r4  r5  r   r6  r7  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gZd f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
dd Z  ZS )ArgumentAttributesZbyvalZinallocaZinregZnestZnoaliasZ	nocaptureZnonnullZreturnedZsignextZsretZzeroextr   c                    s&   d| _ d| _d| _tt| | d S r  )_align_dereferenceable_dereferenceable_or_nullr   r8  r   r  r   r   r   r     s    zArgumentAttributes.__init__c                 C   s   | j S r   )r9  r   r   r   r   r     s    zArgumentAttributes.alignc                 C   s    t |tr|dkst|| _d S r  )r   r   r    r9  r   r   r   r   r     s    c                 C   s   | j S r   )r:  r   r   r   r   dereferenceable  s    z"ArgumentAttributes.dereferenceablec                 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   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   r=    s    c                 C   sX   t | }| jr |d| j | jr8|d| j | jrTd}||| j |S )Nzalign {0:d}zdereferenceable({0:d})zdereferenceable_or_null({0:d}))r  r   r   r+   r<  r=  )r<   r  Zdrefr   r   r   _to_list"  s    zArgumentAttributes._to_list)r   )r   r   r   r  r  r   r   r   r  r<  r=  r>  r   r   r   r   r   r8    s,       





r8  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   r?  r   r   r8  r  )r<   r   r=   r   r   r   r   r   /  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   5  s    z_BaseArgument.__repr__c                 C   s   | j | d S r   )r  rF   )r<   attrr   r   r   add_attribute9  s    z_BaseArgument.add_attribute)r   )r   r   r   r   r   rA  r   r   r   r   r   r?  .  s   r?  c                   @   s   e Zd ZdZdd ZdS )r  z3
    The specification of a function argument.
    c                 C   s>   | 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   r6  B  s    
zArgument.__str__Nr   r   r   r   r6  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   s0   | j  }|r"dd|| jS t| jS d S )Nr   r   )r  r>  r+   r$   r)   r   r  r   r   r   r6  P  s    
zReturnValue.__str__NrB  r   r   r   r   r  K  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   a  s    zBlock.__init__c                 C   s
   | j d k	S r   )rD  r   r   r   r   is_terminatedg  s    zBlock.is_terminatedc                 C   s   | j S r   r!  r   r   r   r   functionk  s    zBlock.functionc                 C   s   | j jS r   )r   r   r   r   r   r   r   o  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   u  s     zBlock.descr.<locals>.<listcomp>)r   r+   _format_namerC  r   r   r   r   r   s  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~   rC  indexremover)  r   r$  Zreplace_usage)r<   oldnewposZbbrG  r   r   r   r   w  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   rH    s
    

zBlock._format_name)r   )r   r   r   r   r   r   rE  rF  r   r   r   rH  r   r   r   r   r   r&  X  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)   rF  basic_block)r<   rF  rR  r   r   r   r     s
    zBlockAddress.__init__c                 C   s   d | j|  S r   r   r   r   r   r   r6    s    zBlockAddress.__str__c                 C   s   d | j | j S )Nzblockaddress({0}, {1}))r+   rF  r,   rR  r   r   r   r   r,     s    zBlockAddress.get_referenceN)r   r   r   r   r   r6  r,   r   r   r   r   rP    s   rP  )2r   r5   r   reZllvmlite.irr   r   r   Zllvmlite.ir._utilsr   r   r   r  mapordascii_lettersdigitsr"   compilerN  rZ   r'   r;   r?   r   r@   r   r   r   rl   r-   r   r   r   r   r   r   r   r   r   setr  r  r  r8  r?  r  r  r&  rP  r   r   r   r   <module>   s^   

  O	J8!,=>4\26