1 """lldb data formatters for clang classes.
5 import this file in your ~/.lldbinit by adding this line:
7 command script import /path/to/ClangDataFormat.py
9 After that, instead of getting this:
12 (clang::SourceLocation) $0 = {
13 (unsigned int) ID = 123582
19 (clang::SourceLocation) $4 = "/usr/include/i386/_types.h:37:1" (offset: 123582, file, local)
25 def __lldb_init_module(debugger
, internal_dict
):
26 debugger
.HandleCommand(
27 "type summary add -F ClangDataFormat.SourceLocation_summary clang::SourceLocation"
29 debugger
.HandleCommand(
30 "type summary add -F ClangDataFormat.QualType_summary clang::QualType"
34 def SourceLocation_summary(srcloc
, internal_dict
):
35 return SourceLocation(srcloc
).summary()
38 def QualType_summary(qualty
, internal_dict
):
39 return QualType(qualty
).summary()
42 class SourceLocation(object):
43 def __init__(self
, srcloc
):
45 self
.ID
= srcloc
.GetChildAtIndex(0).GetValueAsUnsigned()
46 self
.frame
= srcloc
.GetFrame()
49 return getValueFromExpression(self
.srcloc
, ".getOffset()").GetValueAsUnsigned()
55 return getValueFromExpression(self
.srcloc
, ".isMacroID()").GetValueAsUnsigned()
57 def isLocal(self
, srcmgr_path
):
58 return self
.frame
.EvaluateExpression(
59 "(%s).isLocalSourceLocation(%s)"
60 % (srcmgr_path
, getExpressionPath(self
.srcloc
))
61 ).GetValueAsUnsigned()
63 def getPrint(self
, srcmgr_path
):
64 print_str
= getValueFromExpression(
65 self
.srcloc
, ".printToString(%s)" % srcmgr_path
67 return print_str
.GetSummary()
71 return "<invalid loc>"
72 srcmgr_path
= findObjectExpressionPath("clang::SourceManager", self
.frame
)
74 return "%s (offset: %d, %s, %s)" % (
75 self
.getPrint(srcmgr_path
),
77 "macro" if self
.isMacro() else "file",
78 "local" if self
.isLocal(srcmgr_path
) else "loaded",
80 return "(offset: %d, %s)" % (
82 "macro" if self
.isMacro() else "file",
86 class QualType(object):
87 def __init__(self
, qualty
):
90 def getAsString(self
):
91 std_str
= getValueFromExpression(self
.qualty
, ".getAsString()")
92 return std_str
.GetSummary()
95 desc
= self
.getAsString()
96 if desc
== '"NULL TYPE"':
101 # Key is a (function address, type name) tuple, value is the expression path for
102 # an object with such a type name from inside that function.
103 FramePathMapCache
= {}
106 def findObjectExpressionPath(typename
, frame
):
107 func_addr
= frame
.GetFunction().GetStartAddress().GetFileAddress()
108 key
= (func_addr
, typename
)
110 return FramePathMapCache
[key
]
114 obj
= findObject(typename
, frame
)
116 path
= getExpressionPath(obj
)
117 FramePathMapCache
[key
] = path
121 def findObject(typename
, frame
):
122 def getTypename(value
):
123 # FIXME: lldb should provide something like getBaseType
125 if ty
.IsPointerType() or ty
.IsReferenceType():
126 return ty
.GetPointeeType().GetName()
129 def searchForType(value
, searched
):
130 tyname
= getTypename(value
)
131 # print "SEARCH:", getExpressionPath(value), value.GetType().GetName()
132 if tyname
== typename
:
137 or ty
.IsReferenceType()
139 # FIXME: lldb should provide something like getCanonicalType
140 tyname
.startswith("llvm::IntrusiveRefCntPtr<")
141 or tyname
.startswith("llvm::OwningPtr<")
144 # FIXME: Hashing for SBTypes does not seem to work correctly, uses the typename instead,
145 # and not the canonical one unfortunately.
146 if tyname
in searched
:
149 for i
in range(value
.GetNumChildren()):
150 child
= value
.GetChildAtIndex(i
, 0, False)
151 found
= searchForType(child
, searched
)
156 value_list
= frame
.GetVariables(True, True, True, True)
157 for val
in value_list
:
158 found
= searchForType(val
, searched
)
160 return found
if not found
.TypeIsPointerType() else found
.Dereference()
163 def getValueFromExpression(val
, expr
):
164 return val
.GetFrame().EvaluateExpression(getExpressionPath(val
) + expr
)
167 def getExpressionPath(val
):
168 stream
= lldb
.SBStream()
169 val
.GetExpressionPath(stream
)
170 return stream
.GetData()