B
    Ꮚ\`                 @   s  d Z ddlmZmZ ddlZddlmZ ddl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i f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Z!G d&d' d'e!Z"G d(d) d)e#Z$G d*d+ d+e$Z%G d,d- d-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,dS ):z_
Classes that are LLVM values: Value, Constant...
Instructions are in the instructions module.
    )print_functionabsolute_importN   )six   )types_utils)_StrCaching_StringReferenceCaching_HasMetadataz !#$%&'()*+,-./:;<=>?@[]^_`{|}~c                s   t | tr| d} t | ttfs&t stxHtdD ]<}|tkrNt| |< nd|  |< t	j
r4 |  t|< q4W  fdd| D }d|S )zL
    Escape the given bytestring for safe use as a LLVM array constant.
    ascii   z\%02xc                s   g | ]} | qS  r   ).0ch)_mapr   1lib/python3.7/site-packages/llvmlite/ir/values.py
<listcomp>%   s    z"_escape_string.<locals>.<listcomp> )
isinstancestrencodebytes	bytearrayAssertionErrorrange_VALID_CHARSchrr   ZPY2join)textr   r   bufr   )r   r   _escape_string   s    

r!   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	_ConstOpMixinzQ
    A mixin defining constant operations, for use in constant-like classes.
    c             C   s,   || j kr| S d| j |  |}t||S )zB
        Bitcast this pointer constant to the given type.
        zbitcast ({0} {1} to {2}))typeformatget_referenceFormattedConstant)selftypopr   r   r   bitcast.   s
    
z_ConstOpMixin.bitcastc             C   sV   t | jtjstd| jf t |tjs8td|f d| j|  |}t||S )zG
        Cast this integer constant to the given pointer type.
        z7can only call inttoptr() on integer constants, not '%s'z-can only inttoptr() to pointer type, not '%s'zinttoptr ({0} {1} to {2}))	r   r#   r   IntType	TypeErrorPointerTyper$   r%   r&   )r'   r(   r)   r   r   r   inttoptr8   s    
z_ConstOpMixin.inttoptrc             C   s|   t | jtjstd| jf | j}x|D ]}||}q*W 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 )z{0} {1})r$   r#   r%   )r   idxr   r   r   r   T   s   z%_ConstOpMixin.gep.<locals>.<listcomp>z!getelementptr ({0}, {1} {2}, {3})z, )r   r#   r   r-   r,   gepr$   pointeer%   r   r&   
as_pointer	addrspace)r'   indicesZouttypeiZ
strindicesr)   r   r   r   r0   H   s    

z_ConstOpMixin.gepN)__name__
__module____qualname____doc__r*   r.   r0   r   r   r   r   r"   )   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__r6   r#   )r'   r   r   r   __repr__b   s    zValue.__repr__N)r6   r7   r8   r9   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$   yt S  tk
r   ttS X d S )N)	Undefined	NameErrorobject__new__r=   )clsr   r   r   rA   j   s    z_Undefined.__new__N)r6   r7   r8   r9   rA   r   r   r   r   r=   f   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 )Constantz 
    A constant LLVM value.
    c             C   s:   t |tjstt |tjr t|| _||}|| _d S )N)r   r   Typer   VoidTyper#   Zwrap_constant_valueconstant)r'   r(   rF   r   r   r   __init__y   s
    
zConstant.__init__c             C   s   d | j|  S )Nz{0} {1})r$   r#   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}")	rF   r#   nullr>   r   r   r$   r!   Zformat_constant)r'   valr   r   r   _get_reference   s    


