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")
28 def SourceLocation_summary(srcloc
, internal_dict
):
29 return SourceLocation(srcloc
).summary()
31 def QualType_summary(qualty
, internal_dict
):
32 return QualType(qualty
).summary()
34 class SourceLocation(object):
35 def __init__(self
, srcloc
):
37 self
.ID
= srcloc
.GetChildAtIndex(0).GetValueAsUnsigned()
38 self
.frame
= srcloc
.GetFrame()
41 return getValueFromExpression(self
.srcloc
, ".getOffset()").GetValueAsUnsigned()
47 return getValueFromExpression(self
.srcloc
, ".isMacroID()").GetValueAsUnsigned()
49 def isLocal(self
, srcmgr_path
):
50 return self
.frame
.EvaluateExpression("(%s).isLocalSourceLocation(%s)" % (srcmgr_path
, getExpressionPath(self
.srcloc
))).GetValueAsUnsigned()
52 def getPrint(self
, srcmgr_path
):
53 print_str
= getValueFromExpression(self
.srcloc
, ".printToString(%s)" % srcmgr_path
)
54 return print_str
.GetSummary()
58 return "<invalid loc>"
59 srcmgr_path
= findObjectExpressionPath("clang::SourceManager", self
.frame
)
61 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")
62 return "(offset: %d, %s)" % (self
.offset(), "macro" if self
.isMacro() else "file")
64 class QualType(object):
65 def __init__(self
, qualty
):
68 def getAsString(self
):
69 std_str
= getValueFromExpression(self
.qualty
, ".getAsString()")
70 return std_str
.GetSummary()
73 desc
= self
.getAsString()
74 if desc
== '"NULL TYPE"':
78 # Key is a (function address, type name) tuple, value is the expression path for
79 # an object with such a type name from inside that function.
80 FramePathMapCache
= {}
82 def findObjectExpressionPath(typename
, frame
):
83 func_addr
= frame
.GetFunction().GetStartAddress().GetFileAddress()
84 key
= (func_addr
, typename
)
86 return FramePathMapCache
[key
]
90 obj
= findObject(typename
, frame
)
92 path
= getExpressionPath(obj
)
93 FramePathMapCache
[key
] = path
96 def findObject(typename
, frame
):
97 def getTypename(value
):
98 # FIXME: lldb should provide something like getBaseType
100 if ty
.IsPointerType() or ty
.IsReferenceType():
101 return ty
.GetPointeeType().GetName()
104 def searchForType(value
, searched
):
105 tyname
= getTypename(value
)
106 #print "SEARCH:", getExpressionPath(value), value.GetType().GetName()
107 if tyname
== typename
:
110 if not (ty
.IsPointerType() or
111 ty
.IsReferenceType() or
112 # FIXME: lldb should provide something like getCanonicalType
113 tyname
.startswith("llvm::IntrusiveRefCntPtr<") or
114 tyname
.startswith("llvm::OwningPtr<")):
116 # FIXME: Hashing for SBTypes does not seem to work correctly, uses the typename instead,
117 # and not the canonical one unfortunately.
118 if tyname
in searched
:
121 for i
in range(value
.GetNumChildren()):
122 child
= value
.GetChildAtIndex(i
, 0, False)
123 found
= searchForType(child
, searched
)
128 value_list
= frame
.GetVariables(True, True, True, True)
129 for val
in value_list
:
130 found
= searchForType(val
, searched
)
132 return found
if not found
.TypeIsPointerType() else found
.Dereference()
134 def getValueFromExpression(val
, expr
):
135 return val
.GetFrame().EvaluateExpression(getExpressionPath(val
) + expr
)
137 def getExpressionPath(val
):
138 stream
= lldb
.SBStream()
139 val
.GetExpressionPath(stream
)
140 return stream
.GetData()