Source code for angr.analyses.typehoon.typeconsts

# pylint:disable=missing-class-docstring
"""
All type constants used in type inference. They can be mapped, translated, or rewritten to C-style types.
"""

from typing import Optional


[docs]class TypeConstant: SIZE = None
[docs] def pp_str(self, mapping) -> str: # pylint:disable=unused-argument return repr(self)
def __eq__(self, other): return type(self) == type(other) def __hash__(self): return hash(type(self)) @property def size(self) -> int: if self.SIZE is None: raise NotImplementedError() return self.SIZE
[docs]class TopType(TypeConstant): def __repr__(self): return "TOP"
[docs]class BottomType(TypeConstant): def __repr__(self): return "BOT"
[docs]class Int(TypeConstant): def __repr__(self): return "intbase"
[docs]class Int1(Int): SIZE = 1
[docs]class Int8(Int): SIZE = 1 def __repr__(self): return "int8"
[docs]class Int16(Int): SIZE = 2 def __repr__(self): return "int16"
[docs]class Int32(Int): SIZE = 4 def __repr__(self): return "int32"
[docs]class Int64(Int): SIZE = 8 def __repr__(self): return "int64"
[docs]class Int128(Int): SIZE = 16 def __repr__(self): return "int128"
[docs]class FloatBase(TypeConstant): def __repr__(self): return "floatbase"
[docs]class Float(FloatBase): SIZE = 4 def __repr__(self): return "float"
[docs]class Double(FloatBase): SIZE = 8 def __repr__(self): return "double"
[docs]class Pointer(TypeConstant):
[docs] def __init__(self, basetype): self.basetype = basetype
def __eq__(self, other): return type(self) is type(other) and self.basetype == other.basetype def __hash__(self): return hash((type(self), hash(self.basetype)))
[docs] def new(self, basetype): return self.__class__(basetype)
[docs]class Pointer32(Pointer, Int32): """ 32-bit pointers. """
[docs] def __init__(self, basetype): Pointer.__init__(self, basetype)
def __repr__(self): return "ptr32(%r)" % self.basetype
[docs]class Pointer64(Pointer, Int64): """ 64-bit pointers. """
[docs] def __init__(self, basetype): Pointer.__init__(self, basetype)
def __repr__(self): return "ptr64(%r)" % self.basetype
[docs]class Array(TypeConstant):
[docs] def __init__(self, element, count=None): self.element: TypeConstant = element self.count: Optional[int] = count
def __repr__(self): if self.count is None: return "%r[?]" % self.element else: return "%r[%d]" % (self.element, self.count) def __eq__(self, other): return type(other) is type(self) and self.element == other.element and self.count == other.count def __hash__(self): return hash((type(self), self.element, self.count))
[docs]class Struct(TypeConstant):
[docs] def __init__(self, fields=None): self.fields = {} if fields is None else fields # offset to type
def _hash_fields(self): keys = sorted(self.fields.keys()) tpl = tuple((k, self.fields[k]) for k in keys) return hash(tpl) def __repr__(self): return "struct%r" % self.fields def __eq__(self, other): return type(other) is type(self) and self.fields == other.fields def __hash__(self): return hash((type(self), self._hash_fields()))
[docs]class TypeVariableReference(TypeConstant):
[docs] def __init__(self, typevar): self.typevar = typevar
def __repr__(self): return "ref(%s)" % self.typevar def __eq__(self, other): return type(other) is type(self) and self.typevar == other.typevar def __hash__(self): return hash((type(self), self.typevar))
# # Methods #
[docs]def int_type(bits: int) -> Optional[Int]: mapping = { 1: Int1, 8: Int8, 16: Int16, 32: Int32, 64: Int64, 128: Int128, } if bits in mapping: return mapping[bits]() return None
[docs]def float_type(bits: int) -> Optional[FloatBase]: if bits == 32: return Float() elif bits == 64: return Double() return None