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<*,*,0>"> 15 <DisplayString>{__value_}</DisplayString> 16 <Expand> 17 <ExpandedItem>__value_</ExpandedItem> 18 </Expand> 19 </Type> 20 <Type Name="std::__Cr::__compressed_pair_elem<*,*,1>"> 21 <DisplayString>{*($T1*)this}</DisplayString> 22 <Expand> 23 <ExpandedItem>*($T1*)this</ExpandedItem> 24 </Expand> 25 </Type> 26 27 <Type Name="std::__Cr::array<*,*>"> 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<char,*>"> 54 <!--<Intrinsic Name="is_long" 55 Expression="((__rep*)&__r_)->__s.__size_ & 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) & 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] & (~((size_t)0) >> 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<wchar_t,*>"> 89 <Intrinsic Name="is_long" 90 Expression="*(((char*)this) + 3*sizeof(size_t) - 1) & 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] & (~((size_t)0) >> 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<*,*>"> 117 <Intrinsic Name="size" Expression="*(size_type*)&__size_" /> 118 <Intrinsic Name="block_size" 119 Expression="sizeof($T1) < 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<*>"> 133 <Intrinsic Name="head" 134 Expression="((__node_pointer)&__before_begin_)->__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<*>"> 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<*>"> 158 <Intrinsic Name="size" Expression="*(size_type*)&__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<$T1,$T2>::__node_pointer)this) 167 ->__value_ 168 </ValueNode> 169 </LinkedListItems> 170 </Expand> 171 </Type> 172 173 <Type Name="std::__Cr::map<*>"> 174 <Intrinsic Name="size" Expression="*(size_type*)&__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)&__tree_.__pair1_)->__left_ 182 </HeadPointer> 183 <LeftPointer> 184 ((std::__Cr::map<$T1,$T2,$T3,$T4>::__node_pointer)this) 185 ->__left_ 186 </LeftPointer> 187 <RightPointer> 188 ((std::__Cr::map<$T1,$T2,$T3,$T4>::__node_pointer)this) 189 ->__right_ 190 </RightPointer> 191 <ValueNode> 192 ((std::__Cr::map<$T1,$T2,$T3,$T4>::__node_pointer)this) 193 ->__value_.__cc_ 194 </ValueNode> 195 </TreeItems> 196 </Expand> 197 </Type> 198 199 <Type Name="std::__Cr::multimap<*>"> 200 <Intrinsic Name="size" Expression="*(size_type*)&__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)&__tree_.__pair1_)->__left_ 208 </HeadPointer> 209 <LeftPointer> 210 ((std::__Cr::multimap<$T1,$T2,$T3,$T4>::__node_pointer)this) 211 ->__left_ 212 </LeftPointer> 213 <RightPointer> 214 ((std::__Cr::multimap<$T1,$T2,$T3,$T4>::__node_pointer)this) 215 ->__right_ 216 </RightPointer> 217 <ValueNode> 218 ((std::__Cr::multimap<$T1,$T2,$T3,$T4>::__node_pointer)this) 219 ->__value_.__cc_ 220 </ValueNode> 221 </TreeItems> 222 </Expand> 223 </Type> 224 225 <Type Name="std::__Cr::multiset<*>"> 226 <Intrinsic Name="size" Expression="*(size_type*)&__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)&__tree_.__pair1_)->__left_ 234 </HeadPointer> 235 <LeftPointer> 236 ((std::__Cr::multiset<$T1,$T2,$T3>::__base::__node_pointer)this) 237 ->__left_ 238 </LeftPointer> 239 <RightPointer> 240 ((std::__Cr::multiset<$T1,$T2,$T3>::__base::__node_pointer)this) 241 ->__right_ 242 </RightPointer> 243 <ValueNode> 244 ((std::__Cr::multiset<$T1,$T2,$T3>::__base::__node_pointer)this) 245 ->__value_ 246 </ValueNode> 247 </TreeItems> 248 </Expand> 249 </Type> 250 251 <Type Name="std::__Cr::optional<*>"> 252 <DisplayString Condition="!__engaged_">nullopt</DisplayString> 253 <DisplayString>{__val_}</DisplayString> 254 <Expand> 255 <ExpandedItem Condition="__engaged_">__val_</ExpandedItem> 256 </Expand> 257 </Type> 258 259 <Type Name="std::__Cr::priority_queue<*>"> 260 <DisplayString>{c}</DisplayString> 261 <Expand> 262 <ExpandedItem>c</ExpandedItem> 263 <Item Name="[comp]">comp</Item> 264 </Expand> 265 </Type> 266 267 <Type Name="std::__Cr::set<*>"> 268 <Intrinsic Name="size" Expression="*(size_type*)&__tree_.__pair3_" /> 269 <DisplayString>{{ size={size()} }}</DisplayString> 270 <Expand> 271 <Item Name="[size]">size()</Item> 272 <TreeItems> 273 <Size>size()</Size> 274 <HeadPointer> 275 ((__base::__node_pointer)&__tree_.__pair1_)->__left_ 276 </HeadPointer> 277 <LeftPointer> 278 ((std::__Cr::set<$T1,$T2,$T3>::__base::__node_pointer)this) 279 ->__left_ 280 </LeftPointer> 281 <RightPointer> 282 ((std::__Cr::set<$T1,$T2,$T3>::__base::__node_pointer)this) 283 ->__right_ 284 </RightPointer> 285 <ValueNode> 286 ((std::__Cr::set<$T1,$T2,$T3>::__base::__node_pointer)this) 287 ->__value_ 288 </ValueNode> 289 </TreeItems> 290 </Expand> 291 </Type> 292 293 <Type Name="std::__Cr::stack<*>"> 294 <AlternativeType Name="std::__Cr::queue<*>" /> 295 <DisplayString>{c}</DisplayString> 296 <Expand> 297 <ExpandedItem>c</ExpandedItem> 298 </Expand> 299 </Type> 300 301 <Type Name="std::__Cr::__tuple_leaf<*,*,0>"> 302 <DisplayString>{__value_}</DisplayString> 303 </Type> 304 305 <Type Name="std::__Cr::tuple<>"> 306 <DisplayString>()</DisplayString> 307 </Type> 308 309 <Type Name="std::__Cr::tuple<*>"> 310 <DisplayString>({(std::__Cr::__tuple_leaf<0,$T1,0>)__base_})</DisplayString> 311 <Expand> 312 <Item Name="[0]">(std::__Cr::__tuple_leaf<0,$T1,0>)__base_</Item> 313 </Expand> 314 </Type> 315 316 <Type Name="std::__Cr::tuple<*,*>"> 317 <DisplayString>({(std::__Cr::__tuple_leaf<0,$T1,0>)__base_}, {(std::__Cr::__tuple_leaf<1,$T2,0>)__base_})</DisplayString> 318 <Expand> 319 <Item Name="[0]">(std::__Cr::__tuple_leaf<0,$T1,0>)__base_</Item> 320 <Item Name="[1]">(std::__Cr::__tuple_leaf<1,$T2,0>)__base_</Item> 321 </Expand> 322 </Type> 323 324 <Type Name="std::__Cr::tuple<*,*,*>"> 325 <DisplayString>({(std::__Cr::__tuple_leaf<0,$T1,0>)__base_}, {(std::__Cr::__tuple_leaf<1,$T2,0>)__base_}, {(std::__Cr::__tuple_leaf<2,$T3,0>)__base_})</DisplayString> 326 <Expand> 327 <Item Name="[0]">(std::__Cr::__tuple_leaf<0,$T1,0>)__base_</Item> 328 <Item Name="[1]">(std::__Cr::__tuple_leaf<1,$T2,0>)__base_</Item> 329 <Item Name="[2]">(std::__Cr::__tuple_leaf<2,$T3,0>)__base_</Item> 330 </Expand> 331 </Type> 332 333 <Type Name="std::__Cr::tuple<*,*,*,*>"> 334 <DisplayString>({(std::__Cr::__tuple_leaf<0,$T1,0>)__base_}, {(std::__Cr::__tuple_leaf<1,$T2,0>)__base_}, {(std::__Cr::__tuple_leaf<2,$T3,0>)__base_}, {(std::__Cr::__tuple_leaf<3,$T4,0>)__base_})</DisplayString> 335 <Expand> 336 <Item Name="[0]">(std::__Cr::__tuple_leaf<0,$T1,0>)__base_</Item> 337 <Item Name="[1]">(std::__Cr::__tuple_leaf<1,$T2,0>)__base_</Item> 338 <Item Name="[2]">(std::__Cr::__tuple_leaf<2,$T3,0>)__base_</Item> 339 <Item Name="[3]">(std::__Cr::__tuple_leaf<3,$T4,0>)__base_</Item> 340 </Expand> 341 </Type> 342 343 <Type Name="std::__Cr::tuple<*,*,*,*,*>"> 344 <DisplayString>({(std::__Cr::__tuple_leaf<0,$T1,0>)__base_}, {(std::__Cr::__tuple_leaf<1,$T2,0>)__base_}, {(std::__Cr::__tuple_leaf<2,$T3,0>)__base_}, {(std::__Cr::__tuple_leaf<3,$T4,0>)__base_}, {(std::__Cr::__tuple_leaf<4,$T5,0>)__base_})</DisplayString> 345 <Expand> 346 <Item Name="[0]">(std::__Cr::__tuple_leaf<0,$T1,0>)__base_</Item> 347 <Item Name="[1]">(std::__Cr::__tuple_leaf<1,$T2,0>)__base_</Item> 348 <Item Name="[2]">(std::__Cr::__tuple_leaf<2,$T3,0>)__base_</Item> 349 <Item Name="[3]">(std::__Cr::__tuple_leaf<3,$T4,0>)__base_</Item> 350 <Item Name="[4]">(std::__Cr::__tuple_leaf<4,$T5,0>)__base_</Item> 351 </Expand> 352 </Type> 353 354 <Type Name="std::__Cr::tuple<*,*,*,*,*,*>"> 355 <DisplayString>({(std::__Cr::__tuple_leaf<0,$T1,0>)__base_}, {(std::__Cr::__tuple_leaf<1,$T2,0>)__base_}, {(std::__Cr::__tuple_leaf<2,$T3,0>)__base_}, {(std::__Cr::__tuple_leaf<3,$T4,0>)__base_}, {(std::__Cr::__tuple_leaf<4,$T5,0>)__base_}, {(std::__Cr::__tuple_leaf<5,$T6,0>)__base_})</DisplayString> 356 <Expand> 357 <Item Name="[0]">(std::__Cr::__tuple_leaf<0,$T1,0>)__base_</Item> 358 <Item Name="[1]">(std::__Cr::__tuple_leaf<1,$T2,0>)__base_</Item> 359 <Item Name="[2]">(std::__Cr::__tuple_leaf<2,$T3,0>)__base_</Item> 360 <Item Name="[3]">(std::__Cr::__tuple_leaf<3,$T4,0>)__base_</Item> 361 <Item Name="[4]">(std::__Cr::__tuple_leaf<4,$T5,0>)__base_</Item> 362 <Item Name="[5]">(std::__Cr::__tuple_leaf<5,$T6,0>)__base_</Item> 363 </Expand> 364 </Type> 365 366 <Type Name="std::__Cr::tuple<*,*,*,*,*,*,*>"> 367 <DisplayString>({(std::__Cr::__tuple_leaf<0,$T1,0>)__base_}, {(std::__Cr::__tuple_leaf<1,$T2,0>)__base_}, {(std::__Cr::__tuple_leaf<2,$T3,0>)__base_}, {(std::__Cr::__tuple_leaf<3,$T4,0>)__base_}, {(std::__Cr::__tuple_leaf<4,$T5,0>)__base_}, {(std::__Cr::__tuple_leaf<5,$T6,0>)__base_}, {(std::__Cr::__tuple_leaf<6,$T7,0>)__base_})</DisplayString> 368 <Expand> 369 <Item Name="[0]">(std::__Cr::__tuple_leaf<0,$T1,0>)__base_</Item> 370 <Item Name="[1]">(std::__Cr::__tuple_leaf<1,$T2,0>)__base_</Item> 371 <Item Name="[2]">(std::__Cr::__tuple_leaf<2,$T3,0>)__base_</Item> 372 <Item Name="[3]">(std::__Cr::__tuple_leaf<3,$T4,0>)__base_</Item> 373 <Item Name="[4]">(std::__Cr::__tuple_leaf<4,$T5,0>)__base_</Item> 374 <Item Name="[5]">(std::__Cr::__tuple_leaf<5,$T6,0>)__base_</Item> 375 <Item Name="[6]">(std::__Cr::__tuple_leaf<6,$T7,0>)__base_</Item> 376 </Expand> 377 </Type> 378 379 <Type Name="std::__Cr::unique_ptr<*>"> 380 <Intrinsic Name="value" Expression="*($T1**)&__ptr_" /> 381 <SmartPointer Usage="Minimal">value()</SmartPointer> 382 <DisplayString Condition="value() == 0">empty</DisplayString> 383 <DisplayString Condition="value() != 0"> 384 unique_ptr {value()}</DisplayString> 385 <Expand> 386 <Item Condition="value() != 0" Name="[ptr]">value()</Item> 387 </Expand> 388 </Type> 389 390<Type Name="std::__Cr::unordered_map<*>"> 391 <AlternativeType Name="std::__Cr::unordered_multimap<*>" /> 392 <AlternativeType Name="std::__Cr::unordered_multiset<*>" /> 393 <AlternativeType Name="std::__Cr::unordered_set<*>" /> 394 <Intrinsic Name="size" Expression="*(size_type*)&__table_.__p2_" /> 395 <Intrinsic Name="bucket_count" 396 Expression="*(size_type*)& 397 ((__table::__bucket_list_deleter*) 398 ((void**)&__table_.__bucket_list_ + 1)) 399 ->__data_" /> 400 <DisplayString>{{ size={size()} }}</DisplayString> 401 <Expand> 402 <Item Name="[bucket_count]">bucket_count()</Item> 403 <Item Name="[load_factor]"> 404 bucket_count() != 0 ? (float)size() / bucket_count() : 0.f</Item> 405 <Item Name="[max_load_factor]">*(float*)&__table_.__p3_</Item> 406 <!-- Use CustomListItems instead of LinkedListItems because we 407 need to cast to __table::__node_pointer and LinkedListItems 408 evaluates <Value> in the context of the node, not of the container, 409 so we'd have to say std::unordered_map<$T1,...>::__table::__node_pointer 410 and then we couldn't share this <Type> between unordered_(multi)map 411 and unordered_(multi)set. --> 412 <CustomListItems> 413 <Variable Name="node" 414 InitialValue="*(__table::__next_pointer*)&__table_.__p1_" /> 415 <Size>size()</Size> 416 <Loop> 417 <Item>(*(__table::__node_pointer*)&node)->__value_</Item> 418 <Exec>node = node->__next_</Exec> 419 </Loop> 420 </CustomListItems> 421 </Expand> 422 </Type> 423 <!-- This is the node __value_ of an unordered_(multi)map. Expand it through 424 a separate formatter instead of in the <Item> expression above so that the 425 same <Type> works for unordered_(multi)set and unordered_(multi)map. --> 426 <Type Name="std::__Cr::__hash_value_type<*>"> 427 <DisplayString>{__cc}</DisplayString> 428 <Expand> 429 <ExpandedItem>__cc</ExpandedItem> 430 </Expand> 431 </Type> 432 433 <Type Name="std::__Cr::vector<*>"> 434 <Intrinsic Name="size" Expression="__end_ - __begin_" /> 435 <DisplayString>{{ size={size()} }}</DisplayString> 436 <Expand> 437 <ArrayItems> 438 <Size>size()</Size> 439 <ValuePointer>__begin_</ValuePointer> 440 </ArrayItems> 441 </Expand> 442 </Type> 443</AutoVisualizer> 444