from __future__ import print_function
import struct
import sys

import gdb.printing
import gdb.types

class Iterator:
  def __iter__(self):
    return self

  if sys.version_info.major == 2:
      def next(self):
        return self.__next__()

  def children(self):
    return self

class SmallStringPrinter:
  """Print an llvm::SmallString object."""

  def __init__(self, val):
    self.val = val

  def to_string(self):
    data = self.val['BeginX'].cast(gdb.lookup_type('char').pointer())
    length = self.val['Size']
    return data.lazy_string(length=length)

  def display_hint (self):
    return 'string'

class StringRefPrinter:
  """Print an llvm::StringRef object."""

  def __init__(self, val):
    self.val = val

  def to_string(self):
    data = self.val['Data']
    length = self.val['Length']
    return data.lazy_string(length=length)

  def display_hint(self):
    return 'string'

class SmallVectorPrinter(Iterator):
  """Print an llvm::SmallVector object."""

  def __init__(self, val):
    self.val = val
    t = val.type.template_argument(0).pointer()
    self.begin = val['BeginX'].cast(t)
    self.size = val['Size']
    self.i = 0

  def __next__(self):
    if self.i == self.size:
      raise StopIteration
    ret = '[{}]'.format(self.i), (self.begin+self.i).dereference()
    self.i += 1
    return ret

  def to_string(self):
    return 'llvm::SmallVector of Size {}, Capacity {}'.format(self.size, self.val['Capacity'])

  def display_hint (self):
    return 'array'

class ArrayRefPrinter:
  """Print an llvm::ArrayRef object."""

  class _iterator:
    def __init__(self, begin, end):
      self.cur = begin
      self.end = end
      self.count = 0

    def __iter__(self):
      return self

    def __next__(self):
      if self.cur == self.end:
        raise StopIteration
      count = self.count
      self.count = self.count + 1
      cur = self.cur
      self.cur = self.cur + 1
      return '[%d]' % count, cur.dereference()

    if sys.version_info.major == 2:
        next = __next__

  def __init__(self, val):
    self.val = val

  def children(self):
    data = self.val['Data']
    return self._iterator(data, data + self.val['Length'])

  def to_string(self):
    return 'llvm::ArrayRef of length %d' % (self.val['Length'])

  def display_hint (self):
    return 'array'

class ExpectedPrinter(Iterator):
  """Print an llvm::Expected object."""

  def __init__(self, val):
    self.val = val

  def __next__(self):
    val = self.val
    if val is None:
      raise StopIteration
    self.val = None
    if val['HasError']:
      return ('error', val['ErrorStorage'].address.cast(
          gdb.lookup_type('llvm::ErrorInfoBase').pointer()).dereference())
    return ('value', val['TStorage'].address.cast(
        val.type.template_argument(0).pointer()).dereference())

  def to_string(self):
    return 'llvm::Expected{}'.format(' is error' if self.val['HasError'] else '')

class OptionalPrinter(Iterator):
  """Print an llvm::Optional object."""

  def __init__(self, val):
    self.val = val

  def __next__(self):
    val = self.val
    if val is None:
      raise StopIteration
    self.val = None
    if not val['Storage']['hasVal']:
      raise StopIteration
    return ('value', val['Storage']['value'])

  def to_string(self):
    return 'llvm::Optional{}'.format('' if self.val['Storage']['hasVal'] else ' is not initialized')

