import lldb
import lldb.formatters.Logger

# libcxx STL formatters for LLDB
# These formatters are based upon the implementation of libc++ that
# ships with current releases of OS X - They will not work for other implementations
# of the standard C++ library - and they are bound to use the libc++-specific namespace

# the std::string summary is just an example for your convenience
# the actual summary that LLDB uses is C++ code inside the debugger's own core

# this could probably be made more efficient but since it only reads a handful of bytes at a time
# we probably don't need to worry too much about this for the time being
def make_string(F,L):
	strval = ''
	G = F.GetData().uint8
	for X in range(L):
		V = G[X]
		if V == 0:
			break
		strval = strval + chr(V % 256)
	return '"' + strval + '"'

# if we ever care about big-endian, these two functions might need to change
def is_short_string(value):
	return True if (value & 1) == 0 else False
def extract_short_size(value):
	return ((value >> 1) % 256)

# some of the members of libc++ std::string are anonymous or have internal names that convey
# no external significance - we access them by index since this saves a name lookup that would add
# no information for readers of the code, but when possible try to use meaningful variable names
def stdstring_SummaryProvider(valobj,dict):
	logger = lldb.formatters.Logger.Logger()
	r = valobj.GetChildAtIndex(0)
	B = r.GetChildAtIndex(0)
	first = B.GetChildAtIndex(0)
	D = first.GetChildAtIndex(0)
	l = D.GetChildAtIndex(0)
	s = D.GetChildAtIndex(1)
	D20 = s.GetChildAtIndex(0)
	size_mode = D20.GetChildAtIndex(0).GetValueAsUnsigned(0)
	if is_short_string(size_mode):
		size = extract_short_size(size_mode)
		return make_string(s.GetChildAtIndex(1),size)
	else:
		data_ptr = l.GetChildAtIndex(2)
		size_vo = l.GetChildAtIndex(1)
		size = size_vo.GetValueAsUnsigned(0)+1 # the NULL terminator must be accounted for
		if size <= 1 or size == None: # should never be the case
			return '""'
		try:
			data = data_ptr.GetPointeeData(0,size)
		except:
			return '""'
		error = lldb.SBError()
		strval = data.GetString(error,0)
		if error.Fail():
			return '<error:' + error.GetCString() + '>'
		else:
			return '"' + strval + '"'

class stdvector_SynthProvider:

	def __init__(self, valobj, dict):
		logger = lldb.formatters.Logger.Logger()
		self.valobj = valobj;

	def num_children(self):
		logger = lldb.formatters.Logger.Logger()
		try:
			start_val = self.start.GetValueAsUnsigned(0)
			finish_val = self.finish.GetValueAsUnsigned(0)
			# Before a vector has been constructed, it will contain bad values
			# so we really need to be careful about the length we return since
			# unitialized data can cause us to return a huge number. We need
			# to also check for any of the start, finish or end of storage values
			# being zero (NULL). If any are, then this vector has not been 
			# initialized yet and we should return zero

			# Make sure nothing is NULL
			if start_val == 0 or finish_val == 0:
				return 0
			# Make sure start is less than finish
			if start_val >= finish_val:
				return 0

			num_children = (finish_val-start_val)
			if (num_children % self.data_size) != 0:
				return 0
			else:
				num_children = num_children/self.data_size
			return num_children
		except:
			return 0;

	def get_child_index(self,name):
		logger = lldb.formatters.Logger.Logger()
		try:
			return int(name.lstrip('[').rstrip(']'))
		except:
			return -1

	def get_child_at_index(self,index):
		logger = lldb.formatters.Logger.Logger()
		logger >> "Retrieving child " + str(index)
		if index < 0:
			return None;
		if index >= self.num_children():
			return None;
		try:
			offset = index * self.data_size
			return self.start.CreateChildAtOffset('['+str(index)+']',offset,self.data_type)
		except:
			return None

	def update(self):
		logger = lldb.formatters.Logger.Logger()
		try:
			self.start = self.valobj.GetChildMemberWithName('__begin_')
			self.finish = self.valobj.GetChildMemberWithName('__end_')
			# the purpose of this field is unclear, but it is the only field whose type is clearly T* for a vector<T>
			# if this ends up not being correct, we can use the APIs to get at template arguments
			data_type_finder = self.valobj.GetChildMemberWithName('__end_cap_').GetChildMemberWithName('__first_')
			self.data_type = data_type_finder.GetType().GetPointeeType()
			self.data_size = self.data_type.GetByteSize()
		except:
			pass

	def has_children(self):
		return True

