diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/libwebrtc/build/config/c++ | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/build/config/c++')
-rw-r--r-- | third_party/libwebrtc/build/config/c++/BUILD.gn | 145 | ||||
-rw-r--r-- | third_party/libwebrtc/build/config/c++/c++.gni | 81 | ||||
-rw-r--r-- | third_party/libwebrtc/build/config/c++/libc++.natvis | 435 |
3 files changed, 661 insertions, 0 deletions
diff --git a/third_party/libwebrtc/build/config/c++/BUILD.gn b/third_party/libwebrtc/build/config/c++/BUILD.gn new file mode 100644 index 0000000000..e7ed69ec81 --- /dev/null +++ b/third_party/libwebrtc/build/config/c++/BUILD.gn @@ -0,0 +1,145 @@ +import("//build/config/c++/c++.gni") +import("//build/config/chrome_build.gni") +import("//build/config/chromeos/ui_mode.gni") +import("//build/config/dcheck_always_on.gni") +import("//buildtools/deps_revisions.gni") + +assert(use_custom_libcxx, "should only be used if use_custom_libcxx is set") + +declare_args() { + # lldb pretty printing only works when libc++ is built in the __1 (or __ndk1) + # namespaces. For pretty printing to work out-of-the-box on Mac (where lldb + # is primarily used), this flag is set to false to build with the __1 + # namespace (to maintain ABI compatibility, this implies building without + # _LIBCPP_ABI_UNSTABLE). This is not necessary on non-component builds + # because we leave the ABI version set to __1 in that case because libc++ + # symbols are not exported. + # TODO(thomasanderson): Set this to true by default once rL352899 is available + # in MacOS's lldb. + libcxx_abi_unstable = !(is_apple && is_debug && is_component_build) +} + +# TODO(xiaohuic): https://crbug/917533 Crashes on internal ChromeOS build. +# Do unconditionally once the underlying problem is fixed. +if (is_chromeos_ash && is_chrome_branded) { + libcxx_abi_unstable = false +} + +# This is included by reference in the //build/config/compiler:runtime_library +# config that is applied to all targets. It is here to separate out the logic +# that is specific to libc++. Please see that target for advice on what should +# go in :runtime_library vs. :compiler. +config("runtime_library") { + cflags = [] + cflags_cc = [] + defines = [] + include_dirs = [] + ldflags = [] + libs = [] + + if (libcxx_abi_unstable) { + defines += [ "_LIBCPP_ABI_UNSTABLE" ] + } + + if (libcxx_is_shared) { + # When libcxx_is_shared is true, symbols from libc++.so are exported for + # all DSOs to use. If the system libc++ gets loaded (indirectly through + # a system library), then it will conflict with our libc++.so. Add a + # custom ABI version if we're building with _LIBCPP_ABI_UNSTABLE to avoid + # conflicts. + # + # Windows doesn't need to set _LIBCPP_ABI_VERSION since there's no system + # C++ library we could conflict with. + if (libcxx_abi_unstable && !is_win) { + defines += [ "_LIBCPP_ABI_VERSION=Cr" ] + } + } else { + # Don't leak any symbols on a static build. + defines += [ "_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS" ] + if (!export_libcxxabi_from_executables && !is_win) { + defines += [ "_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS" ] + } + } + + defines += [ "_LIBCPP_ENABLE_NODISCARD" ] + + include_dirs += [ "//buildtools/third_party/libc++" ] + + # Work around a symbol conflict between GRPC and the Fuchsia SDK. + # TODO(crbug.com/1166970): Remove this when resolved. + if (is_fuchsia) { + defines += [ "_LIBCPP_NO_NATIVE_SEMAPHORES" ] + } + + # The Windows component build fails to link with libc++'s debug mode. See + # https://crbug.com/923166#c33, https://crbug.com/923166#c44, and + # https://llvm.org/PR41018. + if (!(is_win && is_component_build)) { + # libc++ has two levels of debug mode. Setting _LIBCPP_DEBUG to zero + # enables most assertions. Setting it to one additionally enables iterator + # debugging. See https://libcxx.llvm.org/docs/DesignDocs/DebugMode.html + if (enable_iterator_debugging) { + defines += [ "_LIBCPP_DEBUG=1" ] + } else if (is_debug || dcheck_always_on) { + defines += [ "_LIBCPP_DEBUG=0" ] + } + } + + if (is_win) { + # Intentionally not using libc++abi on Windows because libc++abi only + # implements the Itanium C++ ABI, and not the Microsoft ABI which we use on + # Windows (and we need to use in order to interoperate correctly with COM + # among other things). + assert(!export_libcxxabi_from_executables, + "Don't use libcxxabi on Windows.") + + cflags_cc += + [ "-I" + rebase_path("$libcxx_prefix/include", root_build_dir) ] + + # Prevent libc++ from embedding linker flags to try to automatically link + # against its runtime library. This is unnecessary with our build system, + # and can also result in build failures if libc++'s name for a library + # does not match ours. + defines += [ "_LIBCPP_NO_AUTO_LINK" ] + + # Add a debug visualizer for Microsoft's debuggers so that they can display + # libc++ types well. + if (libcxx_natvis_include) { + # chrome.natvis listed as an input in //buildtools/third_party/libc++ to + # guarantee relinking on changes. + ldflags += [ "/NATVIS:" + rebase_path("libc++.natvis", root_build_dir) ] + } + } else { + cflags_cc += [ + "-nostdinc++", + "-isystem" + rebase_path("$libcxx_prefix/include", root_build_dir), + "-isystem" + rebase_path("$libcxxabi_prefix/include", root_build_dir), + ] + cflags_objcc = cflags_cc + + defines += [ "CR_LIBCXX_REVISION=$libcxx_revision" ] + + # Make sure we don't link against the system libstdc++ or libc++. + if (is_clang) { + ldflags += [ "-nostdlib++" ] + } else { + # Gcc has a built-in abs() definition with default visibility. + # If it was not disabled, it would conflict with libc++'s abs() + # with hidden visibility. + cflags += [ "-fno-builtin-abs" ] + + ldflags += [ "-nodefaultlibs" ] + + # Unfortunately, there's no way to disable linking against just libc++ + # (gcc doesn't have -notstdlib++: + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83931); -nodefaultlibs + # removes all of the default libraries, so add back the ones that we need. + libs += [ + "c", + "gcc_s", + "m", + "rt", + ] + } + } +} diff --git a/third_party/libwebrtc/build/config/c++/c++.gni b/third_party/libwebrtc/build/config/c++/c++.gni new file mode 100644 index 0000000000..10a780c19b --- /dev/null +++ b/third_party/libwebrtc/build/config/c++/c++.gni @@ -0,0 +1,81 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/chromeos/ui_mode.gni") +import("//build/config/sanitizers/sanitizers.gni") + +declare_args() { + # Use in-tree libc++ (buildtools/third_party/libc++ and + # buildtools/third_party/libc++abi) instead of the system C++ library for C++ + # standard library support. + # Don't check in changes that set this to false for more platforms; doing so + # is not supported. + use_custom_libcxx = + is_fuchsia || is_android || is_mac || is_linux || is_chromeos_lacros || + (is_ios && !use_xcode_clang) || (is_win && is_clang) || + (is_chromeos && default_toolchain != "//build/toolchain/cros:target") + + # Use libc++ instead of stdlibc++ when using the host_cpu toolchain, even if + # use_custom_libcxx is false. This is useful for cross-compiles where a custom + # toolchain for the target_cpu has been set as the default toolchain, but + # use_custom_libcxx should still be true when building for the host. The + # expected usage is to set use_custom_libcxx=false and + # use_custom_libcxx_for_host=true in the passed in buildargs. + use_custom_libcxx_for_host = false + + # Builds libcxx Natvis into the symbols for type visualization. + # Set to false to workaround http://crbug.com/966676 and + # http://crbug.com/966687. + libcxx_natvis_include = true + + # When set, enables libc++ debug mode with iterator debugging. + # + # Iterator debugging is generally useful for catching bugs. But it can + # introduce extra locking to check the state of an iterator against the state + # of the current object. For iterator- and thread-heavy code, this can + # significantly slow execution - two orders of magnitude slowdown has been + # seen (crbug.com/903553) and iterator debugging also slows builds by making + # generation of snapshot_blob.bin take ~40-60 s longer. Therefore this + # defaults to off. + enable_iterator_debugging = false +} + +use_custom_libcxx = + use_custom_libcxx || (use_custom_libcxx_for_host && !is_a_target_toolchain) +use_custom_libcxx = use_custom_libcxx && !is_nacl + +declare_args() { + # WARNING: Setting this to a non-default value is highly discouraged. + # If true, libc++ will be built as a shared library; otherwise libc++ will be + # linked statically. Setting this to something other than the default is + # unsupported and can be broken by libc++ rolls. Note that if this is set to + # true, you must also set libcxx_abi_unstable=false, which is bad for + # performance and memory use. + libcxx_is_shared = use_custom_libcxx && is_component_build +} + +# libc++abi needs to be exported from executables to be picked up by shared +# libraries on certain instrumented builds. +export_libcxxabi_from_executables = + use_custom_libcxx && !is_apple && !is_win && !is_component_build && + (is_asan || is_ubsan_vptr) + +# On Android, many shared libraries get loaded from the context of a JRE. In +# this case, there's no "main executable" to export libc++abi from. We could +# export libc++abi from each "toplevel" shared library instead, but that would +# require adding an explicit dependency for each one, and might introduce +# subtle, hard-to-fix problems down the line if the dependency is missing. +# +# export_libcxxabi_from_executables was added to avoid having an RPATH set in +# static sanitizer builds just for executables to find libc++. But on Android, +# the Bionic dynamic loader doesn't even look at RPATH; instead, LD_LIBRARY_PATH +# is set for tests. Because of this, we make libc++ a shared library on android +# since it should get loaded properly. +if (is_android && export_libcxxabi_from_executables) { + export_libcxxabi_from_executables = false + libcxx_is_shared = true +} + +libcxx_prefix = "//buildtools/third_party/libc++/trunk" +libcxxabi_prefix = "//buildtools/third_party/libc++abi/trunk" diff --git a/third_party/libwebrtc/build/config/c++/libc++.natvis b/third_party/libwebrtc/build/config/c++/libc++.natvis new file mode 100644 index 0000000000..9a49a2935a --- /dev/null +++ b/third_party/libwebrtc/build/config/c++/libc++.natvis @@ -0,0 +1,435 @@ +<?xml version="1.0" encoding="utf-8" ?> +<AutoVisualizer + xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> + + <!-- libc++'s __compressed_pair is an internal type used pervasively for + doing the empty base class optimization. + + __compressed_pair<U,V> derives from __compressed_pair_elem<U,0> and + __compressed_pair_elem<V,1>. __compressed_pair_elem<T> is specialized on + a 3rd template parameter: + * if T is empty and non-final the 3rd param is 1 and it derives from T + * else it has a member variable __value_ of type T + --> + <Type Name="std::__1::__compressed_pair_elem<*,*,0>"> + <DisplayString>{__value_}</DisplayString> + <Expand> + <ExpandedItem>__value_</ExpandedItem> + </Expand> + </Type> + <Type Name="std::__1::__compressed_pair_elem<*,*,1>"> + <DisplayString>{*($T1*)this}</DisplayString> + <Expand> + <ExpandedItem>*($T1*)this</ExpandedItem> + </Expand> + </Type> + + <Type Name="std::__1::array<*,*>"> + <DisplayString>{{ size={$T2} }}</DisplayString> + <Expand> + <ArrayItems> + <Size>$T2</Size> + <ValuePointer>__elems_</ValuePointer> + </ArrayItems> + </Expand> + </Type> + + <!--libc++'s short string optimization: + A basic_string is 3 size_t words long. In the "alternate string layout" + that we use, they are: pointer to data, size, capacity. + (In the normal layout, it's capacity, size, data instead.) + If a string is short enough that it fits in these three size_ts instead, + the string data is stored inline in these 3 words, with the last byte of + the storage storing the length of the string. + The highest bit of the "capacity" word is set for normal, "long" strings, + and that bit needs to be masked out to know the real capacity. + If this bit is not set, the string data is stored inline. + (In the normal layout, if the lowest bit in the first byte is set, + it's a "long" string, requiring a long string to always have even + capacity. A short string here stores its length in the first byte + and the inline data in the remaining storage.) + --> + + <Type Name="std::__1::basic_string<char,*>"> + <!--<Intrinsic Name="is_long" + Expression="((__rep*)&__r_)->__s.__size_ & 0x80" />--> + <!-- The above doesn't work because of https://llvm.org/PR41615 + TODO(thakis): Now that we have clang r362038, try the above approach + again. + The below assumes the alternate string layout and little endianness :/ + --> + <Intrinsic Name="is_long" + Expression="*(((char*)this) + 3*sizeof(size_t) - 1) & 0x80" /> + <DisplayString Condition="is_long()">{*(char**)this}</DisplayString> + <DisplayString Condition="!is_long()">{(char*)this}</DisplayString> + <StringView Condition="is_long()">*(char**)this</StringView> + <StringView Condition="!is_long()">(char*)this</StringView> + <Expand> + <Item Name="[size]" Condition="is_long()" + ExcludeView="simple">((size_t*)this)[1]</Item> + <Item Name="[size]" Condition="!is_long()" + ExcludeView="simple">*(((char*)this) + 3*sizeof(size_t) - 1)</Item> + <Item Name="[capacity]" Condition="is_long()" ExcludeView="simple"> + ((size_t*)this)[2] & (~((size_t)0) >> 1) + </Item> + <Item Name="[capacity]" Condition="!is_long()" + ExcludeView="simple">22</Item> + <ArrayItems> + <Size Condition="is_long()">((size_t*)this)[1]</Size> + <Size Condition="!is_long()"> + *(((char*)this) + 3*sizeof(size_t) - 1) + </Size> + <ValuePointer Condition="is_long()">*(char**)this</ValuePointer> + <ValuePointer Condition="!is_long()">(char*)this</ValuePointer> + </ArrayItems> + </Expand> + </Type> + + <Type Name="std::__1::basic_string<wchar_t,*>"> + <Intrinsic Name="is_long" + Expression="*(((char*)this) + 3*sizeof(size_t) - 1) & 0x80" /> + <DisplayString Condition="is_long()">{*(wchar_t**)this}</DisplayString> + <DisplayString Condition="!is_long()">{(wchar_t*)this}</DisplayString> + <StringView Condition="is_long()">*(wchar_t**)this</StringView> + <StringView Condition="!is_long()">(wchar_t*)this</StringView> + <Expand> + <Item Name="[size]" Condition="is_long()" + ExcludeView="simple">((size_t*)this)[1]</Item> + <Item Name="[size]" Condition="!is_long()" + ExcludeView="simple">*(((char*)this) + 3*sizeof(size_t) - 1)</Item> + <Item Name="[capacity]" Condition="is_long()" ExcludeView="simple"> + ((size_t*)this)[2] & (~((size_t)0) >> 1) + </Item> + <Item Name="[capacity]" Condition="!is_long()" + ExcludeView="simple">10</Item> + <ArrayItems> + <Size Condition="is_long()">((size_t*)this)[1]</Size> + <Size Condition="!is_long()"> + *(((char*)this) + 3*sizeof(size_t) - 1) + </Size> + <ValuePointer Condition="is_long()">*(wchar_t**)this</ValuePointer> + <ValuePointer Condition="!is_long()">(wchar_t*)this</ValuePointer> + </ArrayItems> + </Expand> + </Type> + + <Type Name="std::__1::deque<*,*>"> + <Intrinsic Name="size" Expression="*(size_type*)&__size_" /> + <Intrinsic Name="block_size" + Expression="sizeof($T1) < 256 ? 4096 / sizeof($T1) : 16" /> + <DisplayString>{{ size={size()} }}</DisplayString> + <Expand> + <IndexListItems> + <Size>size()</Size> + <ValueNode> + *(*(__map_.__begin_ + ($i + __start_) / block_size()) + + ($i + __start_) % block_size()) + </ValueNode> + </IndexListItems> + </Expand> + </Type> + + <Type Name="std::__1::forward_list<*>"> + <Intrinsic Name="head" + Expression="((__node_pointer)&__before_begin_)->__next_" /> + <DisplayString Condition="head() == 0">empty</DisplayString> + <DisplayString Condition="head() != 0">non-empty</DisplayString> + <Expand> + <LinkedListItems> + <HeadPointer>head()</HeadPointer> + <NextPointer>__next_</NextPointer> + <ValueNode>__value_</ValueNode> + </LinkedListItems> + </Expand> + </Type> + + <!-- Note: Not in __1! But will win over the one in stl.natvis --> + <Type Name="std::initializer_list<*>"> + <DisplayString>{{ size={__size_} }}</DisplayString> + <Expand> + <ArrayItems> + <Size>__size_</Size> + <ValuePointer>__begin_</ValuePointer> + </ArrayItems> + </Expand> + </Type> + + <Type Name="std::__1::list<*>"> + <Intrinsic Name="size" Expression="*(size_type*)&__size_alloc_" /> + <DisplayString>{{ size={size()} }}</DisplayString> + <Expand> + <LinkedListItems> + <Size>size()</Size> + <HeadPointer>__end_.__next_</HeadPointer> + <NextPointer>__next_</NextPointer> + <ValueNode> + ((std::__1::list<$T1,$T2>::__node_pointer)this) + ->__value_ + </ValueNode> + </LinkedListItems> + </Expand> + </Type> + + <Type Name="std::__1::map<*>"> + <Intrinsic Name="size" Expression="*(size_type*)&__tree_.__pair3_" /> + <DisplayString>{{ size={size()} }}</DisplayString> + <Expand> + <Item Name="[size]">size()</Item> + <TreeItems> + <Size>size()</Size> + <HeadPointer> + ((__node_pointer)&__tree_.__pair1_)->__left_ + </HeadPointer> + <LeftPointer> + ((std::__1::map<$T1,$T2,$T3,$T4>::__node_pointer)this) + ->__left_ + </LeftPointer> + <RightPointer> + ((std::__1::map<$T1,$T2,$T3,$T4>::__node_pointer)this) + ->__right_ + </RightPointer> + <ValueNode> + ((std::__1::map<$T1,$T2,$T3,$T4>::__node_pointer)this) + ->__value_.__cc + </ValueNode> + </TreeItems> + </Expand> + </Type> + + <Type Name="std::__1::multimap<*>"> + <Intrinsic Name="size" Expression="*(size_type*)&__tree_.__pair3_" /> + <DisplayString>{{ size={size()} }}</DisplayString> + <Expand> + <Item Name="[size]">size()</Item> + <TreeItems> + <Size>size()</Size> + <HeadPointer> + ((__node_pointer)&__tree_.__pair1_)->__left_ + </HeadPointer> + <LeftPointer> + ((std::__1::multimap<$T1,$T2,$T3,$T4>::__node_pointer)this) + ->__left_ + </LeftPointer> + <RightPointer> + ((std::__1::multimap<$T1,$T2,$T3,$T4>::__node_pointer)this) + ->__right_ + </RightPointer> + <ValueNode> + ((std::__1::multimap<$T1,$T2,$T3,$T4>::__node_pointer)this) + ->__value_.__cc + </ValueNode> + </TreeItems> + </Expand> + </Type> + + <Type Name="std::__1::multiset<*>"> + <Intrinsic Name="size" Expression="*(size_type*)&__tree_.__pair3_" /> + <DisplayString>{{ size={size()} }}</DisplayString> + <Expand> + <Item Name="[size]">size()</Item> + <TreeItems> + <Size>size()</Size> + <HeadPointer> + ((__base::__node_pointer)&__tree_.__pair1_)->__left_ + </HeadPointer> + <LeftPointer> + ((std::__1::multiset<$T1,$T2,$T3>::__base::__node_pointer)this) + ->__left_ + </LeftPointer> + <RightPointer> + ((std::__1::multiset<$T1,$T2,$T3>::__base::__node_pointer)this) + ->__right_ + </RightPointer> + <ValueNode> + ((std::__1::multiset<$T1,$T2,$T3>::__base::__node_pointer)this) + ->__value_ + </ValueNode> + </TreeItems> + </Expand> + </Type> + + <Type Name="std::__1::priority_queue<*>"> + <DisplayString>{c}</DisplayString> + <Expand> + <ExpandedItem>c</ExpandedItem> + <Item Name="[comp]">comp</Item> + </Expand> + </Type> + + <Type Name="std::__1::set<*>"> + <Intrinsic Name="size" Expression="*(size_type*)&__tree_.__pair3_" /> + <DisplayString>{{ size={size()} }}</DisplayString> + <Expand> + <Item Name="[size]">size()</Item> + <TreeItems> + <Size>size()</Size> + <HeadPointer> + ((__base::__node_pointer)&__tree_.__pair1_)->__left_ + </HeadPointer> + <LeftPointer> + ((std::__1::set<$T1,$T2,$T3>::__base::__node_pointer)this) + ->__left_ + </LeftPointer> + <RightPointer> + ((std::__1::set<$T1,$T2,$T3>::__base::__node_pointer)this) + ->__right_ + </RightPointer> + <ValueNode> + ((std::__1::set<$T1,$T2,$T3>::__base::__node_pointer)this) + ->__value_ + </ValueNode> + </TreeItems> + </Expand> + </Type> + + <Type Name="std::__1::stack<*>"> + <AlternativeType Name="std::__1::queue<*>" /> + <DisplayString>{c}</DisplayString> + <Expand> + <ExpandedItem>c</ExpandedItem> + </Expand> + </Type> + + <Type Name="std::__1::__tuple_leaf<*,*,0>"> + <DisplayString>{__value_}</DisplayString> + </Type> + + <Type Name="std::__1::tuple<>"> + <DisplayString>()</DisplayString> + </Type> + + <Type Name="std::__1::tuple<*>"> + <DisplayString>({(std::__1::__tuple_leaf<0,$T1,0>)__base_})</DisplayString> + <Expand> + <Item Name="[0]">(std::__1::__tuple_leaf<0,$T1,0>)__base_</Item> + </Expand> + </Type> + + <Type Name="std::__1::tuple<*,*>"> + <DisplayString>({(std::__1::__tuple_leaf<0,$T1,0>)__base_}, {(std::__1::__tuple_leaf<1,$T2,0>)__base_})</DisplayString> + <Expand> + <Item Name="[0]">(std::__1::__tuple_leaf<0,$T1,0>)__base_</Item> + <Item Name="[1]">(std::__1::__tuple_leaf<1,$T2,0>)__base_</Item> + </Expand> + </Type> + + <Type Name="std::__1::tuple<*,*,*>"> + <DisplayString>({(std::__1::__tuple_leaf<0,$T1,0>)__base_}, {(std::__1::__tuple_leaf<1,$T2,0>)__base_}, {(std::__1::__tuple_leaf<2,$T3,0>)__base_})</DisplayString> + <Expand> + <Item Name="[0]">(std::__1::__tuple_leaf<0,$T1,0>)__base_</Item> + <Item Name="[1]">(std::__1::__tuple_leaf<1,$T2,0>)__base_</Item> + <Item Name="[2]">(std::__1::__tuple_leaf<2,$T3,0>)__base_</Item> + </Expand> + </Type> + + <Type Name="std::__1::tuple<*,*,*,*>"> + <DisplayString>({(std::__1::__tuple_leaf<0,$T1,0>)__base_}, {(std::__1::__tuple_leaf<1,$T2,0>)__base_}, {(std::__1::__tuple_leaf<2,$T3,0>)__base_}, {(std::__1::__tuple_leaf<3,$T4,0>)__base_})</DisplayString> + <Expand> + <Item Name="[0]">(std::__1::__tuple_leaf<0,$T1,0>)__base_</Item> + <Item Name="[1]">(std::__1::__tuple_leaf<1,$T2,0>)__base_</Item> + <Item Name="[2]">(std::__1::__tuple_leaf<2,$T3,0>)__base_</Item> + <Item Name="[3]">(std::__1::__tuple_leaf<3,$T4,0>)__base_</Item> + </Expand> + </Type> + + <Type Name="std::__1::tuple<*,*,*,*,*>"> + <DisplayString>({(std::__1::__tuple_leaf<0,$T1,0>)__base_}, {(std::__1::__tuple_leaf<1,$T2,0>)__base_}, {(std::__1::__tuple_leaf<2,$T3,0>)__base_}, {(std::__1::__tuple_leaf<3,$T4,0>)__base_}, {(std::__1::__tuple_leaf<4,$T5,0>)__base_})</DisplayString> + <Expand> + <Item Name="[0]">(std::__1::__tuple_leaf<0,$T1,0>)__base_</Item> + <Item Name="[1]">(std::__1::__tuple_leaf<1,$T2,0>)__base_</Item> + <Item Name="[2]">(std::__1::__tuple_leaf<2,$T3,0>)__base_</Item> + <Item Name="[3]">(std::__1::__tuple_leaf<3,$T4,0>)__base_</Item> + <Item Name="[4]">(std::__1::__tuple_leaf<4,$T5,0>)__base_</Item> + </Expand> + </Type> + + <Type Name="std::__1::tuple<*,*,*,*,*,*>"> + <DisplayString>({(std::__1::__tuple_leaf<0,$T1,0>)__base_}, {(std::__1::__tuple_leaf<1,$T2,0>)__base_}, {(std::__1::__tuple_leaf<2,$T3,0>)__base_}, {(std::__1::__tuple_leaf<3,$T4,0>)__base_}, {(std::__1::__tuple_leaf<4,$T5,0>)__base_}, {(std::__1::__tuple_leaf<5,$T6,0>)__base_})</DisplayString> + <Expand> + <Item Name="[0]">(std::__1::__tuple_leaf<0,$T1,0>)__base_</Item> + <Item Name="[1]">(std::__1::__tuple_leaf<1,$T2,0>)__base_</Item> + <Item Name="[2]">(std::__1::__tuple_leaf<2,$T3,0>)__base_</Item> + <Item Name="[3]">(std::__1::__tuple_leaf<3,$T4,0>)__base_</Item> + <Item Name="[4]">(std::__1::__tuple_leaf<4,$T5,0>)__base_</Item> + <Item Name="[5]">(std::__1::__tuple_leaf<5,$T6,0>)__base_</Item> + </Expand> + </Type> + + <Type Name="std::__1::tuple<*,*,*,*,*,*,*>"> + <DisplayString>({(std::__1::__tuple_leaf<0,$T1,0>)__base_}, {(std::__1::__tuple_leaf<1,$T2,0>)__base_}, {(std::__1::__tuple_leaf<2,$T3,0>)__base_}, {(std::__1::__tuple_leaf<3,$T4,0>)__base_}, {(std::__1::__tuple_leaf<4,$T5,0>)__base_}, {(std::__1::__tuple_leaf<5,$T6,0>)__base_}, {(std::__1::__tuple_leaf<6,$T7,0>)__base_})</DisplayString> + <Expand> + <Item Name="[0]">(std::__1::__tuple_leaf<0,$T1,0>)__base_</Item> + <Item Name="[1]">(std::__1::__tuple_leaf<1,$T2,0>)__base_</Item> + <Item Name="[2]">(std::__1::__tuple_leaf<2,$T3,0>)__base_</Item> + <Item Name="[3]">(std::__1::__tuple_leaf<3,$T4,0>)__base_</Item> + <Item Name="[4]">(std::__1::__tuple_leaf<4,$T5,0>)__base_</Item> + <Item Name="[5]">(std::__1::__tuple_leaf<5,$T6,0>)__base_</Item> + <Item Name="[6]">(std::__1::__tuple_leaf<6,$T7,0>)__base_</Item> + </Expand> + </Type> + + <Type Name="std::__1::unique_ptr<*>"> + <Intrinsic Name="value" Expression="*($T1**)&__ptr_" /> + <SmartPointer Usage="Minimal">value()</SmartPointer> + <DisplayString Condition="value() == 0">empty</DisplayString> + <DisplayString Condition="value() != 0"> + unique_ptr {value()}</DisplayString> + <Expand> + <Item Condition="value() != 0" Name="[ptr]">value()</Item> + </Expand> + </Type> + +<Type Name="std::__1::unordered_map<*>"> + <AlternativeType Name="std::__1::unordered_multimap<*>" /> + <AlternativeType Name="std::__1::unordered_multiset<*>" /> + <AlternativeType Name="std::__1::unordered_set<*>" /> + <Intrinsic Name="size" Expression="*(size_type*)&__table_.__p2_" /> + <Intrinsic Name="bucket_count" + Expression="*(size_type*)& + ((__table::__bucket_list_deleter*) + ((void**)&__table_.__bucket_list_ + 1)) + ->__data_" /> + <DisplayString>{{ size={size()} }}</DisplayString> + <Expand> + <Item Name="[bucket_count]">bucket_count()</Item> + <Item Name="[load_factor]"> + bucket_count() != 0 ? (float)size() / bucket_count() : 0.f</Item> + <Item Name="[max_load_factor]">*(float*)&__table_.__p3_</Item> + <!-- Use CustomListItems instead of LinkedListItems because we + need to cast to __table::__node_pointer and LinkedListItems + evaluates <Value> in the context of the node, not of the container, + so we'd have to say std::unordered_map<$T1,...>::__table::__node_pointer + and then we couldn't share this <Type> between unordered_(multi)map + and unordered_(multi)set. --> + <CustomListItems> + <Variable Name="node" + InitialValue="*(__table::__next_pointer*)&__table_.__p1_" /> + <Size>size()</Size> + <Loop> + <Item>(*(__table::__node_pointer*)&node)->__value_</Item> + <Exec>node = node->__next_</Exec> + </Loop> + </CustomListItems> + </Expand> + </Type> + <!-- This is the node __value_ of an unordered_(multi)map. Expand it through + a separate formatter instead of in the <Item> expression above so that the + same <Type> works for unordered_(multi)set and unordered_(multi)map. --> + <Type Name="std::__1::__hash_value_type<*>"> + <DisplayString>{__cc}</DisplayString> + <Expand> + <ExpandedItem>__cc</ExpandedItem> + </Expand> + </Type> + + <Type Name="std::__1::vector<*>"> + <Intrinsic Name="size" Expression="__end_ - __begin_" /> + <DisplayString>{{ size={size()} }}</DisplayString> + <Expand> + <ArrayItems> + <Size>size()</Size> + <ValuePointer>__begin_</ValuePointer> + </ArrayItems> + </Expand> + </Type> +</AutoVisualizer> |