class DenseMapPrinter:
  "Print a DenseMap"

  class _iterator:
    def __init__(self, key_info_t, begin, end):
      self.key_info_t = key_info_t
      self.cur = begin
      self.end = end
      self.advancePastEmptyBuckets()
      self.first = True

    def __iter__(self):
      return self

    def advancePastEmptyBuckets(self):
      # disabled until the comments below can be addressed
      # keeping as notes/posterity/hints for future contributors
      return
      n = self.key_info_t.name
      is_equal = gdb.parse_and_eval(n + '::isEqual')
      empty = gdb.parse_and_eval(n + '::getEmptyKey()')
      tombstone = gdb.parse_and_eval(n + '::getTombstoneKey()')
      # the following is invalid, GDB fails with:
      #   Python Exception <class 'gdb.error'> Attempt to take address of value
      #   not located in memory.
      # because isEqual took parameter (for the unsigned long key I was testing)
      # by const ref, and GDB
      # It's also not entirely general - we should be accessing the "getFirst()"
      # member function, not the 'first' member variable, but I've yet to figure
      # out how to find/call member functions (especially (const) overloaded
      # ones) on a gdb.Value.
      while self.cur != self.end and (is_equal(self.cur.dereference()['first'], empty) or is_equal(self.cur.dereference()['first'], tombstone)):
        self.cur = self.cur + 1

    def __next__(self):
      if self.cur == self.end:
        raise StopIteration
      cur = self.cur
      v = cur.dereference()['first' if self.first else 'second']
      if not self.first:
        self.cur = self.cur + 1
        self.advancePastEmptyBuckets()
        self.first = True
      else:
        self.first = False
      return 'x', v

    if sys.version_info.major == 2:
        next = __next__

  def __init__(self, val):
    self.val = val

  def children(self):
    t = self.val.type.template_argument(3).pointer()
    begin = self.val['Buckets'].cast(t)
    end = (begin + self.val['NumBuckets']).cast(t)
    return self._iterator(self.val.type.template_argument(2), begin, end)

  def to_string(self):
    return 'llvm::DenseMap with %d elements' % (self.val['NumEntries'])

  def display_hint(self):
    return 'map'

class StringMapPrinter:
  "Print a StringMap"

  def __init__(self, val):
    self.val = val

  def children(self):
    it = self.val['TheTable']
    end = (it + self.val['NumBuckets'])
    value_ty = self.val.type.template_argument(0)
    entry_base_ty = gdb.lookup_type('llvm::StringMapEntryBase')
    tombstone = gdb.parse_and_eval('llvm::StringMapImpl::TombstoneIntVal');

    while it != end:
      it_deref = it.dereference()
      if it_deref == 0 or it_deref == tombstone:
        it = it + 1
        continue

      entry_ptr = it_deref.cast(entry_base_ty.pointer())
      entry = entry_ptr.dereference()

      str_len = entry['keyLength']
      value_ptr = (entry_ptr + 1).cast(value_ty.pointer())
      str_data = (entry_ptr + 1).cast(gdb.lookup_type('uintptr_t')) + max(value_ty.sizeof, entry_base_ty.alignof)
      str_data = str_data.cast(gdb.lookup_type('char').const().pointer())
      string_ref = gdb.Value(struct.pack('PN', int(str_data), int(str_len)), gdb.lookup_type('llvm::StringRef'))
      yield 'key', string_ref

      value = value_ptr.dereference()
      yield 'value', value

      it = it + 1

  def to_string(self):
    return 'llvm::StringMap with %d elements' % (self.val['NumItems'])

  def display_hint(self):
    return 'map'