# Just an example: the actual summary is produced by a summary string: size=${svar%#}
def stdvector_SummaryProvider(valobj,dict):
	prov = stdvector_SynthProvider(valobj,None)
	return 'size=' + str(prov.num_children())

class stdlist_entry:

	def __init__(self,entry):
		logger = lldb.formatters.Logger.Logger()
		self.entry = entry

	def _next_impl(self):
		logger = lldb.formatters.Logger.Logger()
		return stdlist_entry(self.entry.GetChildMemberWithName('__next_'))

	def _prev_impl(self):
		logger = lldb.formatters.Logger.Logger()
		return stdlist_entry(self.entry.GetChildMemberWithName('__prev_'))

	def _value_impl(self):
		logger = lldb.formatters.Logger.Logger()
		return self.entry.GetValueAsUnsigned(0)

	def _isnull_impl(self):
		logger = lldb.formatters.Logger.Logger()
		return self._value_impl() == 0

	def _sbvalue_impl(self):
		logger = lldb.formatters.Logger.Logger()
		return self.entry

	next = property(_next_impl,None)
	value = property(_value_impl,None)
	is_null = property(_isnull_impl,None)
	sbvalue = property(_sbvalue_impl,None)

class stdlist_iterator:

	def increment_node(self,node):
		logger = lldb.formatters.Logger.Logger()
		if node.is_null:
			return None
		return node.next

	def __init__(self,node):
		logger = lldb.formatters.Logger.Logger()
		self.node = stdlist_entry(node) # we convert the SBValue to an internal node object on entry

	def value(self):
		logger = lldb.formatters.Logger.Logger()
		return self.node.sbvalue # and return the SBValue back on exit

	def next(self):
		logger = lldb.formatters.Logger.Logger()
		node = self.increment_node(self.node)
		if node != None and node.sbvalue.IsValid() and not(node.is_null):
			self.node = node
			return self.value()
		else:
			return None

	def advance(self,N):
		logger = lldb.formatters.Logger.Logger()
		if N < 0:
			return None
		if N == 0:
			return self.value()
		if N == 1:
			return self.next()
		while N > 0:
			self.next()
			N = N - 1
		return self.value()