zConstant._get_referencec             C   s^   dd |D }t |dkr"td|d }x|D ]}||kr0tdq0W | 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)len
ValueErrorr,   r   Z	ArrayType)rB   elemstystyotherr   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   rL   r   r   r   r      s    z+Constant.literal_struct.<locals>.<listcomp>)r   ZLiteralStructType)rB   rO   rP   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,   r3   )r'   r   r   r   r3      s    zConstant.addrspacec             C   s"   t |trt| t|kS dS d S )NF)r   rC   r   )r'   rR   r   r   r   __eq__   s    
zConstant.__eq__c             C   s   |  | S )N)rU   )r'   rR   r   r   r   __ne__   s    zConstant.__ne__c             C   s   t t| S )N)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#   rF   )r'   r   r   r   r<      s    zConstant.__repr__N)r6   r7   r8   r9   rG   rH   rK   classmethodrS   rT   propertyr3   rU   rV   rX   r<   r   r   r   r   rC   t   s   rC   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 )N)r   r   r   rC   rG   )r'   r(   rF   r   r   r   rG      s    zFormattedConstant.__init__c             C   s   | j S )N)rF   )r'   r   r   r   rH      s    zFormattedConstant._to_stringc             C   s   | j S )N)rF   )r'   r   r   r   rK      s    z FormattedConstant._get_referenceN)r6   r7   r8   r9   rG   rH   rK   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 )N)r   r   r   rD   parentr#   	_set_name)r'   r]   r#   namer   r   r   rG      s
    zNamedValue.__init__c             C   s>   g }| j t kr&|d|   | | d| S )Nz{0} = r   )	r#   r   rE   appendr$   r%   descrr   rstrip)r'   r    r   r   r   rH      s
    
zNamedValue._to_stringc             C   s   t d S )N)NotImplementedError)r'   r    r   r   r   ra      s    zNamedValue.descrc             C   s   | j S )N)_name)r'   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_namerd   )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\"z\5cz\22z{0}"{1}")r_   replacer$   name_prefix)r'   r_   r   r   r   rK      s    zNamedValue._get_referencec             C   s   d| j j| j| jf S )Nz<ir.%s %r of type '%s'>)r;   r6   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-   r1   FunctionTyper,   r$   )r'   rQ   r   r   r   function_type   s    zNamedValue.function_typeN)r6   r7   r8   r9   rl   rh   rG   rH   ra   re   r^   rZ   r_   rK   r<   rn   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_   )superro   rG   r   MetaDataTypestring)r'   r]   rr   )r;   r   r   rG     s    zMetaDataString.__init__c             C   s   ||   df7 }d S )N
)r%   )r'   r    r   r   r   ra     s    zMetaDataString.descrc             C   s   d t| jS )Nz!"{0}")r$   r!   rr   )r'   r   r   r   rK     s    zMetaDataString._get_referencec             C   s   t |tr| j|jkS dS d S )NF)r   ro   rr   )r'   rR   r   r   r   rU     s    
zMetaDataString.__eq__c             C   s   |  | S )N)rU   )r'   rR   r   r   r   rV     s    zMetaDataString.__ne__c             C   s
   t | jS )N)rW   rr   )r'   r   r   r   rX   "  s    zMetaDataString.__hash__)r6   r7   r8   r9   rG   ra   rK   rH   rU   rV   rX   __classcell__r   r   )r;   r   ro     s   ro   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 )N)r   r:   r   r#   r   rq   wrapped_value)r'   valuer   r   r   rG   /  s    