class TwinePrinter:
  "Print a Twine"

  def __init__(self, val):
    self._val = val

  def display_hint(self):
    return 'string'

  def string_from_pretty_printer_lookup(self, val):
    '''Lookup the default pretty-printer for val and use it.

    If no pretty-printer is defined for the type of val, print an error and
    return a placeholder string.'''

    pp = gdb.default_visualizer(val)
    if pp:
      s = pp.to_string()

      # The pretty-printer may return a LazyString instead of an actual Python
      # string.  Convert it to a Python string.  However, GDB doesn't seem to
      # register the LazyString type, so we can't check
      # "type(s) == gdb.LazyString".
      if 'LazyString' in type(s).__name__:
        s = s.value().string()

    else:
      print(('No pretty printer for {} found. The resulting Twine ' +
             'representation will be incomplete.').format(val.type.name))
      s = '(missing {})'.format(val.type.name)

    return s

  def is_twine_kind(self, kind, expected):
    if not kind.endswith(expected):
      return False
    # apparently some GDB versions add the NodeKind:: namespace
    # (happens for me on GDB 7.11)
    return kind in ('llvm::Twine::' + expected,
                    'llvm::Twine::NodeKind::' + expected)

  def string_from_child(self, child, kind):
    '''Return the string representation of the Twine::Child child.'''

    if self.is_twine_kind(kind, 'EmptyKind') or self.is_twine_kind(kind, 'NullKind'):
      return ''

    if self.is_twine_kind(kind, 'TwineKind'):
      return self.string_from_twine_object(child['twine'].dereference())

    if self.is_twine_kind(kind, 'CStringKind'):
      return child['cString'].string()

    if self.is_twine_kind(kind, 'StdStringKind'):
      val = child['stdString'].dereference()
      return self.string_from_pretty_printer_lookup(val)

    if self.is_twine_kind(kind, 'PtrAndLengthKind'):
      val = child['ptrAndLength']
      data = val['ptr']
      length = val['length']
      return data.string(length=length)

    if self.is_twine_kind(kind, 'CharKind'):
      return chr(child['character'])

    if self.is_twine_kind(kind, 'DecUIKind'):
      return str(child['decUI'])

    if self.is_twine_kind(kind, 'DecIKind'):
      return str(child['decI'])

    if self.is_twine_kind(kind, 'DecULKind'):
      return str(child['decUL'].dereference())

    if self.is_twine_kind(kind, 'DecLKind'):
      return str(child['decL'].dereference())

    if self.is_twine_kind(kind, 'DecULLKind'):
      return str(child['decULL'].dereference())

    if self.is_twine_kind(kind, 'DecLLKind'):
      return str(child['decLL'].dereference())

    if self.is_twine_kind(kind, 'UHexKind'):
      val = child['uHex'].dereference()
      return hex(int(val))

    print(('Unhandled NodeKind {} in Twine pretty-printer. The result will be '
           'incomplete.').format(kind))

    return '(unhandled {})'.format(kind)

  def string_from_twine_object(self, twine):
    '''Return the string representation of the Twine object twine.'''

    lhs = twine['LHS']
    rhs = twine['RHS']

    lhs_kind = str(twine['LHSKind'])
    rhs_kind = str(twine['RHSKind'])

    lhs_str = self.string_from_child(lhs, lhs_kind)
    rhs_str = self.string_from_child(rhs, rhs_kind)

    return lhs_str + rhs_str

  def to_string(self):
    return self.string_from_twine_object(self._val)

  def display_hint(self):
    return 'string'

def get_pointer_int_pair(val):
  """Get tuple from llvm::PointerIntPair."""
  info_name = val.type.template_argument(4).strip_typedefs().name
  # Note: this throws a gdb.error if the info type is not used (by means of a
  # call to getPointer() or similar) in the current translation unit.
  enum_type = gdb.lookup_type(info_name + '::MaskAndShiftConstants')
  enum_dict = gdb.types.make_enum_dict(enum_type)
  ptr_mask = enum_dict[info_name + '::PointerBitMask']
  int_shift = enum_dict[info_name + '::IntShift']
  int_mask = enum_dict[info_name + '::IntMask']
  pair_union = val['Value']
  pointer = (pair_union & ptr_mask)
  value = ((pair_union >> int_shift) & int_mask)
  return (pointer, value)

class PointerIntPairPrinter:
  """Print a PointerIntPair."""

  def __init__(self, pointer, value):
    self.pointer = pointer
    self.value = value

  def children(self):
    yield ('pointer', self.pointer)
    yield ('value', self.value)

def make_pointer_int_pair_printer(val):
  """Factory for an llvm::PointerIntPair printer."""
  try:
    pointer, value = get_pointer_int_pair(val)
  except gdb.error:
    return None  # If PointerIntPair cannot be analyzed, print as raw value.
  pointer_type = val.type.template_argument(0)
  value_type = val.type.template_argument(2)
  return PointerIntPairPrinter(pointer.cast(pointer_type),
                               value.cast(value_type))

class PointerUnionPrinter:
  """Print a PointerUnion."""

  def __init__(self, pointer):
    self.pointer = pointer

  def children(self):
    yield ('pointer', self.pointer)

  def to_string(self):
    return "Containing %s" % self.pointer.type