class stdlist_SynthProvider:
	def __init__(self, valobj, dict):
		logger = lldb.formatters.Logger.Logger()
		self.valobj = valobj
		self.count = None

	def next_node(self,node):
		logger = lldb.formatters.Logger.Logger()
		return node.GetChildMemberWithName('__next_')

	def value(self,node):
		logger = lldb.formatters.Logger.Logger()
		return node.GetValueAsUnsigned()

	# Floyd's cyle-finding algorithm
	# try to detect if this list has a loop
	def has_loop(self):
		global _list_uses_loop_detector
		logger = lldb.formatters.Logger.Logger()
		if _list_uses_loop_detector == False:
			logger >> "Asked not to use loop detection"
			return False
		slow = stdlist_entry(self.head)
		fast1 = stdlist_entry(self.head)
		fast2 = stdlist_entry(self.head)
		while slow.next.value != self.node_address:
			slow_value = slow.value
			fast1 = fast2.next
			fast2 = fast1.next
			if fast1.value == slow_value or fast2.value == slow_value:
				return True
			slow = slow.next
		return False

	def num_children(self):
		global _list_capping_size
		logger = lldb.formatters.Logger.Logger()
		if self.count == None:
			self.count = self.num_children_impl()
			if self.count > _list_capping_size:
				self.count = _list_capping_size
		return self.count

	def num_children_impl(self):
		global _list_capping_size
		logger = lldb.formatters.Logger.Logger()
		try:
			next_val = self.head.GetValueAsUnsigned(0)
			prev_val = self.tail.GetValueAsUnsigned(0)
			# After a std::list has been initialized, both next and prev will be non-NULL
			if next_val == 0 or prev_val == 0:
				return 0
			if next_val == self.node_address:
				return 0
			if next_val == prev_val:
				return 1
			if self.has_loop():
				return 0
			size = 2
			current = stdlist_entry(self.head)
			while current.next.value != self.node_address:
				size = size + 1
				current = current.next
				if size > _list_capping_size:
					return _list_capping_size
			return (size - 1)
		except:
			return 0;

	def get_child_index(self,name):
		logger = lldb.formatters.Logger.Logger()
		try:
			return int(name.lstrip('[').rstrip(']'))
		except:
			return -1

	def get_child_at_index(self,index):
		logger = lldb.formatters.Logger.Logger()
		logger >> "Fetching child " + str(index)
		if index < 0:
			return None;
		if index >= self.num_children():
			return None;
		try:
			current = stdlist_iterator(self.head)
			current = current.advance(index)
			# we do not return __value_ because then all our children would be named __value_
			# we need to make a copy of __value__ with the right name - unfortunate
			obj = current.GetChildMemberWithName('__value_')
			obj_data = obj.GetData()
			return self.valobj.CreateValueFromData('[' + str(index) + ']',obj_data,self.data_type)
		except:
			return None

	def extract_type(self):
		logger = lldb.formatters.Logger.Logger()
		list_type = self.valobj.GetType().GetUnqualifiedType()
		if list_type.IsReferenceType():
			list_type = list_type.GetDereferencedType()
		if list_type.GetNumberOfTemplateArguments() > 0:
			data_type = list_type.GetTemplateArgumentType(0)
		else:
			data_type = None
		return data_type

	def update(self):
		logger = lldb.formatters.Logger.Logger()
		self.count = None
		try:
			impl = self.valobj.GetChildMemberWithName('__end_')
			self.node_address = self.valobj.AddressOf().GetValueAsUnsigned(0)
			self.head = impl.GetChildMemberWithName('__next_')
			self.tail = impl.GetChildMemberWithName('__prev_')
			self.data_type = self.extract_type()
			self.data_size = self.data_type.GetByteSize()
		except:
			pass

	def has_children(self):
		return True


# Just an example: the actual summary is produced by a summary string: size=${svar%#}
def stdlist_SummaryProvider(valobj,dict):
	prov = stdlist_SynthProvider(valobj,None)
	return 'size=' + str(prov.num_children())

# a tree node - this class makes the syntax in the actual iterator nicer to read and maintain
class stdmap_iterator_node:
	def _left_impl(self):
		logger = lldb.formatters.Logger.Logger()
		return stdmap_iterator_node(self.node.GetChildMemberWithName("__left_"))

	def _right_impl(self):
		logger = lldb.formatters.Logger.Logger()
		return stdmap_iterator_node(self.node.GetChildMemberWithName("__right_"))

	def _parent_impl(self):
		logger = lldb.formatters.Logger.Logger()
		return stdmap_iterator_node(self.node.GetChildMemberWithName("__parent_"))

	def _value_impl(self):
		logger = lldb.formatters.Logger.Logger()
		return self.node.GetValueAsUnsigned(0)

	def _sbvalue_impl(self):
		logger = lldb.formatters.Logger.Logger()
		return self.node

	def _null_impl(self):
		logger = lldb.formatters.Logger.Logger()
		return self.value == 0

	def __init__(self,node):
		logger = lldb.formatters.Logger.Logger()
		self.node = node

	left = property(_left_impl,None)
	right = property(_right_impl,None)
	parent = property(_parent_impl,None)
	value = property(_value_impl,None)
	is_null = property(_null_impl,None)
	sbvalue = property(_sbvalue_impl,None)