zMetaDataArgument.__init__c             C   s   d | jj| j S )Nz{0} {1})r$   rv   r#   r%   )r'   r   r   r   rK   5  s    
zMetaDataArgument._get_referenceN)r6   r7   r8   r9   rG   rK   rH   r   r   r   r   ru   &  s   ru   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 )N)r]   operands)r'   r]   r   r   r   rG   D  s    zNamedMetaData.__init__c             C   s   | j | d S )N)ry   r`   )r'   Zmdr   r   r   addH  s    zNamedMetaData.addN)r6   r7   r8   r9   rG   rz   r   r   r   r   rx   =  s   rx   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 )N)r_   )	rp   r{   rG   r   rq   tuplery   metadatar`   )r'   r]   valuesr_   )r;   r   r   rG   T  s
    
zMDValue.__init__c             C   s   g }xd| j D ]Z}t|jtjrNt|tr>|jd kr>|d qf||  q|d	|j|  qW d
|}|d	|df7 }d S )NrI   z{0} {1}z, z
!{{ {0} }}rs   )ry   r   r#   r   rq   rC   rF   r`   r%   r$   r   )r'   r    ry   r)   r   r   r   ra   [  s    
zMDValue.descrc             C   s   | j t| j S )N)rl   r   r_   )r'   r   r   r   rK   h  s    zMDValue._get_referencec             C   s   t |tr| j|jkS dS d S )NF)r   r{   ry   )r'   rR   r   r   r   rU   k  s    
zMDValue.__eq__c             C   s   |  | S )N)rU   )r'   rR   r   r   r   rV   q  s    zMDValue.__ne__c             C   s
   t | jS )N)rW   ry   )r'   r   r   r   rX   t  s    zMDValue.__hash__)r6   r7   r8   r9   rl   rG   ra   rK   rU   rV   rX   rt   r   r   )r;   r   r{   L  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 )N)rw   )r'   rw   r   r   r   rG     s    zDIToken.__init__N)r6   r7   r8   r9   rG   r   r   r   r   r   x  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 )N)r_   )rp   r   rG   r   rq   is_distinctkindr}   ry   r~   r`   )r'   r]   r   r   ry   r_   )r;   r   r   rG     s    
zDIValue.__init__c             C   s   | j r|d7 }g }x| jD ]\}}|d kr0d}n|dkr>d}nr|dkrLd}ndt|tr^|j}nRt|trxdt|}n8t|tj	rt|}n"t|t
r| }ntd|f |d	|| qW d
|}|d| jd|df7 }d S )N)z	distinct rI   TtrueFZfalsez"{}"z'invalid operand type for debug info: %rz{0}: {1}z, r|   (z)
)r   ry   r   r   rw   r   r$   r!   r   integer_typesr[   r%   r,   r`   r   r   )r'   r    ry   keyrw   Zstrvaluer   r   r   ra     s.    






zDIValue.descrc             C   s   | j t| j S )N)rl   r   r_   )r'   r   r   r   rK     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 )NF)r   r   r   r   ry   )r'   rR   r   r   r   rU     s
    