def make_pointer_union_printer(val):
  """Factory for an llvm::PointerUnion printer."""
  try:
    pointer, value = get_pointer_int_pair(val['Val'])
  except gdb.error:
    return None  # If PointerIntPair cannot be analyzed, print as raw value.
  pointer_type = val.type.template_argument(int(value))
  return PointerUnionPrinter(pointer.cast(pointer_type))

class IlistNodePrinter:
  """Print an llvm::ilist_node object."""

  def __init__(self, val):
    impl_type = val.type.fields()[0].type
    base_type = impl_type.fields()[0].type
    derived_type = val.type.template_argument(0)

    def get_prev_and_sentinel(base):
      # One of Prev and PrevAndSentinel exists. Depending on #defines used to
      # compile LLVM, the base_type's template argument is either true of false.
      if base_type.template_argument(0):
        return get_pointer_int_pair(base['PrevAndSentinel'])
      return base['Prev'], None

    # Casts a base_type pointer to the appropriate derived type.
    def cast_pointer(pointer):
      sentinel = get_prev_and_sentinel(pointer.dereference())[1]
      pointer = pointer.cast(impl_type.pointer())
      if sentinel:
          return pointer
      return pointer.cast(derived_type.pointer())

    # Repeated cast becaue val.type's base_type is ambiguous when using tags.
    base = val.cast(impl_type).cast(base_type)
    (prev, sentinel) = get_prev_and_sentinel(base)
    prev = prev.cast(base_type.pointer())
    self.prev = cast_pointer(prev)
    self.next = cast_pointer(val['Next'])
    self.sentinel = sentinel

  def children(self):
    if self.sentinel:
      yield 'sentinel', 'yes'
    yield 'prev', self.prev
    yield 'next', self.next

class IlistPrinter:
  """Print an llvm::simple_ilist or llvm::iplist object."""

  def __init__(self, val):
    self.node_type = val.type.template_argument(0)
    sentinel = val['Sentinel']
    # First field is common base type of sentinel and ilist_node.
    base_type = sentinel.type.fields()[0].type
    self.sentinel = sentinel.address.cast(base_type.pointer())

  def _pointers(self):
    pointer = self.sentinel
    while True:
      pointer = pointer['Next'].cast(pointer.type)
      if pointer == self.sentinel:
        return
      yield pointer.cast(self.node_type.pointer())

  def children(self):
    for k, v in enumerate(self._pointers()):
      yield ('[%d]' % k, v.dereference())


pp = gdb.printing.RegexpCollectionPrettyPrinter("LLVMSupport")
pp.add_printer('llvm::SmallString', '^llvm::SmallString<.*>$', SmallStringPrinter)
pp.add_printer('llvm::StringRef', '^llvm::StringRef$', StringRefPrinter)
pp.add_printer('llvm::SmallVectorImpl', '^llvm::SmallVector(Impl)?<.*>$', SmallVectorPrinter)
pp.add_printer('llvm::ArrayRef', '^llvm::(Mutable)?ArrayRef<.*>$', ArrayRefPrinter)
pp.add_printer('llvm::Expected', '^llvm::Expected<.*>$', ExpectedPrinter)
pp.add_printer('llvm::Optional', '^llvm::Optional<.*>$', OptionalPrinter)
pp.add_printer('llvm::DenseMap', '^llvm::DenseMap<.*>$', DenseMapPrinter)
pp.add_printer('llvm::StringMap', '^llvm::StringMap<.*>$', StringMapPrinter)
pp.add_printer('llvm::Twine', '^llvm::Twine$', TwinePrinter)
pp.add_printer('llvm::PointerIntPair', '^llvm::PointerIntPair<.*>$', make_pointer_int_pair_printer)
pp.add_printer('llvm::PointerUnion', '^llvm::PointerUnion<.*>$', make_pointer_union_printer)
pp.add_printer('llvm::ilist_node', '^llvm::ilist_node<.*>$', IlistNodePrinter)
pp.add_printer('llvm::iplist', '^llvm::iplist<.*>$', IlistPrinter)
pp.add_printer('llvm::simple_ilist', '^llvm::simple_ilist<.*>$', IlistPrinter)
gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
