"""lldb data formatters for clang classes.

Usage
--
import this file in your ~/.lldbinit by adding this line:

command script import /path/to/ClangDataFormat.py

After that, instead of getting this:

(lldb) p Tok.Loc
(clang::SourceLocation) $0 = {
  (unsigned int) ID = 123582
}

you'll get:

(lldb) p Tok.Loc
(clang::SourceLocation) $4 = "/usr/include/i386/_types.h:37:1" (offset: 123582, file, local)
"""

import lldb

def __lldb_init_module(debugger, internal_dict):
	debugger.HandleCommand("type summary add -F ClangDataFormat.SourceLocation_summary clang::SourceLocation")
	debugger.HandleCommand("type summary add -F ClangDataFormat.QualType_summary clang::QualType")
	debugger.HandleCommand("type summary add -F ClangDataFormat.StringRef_summary llvm::StringRef")

def SourceLocation_summary(srcloc, internal_dict):
	return SourceLocation(srcloc).summary()

def QualType_summary(qualty, internal_dict):
	return QualType(qualty).summary()

def StringRef_summary(strref, internal_dict):
	return StringRef(strref).summary()

class SourceLocation(object):
	def __init__(self, srcloc):
		self.srcloc = srcloc
		self.ID = srcloc.GetChildAtIndex(0).GetValueAsUnsigned()
		self.frame = srcloc.GetFrame()
	
	def offset(self):
		return getValueFromExpression(self.srcloc, ".getOffset()").GetValueAsUnsigned()

	def isInvalid(self):
		return self.ID == 0

	def isMacro(self):
		return getValueFromExpression(self.srcloc, ".isMacroID()").GetValueAsUnsigned()

	def isLocal(self, srcmgr_path):
		return self.frame.EvaluateExpression("(%s).isLocalSourceLocation(%s)" % (srcmgr_path, getExpressionPath(self.srcloc))).GetValueAsUnsigned()

	def getPrint(self, srcmgr_path):
		print_str = getValueFromExpression(self.srcloc, ".printToString(%s)" % srcmgr_path)
		return print_str.GetSummary()

	def summary(self):
		if self.isInvalid():
			return "<invalid loc>"
		srcmgr_path = findObjectExpressionPath("clang::SourceManager", self.frame)
		if srcmgr_path:
			return "%s (offset: %d, %s, %s)" % (self.getPrint(srcmgr_path), self.offset(), "macro" if self.isMacro() else "file", "local" if self.isLocal(srcmgr_path) else "loaded")
		return "(offset: %d, %s)" % (self.offset(), "macro" if self.isMacro() else "file")

class QualType(object):
	def __init__(self, qualty):
		self.qualty = qualty

	def getAsString(self):
		std_str = getValueFromExpression(self.qualty, ".getAsString()")
		return std_str.GetSummary()

	def summary(self):
		desc = self.getAsString()
		if desc == '"NULL TYPE"':
			return "<NULL TYPE>"
		return desc

class StringRef(object):
	def __init__(self, strref):
		self.strref = strref
		self.Data_value = strref.GetChildAtIndex(0)
		self.Length = strref.GetChildAtIndex(1).GetValueAsUnsigned()

	def summary(self):
		if self.Length == 0:
			return '""'
		data = self.Data_value.GetPointeeData(0, self.Length)
		error = lldb.SBError()
		string = data.ReadRawData(error, 0, data.GetByteSize())
		if error.Fail():
			return None
		return '"%s"' % string


# Key is a (function address, type name) tuple, value is the expression path for
# an object with such a type name from inside that function.
FramePathMapCache = {}

def findObjectExpressionPath(typename, frame):
	func_addr = frame.GetFunction().GetStartAddress().GetFileAddress()
	key = (func_addr, typename)
	try:
		return FramePathMapCache[key]
	except KeyError:
		#print "CACHE MISS"
		path = None
		obj = findObject(typename, frame)
		if obj:
			path = getExpressionPath(obj)
		FramePathMapCache[key] = path
		return path

def findObject(typename, frame):
	def getTypename(value):
		# FIXME: lldb should provide something like getBaseType
		ty = value.GetType()
		if ty.IsPointerType() or ty.IsReferenceType():
			return ty.GetPointeeType().GetName()
		return ty.GetName()

	def searchForType(value, searched):
		tyname = getTypename(value)
		#print "SEARCH:", getExpressionPath(value), value.GetType().GetName()
		if tyname == typename:
			return value
		ty = value.GetType()
		if not (ty.IsPointerType() or
		        ty.IsReferenceType() or
				# FIXME: lldb should provide something like getCanonicalType
		        tyname.startswith("llvm::IntrusiveRefCntPtr<") or
		        tyname.startswith("llvm::OwningPtr<")):
			return None
		# FIXME: Hashing for SBTypes does not seem to work correctly, uses the typename instead,
		# and not the canonical one unfortunately.
		if tyname in searched:
			return None
		searched.add(tyname)
		for i in range(value.GetNumChildren()):
			child = value.GetChildAtIndex(i, 0, False)
			found = searchForType(child, searched)
			if found:
				return found

	searched = set()
	value_list = frame.GetVariables(True, True, True, True)
	for val in value_list:
		found = searchForType(val, searched)
		if found:
			return found if not found.TypeIsPointerType() else found.Dereference()

def getValueFromExpression(val, expr):
	return val.GetFrame().EvaluateExpression(getExpressionPath(val) + expr)

def getExpressionPath(val):
	stream = lldb.SBStream()
	val.GetExpressionPath(stream)
	return stream.GetData()