# a Python implementation of the tree iterator used by libc++
class stdmap_iterator:

	def tree_min(self,x):
		logger = lldb.formatters.Logger.Logger()
		steps = 0
		if x.is_null:
			return None
		while (not x.left.is_null):
			x = x.left
			steps += 1
			if steps > self.max_count:
				logger >> "Returning None - we overflowed"
				return None
		return x

	def tree_max(self,x):
		logger = lldb.formatters.Logger.Logger()
		if x.is_null:
			return None
		while (not x.right.is_null):
			x =  x.right
		return x

	def tree_is_left_child(self,x):
		logger = lldb.formatters.Logger.Logger()
		if x.is_null:
			return None
		return True if x.value == x.parent.left.value else False

	def increment_node(self,node):
		logger = lldb.formatters.Logger.Logger()
		if node.is_null:
			return None
		if not node.right.is_null:
			return self.tree_min(node.right)
		steps = 0
		while (not self.tree_is_left_child(node)):
			steps += 1
			if steps > self.max_count:
				logger >> "Returning None - we overflowed"
				return None
			node = node.parent
		return node.parent

	def __init__(self,node,max_count=0):
		logger = lldb.formatters.Logger.Logger()
		self.node = stdmap_iterator_node(node) # we convert the SBValue to an internal node object on entry
		self.max_count = max_count

	def value(self):
		logger = lldb.formatters.Logger.Logger()
		return self.node.sbvalue # and return the SBValue back on exit

	def next(self):
		logger = lldb.formatters.Logger.Logger()
		node = self.increment_node(self.node)
		if node != None and node.sbvalue.IsValid() and not(node.is_null):
			self.node = node
			return self.value()
		else:
			return None

	def advance(self,N):
		logger = lldb.formatters.Logger.Logger()
		if N < 0:
			return None
		if N == 0:
			return self.value()
		if N == 1:
			return self.next()
		while N > 0:
			if self.next() == None:
				return None
			N = N - 1
		return self.value()

