[clang-format] Fix a bug in aligning comments above PPDirective (#72791)
[llvm-project.git] / clang / utils / ClangDataFormat.py
blob28c32a123bdf9a7e88a1250dd3578cbac9e69793
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
25 def __lldb_init_module(debugger, internal_dict):
26 debugger.HandleCommand(
27 "type summary add -F ClangDataFormat.SourceLocation_summary clang::SourceLocation"
29 debugger.HandleCommand(
30 "type summary add -F ClangDataFormat.QualType_summary clang::QualType"
34 def SourceLocation_summary(srcloc, internal_dict):
35 return SourceLocation(srcloc).summary()
38 def QualType_summary(qualty, internal_dict):
39 return QualType(qualty).summary()
42 class SourceLocation(object):
43 def __init__(self, srcloc):
44 self.srcloc = srcloc
45 self.ID = srcloc.GetChildAtIndex(0).GetValueAsUnsigned()
46 self.frame = srcloc.GetFrame()
48 def offset(self):
49 return getValueFromExpression(self.srcloc, ".getOffset()").GetValueAsUnsigned()
51 def isInvalid(self):
52 return self.ID == 0
54 def isMacro(self):
55 return getValueFromExpression(self.srcloc, ".isMacroID()").GetValueAsUnsigned()
57 def isLocal(self, srcmgr_path):
58 return self.frame.EvaluateExpression(
59 "(%s).isLocalSourceLocation(%s)"
60 % (srcmgr_path, getExpressionPath(self.srcloc))
61 ).GetValueAsUnsigned()
63 def getPrint(self, srcmgr_path):
64 print_str = getValueFromExpression(
65 self.srcloc, ".printToString(%s)" % srcmgr_path
67 return print_str.GetSummary()
69 def summary(self):
70 if self.isInvalid():
71 return "<invalid loc>"
72 srcmgr_path = findObjectExpressionPath("clang::SourceManager", self.frame)
73 if srcmgr_path:
74 return "%s (offset: %d, %s, %s)" % (
75 self.getPrint(srcmgr_path),
76 self.offset(),
77 "macro" if self.isMacro() else "file",
78 "local" if self.isLocal(srcmgr_path) else "loaded",
80 return "(offset: %d, %s)" % (
81 self.offset(),
82 "macro" if self.isMacro() else "file",
86 class QualType(object):
87 def __init__(self, qualty):
88 self.qualty = qualty
90 def getAsString(self):
91 std_str = getValueFromExpression(self.qualty, ".getAsString()")
92 return std_str.GetSummary()
94 def summary(self):
95 desc = self.getAsString()
96 if desc == '"NULL TYPE"':
97 return "<NULL TYPE>"
98 return desc
101 # Key is a (function address, type name) tuple, value is the expression path for
102 # an object with such a type name from inside that function.
103 FramePathMapCache = {}
106 def findObjectExpressionPath(typename, frame):
107 func_addr = frame.GetFunction().GetStartAddress().GetFileAddress()
108 key = (func_addr, typename)
109 try:
110 return FramePathMapCache[key]
111 except KeyError:
112 # print "CACHE MISS"
113 path = None
114 obj = findObject(typename, frame)
115 if obj:
116 path = getExpressionPath(obj)
117 FramePathMapCache[key] = path
118 return path
121 def findObject(typename, frame):
122 def getTypename(value):
123 # FIXME: lldb should provide something like getBaseType
124 ty = value.GetType()
125 if ty.IsPointerType() or ty.IsReferenceType():
126 return ty.GetPointeeType().GetName()
127 return ty.GetName()
129 def searchForType(value, searched):
130 tyname = getTypename(value)
131 # print "SEARCH:", getExpressionPath(value), value.GetType().GetName()
132 if tyname == typename:
133 return value
134 ty = value.GetType()
135 if not (
136 ty.IsPointerType()
137 or ty.IsReferenceType()
139 # FIXME: lldb should provide something like getCanonicalType
140 tyname.startswith("llvm::IntrusiveRefCntPtr<")
141 or tyname.startswith("llvm::OwningPtr<")
143 return None
144 # FIXME: Hashing for SBTypes does not seem to work correctly, uses the typename instead,
145 # and not the canonical one unfortunately.
146 if tyname in searched:
147 return None
148 searched.add(tyname)
149 for i in range(value.GetNumChildren()):
150 child = value.GetChildAtIndex(i, 0, False)
151 found = searchForType(child, searched)
152 if found:
153 return found
155 searched = set()
156 value_list = frame.GetVariables(True, True, True, True)
157 for val in value_list:
158 found = searchForType(val, searched)
159 if found:
160 return found if not found.TypeIsPointerType() else found.Dereference()
163 def getValueFromExpression(val, expr):
164 return val.GetFrame().EvaluateExpression(getExpressionPath(val) + expr)
167 def getExpressionPath(val):
168 stream = lldb.SBStream()
169 val.GetExpressionPath(stream)
170 return stream.GetData()