zDIValue.__eq__c             C   s   |  | S )N)rU   )r'   rR   r   r   r   rV     s    zDIValue.__ne__c             C   s   t | j| j| jfS )N)rW   r   r   ry   )r'   r   r   r   rX     s    zDIValue.__hash__)r6   r7   r8   r9   rl   rG   ra   rK   rU   rV   rX   rt   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 S )Nr   )rp   r   rG   linkagestorage_class)r'   argskwargs)r;   r   r   rG     s    zGlobalValue.__init__)r6   r7   r8   r9   rl   rh   rG   rt   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 )N)r_   F)r   r   rD   r   rp   r   rG   r2   
value_typeinitializerunnamed_addrglobal_constantr3   alignr]   
add_global)r'   moduler(   r_   r3   )r;   r   r   rG     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d k	r|d| jf  |d d S )NrF   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
, align %drs   )r   r   r   r`   r   r   r3   r$   r   r#   r,   r%   r>   r   )r'   r    r   r   r   r   r   ra     s2    


zGlobalVariable.descr)r   )r6   r7   r8   r9   rG   ra   rt   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}x|D ]}| | qW d S )N)r   r   rz   )r'   r   r_   r   r   r   rG     s    

zAttributeSet.__init__c                s*   || j krtd|| tt| |S )Nzunknown attr {!r} for {})_knownrN   r$   rp   r   rz   )r'   r_   )r;   r   r   rz     s    
zAttributeSet.addc                s   t ttt|  S )N)itersortedrp   r   __iter__)r'   )r;   r   r   r     s    zAttributeSet.__iter__)r   )	r6   r7   r8   r9   r   rG   rz   r   rt   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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	d)d* Z
  ZS ),FunctionAttributesZ
argmemonlyZalwaysinlineZbuiltinZcoldZinaccessiblememonlyZinaccessiblemem_or_argmemonlyZ
inlinehintZ	jumptableZminsizeZnakedZ	nobuiltinZnoduplicateZnoimplicitfloatZ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_personalityrp   r   rG   )r'   r   )r;   r   r   rG   )  s    zFunctionAttributes.__init__c             C   s   | j S )N)r   )r'   r   r   r   
alignstack.  s    zFunctionAttributes.alignstackc             C   s   |dkst || _d S )Nr   )r   r   )r'   rJ   r   r   r   r   2  s    c             C   s   | j S )N)r   )r'   r   r   r   personality7  s    zFunctionAttributes.personalityc             C   s    |d kst |tst|| _d S )N)r   r   r   r   )r'   rJ   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   )r6   r7   r8   	frozensetr   rG   rZ   r   setterr   r<   rt   r   r   )r;   r   r     s   

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 _i  _d S )N)r_   c                s   g | ]}t  |qS r   )Argument)r   t)r'   r   r   r   V  s   z%Function.__init__.<locals>.<listcomp>r   )r   r   rD   r   rp   r   rG   r2   ftyper   Z	NameScoperf   blocksr   
attributesr}   r   ReturnValueZreturn_typereturn_valuer]   r   calling_conventionr~   )r'   r   r   r_   )r;   )r'   r   rG   O  s    
zFunction.__init__c             C   s   | j S )N)r]   )r'   r   r   r   r   ]  s    zFunction.modulec             C   s
   | j d S )Nr   )r   )r'   r   r   r   entry_basic_blocka  s    zFunction.entry_basic_blockc             C   s   | j S )N)r   )r'   r   r   r   basic_blockse  s    zFunction.basic_blocksr   c             C   s   t | |d}| j| |S )N)r]   r_   )Blockr   r`   )r'   r_   blkr   r   r   append_basic_blocki  s    zFunction.append_basic_blockc             C   s   t | |d}| j|| |S )zInsert block before
        )r]   r_   )r   r   insert)r'   Zbeforer_   r   r   r   r   insert_basic_blockn  s    zFunction.insert_basic_blockc             C   s   | j r
dnd}| j}ddd | jD }|  }| j}t| jrT| jjrNdnd}n| jjr`dnd}| j	}| j
}	d	d
d |||	|gD }
|  }dj|
|||||d}|| dS )zB
        Describe the prototype ("head") of the function.
        ZdefineZdeclarez, c             s   s   | ]}t |V  qd S )N)r   )r   ar   r   r   	<genexpr>{  s    z+Function.descr_prototype.<locals>.<genexpr>z, ...r   z...r   c             s   s   | ]}|rt |V  qd S )N)r   )r   xr   r   r   r     s    z2{prefix} {name}({args}{vararg}) {attrs}{metadata}
)prefixr_   r   varargr   r~   N)r   r   r   r   r%   r   anyr   Zvar_argr   r   Z_stringify_metadatar$   r`   )r'   r    stateZretr   r_   r   r   r   Zcconvr   r~   Z	prototyper   r   r   descr_prototypeu  s     

zFunction.descr_prototypec             C   s   x| j D ]}|| qW dS )z7
        Describe of the body of the function.
        N)r   ra   )r'   r    r   r   r   r   