class stdmap_SynthProvider:

	def __init__(self, valobj, dict):
		logger = lldb.formatters.Logger.Logger()
		self.valobj = valobj;
		self.pointer_size = self.valobj.GetProcess().GetAddressByteSize()
		self.count = None

	def update(self):
		logger = lldb.formatters.Logger.Logger()
		self.count = None
		try:
			# we will set this to True if we find out that discovering a node in the map takes more steps than the overall size of the RB tree
			# if this gets set to True, then we will merrily return None for any child from that moment on
			self.garbage = False
			self.tree = self.valobj.GetChildMemberWithName('__tree_')
			self.root_node = self.tree.GetChildMemberWithName('__begin_node_')
			# this data is either lazily-calculated, or cannot be inferred at this moment
			# we still need to mark it as None, meaning "please set me ASAP"
			self.data_type = None
			self.data_size = None
			self.skip_size = None
		except:
			pass

	def num_children(self):
		global _map_capping_size
		logger = lldb.formatters.Logger.Logger()
		if self.count == None:
			self.count = self.num_children_impl()
			if self.count > _map_capping_size:
				self.count = _map_capping_size
		return self.count

	def num_children_impl(self):
		logger = lldb.formatters.Logger.Logger()
		try:
			return self.valobj.GetChildMemberWithName('__tree_').GetChildMemberWithName('__pair3_').GetChildMemberWithName('__first_').GetValueAsUnsigned()
		except:
			return 0;

	def has_children(self):
		return True

	def get_data_type(self):
		logger = lldb.formatters.Logger.Logger()
		if self.data_type == None or self.data_size == None:
			if self.num_children() == 0:
				return False
			deref = self.root_node.Dereference()
			if not(deref.IsValid()):
				return False
			value = deref.GetChildMemberWithName('__value_')
			if not(value.IsValid()):
				return False
			self.data_type = value.GetType()
			self.data_size = self.data_type.GetByteSize()
			self.skip_size = None
			return True
		else:
			return True

	def get_value_offset(self,node):
		logger = lldb.formatters.Logger.Logger()
		if self.skip_size == None:
			node_type = node.GetType()
			fields_count = node_type.GetNumberOfFields()
			for i in range(fields_count):
				field = node_type.GetFieldAtIndex(i)
				if field.GetName() == '__value_':
					self.skip_size = field.GetOffsetInBytes()
					break
		return (self.skip_size != None)

	def get_child_index(self,name):
		logger = lldb.formatters.Logger.Logger()
		try:
			return int(name.lstrip('[').rstrip(']'))
		except:
			return -1

	def get_child_at_index(self,index):
		logger = lldb.formatters.Logger.Logger()
		logger >> "Retrieving child " + str(index)
		if index < 0:
			return None
		if index >= self.num_children():
			return None;
		if self.garbage:
			logger >> "Returning None since this tree is garbage"
			return None
		try:
			iterator = stdmap_iterator(self.root_node,max_count=self.num_children())
			# the debug info for libc++ std::map is such that __begin_node_ has a very nice and useful type
			# out of which we can grab the information we need - every other node has a less informative
			# type which omits all value information and only contains housekeeping information for the RB tree
			# hence, we need to know if we are at a node != 0, so that we can still get at the data
			need_to_skip = (index > 0)
			current = iterator.advance(index)
			if current == None:
				logger >> "Tree is garbage - returning None"
				self.garbage = True
				return None
			if self.get_data_type():
				if not(need_to_skip):
					current = current.Dereference()
					obj = current.GetChildMemberWithName('__value_')
					obj_data = obj.GetData()
					self.get_value_offset(current) # make sure we have a valid offset for the next items
					# we do not return __value_ because then we would end up with a child named
					# __value_ instead of [0]
					return self.valobj.CreateValueFromData('[' + str(index) + ']',obj_data,self.data_type)
				else:
					# FIXME we need to have accessed item 0 before accessing any other item!
					if self.skip_size == None:
						logger >> "You asked for item > 0 before asking for item == 0, I will fetch 0 now then retry"
						if self.get_child_at_index(0):
							return self.get_child_at_index(index)
						else:
							logger >> "item == 0 could not be found. sorry, nothing can be done here."
							return None
					return current.CreateChildAtOffset('[' + str(index) + ']',self.skip_size,self.data_type)
			else:
				logger >> "Unable to infer data-type - returning None (should mark tree as garbage here?)"
				return None
		except Exception as err:
			logger >> "Hit an exception: " + str(err)
			return None

# Just an example: the actual summary is produced by a summary string: size=${svar%#}
def stdmap_SummaryProvider(valobj,dict):
	prov = stdmap_SynthProvider(valobj,None)
	return 'size=' + str(prov.num_children())

