summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/build/config/c++
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/build/config/c++')
-rw-r--r--third_party/libwebrtc/build/config/c++/BUILD.gn145
-rw-r--r--third_party/libwebrtc/build/config/c++/c++.gni81
-rw-r--r--third_party/libwebrtc/build/config/c++/libc++.natvis435
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&lt;*,*,0&gt;">
+ <DisplayString>{__value_}</DisplayString>
+ <Expand>
+ <ExpandedItem>__value_</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="std::__1::__compressed_pair_elem&lt;*,*,1&gt;">
+ <DisplayString>{*($T1*)this}</DisplayString>
+ <Expand>
+ <ExpandedItem>*($T1*)this</ExpandedItem>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::array&lt;*,*&gt;">
+ <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&lt;char,*&gt;">
+ <!--<Intrinsic Name="is_long"
+ Expression="((__rep*)&amp;__r_)-&gt;__s.__size_ &amp; 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) &amp; 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] &amp; (~((size_t)0) &gt;&gt; 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&lt;wchar_t,*&gt;">
+ <Intrinsic Name="is_long"
+ Expression="*(((char*)this) + 3*sizeof(size_t) - 1) &amp; 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] &amp; (~((size_t)0) &gt;&gt; 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&lt;*,*&gt;">
+ <Intrinsic Name="size" Expression="*(size_type*)&amp;__size_" />
+ <Intrinsic Name="block_size"
+ Expression="sizeof($T1) &lt; 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&lt;*&gt;">
+ <Intrinsic Name="head"
+ Expression="((__node_pointer)&amp;__before_begin_)-&gt;__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&lt;*&gt;">
+ <DisplayString>{{ size={__size_} }}</DisplayString>
+ <Expand>
+ <ArrayItems>
+ <Size>__size_</Size>
+ <ValuePointer>__begin_</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::list&lt;*&gt;">
+ <Intrinsic Name="size" Expression="*(size_type*)&amp;__size_alloc_" />
+ <DisplayString>{{ size={size()} }}</DisplayString>
+ <Expand>
+ <LinkedListItems>
+ <Size>size()</Size>
+ <HeadPointer>__end_.__next_</HeadPointer>
+ <NextPointer>__next_</NextPointer>
+ <ValueNode>
+ ((std::__1::list&lt;$T1,$T2&gt;::__node_pointer)this)
+ -&gt;__value_
+ </ValueNode>
+ </LinkedListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::map&lt;*&gt;">
+ <Intrinsic Name="size" Expression="*(size_type*)&amp;__tree_.__pair3_" />
+ <DisplayString>{{ size={size()} }}</DisplayString>
+ <Expand>
+ <Item Name="[size]">size()</Item>
+ <TreeItems>
+ <Size>size()</Size>
+ <HeadPointer>
+ ((__node_pointer)&amp;__tree_.__pair1_)-&gt;__left_
+ </HeadPointer>
+ <LeftPointer>
+ ((std::__1::map&lt;$T1,$T2,$T3,$T4&gt;::__node_pointer)this)
+ -&gt;__left_
+ </LeftPointer>
+ <RightPointer>
+ ((std::__1::map&lt;$T1,$T2,$T3,$T4&gt;::__node_pointer)this)
+ -&gt;__right_
+ </RightPointer>
+ <ValueNode>
+ ((std::__1::map&lt;$T1,$T2,$T3,$T4&gt;::__node_pointer)this)
+ -&gt;__value_.__cc
+ </ValueNode>
+ </TreeItems>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::multimap&lt;*&gt;">
+ <Intrinsic Name="size" Expression="*(size_type*)&amp;__tree_.__pair3_" />
+ <DisplayString>{{ size={size()} }}</DisplayString>
+ <Expand>
+ <Item Name="[size]">size()</Item>
+ <TreeItems>
+ <Size>size()</Size>
+ <HeadPointer>
+ ((__node_pointer)&amp;__tree_.__pair1_)-&gt;__left_
+ </HeadPointer>
+ <LeftPointer>
+ ((std::__1::multimap&lt;$T1,$T2,$T3,$T4&gt;::__node_pointer)this)
+ -&gt;__left_
+ </LeftPointer>
+ <RightPointer>
+ ((std::__1::multimap&lt;$T1,$T2,$T3,$T4&gt;::__node_pointer)this)
+ -&gt;__right_
+ </RightPointer>
+ <ValueNode>
+ ((std::__1::multimap&lt;$T1,$T2,$T3,$T4&gt;::__node_pointer)this)
+ -&gt;__value_.__cc
+ </ValueNode>
+ </TreeItems>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::multiset&lt;*&gt;">
+ <Intrinsic Name="size" Expression="*(size_type*)&amp;__tree_.__pair3_" />
+ <DisplayString>{{ size={size()} }}</DisplayString>
+ <Expand>
+ <Item Name="[size]">size()</Item>
+ <TreeItems>
+ <Size>size()</Size>
+ <HeadPointer>
+ ((__base::__node_pointer)&amp;__tree_.__pair1_)-&gt;__left_
+ </HeadPointer>
+ <LeftPointer>
+ ((std::__1::multiset&lt;$T1,$T2,$T3&gt;::__base::__node_pointer)this)
+ -&gt;__left_
+ </LeftPointer>
+ <RightPointer>
+ ((std::__1::multiset&lt;$T1,$T2,$T3&gt;::__base::__node_pointer)this)
+ -&gt;__right_
+ </RightPointer>
+ <ValueNode>
+ ((std::__1::multiset&lt;$T1,$T2,$T3&gt;::__base::__node_pointer)this)
+ -&gt;__value_
+ </ValueNode>
+ </TreeItems>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::priority_queue&lt;*&gt;">
+ <DisplayString>{c}</DisplayString>
+ <Expand>
+ <ExpandedItem>c</ExpandedItem>
+ <Item Name="[comp]">comp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::set&lt;*&gt;">
+ <Intrinsic Name="size" Expression="*(size_type*)&amp;__tree_.__pair3_" />
+ <DisplayString>{{ size={size()} }}</DisplayString>
+ <Expand>
+ <Item Name="[size]">size()</Item>
+ <TreeItems>
+ <Size>size()</Size>
+ <HeadPointer>
+ ((__base::__node_pointer)&amp;__tree_.__pair1_)-&gt;__left_
+ </HeadPointer>
+ <LeftPointer>
+ ((std::__1::set&lt;$T1,$T2,$T3&gt;::__base::__node_pointer)this)
+ -&gt;__left_
+ </LeftPointer>
+ <RightPointer>
+ ((std::__1::set&lt;$T1,$T2,$T3&gt;::__base::__node_pointer)this)
+ -&gt;__right_
+ </RightPointer>
+ <ValueNode>
+ ((std::__1::set&lt;$T1,$T2,$T3&gt;::__base::__node_pointer)this)
+ -&gt;__value_
+ </ValueNode>
+ </TreeItems>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::stack&lt;*&gt;">
+ <AlternativeType Name="std::__1::queue&lt;*&gt;" />
+ <DisplayString>{c}</DisplayString>
+ <Expand>
+ <ExpandedItem>c</ExpandedItem>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::__tuple_leaf&lt;*,*,0&gt;">
+ <DisplayString>{__value_}</DisplayString>
+ </Type>
+
+ <Type Name="std::__1::tuple&lt;&gt;">
+ <DisplayString>()</DisplayString>
+ </Type>
+
+ <Type Name="std::__1::tuple&lt;*&gt;">
+ <DisplayString>({(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_})</DisplayString>
+ <Expand>
+ <Item Name="[0]">(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::tuple&lt;*,*&gt;">
+ <DisplayString>({(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;1,$T2,0&gt;)__base_})</DisplayString>
+ <Expand>
+ <Item Name="[0]">(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
+ <Item Name="[1]">(std::__1::__tuple_leaf&lt;1,$T2,0&gt;)__base_</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::tuple&lt;*,*,*&gt;">
+ <DisplayString>({(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;1,$T2,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;2,$T3,0&gt;)__base_})</DisplayString>
+ <Expand>
+ <Item Name="[0]">(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
+ <Item Name="[1]">(std::__1::__tuple_leaf&lt;1,$T2,0&gt;)__base_</Item>
+ <Item Name="[2]">(std::__1::__tuple_leaf&lt;2,$T3,0&gt;)__base_</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::tuple&lt;*,*,*,*&gt;">
+ <DisplayString>({(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;1,$T2,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;2,$T3,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;3,$T4,0&gt;)__base_})</DisplayString>
+ <Expand>
+ <Item Name="[0]">(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
+ <Item Name="[1]">(std::__1::__tuple_leaf&lt;1,$T2,0&gt;)__base_</Item>
+ <Item Name="[2]">(std::__1::__tuple_leaf&lt;2,$T3,0&gt;)__base_</Item>
+ <Item Name="[3]">(std::__1::__tuple_leaf&lt;3,$T4,0&gt;)__base_</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::tuple&lt;*,*,*,*,*&gt;">
+ <DisplayString>({(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;1,$T2,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;2,$T3,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;3,$T4,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;4,$T5,0&gt;)__base_})</DisplayString>
+ <Expand>
+ <Item Name="[0]">(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
+ <Item Name="[1]">(std::__1::__tuple_leaf&lt;1,$T2,0&gt;)__base_</Item>
+ <Item Name="[2]">(std::__1::__tuple_leaf&lt;2,$T3,0&gt;)__base_</Item>
+ <Item Name="[3]">(std::__1::__tuple_leaf&lt;3,$T4,0&gt;)__base_</Item>
+ <Item Name="[4]">(std::__1::__tuple_leaf&lt;4,$T5,0&gt;)__base_</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::tuple&lt;*,*,*,*,*,*&gt;">
+ <DisplayString>({(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;1,$T2,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;2,$T3,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;3,$T4,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;4,$T5,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;5,$T6,0&gt;)__base_})</DisplayString>
+ <Expand>
+ <Item Name="[0]">(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
+ <Item Name="[1]">(std::__1::__tuple_leaf&lt;1,$T2,0&gt;)__base_</Item>
+ <Item Name="[2]">(std::__1::__tuple_leaf&lt;2,$T3,0&gt;)__base_</Item>
+ <Item Name="[3]">(std::__1::__tuple_leaf&lt;3,$T4,0&gt;)__base_</Item>
+ <Item Name="[4]">(std::__1::__tuple_leaf&lt;4,$T5,0&gt;)__base_</Item>
+ <Item Name="[5]">(std::__1::__tuple_leaf&lt;5,$T6,0&gt;)__base_</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::tuple&lt;*,*,*,*,*,*,*&gt;">
+ <DisplayString>({(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;1,$T2,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;2,$T3,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;3,$T4,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;4,$T5,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;5,$T6,0&gt;)__base_}, {(std::__1::__tuple_leaf&lt;6,$T7,0&gt;)__base_})</DisplayString>
+ <Expand>
+ <Item Name="[0]">(std::__1::__tuple_leaf&lt;0,$T1,0&gt;)__base_</Item>
+ <Item Name="[1]">(std::__1::__tuple_leaf&lt;1,$T2,0&gt;)__base_</Item>
+ <Item Name="[2]">(std::__1::__tuple_leaf&lt;2,$T3,0&gt;)__base_</Item>
+ <Item Name="[3]">(std::__1::__tuple_leaf&lt;3,$T4,0&gt;)__base_</Item>
+ <Item Name="[4]">(std::__1::__tuple_leaf&lt;4,$T5,0&gt;)__base_</Item>
+ <Item Name="[5]">(std::__1::__tuple_leaf&lt;5,$T6,0&gt;)__base_</Item>
+ <Item Name="[6]">(std::__1::__tuple_leaf&lt;6,$T7,0&gt;)__base_</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::unique_ptr&lt;*&gt;">
+ <Intrinsic Name="value" Expression="*($T1**)&amp;__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&lt;*&gt;">
+ <AlternativeType Name="std::__1::unordered_multimap&lt;*&gt;" />
+ <AlternativeType Name="std::__1::unordered_multiset&lt;*&gt;" />
+ <AlternativeType Name="std::__1::unordered_set&lt;*&gt;" />
+ <Intrinsic Name="size" Expression="*(size_type*)&amp;__table_.__p2_" />
+ <Intrinsic Name="bucket_count"
+ Expression="*(size_type*)&amp;
+ ((__table::__bucket_list_deleter*)
+ ((void**)&amp;__table_.__bucket_list_ + 1))
+ -&gt;__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*)&amp;__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*)&amp;__table_.__p1_" />
+ <Size>size()</Size>
+ <Loop>
+ <Item>(*(__table::__node_pointer*)&amp;node)-&gt;__value_</Item>
+ <Exec>node = node-&gt;__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&lt;*&gt;">
+ <DisplayString>{__cc}</DisplayString>
+ <Expand>
+ <ExpandedItem>__cc</ExpandedItem>
+ </Expand>
+ </Type>
+
+ <Type Name="std::__1::vector&lt;*&gt;">
+ <Intrinsic Name="size" Expression="__end_ - __begin_" />
+ <DisplayString>{{ size={size()} }}</DisplayString>
+ <Expand>
+ <ArrayItems>
+ <Size>size()</Size>
+ <ValuePointer>__begin_</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+</AutoVisualizer>