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)
24 def __lldb_init_module(debugger
, internal_dict
):
25 debugger
.HandleCommand("type summary add -F ClangDataFormat.SourceLocation_summary clang::SourceLocation")
26 debugger
.HandleCommand("type summary add -F ClangDataFormat.QualType_summary clang::QualType")
27 debugger
.HandleCommand("type summary add -F ClangDataFormat.StringRef_summary llvm::StringRef")
29 def SourceLocation_summary(srcloc
, internal_dict
):
30 return SourceLocation(srcloc
).summary()
32 def QualType_summary(qualty
, internal_dict
):
33 return QualType(qualty
).summary()
35 def StringRef_summary(strref
, internal_dict
):
36 return StringRef(strref
).summary()
38 class SourceLocation(object):
39 def __init__(self
, srcloc
):
41 self
.ID
= srcloc
.GetChildAtIndex(0).GetValueAsUnsigned()
42 self
.frame
= srcloc
.GetFrame()
45 return getValueFromExpression(self
.srcloc
, ".getOffset()").GetValueAsUnsigned()
51 return getValueFromExpression(self
.srcloc
, ".isMacroID()").GetValueAsUnsigned()
53 def isLocal(self
, srcmgr_path
):
54 return self
.frame
.EvaluateExpression("(%s).isLocalSourceLocation(%s)" % (srcmgr_path
, getExpressionPath(self
.srcloc
))).GetValueAsUnsigned()
56 def getPrint(self
, srcmgr_path
):
57 print_str
= getValueFromExpression(self
.srcloc
, ".printToString(%s)" % srcmgr_path
)
58 return print_str
.GetSummary()
62 return "<invalid loc>"
63 srcmgr_path
= findObjectExpressionPath("clang::SourceManager", self
.frame
)
65 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 return "(offset: %d, %s)" % (self
.offset(), "macro" if self
.isMacro() else "file")
68 class QualType(object):
69 def __init__(self
, qualty
):
72 def getAsString(self
):
73 std_str
= getValueFromExpression(self
.qualty
, ".getAsString()")
74 return std_str
.GetSummary()
77 desc
= self
.getAsString()
78 if desc
== '"NULL TYPE"':
82 class StringRef(object):
83 def __init__(self
, strref
):
85 self
.Data_value
= strref
.GetChildAtIndex(0)
86 self
.Length
= strref
.GetChildAtIndex(1).GetValueAsUnsigned()
91 data
= self
.Data_value
.GetPointeeData(0, self
.Length
)
92 error
= lldb
.SBError()
93 string
= data
.ReadRawData(error
, 0, data
.GetByteSize())
96 return '"%s"' % string
99 # Key is a (function address, type name) tuple, value is the expression path for
100 # an object with such a type name from inside that function.
101 FramePathMapCache
= {}
103 def findObjectExpressionPath(typename
, frame
):
104 func_addr
= frame
.GetFunction().GetStartAddress().GetFileAddress()
105 key
= (func_addr
, typename
)
107 return FramePathMapCache
[key
]
111 obj
= findObject(typename
, frame
)
113 path
= getExpressionPath(obj
)
114 FramePathMapCache
[key
] = path
117 def findObject(typename
, frame
):
118 def getTypename(value
):
119 # FIXME: lldb should provide something like getBaseType
121 if ty
.IsPointerType() or ty
.IsReferenceType():
122 return ty
.GetPointeeType().GetName()
125 def searchForType(value
, searched
):
126 tyname
= getTypename(value
)
127 #print "SEARCH:", getExpressionPath(value), value.GetType().GetName()
128 if tyname
== typename
:
131 if not (ty
.IsPointerType() or
132 ty
.IsReferenceType() or
133 # FIXME: lldb should provide something like getCanonicalType
134 tyname
.startswith("llvm::IntrusiveRefCntPtr<") or
135 tyname
.startswith("llvm::OwningPtr<")):
137 # FIXME: Hashing for SBTypes does not seem to work correctly, uses the typename instead,
138 # and not the canonical one unfortunately.
139 if tyname
in searched
:
142 for i
in range(value
.GetNumChildren()):
143 child
= value
.GetChildAtIndex(i
, 0, False)
144 found
= searchForType(child
, searched
)
149 value_list
= frame
.GetVariables(True, True, True, True)
150 for val
in value_list
:
151 found
= searchForType(val
, searched
)
153 return found
if not found
.TypeIsPointerType() else found
.Dereference()
155 def getValueFromExpression(val
, expr
):
156 return val
.GetFrame().EvaluateExpression(getExpressionPath(val
) + expr
)
158 def getExpressionPath(val
):
159 stream
= lldb
.SBStream()
160 val
.GetExpressionPath(stream
)
161 return stream
.GetData()