[cfe-commits] r167640 - /cfe/trunk/utils/ClangDataFormat.py

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Nov 9 14:59:02 PST 2012


Author: akirtzidis
Date: Fri Nov  9 16:59:01 2012
New Revision: 167640

URL: http://llvm.org/viewvc/llvm-project?rev=167640&view=rev
Log:
Add lldb data formatters for clang classes, starting with SourceLocation.

When installed, 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)

This depends on r167629.

Added:
    cfe/trunk/utils/ClangDataFormat.py

Added: cfe/trunk/utils/ClangDataFormat.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/ClangDataFormat.py?rev=167640&view=auto
==============================================================================
--- cfe/trunk/utils/ClangDataFormat.py (added)
+++ cfe/trunk/utils/ClangDataFormat.py Fri Nov  9 16:59:01 2012
@@ -0,0 +1,116 @@
+"""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)
+"""
+
+import lldb
+
+def __lldb_init_module(debugger, internal_dict):
+	debugger.HandleCommand("type summary add -F ClangDataFormat.SourceLocation_summary clang::SourceLocation")
+
+def SourceLocation_summary(srcloc, internal_dict):
+	return SourceLocation(srcloc).summary()
+
+class SourceLocation(object):
+	def __init__(self, srcloc):
+		self.srcloc = srcloc
+	
+	def offset(self):
+		return getValueFromExpression(self.srcloc, ".getOffset()").GetValueAsUnsigned()
+
+	def isMacro(self):
+		return getValueFromExpression(self.srcloc, ".isMacroID()").GetValueAsUnsigned()
+
+	def getPrint(self, srcmgr_path):
+		print_str = getValueFromExpression(self.srcloc, ".printToString(%s)" % srcmgr_path)
+		return print_str.GetSummary()
+
+	def summary(self):
+		desc = "(offset: %d, %s)" % (self.offset(), "macro" if self.isMacro() else "file")
+		srcmgr_path = findObjectExpressionPath("clang::SourceManager", lldb.frame)
+		if srcmgr_path:
+			desc = self.getPrint(srcmgr_path) + " " + desc
+		return desc
+
+# 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 findSourceManager(frame):
+	return findObject("clang::SourceManager", SourceManager_Paths, frame)
+
+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 lldb.frame.EvaluateExpression(getExpressionPath(val) + expr)
+
+def getExpressionPath(val):
+	stream = lldb.SBStream()
+	val.GetExpressionPath(stream)
+	return stream.GetData()





More information about the cfe-commits mailing list