blob: 817c0b6056f00e6b6bbbe8f477c0c715153a9885 [file] [log] [blame]
Argyrios Kyrtzidis32f17642012-11-09 22:59:01 +00001"""lldb data formatters for clang classes.
2
3Usage
4--
5import this file in your ~/.lldbinit by adding this line:
6
7command script import /path/to/ClangDataFormat.py
8
9After that, instead of getting this:
10
11(lldb) p Tok.Loc
12(clang::SourceLocation) $0 = {
13 (unsigned int) ID = 123582
14}
15
16you'll get:
17
18(lldb) p Tok.Loc
Argyrios Kyrtzidisa3caaf32012-11-14 23:52:11 +000019(clang::SourceLocation) $4 = "/usr/include/i386/_types.h:37:1" (offset: 123582, file, local)
Argyrios Kyrtzidis32f17642012-11-09 22:59:01 +000020"""
21
22import lldb
23
24def __lldb_init_module(debugger, internal_dict):
25 debugger.HandleCommand("type summary add -F ClangDataFormat.SourceLocation_summary clang::SourceLocation")
26
27def SourceLocation_summary(srcloc, internal_dict):
28 return SourceLocation(srcloc).summary()
29
30class SourceLocation(object):
31 def __init__(self, srcloc):
32 self.srcloc = srcloc
33
34 def offset(self):
35 return getValueFromExpression(self.srcloc, ".getOffset()").GetValueAsUnsigned()
36
37 def isMacro(self):
38 return getValueFromExpression(self.srcloc, ".isMacroID()").GetValueAsUnsigned()
39
Argyrios Kyrtzidisa3caaf32012-11-14 23:52:11 +000040 def isLocal(self, srcmgr_path):
41 return lldb.frame.EvaluateExpression("(%s).isLocalSourceLocation(%s)" % (srcmgr_path, getExpressionPath(self.srcloc))).GetValueAsUnsigned()
42
Argyrios Kyrtzidis32f17642012-11-09 22:59:01 +000043 def getPrint(self, srcmgr_path):
44 print_str = getValueFromExpression(self.srcloc, ".printToString(%s)" % srcmgr_path)
45 return print_str.GetSummary()
46
47 def summary(self):
48 desc = "(offset: %d, %s)" % (self.offset(), "macro" if self.isMacro() else "file")
49 srcmgr_path = findObjectExpressionPath("clang::SourceManager", lldb.frame)
50 if srcmgr_path:
Argyrios Kyrtzidisa3caaf32012-11-14 23:52:11 +000051 desc = "%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")
Argyrios Kyrtzidis32f17642012-11-09 22:59:01 +000052 return desc
53
54# Key is a (function address, type name) tuple, value is the expression path for
55# an object with such a type name from inside that function.
56FramePathMapCache = {}
57
Argyrios Kyrtzidis32f17642012-11-09 22:59:01 +000058def findObjectExpressionPath(typename, frame):
59 func_addr = frame.GetFunction().GetStartAddress().GetFileAddress()
60 key = (func_addr, typename)
61 try:
62 return FramePathMapCache[key]
63 except KeyError:
64 #print "CACHE MISS"
65 path = None
66 obj = findObject(typename, frame)
67 if obj:
68 path = getExpressionPath(obj)
69 FramePathMapCache[key] = path
70 return path
71
72def findObject(typename, frame):
73 def getTypename(value):
74 # FIXME: lldb should provide something like getBaseType
75 ty = value.GetType()
76 if ty.IsPointerType() or ty.IsReferenceType():
77 return ty.GetPointeeType().GetName()
78 return ty.GetName()
79
80 def searchForType(value, searched):
81 tyname = getTypename(value)
82 #print "SEARCH:", getExpressionPath(value), value.GetType().GetName()
83 if tyname == typename:
84 return value
85 ty = value.GetType()
86 if not (ty.IsPointerType() or
87 ty.IsReferenceType() or
88 # FIXME: lldb should provide something like getCanonicalType
89 tyname.startswith("llvm::IntrusiveRefCntPtr<") or
90 tyname.startswith("llvm::OwningPtr<")):
91 return None
92 # FIXME: Hashing for SBTypes does not seem to work correctly, uses the typename instead,
93 # and not the canonical one unfortunately.
94 if tyname in searched:
95 return None
96 searched.add(tyname)
97 for i in range(value.GetNumChildren()):
98 child = value.GetChildAtIndex(i, 0, False)
99 found = searchForType(child, searched)
100 if found:
101 return found
102
103 searched = set()
104 value_list = frame.GetVariables(True, True, True, True)
105 for val in value_list:
106 found = searchForType(val, searched)
107 if found:
108 return found if not found.TypeIsPointerType() else found.Dereference()
109
110def getValueFromExpression(val, expr):
111 return lldb.frame.EvaluateExpression(getExpressionPath(val) + expr)
112
113def getExpressionPath(val):
114 stream = lldb.SBStream()
115 val.GetExpressionPath(stream)
116 return stream.GetData()