]> granicus.if.org Git - clang/blob - utils/ClangDataFormat.py
Revert r291477 "[Frontend] Correct values of ATOMIC_*_LOCK_FREE to match builtin"
[clang] / utils / ClangDataFormat.py
1 """lldb data formatters for clang classes.
2
3 Usage
4 --
5 import this file in your ~/.lldbinit by adding this line:
6
7 command script import /path/to/ClangDataFormat.py
8
9 After that, instead of getting this:
10
11 (lldb) p Tok.Loc
12 (clang::SourceLocation) $0 = {
13   (unsigned int) ID = 123582
14 }
15
16 you'll get:
17
18 (lldb) p Tok.Loc
19 (clang::SourceLocation) $4 = "/usr/include/i386/_types.h:37:1" (offset: 123582, file, local)
20 """
21
22 import lldb
23
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")
28
29 def SourceLocation_summary(srcloc, internal_dict):
30         return SourceLocation(srcloc).summary()
31
32 def QualType_summary(qualty, internal_dict):
33         return QualType(qualty).summary()
34
35 def StringRef_summary(strref, internal_dict):
36         return StringRef(strref).summary()
37
38 class SourceLocation(object):
39         def __init__(self, srcloc):
40                 self.srcloc = srcloc
41                 self.ID = srcloc.GetChildAtIndex(0).GetValueAsUnsigned()
42                 self.frame = srcloc.GetFrame()
43         
44         def offset(self):
45                 return getValueFromExpression(self.srcloc, ".getOffset()").GetValueAsUnsigned()
46
47         def isInvalid(self):
48                 return self.ID == 0
49
50         def isMacro(self):
51                 return getValueFromExpression(self.srcloc, ".isMacroID()").GetValueAsUnsigned()
52
53         def isLocal(self, srcmgr_path):
54                 return self.frame.EvaluateExpression("(%s).isLocalSourceLocation(%s)" % (srcmgr_path, getExpressionPath(self.srcloc))).GetValueAsUnsigned()
55
56         def getPrint(self, srcmgr_path):
57                 print_str = getValueFromExpression(self.srcloc, ".printToString(%s)" % srcmgr_path)
58                 return print_str.GetSummary()
59
60         def summary(self):
61                 if self.isInvalid():
62                         return "<invalid loc>"
63                 srcmgr_path = findObjectExpressionPath("clang::SourceManager", self.frame)
64                 if srcmgr_path:
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")
67
68 class QualType(object):
69         def __init__(self, qualty):
70                 self.qualty = qualty
71
72         def getAsString(self):
73                 std_str = getValueFromExpression(self.qualty, ".getAsString()")
74                 return std_str.GetSummary()
75
76         def summary(self):
77                 desc = self.getAsString()
78                 if desc == '"NULL TYPE"':
79                         return "<NULL TYPE>"
80                 return desc
81
82 class StringRef(object):
83         def __init__(self, strref):
84                 self.strref = strref
85                 self.Data_value = strref.GetChildAtIndex(0)
86                 self.Length = strref.GetChildAtIndex(1).GetValueAsUnsigned()
87
88         def summary(self):
89                 if self.Length == 0:
90                         return '""'
91                 data = self.Data_value.GetPointeeData(0, self.Length)
92                 error = lldb.SBError()
93                 string = data.ReadRawData(error, 0, data.GetByteSize())
94                 if error.Fail():
95                         return None
96                 return '"%s"' % string
97
98
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 = {}
102
103 def findObjectExpressionPath(typename, frame):
104         func_addr = frame.GetFunction().GetStartAddress().GetFileAddress()
105         key = (func_addr, typename)
106         try:
107                 return FramePathMapCache[key]
108         except KeyError:
109                 #print "CACHE MISS"
110                 path = None
111                 obj = findObject(typename, frame)
112                 if obj:
113                         path = getExpressionPath(obj)
114                 FramePathMapCache[key] = path
115                 return path
116
117 def findObject(typename, frame):
118         def getTypename(value):
119                 # FIXME: lldb should provide something like getBaseType
120                 ty = value.GetType()
121                 if ty.IsPointerType() or ty.IsReferenceType():
122                         return ty.GetPointeeType().GetName()
123                 return ty.GetName()
124
125         def searchForType(value, searched):
126                 tyname = getTypename(value)
127                 #print "SEARCH:", getExpressionPath(value), value.GetType().GetName()
128                 if tyname == typename:
129                         return value
130                 ty = value.GetType()
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<")):
136                         return None
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:
140                         return None
141                 searched.add(tyname)
142                 for i in range(value.GetNumChildren()):
143                         child = value.GetChildAtIndex(i, 0, False)
144                         found = searchForType(child, searched)
145                         if found:
146                                 return found
147
148         searched = set()
149         value_list = frame.GetVariables(True, True, True, True)
150         for val in value_list:
151                 found = searchForType(val, searched)
152                 if found:
153                         return found if not found.TypeIsPointerType() else found.Dereference()
154
155 def getValueFromExpression(val, expr):
156         return val.GetFrame().EvaluateExpression(getExpressionPath(val) + expr)
157
158 def getExpressionPath(val):
159         stream = lldb.SBStream()
160         val.GetExpressionPath(stream)
161         return stream.GetData()