class stddeque_SynthProvider:
    def __init__(self, valobj, d):
        logger = lldb.formatters.Logger.Logger()
        logger.write("init")
        self.valobj = valobj
        self.pointer_size = self.valobj.GetProcess().GetAddressByteSize()
        self.count = None
        try:
            self.find_block_size()
        except:
            self.block_size = -1
            self.element_size = -1
        logger.write("block_size=%d, element_size=%d" % (self.block_size, self.element_size))

    def find_block_size(self):
        # in order to use the deque we must have the block size, or else
        # it's impossible to know what memory addresses are valid
        self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)
        self.element_size = self.element_type.GetByteSize()
        # The code says this, but there must be a better way:
        # template <class _Tp, class _Allocator>
        # class __deque_base {
        #    static const difference_type __block_size = sizeof(value_type) < 256 ? 4096 / sizeof(value_type) : 16;
        # }
        if self.element_size < 256:
            self.block_size =  4096 / self.element_size
        else:
            self.block_size = 16

    def num_children(self):
        global _deque_capping_size
        logger = lldb.formatters.Logger.Logger()
        if self.count is None:
            return 0
        return min(self.count, _deque_capping_size)

    def has_children(self):
        return True

    def get_child_index(self,name):
        logger = lldb.formatters.Logger.Logger()
        try:
            return int(name.lstrip('[').rstrip(']'))
        except:
            return -1

    def get_child_at_index(self,index):
        logger = lldb.formatters.Logger.Logger()
        logger.write("Fetching child " + str(index))
        if index < 0 or self.count is None:
                return None;
        if index >= self.num_children():
                return None;
        try:
            i, j = divmod(self.start+index, self.block_size)
            return self.first.CreateValueFromExpression('[' + str(index) + ']',
                                                        '*(*(%s + %d) + %d)' % (self.first.get_expr_path(), i, j))
        except:
            return None

    def update(self):
        logger = lldb.formatters.Logger.Logger()
        try:
            # A deque is effectively a two-dim array, with fixed width.
            # 'map' contains pointers to the rows of this array. The
            # full memory area allocated by the deque is delimited
            # by 'first' and 'end_cap'. However, only a subset of this
            # memory contains valid data since a deque may have some slack
            # at the front and back in order to have O(1) insertion at
            # both ends. The rows in active use are delimited by
            # 'begin' and 'end'.
            #
            # To find the elements that are actually constructed, the 'start'
            # variable tells which element in this NxM array is the 0th
            # one, and the 'size' element gives the number of elements
            # in the deque.
            count = self.valobj.GetChildMemberWithName('__size_').GetChildMemberWithName('__first_').GetValueAsUnsigned(0)
            # give up now if we cant access memory reliably
            if self.block_size < 0:
                logger.write("block_size < 0")
                return
            map_ = self.valobj.GetChildMemberWithName('__map_')
            start = self.valobj.GetChildMemberWithName('__start_').GetValueAsUnsigned(0)
            first = map_.GetChildMemberWithName('__first_')
            map_first = first.GetValueAsUnsigned(0)
            map_begin = map_.GetChildMemberWithName('__begin_').GetValueAsUnsigned(0)
            map_end   = map_.GetChildMemberWithName('__end_').GetValueAsUnsigned(0)
            map_endcap= map_.GetChildMemberWithName('__end_cap_').GetChildMemberWithName('__first_').GetValueAsUnsigned(0)
            # check consistency
            if not map_first <= map_begin <= map_end <= map_endcap:
                logger.write("map pointers are not monotonic")
                return
            total_rows, junk = divmod(map_endcap - map_first, self.pointer_size)
            if junk:
                logger.write("endcap-first doesnt align correctly")
                return
            active_rows, junk = divmod(map_end - map_begin, self.pointer_size)
            if junk:
                logger.write("end-begin doesnt align correctly")
                return
            start_row, junk = divmod(map_begin - map_first, self.pointer_size)
            if junk:
                logger.write("begin-first doesnt align correctly")
                return
            if not start_row*self.block_size <= start < (start_row+1)*self.block_size:
                logger.write("0th element must be in the 'begin' row")
                return
            end_row = start_row + active_rows
            if not count:
                if active_rows:
                    logger.write("empty deque but begin!=end")
                    return                            
            elif not (end_row-1)*self.block_size <= start+count < end_row*self.block_size:
                logger.write("nth element must be before the 'end' row")
                return
            logger.write("update success: count=%r, start=%r, first=%r" % (count,start,first))
            # if consistent, save all we really need:
            self.count = count
            self.start = start
            self.first = first
        except:
            self.count = None
            self.start = None
            self.map_first = None
            self.map_begin = None

