xref: /minix3/external/bsd/llvm/dist/clang/utils/ClangDataFormat.py (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc"""lldb data formatters for clang classes.
2*f4a2713aSLionel Sambuc
3*f4a2713aSLionel SambucUsage
4*f4a2713aSLionel Sambuc--
5*f4a2713aSLionel Sambucimport this file in your ~/.lldbinit by adding this line:
6*f4a2713aSLionel Sambuc
7*f4a2713aSLionel Sambuccommand script import /path/to/ClangDataFormat.py
8*f4a2713aSLionel Sambuc
9*f4a2713aSLionel SambucAfter that, instead of getting this:
10*f4a2713aSLionel Sambuc
11*f4a2713aSLionel Sambuc(lldb) p Tok.Loc
12*f4a2713aSLionel Sambuc(clang::SourceLocation) $0 = {
13*f4a2713aSLionel Sambuc  (unsigned int) ID = 123582
14*f4a2713aSLionel Sambuc}
15*f4a2713aSLionel Sambuc
16*f4a2713aSLionel Sambucyou'll get:
17*f4a2713aSLionel Sambuc
18*f4a2713aSLionel Sambuc(lldb) p Tok.Loc
19*f4a2713aSLionel Sambuc(clang::SourceLocation) $4 = "/usr/include/i386/_types.h:37:1" (offset: 123582, file, local)
20*f4a2713aSLionel Sambuc"""
21*f4a2713aSLionel Sambuc
22*f4a2713aSLionel Sambucimport lldb
23*f4a2713aSLionel Sambuc
24*f4a2713aSLionel Sambucdef __lldb_init_module(debugger, internal_dict):
25*f4a2713aSLionel Sambuc	debugger.HandleCommand("type summary add -F ClangDataFormat.SourceLocation_summary clang::SourceLocation")
26*f4a2713aSLionel Sambuc	debugger.HandleCommand("type summary add -F ClangDataFormat.QualType_summary clang::QualType")
27*f4a2713aSLionel Sambuc	debugger.HandleCommand("type summary add -F ClangDataFormat.StringRef_summary llvm::StringRef")
28*f4a2713aSLionel Sambuc
29*f4a2713aSLionel Sambucdef SourceLocation_summary(srcloc, internal_dict):
30*f4a2713aSLionel Sambuc	return SourceLocation(srcloc).summary()
31*f4a2713aSLionel Sambuc
32*f4a2713aSLionel Sambucdef QualType_summary(qualty, internal_dict):
33*f4a2713aSLionel Sambuc	return QualType(qualty).summary()
34*f4a2713aSLionel Sambuc
35*f4a2713aSLionel Sambucdef StringRef_summary(strref, internal_dict):
36*f4a2713aSLionel Sambuc	return StringRef(strref).summary()
37*f4a2713aSLionel Sambuc
38*f4a2713aSLionel Sambucclass SourceLocation(object):
39*f4a2713aSLionel Sambuc	def __init__(self, srcloc):
40*f4a2713aSLionel Sambuc		self.srcloc = srcloc
41*f4a2713aSLionel Sambuc		self.ID = srcloc.GetChildAtIndex(0).GetValueAsUnsigned()
42*f4a2713aSLionel Sambuc		self.frame = srcloc.GetFrame()
43*f4a2713aSLionel Sambuc
44*f4a2713aSLionel Sambuc	def offset(self):
45*f4a2713aSLionel Sambuc		return getValueFromExpression(self.srcloc, ".getOffset()").GetValueAsUnsigned()
46*f4a2713aSLionel Sambuc
47*f4a2713aSLionel Sambuc	def isInvalid(self):
48*f4a2713aSLionel Sambuc		return self.ID == 0
49*f4a2713aSLionel Sambuc
50*f4a2713aSLionel Sambuc	def isMacro(self):
51*f4a2713aSLionel Sambuc		return getValueFromExpression(self.srcloc, ".isMacroID()").GetValueAsUnsigned()
52*f4a2713aSLionel Sambuc
53*f4a2713aSLionel Sambuc	def isLocal(self, srcmgr_path):
54*f4a2713aSLionel Sambuc		return self.frame.EvaluateExpression("(%s).isLocalSourceLocation(%s)" % (srcmgr_path, getExpressionPath(self.srcloc))).GetValueAsUnsigned()
55*f4a2713aSLionel Sambuc
56*f4a2713aSLionel Sambuc	def getPrint(self, srcmgr_path):
57*f4a2713aSLionel Sambuc		print_str = getValueFromExpression(self.srcloc, ".printToString(%s)" % srcmgr_path)
58*f4a2713aSLionel Sambuc		return print_str.GetSummary()
59*f4a2713aSLionel Sambuc
60*f4a2713aSLionel Sambuc	def summary(self):
61*f4a2713aSLionel Sambuc		if self.isInvalid():
62*f4a2713aSLionel Sambuc			return "<invalid loc>"
63*f4a2713aSLionel Sambuc		srcmgr_path = findObjectExpressionPath("clang::SourceManager", self.frame)
64*f4a2713aSLionel Sambuc		if srcmgr_path:
65*f4a2713aSLionel Sambuc			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")
66*f4a2713aSLionel Sambuc		return "(offset: %d, %s)" % (self.offset(), "macro" if self.isMacro() else "file")
67*f4a2713aSLionel Sambuc
68*f4a2713aSLionel Sambucclass QualType(object):
69*f4a2713aSLionel Sambuc	def __init__(self, qualty):
70*f4a2713aSLionel Sambuc		self.qualty = qualty
71*f4a2713aSLionel Sambuc
72*f4a2713aSLionel Sambuc	def getAsString(self):
73*f4a2713aSLionel Sambuc		std_str = getValueFromExpression(self.qualty, ".getAsString()")
74*f4a2713aSLionel Sambuc		return std_str.GetSummary()
75*f4a2713aSLionel Sambuc
76*f4a2713aSLionel Sambuc	def summary(self):
77*f4a2713aSLionel Sambuc		desc = self.getAsString()
78*f4a2713aSLionel Sambuc		if desc == '"NULL TYPE"':
79*f4a2713aSLionel Sambuc			return "<NULL TYPE>"
80*f4a2713aSLionel Sambuc		return desc
81*f4a2713aSLionel Sambuc
82*f4a2713aSLionel Sambucclass StringRef(object):
83*f4a2713aSLionel Sambuc	def __init__(self, strref):
84*f4a2713aSLionel Sambuc		self.strref = strref
85*f4a2713aSLionel Sambuc		self.Data_value = strref.GetChildAtIndex(0)
86*f4a2713aSLionel Sambuc		self.Length = strref.GetChildAtIndex(1).GetValueAsUnsigned()
87*f4a2713aSLionel Sambuc
88*f4a2713aSLionel Sambuc	def summary(self):
89*f4a2713aSLionel Sambuc		if self.Length == 0:
90*f4a2713aSLionel Sambuc			return '""'
91*f4a2713aSLionel Sambuc		data = self.Data_value.GetPointeeData(0, self.Length)
92*f4a2713aSLionel Sambuc		error = lldb.SBError()
93*f4a2713aSLionel Sambuc		string = data.ReadRawData(error, 0, data.GetByteSize())
94*f4a2713aSLionel Sambuc		if error.Fail():
95*f4a2713aSLionel Sambuc			return None
96*f4a2713aSLionel Sambuc		return '"%s"' % string
97*f4a2713aSLionel Sambuc
98*f4a2713aSLionel Sambuc
99*f4a2713aSLionel Sambuc# Key is a (function address, type name) tuple, value is the expression path for
100*f4a2713aSLionel Sambuc# an object with such a type name from inside that function.
101*f4a2713aSLionel SambucFramePathMapCache = {}
102*f4a2713aSLionel Sambuc
103*f4a2713aSLionel Sambucdef findObjectExpressionPath(typename, frame):
104*f4a2713aSLionel Sambuc	func_addr = frame.GetFunction().GetStartAddress().GetFileAddress()
105*f4a2713aSLionel Sambuc	key = (func_addr, typename)
106*f4a2713aSLionel Sambuc	try:
107*f4a2713aSLionel Sambuc		return FramePathMapCache[key]
108*f4a2713aSLionel Sambuc	except KeyError:
109*f4a2713aSLionel Sambuc		#print "CACHE MISS"
110*f4a2713aSLionel Sambuc		path = None
111*f4a2713aSLionel Sambuc		obj = findObject(typename, frame)
112*f4a2713aSLionel Sambuc		if obj:
113*f4a2713aSLionel Sambuc			path = getExpressionPath(obj)
114*f4a2713aSLionel Sambuc		FramePathMapCache[key] = path
115*f4a2713aSLionel Sambuc		return path
116*f4a2713aSLionel Sambuc
117*f4a2713aSLionel Sambucdef findObject(typename, frame):
118*f4a2713aSLionel Sambuc	def getTypename(value):
119*f4a2713aSLionel Sambuc		# FIXME: lldb should provide something like getBaseType
120*f4a2713aSLionel Sambuc		ty = value.GetType()
121*f4a2713aSLionel Sambuc		if ty.IsPointerType() or ty.IsReferenceType():
122*f4a2713aSLionel Sambuc			return ty.GetPointeeType().GetName()
123*f4a2713aSLionel Sambuc		return ty.GetName()
124*f4a2713aSLionel Sambuc
125*f4a2713aSLionel Sambuc	def searchForType(value, searched):
126*f4a2713aSLionel Sambuc		tyname = getTypename(value)
127*f4a2713aSLionel Sambuc		#print "SEARCH:", getExpressionPath(value), value.GetType().GetName()
128*f4a2713aSLionel Sambuc		if tyname == typename:
129*f4a2713aSLionel Sambuc			return value
130*f4a2713aSLionel Sambuc		ty = value.GetType()
131*f4a2713aSLionel Sambuc		if not (ty.IsPointerType() or
132*f4a2713aSLionel Sambuc		        ty.IsReferenceType() or
133*f4a2713aSLionel Sambuc				# FIXME: lldb should provide something like getCanonicalType
134*f4a2713aSLionel Sambuc		        tyname.startswith("llvm::IntrusiveRefCntPtr<") or
135*f4a2713aSLionel Sambuc		        tyname.startswith("llvm::OwningPtr<")):
136*f4a2713aSLionel Sambuc			return None
137*f4a2713aSLionel Sambuc		# FIXME: Hashing for SBTypes does not seem to work correctly, uses the typename instead,
138*f4a2713aSLionel Sambuc		# and not the canonical one unfortunately.
139*f4a2713aSLionel Sambuc		if tyname in searched:
140*f4a2713aSLionel Sambuc			return None
141*f4a2713aSLionel Sambuc		searched.add(tyname)
142*f4a2713aSLionel Sambuc		for i in range(value.GetNumChildren()):
143*f4a2713aSLionel Sambuc			child = value.GetChildAtIndex(i, 0, False)
144*f4a2713aSLionel Sambuc			found = searchForType(child, searched)
145*f4a2713aSLionel Sambuc			if found:
146*f4a2713aSLionel Sambuc				return found
147*f4a2713aSLionel Sambuc
148*f4a2713aSLionel Sambuc	searched = set()
149*f4a2713aSLionel Sambuc	value_list = frame.GetVariables(True, True, True, True)
150*f4a2713aSLionel Sambuc	for val in value_list:
151*f4a2713aSLionel Sambuc		found = searchForType(val, searched)
152*f4a2713aSLionel Sambuc		if found:
153*f4a2713aSLionel Sambuc			return found if not found.TypeIsPointerType() else found.Dereference()
154*f4a2713aSLionel Sambuc
155*f4a2713aSLionel Sambucdef getValueFromExpression(val, expr):
156*f4a2713aSLionel Sambuc	return val.GetFrame().EvaluateExpression(getExpressionPath(val) + expr)
157*f4a2713aSLionel Sambuc
158*f4a2713aSLionel Sambucdef getExpressionPath(val):
159*f4a2713aSLionel Sambuc	stream = lldb.SBStream()
160*f4a2713aSLionel Sambuc	val.GetExpressionPath(stream)
161*f4a2713aSLionel Sambuc	return stream.GetData()
162