• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<?xml version="1.0" encoding="utf-8" ?>
2<AutoVisualizer
3  xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
4
5  <!-- libc++'s __compressed_pair is an internal type used pervasively for
6       doing the empty base class optimization.
7
8       __compressed_pair<U,V> derives from __compressed_pair_elem<U,0> and
9       __compressed_pair_elem<V,1>. __compressed_pair_elem<T> is specialized on
10       a 3rd template parameter:
11       * if T is empty and non-final the 3rd param is 1 and it derives from T
12       * else it has a member variable __value_ of type T
13  -->
14  <Type Name="std::Cr::__compressed_pair_elem&lt;*,*,0&gt;">
15    <DisplayString>{__value_}</DisplayString>
16    <Expand>
17      <ExpandedItem>__value_</ExpandedItem>
18    </Expand>
19  </Type>
20  <Type Name="std::Cr::__compressed_pair_elem&lt;*,*,1&gt;">
21    <DisplayString>{*($T1*)this}</DisplayString>
22    <Expand>
23      <ExpandedItem>*($T1*)this</ExpandedItem>
24    </Expand>
25  </Type>
26
27  <Type Name="std::Cr::array&lt;*,*&gt;">
28    <DisplayString>{{ size={$T2} }}</DisplayString>
29    <Expand>
30      <ArrayItems>
31        <Size>$T2</Size>
32        <ValuePointer>__elems_</ValuePointer>
33      </ArrayItems>
34    </Expand>
35  </Type>
36
37  <!--libc++'s short string optimization:
38      A basic_string is 3 size_t words long. In the "alternate string layout"
39      that we use, they are: pointer to data, size, capacity.
40      (In the normal layout, it's capacity, size, data instead.)
41      If a string is short enough that it fits in these three size_ts instead,
42      the string data is stored inline in these 3 words, with the last byte of
43      the storage storing the length of the string.
44      The highest bit of the "capacity" word is set for normal, "long" strings,
45      and that bit needs to be masked out to know the real capacity.
46      If this bit is not set, the string data is stored inline.
47      (In the normal layout, if the lowest bit in the first byte is set,
48      it's a "long" string, requiring a long string to always have even
49      capacity. A short string here stores its length in the first byte
50      and the inline data in the remaining storage.)
51  -->
52
53  <Type Name="std::Cr::basic_string&lt;char,*&gt;">
54    <!--<Intrinsic Name="is_long"
55            Expression="((__rep*)&amp;__r_)-&gt;__s.__size_ &amp; 0x80" />-->
56    <!-- The above doesn't work because of https://llvm.org/PR41615
57         TODO(thakis): Now that we have clang r362038, try the above approach
58                       again.
59         The below assumes the alternate string layout and little endianness :/
60    -->
61    <Intrinsic Name="is_long"
62        Expression="*(((char*)this) + 3*sizeof(size_t) - 1) &amp; 0x80" />
63    <DisplayString Condition="is_long()">{*(char**)this}</DisplayString>
64    <DisplayString Condition="!is_long()">{(char*)this}</DisplayString>
65    <StringView Condition="is_long()">*(char**)this</StringView>
66    <StringView Condition="!is_long()">(char*)this</StringView>
67    <Expand>
68      <Item Name="[size]" Condition="is_long()"
69          ExcludeView="simple">((size_t*)this)[1]</Item>
70      <Item Name="[size]" Condition="!is_long()"
71          ExcludeView="simple">*(((char*)this) + 3*sizeof(size_t) - 1)</Item>
72      <Item Name="[capacity]" Condition="is_long()" ExcludeView="simple">
73        ((size_t*)this)[2] &amp; (~((size_t)0) &gt;&gt; 1)
74      </Item>
75      <Item Name="[capacity]" Condition="!is_long()"
76          ExcludeView="simple">22</Item>
77      <ArrayItems>
78        <Size Condition="is_long()">((size_t*)this)[1]</Size>
79        <Size Condition="!is_long()">
80          *(((char*)this) + 3*sizeof(size_t) - 1)
81        </Size>
82        <ValuePointer Condition="is_long()">*(char**)this</ValuePointer>
83        <ValuePointer Condition="!is_long()">(char*)this</ValuePointer>
84      </ArrayItems>
85    </Expand>
86  </Type>
87
88  <Type Name="std::Cr::basic_string&lt;wchar_t,*&gt;">
89    <Intrinsic Name="is_long"
90        Expression="*(((char*)this) + 3*sizeof(size_t) - 1) &amp; 0x80" />
91    <DisplayString Condition="is_long()">{*(wchar_t**)this}</DisplayString>
92    <DisplayString Condition="!is_long()">{(wchar_t*)this}</DisplayString>
93    <StringView Condition="is_long()">*(wchar_t**)this</StringView>
94    <StringView Condition="!is_long()">(wchar_t*)this</StringView>
95    <Expand>
96      <Item Name="[size]" Condition="is_long()"
97          ExcludeView="simple">((size_t*)this)[1]</Item>
98      <Item Name="[size]" Condition="!is_long()"
99          ExcludeView="simple">*(((char*)this) + 3*sizeof(size_t) - 1)</Item>
100      <Item Name="[capacity]" Condition="is_long()" ExcludeView="simple">
101        ((size_t*)this)[2] &amp; (~((size_t)0) &gt;&gt; 1)
102      </Item>
103      <Item Name="[capacity]" Condition="!is_long()"
104          ExcludeView="simple">10</Item>
105      <ArrayItems>
106        <Size Condition="is_long()">((size_t*)this)[1]</Size>
107        <Size Condition="!is_long()">
108          *(((char*)this) + 3*sizeof(size_t) - 1)
109        </Size>
110        <ValuePointer Condition="is_long()">*(wchar_t**)this</ValuePointer>
111        <ValuePointer Condition="!is_long()">(wchar_t*)this</ValuePointer>
112      </ArrayItems>
113    </Expand>
114  </Type>
115
116  <Type Name="std::Cr::deque&lt;*,*&gt;">
117    <Intrinsic Name="size" Expression="*(size_type*)&amp;__size_" />
118    <Intrinsic Name="block_size"
119        Expression="sizeof($T1) &lt; 256 ? 4096 / sizeof($T1) : 16" />
120    <DisplayString>{{ size={size()} }}</DisplayString>
121    <Expand>
122      <IndexListItems>
123        <Size>size()</Size>
124        <ValueNode>
125          *(*(__map_.__begin_ + ($i + __start_) / block_size()) +
126                                ($i + __start_) % block_size())
127        </ValueNode>
128      </IndexListItems>
129    </Expand>
130  </Type>
131
132  <Type Name="std::Cr::forward_list&lt;*&gt;">
133    <Intrinsic Name="head"
134        Expression="((__node_pointer)&amp;__before_begin_)-&gt;__next_" />
135    <DisplayString Condition="head() == 0">empty</DisplayString>
136    <DisplayString Condition="head() != 0">non-empty</DisplayString>
137    <Expand>
138      <LinkedListItems>
139        <HeadPointer>head()</HeadPointer>
140        <NextPointer>__next_</NextPointer>
141        <ValueNode>__value_</ValueNode>
142      </LinkedListItems>
143    </Expand>
144  </Type>
145
146  <!-- Note: Not in Cr! But will win over the one in stl.natvis -->
147  <Type Name="std::initializer_list&lt;*&gt;">
148    <DisplayString>{{ size={__size_} }}</DisplayString>
149    <Expand>
150      <ArrayItems>
151        <Size>__size_</Size>
152        <ValuePointer>__begin_</ValuePointer>
153      </ArrayItems>
154    </Expand>
155  </Type>
156
157  <Type Name="std::Cr::list&lt;*&gt;">
158    <Intrinsic Name="size" Expression="*(size_type*)&amp;__size_alloc_" />
159    <DisplayString>{{ size={size()} }}</DisplayString>
160    <Expand>
161      <LinkedListItems>
162        <Size>size()</Size>
163        <HeadPointer>__end_.__next_</HeadPointer>
164        <NextPointer>__next_</NextPointer>
165        <ValueNode>
166          ((std::Cr::list&lt;$T1,$T2&gt;::__node_pointer)this)
167              -&gt;__value_
168        </ValueNode>
169      </LinkedListItems>
170    </Expand>
171  </Type>
172
173  <Type Name="std::Cr::map&lt;*&gt;">
174    <Intrinsic Name="size" Expression="*(size_type*)&amp;__tree_.__pair3_" />
175    <DisplayString>{{ size={size()} }}</DisplayString>
176    <Expand>
177      <Item Name="[size]">size()</Item>
178      <TreeItems>
179        <Size>size()</Size>
180        <HeadPointer>
181          ((__node_pointer)&amp;__tree_.__pair1_)-&gt;__left_
182        </HeadPointer>
183        <LeftPointer>
184          ((std::Cr::map&lt;$T1,$T2,$T3,$T4&gt;::__node_pointer)this)
185              -&gt;__left_
186        </LeftPointer>
187        <RightPointer>
188          ((std::Cr::map&lt;$T1,$T2,$T3,$T4&gt;::__node_pointer)this)
189              -&gt;__right_
190        </RightPointer>
191        <ValueNode>
192          ((std::Cr::map&lt;$T1,$T2,$T3,$T4&gt;::__node_pointer)this)
193              -&gt;__value_.__cc_
194        </ValueNode>
195      </TreeItems>
196    </Expand>
197  </Type>
198
199  <Type Name="std::Cr::multimap&lt;*&gt;">
200    <Intrinsic Name="size" Expression="*(size_type*)&amp;__tree_.__pair3_" />
201    <DisplayString>{{ size={size()} }}</DisplayString>
202    <Expand>
203      <Item Name="[size]">size()</Item>
204      <TreeItems>
205        <Size>size()</Size>
206        <HeadPointer>
207          ((__node_pointer)&amp;__tree_.__pair1_)-&gt;__left_
208        </HeadPointer>
209        <LeftPointer>
210          ((std::Cr::multimap&lt;$T1,$T2,$T3,$T4&gt;::__node_pointer)this)
211              -&gt;__left_
212        </LeftPointer>
213        <RightPointer>
214          ((std::Cr::multimap&lt;$T1,$T2,$T3,$T4&gt;::__node_pointer)this)
215              -&gt;__right_
216        </RightPointer>
217        <ValueNode>
218          ((std::Cr::multimap&lt;$T1,$T2,$T3,$T4&gt;::__node_pointer)this)
219              -&gt;__value_.__cc_
220        </ValueNode>
221      </TreeItems>
222    </Expand>
223  </Type>
224
225  <Type Name="std::Cr::multiset&lt;*&gt;">
226    <Intrinsic Name="size" Expression="*(size_type*)&amp;__tree_.__pair3_" />
227    <DisplayString>{{ size={size()} }}</DisplayString>
228    <Expand>
229      <Item Name="[size]">size()</Item>
230      <TreeItems>
231        <Size>size()</Size>
232        <HeadPointer>
233          ((__base::__node_pointer)&amp;__tree_.__pair1_)-&gt;__left_
234        </HeadPointer>
235        <LeftPointer>
236          ((std::Cr::multiset&lt;$T1,$T2,$T3&gt;::__base::__node_pointer)this)
237              -&gt;__left_
238        </LeftPointer>
239        <RightPointer>
240          ((std::Cr::multiset&lt;$T1,$T2,$T3&gt;::__base::__node_pointer)this)
241              -&gt;__right_
242        </RightPointer>
243        <ValueNode>
244          ((std::Cr::multiset&lt;$T1,$T2,$T3&gt;::__base::__node_pointer)this)
245              -&gt;__value_
246        </ValueNode>
247      </TreeItems>
248    </Expand>
249  </Type>
250
251  <Type Name="std::Cr::priority_queue&lt;*&gt;">
252    <DisplayString>{c}</DisplayString>
253    <Expand>
254      <ExpandedItem>c</ExpandedItem>
255      <Item Name="[comp]">comp</Item>
256    </Expand>
257  </Type>
258
259  <Type Name="std::Cr::set&lt;*&gt;">
260    <Intrinsic Name="size" Expression="*(size_type*)&amp;__tree_.__pair3_" />
261    <DisplayString>{{ size={size()} }}</DisplayString>
262    <Expand>
263      <Item Name="[size]">size()</Item>
264      <TreeItems>
265        <Size>size()</Size>
266        <HeadPointer>
267          ((__base::__node_pointer)&amp;__tree_.__pair1_)-&gt;__left_
268        </HeadPointer>
269        <LeftPointer>
270          ((std::Cr::set&lt;$T1,$T2,$T3&gt;::__base::__node_pointer)this)
271              -&gt;__left_
272        </LeftPointer>
273        <RightPointer>
274          ((std::Cr::set&lt;$T1,$T2,$T3&gt;::__base::__node_pointer)this)
275              -&gt;__right_
276        </RightPointer>
277        <ValueNode>
278          ((std::Cr::set&lt;$T1,$T2,$T3&gt;::__base::__node_pointer)this)
279              -&gt;__value_
280        </ValueNode>
281      </TreeItems>
282    </Expand>
283  </Type>
284
285  <Type Name="std::Cr::stack&lt;*&gt;">
286    <AlternativeType Name="std::Cr::queue&lt;*&gt;" />
287    <DisplayString>{c}</DisplayString>
288    <Expand>
289      <ExpandedItem>c</ExpandedItem>
290    </Expand>
291  </Type>
292
293  <Type Name="std::Cr::__tuple_leaf&lt;*,*,0&gt;">
294    <DisplayString>{__value_}</DisplayString>
295  </Type>
296
297  <Type Name="std::Cr::tuple&lt;&gt;">
298    <DisplayString>()</DisplayString>
299  </Type>
300
301  <Type Name="std::Cr::tuple&lt;*&gt;">
302    <DisplayString>({(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_})</DisplayString>
303      <Expand>
304          <Item Name="[0]">(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
305      </Expand>
306  </Type>
307
308  <Type Name="std::Cr::tuple&lt;*,*&gt;">
309    <DisplayString>({(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;1,$T2,0&gt;)__base_})</DisplayString>
310    <Expand>
311      <Item Name="[0]">(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
312      <Item Name="[1]">(std::Cr::__tuple_leaf&lt;1,$T2,0&gt;)__base_</Item>
313    </Expand>
314  </Type>
315
316  <Type Name="std::Cr::tuple&lt;*,*,*&gt;">
317    <DisplayString>({(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;1,$T2,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;2,$T3,0&gt;)__base_})</DisplayString>
318    <Expand>
319      <Item Name="[0]">(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
320      <Item Name="[1]">(std::Cr::__tuple_leaf&lt;1,$T2,0&gt;)__base_</Item>
321      <Item Name="[2]">(std::Cr::__tuple_leaf&lt;2,$T3,0&gt;)__base_</Item>
322    </Expand>
323  </Type>
324
325  <Type Name="std::Cr::tuple&lt;*,*,*,*&gt;">
326    <DisplayString>({(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;1,$T2,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;2,$T3,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;3,$T4,0&gt;)__base_})</DisplayString>
327    <Expand>
328      <Item Name="[0]">(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
329      <Item Name="[1]">(std::Cr::__tuple_leaf&lt;1,$T2,0&gt;)__base_</Item>
330      <Item Name="[2]">(std::Cr::__tuple_leaf&lt;2,$T3,0&gt;)__base_</Item>
331      <Item Name="[3]">(std::Cr::__tuple_leaf&lt;3,$T4,0&gt;)__base_</Item>
332    </Expand>
333  </Type>
334
335  <Type Name="std::Cr::tuple&lt;*,*,*,*,*&gt;">
336    <DisplayString>({(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;1,$T2,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;2,$T3,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;3,$T4,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;4,$T5,0&gt;)__base_})</DisplayString>
337    <Expand>
338      <Item Name="[0]">(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
339      <Item Name="[1]">(std::Cr::__tuple_leaf&lt;1,$T2,0&gt;)__base_</Item>
340      <Item Name="[2]">(std::Cr::__tuple_leaf&lt;2,$T3,0&gt;)__base_</Item>
341      <Item Name="[3]">(std::Cr::__tuple_leaf&lt;3,$T4,0&gt;)__base_</Item>
342      <Item Name="[4]">(std::Cr::__tuple_leaf&lt;4,$T5,0&gt;)__base_</Item>
343    </Expand>
344  </Type>
345
346  <Type Name="std::Cr::tuple&lt;*,*,*,*,*,*&gt;">
347    <DisplayString>({(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;1,$T2,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;2,$T3,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;3,$T4,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;4,$T5,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;5,$T6,0&gt;)__base_})</DisplayString>
348    <Expand>
349      <Item Name="[0]">(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
350      <Item Name="[1]">(std::Cr::__tuple_leaf&lt;1,$T2,0&gt;)__base_</Item>
351      <Item Name="[2]">(std::Cr::__tuple_leaf&lt;2,$T3,0&gt;)__base_</Item>
352      <Item Name="[3]">(std::Cr::__tuple_leaf&lt;3,$T4,0&gt;)__base_</Item>
353      <Item Name="[4]">(std::Cr::__tuple_leaf&lt;4,$T5,0&gt;)__base_</Item>
354      <Item Name="[5]">(std::Cr::__tuple_leaf&lt;5,$T6,0&gt;)__base_</Item>
355    </Expand>
356  </Type>
357
358  <Type Name="std::Cr::tuple&lt;*,*,*,*,*,*,*&gt;">
359    <DisplayString>({(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;1,$T2,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;2,$T3,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;3,$T4,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;4,$T5,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;5,$T6,0&gt;)__base_}, {(std::Cr::__tuple_leaf&lt;6,$T7,0&gt;)__base_})</DisplayString>
360    <Expand>
361      <Item Name="[0]">(std::Cr::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
362      <Item Name="[1]">(std::Cr::__tuple_leaf&lt;1,$T2,0&gt;)__base_</Item>
363      <Item Name="[2]">(std::Cr::__tuple_leaf&lt;2,$T3,0&gt;)__base_</Item>
364      <Item Name="[3]">(std::Cr::__tuple_leaf&lt;3,$T4,0&gt;)__base_</Item>
365      <Item Name="[4]">(std::Cr::__tuple_leaf&lt;4,$T5,0&gt;)__base_</Item>
366      <Item Name="[5]">(std::Cr::__tuple_leaf&lt;5,$T6,0&gt;)__base_</Item>
367      <Item Name="[6]">(std::Cr::__tuple_leaf&lt;6,$T7,0&gt;)__base_</Item>
368    </Expand>
369  </Type>
370
371  <Type Name="std::Cr::unique_ptr&lt;*&gt;">
372    <Intrinsic Name="value" Expression="*($T1**)&amp;__ptr_" />
373    <SmartPointer Usage="Minimal">value()</SmartPointer>
374      <DisplayString Condition="value() == 0">empty</DisplayString>
375      <DisplayString Condition="value() != 0">
376        unique_ptr {value()}</DisplayString>
377      <Expand>
378        <Item Condition="value() != 0" Name="[ptr]">value()</Item>
379      </Expand>
380  </Type>
381
382<Type Name="std::Cr::unordered_map&lt;*&gt;">
383    <AlternativeType Name="std::Cr::unordered_multimap&lt;*&gt;" />
384    <AlternativeType Name="std::Cr::unordered_multiset&lt;*&gt;" />
385    <AlternativeType Name="std::Cr::unordered_set&lt;*&gt;" />
386    <Intrinsic Name="size" Expression="*(size_type*)&amp;__table_.__p2_" />
387    <Intrinsic Name="bucket_count"
388        Expression="*(size_type*)&amp;
389                    ((__table::__bucket_list_deleter*)
390                        ((void**)&amp;__table_.__bucket_list_ + 1))
391                        -&gt;__data_" />
392    <DisplayString>{{ size={size()} }}</DisplayString>
393    <Expand>
394      <Item Name="[bucket_count]">bucket_count()</Item>
395      <Item Name="[load_factor]">
396        bucket_count() != 0 ? (float)size() / bucket_count() : 0.f</Item>
397      <Item Name="[max_load_factor]">*(float*)&amp;__table_.__p3_</Item>
398      <!-- Use CustomListItems instead of LinkedListItems because we
399        need to cast to __table::__node_pointer and LinkedListItems
400        evaluates <Value> in the context of the node, not of the container,
401        so we'd have to say std::unordered_map<$T1,...>::__table::__node_pointer
402        and then we couldn't share this <Type> between unordered_(multi)map
403        and unordered_(multi)set. -->
404      <CustomListItems>
405        <Variable Name="node"
406            InitialValue="*(__table::__next_pointer*)&amp;__table_.__p1_" />
407        <Size>size()</Size>
408        <Loop>
409          <Item>(*(__table::__node_pointer*)&amp;node)-&gt;__value_</Item>
410          <Exec>node = node-&gt;__next_</Exec>
411        </Loop>
412      </CustomListItems>
413    </Expand>
414  </Type>
415  <!-- This is the node __value_ of an unordered_(multi)map. Expand it through
416    a separate formatter instead of in the <Item> expression above so that the
417    same <Type> works for unordered_(multi)set and unordered_(multi)map. -->
418  <Type Name="std::Cr::__hash_value_type&lt;*&gt;">
419    <DisplayString>{__cc}</DisplayString>
420    <Expand>
421      <ExpandedItem>__cc</ExpandedItem>
422    </Expand>
423  </Type>
424
425  <Type Name="std::Cr::vector&lt;*&gt;">
426    <Intrinsic Name="size" Expression="__end_ - __begin_" />
427    <DisplayString>{{ size={size()} }}</DisplayString>
428    <Expand>
429      <ArrayItems>
430        <Size>size()</Size>
431        <ValuePointer>__begin_</ValuePointer>
432      </ArrayItems>
433    </Expand>
434  </Type>
435</AutoVisualizer>
436