class stdsharedptr_SynthProvider:
    def __init__(self, valobj, d):
        logger = lldb.formatters.Logger.Logger()
        logger.write("init")
        self.valobj = valobj
        #self.element_ptr_type = self.valobj.GetType().GetTemplateArgumentType(0).GetPointerType()
        self.ptr = None
        self.cntrl = None
        process = valobj.GetProcess()
        self.endianness = process.GetByteOrder()
        self.pointer_size = process.GetAddressByteSize()
        self.count_type = valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)

    def num_children(self):
        return 1

    def has_children(self):
        return True

    def get_child_index(self,name):
        if name=="__ptr_":
            return 0
        if name=="count":
            return 1
        if name=="weak_count":
            return 2
        return -1

    def get_child_at_index(self,index):
        if index == 0:
            return self.ptr
        if index == 1:
            if self.cntrl == None:
                count = 0
            else:
                count = 1 + self.cntrl.GetChildMemberWithName('__shared_owners_').GetValueAsSigned()
            return self.valobj.CreateValueFromData("count",
                                                   lldb.SBData.CreateDataFromUInt64Array(self.endianness, self.pointer_size, [count]),
                                                   self.count_type)
        if index == 2:
            if self.cntrl == None:
                count = 0
            else:
                count = 1 + self.cntrl.GetChildMemberWithName('__shared_weak_owners_').GetValueAsSigned()
            return self.valobj.CreateValueFromData("weak_count",
                                                   lldb.SBData.CreateDataFromUInt64Array(self.endianness, self.pointer_size, [count]),
                                                   self.count_type)
        return None

    def update(self):
        logger = lldb.formatters.Logger.Logger()
        self.ptr = self.valobj.GetChildMemberWithName('__ptr_')#.Cast(self.element_ptr_type)
        cntrl = self.valobj.GetChildMemberWithName('__cntrl_')
        if cntrl.GetValueAsUnsigned(0):
            self.cntrl = cntrl.Dereference()
        else:
            self.cntrl = None

# we can use two different categories for old and new formatters - type names are different enough that we should make no confusion
# talking with libc++ developer: "std::__1::class_name is set in stone until we decide to change the ABI. That shouldn't happen within a 5 year time frame"
def __lldb_init_module(debugger,dict):
	debugger.HandleCommand('type summary add -F libcxx.stdstring_SummaryProvider "std::__1::string" -w libcxx')
	debugger.HandleCommand('type summary add -F libcxx.stdstring_SummaryProvider "std::__1::basic_string<char, class std::__1::char_traits<char>, class std::__1::allocator<char> >" -w libcxx')
	debugger.HandleCommand('type synthetic add -l libcxx.stdvector_SynthProvider -x "^(std::__1::)vector<.+>$" -w libcxx')
	debugger.HandleCommand('type summary add -F libcxx.stdvector_SummaryProvider -e -x "^(std::__1::)vector<.+>$" -w libcxx')
	debugger.HandleCommand('type synthetic add -l libcxx.stdlist_SynthProvider -x "^(std::__1::)list<.+>$" -w libcxx')
	debugger.HandleCommand('type summary add -F libcxx.stdlist_SummaryProvider -e -x "^(std::__1::)list<.+>$" -w libcxx')
	debugger.HandleCommand('type synthetic add -l libcxx.stdmap_SynthProvider -x "^(std::__1::)map<.+> >$" -w libcxx')
	debugger.HandleCommand('type summary add -F libcxx.stdmap_SummaryProvider -e -x "^(std::__1::)map<.+> >$" -w libcxx')
	debugger.HandleCommand("type category enable libcxx")
	debugger.HandleCommand('type synthetic add -l libcxx.stddeque_SynthProvider -x "^(std::__1::)deque<.+>$" -w libcxx')
	debugger.HandleCommand('type synthetic add -l libcxx.stdsharedptr_SynthProvider -x "^(std::__1::)shared_ptr<.+>$" -w libcxx')
	# turns out the structs look the same, so weak_ptr can be handled the same!
	debugger.HandleCommand('type synthetic add -l libcxx.stdsharedptr_SynthProvider -x "^(std::__1::)weak_ptr<.+>$" -w libcxx')

_map_capping_size = 255
_list_capping_size = 255
_list_uses_loop_detector = True
_deque_capping_size = 255
