llvm.org GIT mirror llvm / 980f5c5
GDB pretty printers: Basic DenseMap support Still prints the empty/tombstone keys (which some people would prefer, but I find pretty noisy) because I haven't yet found a reliable way to skip them (it requires calling into the running process to do so, which isn't ideal for a pretty printer (doesn't work on a core file, for example) - and gdb's ability to do so (or my ability to figure out how to get gdb to do so) is limited) left some breadcrumbs for the next person who might try to address that. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290011 91177308-0d34-0410-b5e6-96231b3b80d8 David Blaikie 2 years ago
1 changed file(s) with 64 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
129129
130130 def to_string(self):
131131 return 'llvm::Optional is %sinitialized' % ('' if self.value['hasVal'] else 'not ')
132
133 class DenseMapPrinter:
134 "Print a DenseMap"
135
136 class _iterator:
137 def __init__(self, key_info_t, begin, end):
138 self.key_info_t = key_info_t
139 self.cur = begin
140 self.end = end
141 self.advancePastEmptyBuckets()
142 self.first = True
143
144 def __iter__(self):
145 return self
146
147 def advancePastEmptyBuckets(self):
148 # disabled until the comments below can be addressed
149 # keeping as notes/posterity/hints for future contributors
150 return
151 n = self.key_info_t.name
152 is_equal = gdb.parse_and_eval(n + '::isEqual')
153 empty = gdb.parse_and_eval(n + '::getEmptyKey()')
154 tombstone = gdb.parse_and_eval(n + '::getTombstoneKey()')
155 # the following is invalid, GDB fails with:
156 # Python Exception Attempt to take address of value
157 # not located in memory.
158 # because isEqual took parameter (for the unsigned long key I was testing)
159 # by const ref, and GDB
160 # It's also not entirely general - we should be accessing the "getFirst()"
161 # member function, not the 'first' member variable, but I've yet to figure
162 # out how to find/call member functions (especially (const) overloaded
163 # ones) on a gdb.Value.
164 while self.cur != self.end and (is_equal(self.cur.dereference()['first'], empty) or is_equal(self.cur.dereference()['first'], tombstone)):
165 self.cur = self.cur + 1
166
167 def next(self):
168 if self.cur == self.end:
169 raise StopIteration
170 cur = self.cur
171 v = cur.dereference()['first' if self.first else 'second']
172 if not self.first:
173 self.cur = self.cur + 1
174 self.advancePastEmptyBuckets()
175 self.first = True
176 else:
177 self.first = False
178 return 'x', v
179
180 def __init__(self, val):
181 self.val = val
182
183 def children(self):
184 t = self.val.type.template_argument(3).pointer()
185 begin = self.val['Buckets'].cast(t)
186 end = (begin + self.val['NumBuckets']).cast(t)
187 return self._iterator(self.val.type.template_argument(2), begin, end)
188
189 def to_string(self):
190 return 'llvm::DenseMap with %d elements' % (self.val['NumEntries'])
191
192 def display_hint(self):
193 return 'map'
194
132195
133196 pp = gdb.printing.RegexpCollectionPrettyPrinter("LLVMSupport")
134197 pp.add_printer('llvm::SmallString', '^llvm::SmallString<.*>$', SmallStringPrinter)
136199 pp.add_printer('llvm::SmallVectorImpl', '^llvm::SmallVector(Impl)?<.*>$', SmallVectorPrinter)
137200 pp.add_printer('llvm::ArrayRef', '^llvm::(Const)?ArrayRef<.*>$', ArrayRefPrinter)
138201 pp.add_printer('llvm::Optional', '^llvm::Optional<.*>$', OptionalPrinter)
202 pp.add_printer('llvm::DenseMap', '^llvm::DenseMap<.*>$', DenseMapPrinter)
139203 gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)