[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / utils / ClangDataFormat.py
blob2a5906db6584807bc8f54b6262e2aac316ea9aad
1 """lldb data formatters for clang classes.
3 Usage
4 --
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:
11 (lldb) p Tok.Loc
12 (clang::SourceLocation) $0 = {
13 (unsigned int) ID = 123582
16 you'll get:
18 (lldb) p Tok.Loc
19 (clang::SourceLocation) $4 = "/usr/include/i386/_types.h:37:1" (offset: 123582, file, local)
20 """
22 import lldb
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):
36 self.srcloc = srcloc
37 self.ID = srcloc.GetChildAtIndex(0).GetValueAsUnsigned()
38 self.frame = srcloc.GetFrame()
40 def offset(self):
41 return getValueFromExpression(self.srcloc, ".getOffset()").GetValueAsUnsigned()
43 def isInvalid(self):
44 return self.ID == 0
46 def isMacro(self):
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()
56 def summary(self):
57 if self.isInvalid():
58 return "<invalid loc>"
59 srcmgr_path = findObjectExpressionPath("clang::SourceManager", self.frame)
60 if srcmgr_path:
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):
66 self.qualty = qualty
68 def getAsString(self):
69 std_str = getValueFromExpression(self.qualty, ".getAsString()")
70 return std_str.GetSummary()
72 def summary(self):
73 desc = self.getAsString()
74 if desc == '"NULL TYPE"':
75 return "<NULL TYPE>"
76 return desc
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)
85 try:
86 return FramePathMapCache[key]
87 except KeyError:
88 #print "CACHE MISS"
89 path = None
90 obj = findObject(typename, frame)
91 if obj:
92 path = getExpressionPath(obj)
93 FramePathMapCache[key] = path
94 return path
96 def findObject(typename, frame):
97 def getTypename(value):
98 # FIXME: lldb should provide something like getBaseType
99 ty = value.GetType()
100 if ty.IsPointerType() or ty.IsReferenceType():
101 return ty.GetPointeeType().GetName()
102 return ty.GetName()
104 def searchForType(value, searched):
105 tyname = getTypename(value)
106 #print "SEARCH:", getExpressionPath(value), value.GetType().GetName()
107 if tyname == typename:
108 return value
109 ty = value.GetType()
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<")):
115 return None
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:
119 return None
120 searched.add(tyname)
121 for i in range(value.GetNumChildren()):
122 child = value.GetChildAtIndex(i, 0, False)
123 found = searchForType(child, searched)
124 if found:
125 return found
127 searched = set()
128 value_list = frame.GetVariables(True, True, True, True)
129 for val in value_list:
130 found = searchForType(val, searched)
131 if found:
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()