annotate clang/utils/ClangDataFormat.py @ 206:f17a3b42b08b

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