descr_body  s    zFunction.descr_bodyc             C   s2   |  | | jr.|d | | |d d S )Nz{
z}
)r   r   r`   r   )r'   r    r   r   r   ra     s
    


zFunction.descrc             C   s   g }|  | d|S )Nr   )ra   r   )r'   r    r   r   r   __str__  s    
zFunction.__str__c             C   s   t | jdkS )Nr   )rM   r   )r'   r   r   r   is_declaration  s    zFunction.is_declaration)r   )r   )r6   r7   r8   r9   rG   rZ   r   r   r   r   r   r   r   ra   r   r   rt   r   r   )r;   r   r   K  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 )Nr   )_align_dereferenceable_dereferenceable_or_nullrp   r   rG   )r'   r   )r;   r   r   rG     s    zArgumentAttributes.__init__c             C   s   | j S )N)r   )r'   r   r   r   r     s    zArgumentAttributes.alignc             C   s"   t |tjr|dkst|| _d S )Nr   )r   r   r   r   r   )r'   rJ   r   r   r   r     s    c             C   s   | j S )N)r   )r'   r   r   r   dereferenceable  s    z"ArgumentAttributes.dereferenceablec             C   s"   t |tjr|dkst|| _d S )Nr   )r   r   r   r   r   )r'   rJ   r   r   r   r     s    c             C   s   | j S )N)r   )r'   r   r   r   dereferenceable_or_null  s    z*ArgumentAttributes.dereferenceable_or_nullc             C   s"   t |tjr|dkst|| _d S )Nr   )r   r   r   r   r   )r'   rJ   r   r   r   r     s    c             C   sT   t | }| jr |d| j | jr8|d| j | jrP|d| j |S )Nzalign {0:d}zdereferenceable({0:d})zdereferenceable_or_null({0:d}))r   r   r`   r$   r   r   )r'   r   r   r   r   _to_list  s    zArgumentAttributes._to_list)r   )r6   r7   r8   r   r   rG   rZ   r   r   r   r   r   rt   r   r   )r;   r   r     s   
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 )N)r_   )
r   r   rD   r   rp   r   rG   r]   r   r   )r'   r]   r(   r_   )r;   r   r   rG     s    z_BaseArgument.__init__c             C   s   d| j j| j| jf S )Nz<ir.%s %r of type %s>)r;   r6   r_   r#   )r'   r   r   r   r<     s    z_BaseArgument.__repr__c             C   s   | j | d S )N)r   rz   )r'   attrr   r   r   add_attribute  s    z_BaseArgument.add_attribute)r   )r6   r7   r8   rG   r<   r   rt   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   z{0} {1})r   r   r$   r#   r   r%   )r'   r   r   r   r   r     s
    

zArgument.__str__N)r6   r7   r8   r9   r   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 )Nz{0} {1}r   )r   r   r$   r   r#   r   )r'   r   r   r   r   r     s    
zReturnValue.__str__N)r6   r7   r8   r9   r   r   r   r   r   r     s   r   c                   sV   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
  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 )N)r_   )rp   r   rG   r   Z	LabelTyperf   instructions
terminator)r'   r]   r_   )r;   r   r   rG     s    zBlock.__init__c             C   s
   | j d k	S )N)r   )r'   r   r   r   is_terminated  s    zBlock.is_terminatedc             C   s   | j S )N)r]   )r'   r   r   r   function  s    zBlock.functionc             C   s   | j jS )N)r]   r   )r'   r   r   r   r     s    zBlock.modulec             C   s*   | d| j |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$   r_   r   )r'   r    r   r   r   ra     s    zBlock.descrc             C   sl   |j |j krtd| j|}| j| | j|| x,| jjD ] }x|jD ]}||| qPW qDW dS )zReplace an instructionz$new instruction has a different typeN)	r#   r,   r   indexremover   r]   r   Zreplace_usage)r'   oldnewposZbbr   r   r   r   rk     s    zBlock.replace)r   )r6   r7   r8   r9   rG   rZ   r   r   r   ra   rk   rt   r   r   )r;   r   r     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+   r2   r#   r   basic_block)r'   r   r   r   r   r   rG   /  s
    zBlockAddress.__init__c             C   s   d | j|  S )Nz{0} {1})r$   r#   r%   )r'   r   r   r   r   6  s    zBlockAddress.__str__c             C   s   d | j | j S )Nzblockaddress({0}, {1}))r$   r   r%   r   )r'   r   r   r   r%   9  s    zBlockAddress.get_referenceN)r6   r7   r8   r9   rG   r   r%   r   r   r   r   r   *  s   r   )-r9   Z
__future__r   r   rr   r   r   r   r   r	   r
   r   r   mapordZascii_lettersZdigitsr   r!   r@   r"   r:   r=   r>   rC   r&   r[   ro   ru   rx   r{   r   r   r   r   setr   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s@   4	J7!,=8-X1-