Browse Source

Add ray_tracing_position_fetch support

Panagiotis Christopoulos Charitos 9 tháng trước cách đây
mục cha
commit
781a476498
100 tập tin đã thay đổi với 2550 bổ sung1330 xóa
  1. 32 0
      AnKi/Gr/Common.cpp
  2. 5 0
      AnKi/Gr/Common.h
  3. 2 1
      AnKi/Gr/Vulkan/VkCommon.h
  4. 21 0
      AnKi/Gr/Vulkan/VkGrManager.cpp
  5. 10 3
      AnKi/Renderer/RtMaterialFetchDbg.cpp
  6. 9 0
      AnKi/ShaderCompiler/ShaderDump.cpp
  7. 22 2
      AnKi/Shaders/Common.hlsl
  8. 15 6
      AnKi/Shaders/GBufferGeneric.ankiprog
  9. 2 2
      AnKi/Shaders/GBufferGpuParticles.ankiprog
  10. 4 6
      AnKi/Shaders/GBufferPost.ankiprog
  11. 5 1
      AnKi/Shaders/GBufferVisualizeProbe.ankiprog
  12. 0 8
      AnKi/Shaders/MaterialShadersCommon.hlsl
  13. 17 5
      AnKi/Shaders/PackFunctions.hlsl
  14. 1 1
      AnKi/Shaders/RtMaterialFetchDbg.ankiprog
  15. BIN
      ThirdParty/Dxc/dxc
  16. BIN
      ThirdParty/Dxc/dxc.exe
  17. 1 1
      ThirdParty/Dxc/dxcapi.h
  18. BIN
      ThirdParty/Dxc/dxcompiler.dll
  19. BIN
      ThirdParty/Dxc/dxil.dll
  20. BIN
      ThirdParty/Dxc/dxv
  21. BIN
      ThirdParty/Dxc/dxv.exe
  22. BIN
      ThirdParty/Dxc/libdxcompiler.so
  23. BIN
      ThirdParty/Dxc/libdxil.so
  24. 15 8
      ThirdParty/SpirvTools/Android.mk
  25. 72 58
      ThirdParty/SpirvTools/BUILD.bazel
  26. 67 21
      ThirdParty/SpirvTools/BUILD.gn
  27. 230 2
      ThirdParty/SpirvTools/CHANGES
  28. 39 39
      ThirdParty/SpirvTools/CMakeLists.txt
  29. 45 81
      ThirdParty/SpirvTools/CONTRIBUTING.md
  30. 11 5
      ThirdParty/SpirvTools/DEPS
  31. 33 0
      ThirdParty/SpirvTools/MODULE.bazel
  32. 35 32
      ThirdParty/SpirvTools/README.md
  33. 13 0
      ThirdParty/SpirvTools/SECURITY.md
  34. 2 12
      ThirdParty/SpirvTools/WORKSPACE
  35. 1 1
      ThirdParty/SpirvTools/android_test/Android.mk
  36. 1 1
      ThirdParty/SpirvTools/android_test/jni/Application.mk
  37. 6 6
      ThirdParty/SpirvTools/build_defs.bzl
  38. 21 18
      ThirdParty/SpirvTools/docs/downloads.md
  39. 2 2
      ThirdParty/SpirvTools/docs/projects.md
  40. 44 0
      ThirdParty/SpirvTools/docs/syntax.md
  41. 18 6
      ThirdParty/SpirvTools/external/CMakeLists.txt
  42. 13 13
      ThirdParty/SpirvTools/external/effcee/BUILD.bazel
  43. 6 2
      ThirdParty/SpirvTools/external/effcee/CHANGES
  44. 8 3
      ThirdParty/SpirvTools/external/effcee/CMakeLists.txt
  45. 7 5
      ThirdParty/SpirvTools/external/effcee/README.md
  46. 0 16
      ThirdParty/SpirvTools/external/effcee/WORKSPACE
  47. 3 11
      ThirdParty/SpirvTools/external/effcee/cmake/setup_build.cmake
  48. 2 2
      ThirdParty/SpirvTools/external/effcee/cmake/utils.cmake
  49. 1 0
      ThirdParty/SpirvTools/external/effcee/effcee/CMakeLists.txt
  50. 12 4
      ThirdParty/SpirvTools/external/effcee/effcee/check.cc
  51. 3 2
      ThirdParty/SpirvTools/external/effcee/effcee/cursor.h
  52. 14 14
      ThirdParty/SpirvTools/external/effcee/effcee/cursor_test.cc
  53. 1 1
      ThirdParty/SpirvTools/external/effcee/effcee/effcee.h
  54. 1 1
      ThirdParty/SpirvTools/external/effcee/effcee/match.cc
  55. 1 1
      ThirdParty/SpirvTools/external/effcee/examples/CMakeLists.txt
  56. 24 0
      ThirdParty/SpirvTools/external/effcee/third_party/CMakeLists.txt
  57. 44 12
      ThirdParty/SpirvTools/external/googletest/BUILD.bazel
  58. 12 15
      ThirdParty/SpirvTools/external/googletest/CMakeLists.txt
  59. 4 4
      ThirdParty/SpirvTools/external/googletest/CONTRIBUTING.md
  60. 1 0
      ThirdParty/SpirvTools/external/googletest/CONTRIBUTORS
  61. 45 23
      ThirdParty/SpirvTools/external/googletest/README.md
  62. 49 28
      ThirdParty/SpirvTools/external/googletest/WORKSPACE
  63. 52 29
      ThirdParty/SpirvTools/external/googletest/ci/linux-presubmit.sh
  64. 9 4
      ThirdParty/SpirvTools/external/googletest/ci/macos-presubmit.sh
  65. 42 23
      ThirdParty/SpirvTools/external/googletest/ci/windows-presubmit.bat
  66. 203 150
      ThirdParty/SpirvTools/external/googletest/docs/advanced.md
  67. 18 39
      ThirdParty/SpirvTools/external/googletest/docs/faq.md
  68. 1 1
      ThirdParty/SpirvTools/external/googletest/docs/gmock_cheat_sheet.md
  69. 127 62
      ThirdParty/SpirvTools/external/googletest/docs/gmock_cook_book.md
  70. 7 5
      ThirdParty/SpirvTools/external/googletest/docs/gmock_for_dummies.md
  71. 5 9
      ThirdParty/SpirvTools/external/googletest/docs/pkgconfig.md
  72. 6 33
      ThirdParty/SpirvTools/external/googletest/docs/platforms.md
  73. 65 66
      ThirdParty/SpirvTools/external/googletest/docs/primer.md
  74. 30 30
      ThirdParty/SpirvTools/external/googletest/docs/quickstart-bazel.md
  75. 1 0
      ThirdParty/SpirvTools/external/googletest/docs/quickstart-cmake.md
  76. 2 1
      ThirdParty/SpirvTools/external/googletest/docs/reference/actions.md
  77. 12 5
      ThirdParty/SpirvTools/external/googletest/docs/reference/assertions.md
  78. 7 4
      ThirdParty/SpirvTools/external/googletest/docs/reference/matchers.md
  79. 1 2
      ThirdParty/SpirvTools/external/googletest/docs/reference/mocking.md
  80. 159 40
      ThirdParty/SpirvTools/external/googletest/docs/reference/testing.md
  81. 24 32
      ThirdParty/SpirvTools/external/googletest/googlemock/CMakeLists.txt
  82. 3 3
      ThirdParty/SpirvTools/external/googletest/googlemock/README.md
  83. 113 33
      ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-actions.h
  84. 2 2
      ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-cardinalities.h
  85. 5 4
      ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-function-mocker.h
  86. 400 159
      ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-matchers.h
  87. 12 11
      ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-more-actions.h
  88. 1 1
      ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-nice-strict.h
  89. 56 21
      ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-spec-builders.h
  90. 8 7
      ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock.h
  91. 11 11
      ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h
  92. 5 4
      ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/internal/gmock-port.h
  93. 4 4
      ThirdParty/SpirvTools/external/googletest/googlemock/src/gmock-cardinalities.cc
  94. 5 3
      ThirdParty/SpirvTools/external/googletest/googlemock/src/gmock-internal-utils.cc
  95. 15 16
      ThirdParty/SpirvTools/external/googletest/googlemock/src/gmock-matchers.cc
  96. 11 9
      ThirdParty/SpirvTools/external/googletest/googlemock/src/gmock-spec-builders.cc
  97. 2 0
      ThirdParty/SpirvTools/external/googletest/googlemock/src/gmock.cc
  98. 5 4
      ThirdParty/SpirvTools/external/googletest/googlemock/src/gmock_main.cc
  99. 66 17
      ThirdParty/SpirvTools/external/googletest/googlemock/test/gmock-actions_test.cc
  100. 3 1
      ThirdParty/SpirvTools/external/googletest/googlemock/test/gmock-cardinalities_test.cc

+ 32 - 0
AnKi/Gr/Common.cpp

@@ -185,4 +185,36 @@ Error ShaderReflection::linkShaderReflection(const ShaderReflection& a, const Sh
 	return Error::kNone;
 }
 
+StringList ShaderReflectionDescriptorRelated::toString() const
+{
+	StringList list;
+	for(U32 s = 0; s < kMaxRegisterSpaces; ++s)
+	{
+		for(U32 i = 0; i < m_bindingCounts[s]; ++i)
+		{
+			list.pushBackSprintf("space: %u, register: %u, type: %u", s, m_bindings[s][i].m_registerBindingPoint, m_bindings[s][i].m_type);
+		}
+	}
+
+	list.pushBackSprintf("Fast constants: %u", m_fastConstantsSize);
+	list.pushBackSprintf("Has VK bindless sets: %u", m_hasVkBindlessDescriptorSet);
+
+	return list;
+}
+
+StringList ShaderReflection::toString() const
+{
+	StringList list = m_descriptor.toString();
+
+	for(VertexAttributeSemantic attrib : EnumBitsIterable<VertexAttributeSemantic, VertexAttributeSemanticBit>(m_vertex.m_vertexAttributeMask))
+	{
+		list.pushBackSprintf("Vert attrib: %u", attrib);
+	}
+
+	list.pushBackSprintf("Color RT mask: %u", m_pixel.m_colorRenderTargetWritemask.getData()[0]);
+	list.pushBackSprintf("Discards: %u", m_pixel.m_discards);
+
+	return list;
+}
+
 } // end namespace anki

+ 5 - 0
AnKi/Gr/Common.h

@@ -11,6 +11,7 @@
 #include <AnKi/Util/Enum.h>
 #include <AnKi/Shaders/Include/Common.h>
 #include <AnKi/Util/CVarSet.h>
+#include <AnKi/Util/StringList.h>
 
 namespace anki {
 
@@ -1021,6 +1022,8 @@ public:
 			}
 		}
 	}
+
+	StringList toString() const;
 };
 ANKI_END_PACKED_STRUCT
 
@@ -1067,6 +1070,8 @@ public:
 
 	/// Combine shader reflection.
 	static Error linkShaderReflection(const ShaderReflection& a, const ShaderReflection& b, ShaderReflection& c);
+
+	StringList toString() const;
 };
 
 /// Clear values for textures or attachments.

+ 2 - 1
AnKi/Gr/Vulkan/VkCommon.h

@@ -67,7 +67,8 @@ enum class VulkanExtensions : U32
 	kNVX_image_view_handle = 1u << 14u,
 	kKHR_push_descriptor = 1u << 15u,
 	kEXT_mesh_shader = 1u << 16u,
-	kKHR_fragment_shader_barycentric = 1u << 17u
+	kKHR_fragment_shader_barycentric = 1u << 17u,
+	kKHR_ray_tracing_position_fetch = 1u << 18u,
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(VulkanExtensions)
 

+ 21 - 0
AnKi/Gr/Vulkan/VkGrManager.cpp

@@ -985,6 +985,11 @@ Error GrManagerImpl::initDevice()
 				m_extensions |= VulkanExtensions::kKHR_fragment_shader_barycentric;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
+			else if(extensionName == VK_KHR_RAY_TRACING_POSITION_FETCH_EXTENSION_NAME && g_rayTracingCVar)
+			{
+				m_extensions |= VulkanExtensions::kKHR_ray_tracing_position_fetch;
+				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
+			}
 		}
 
 		ANKI_VK_LOGI("Will enable the following device extensions:");
@@ -1079,17 +1084,26 @@ Error GrManagerImpl::initDevice()
 	VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeatures = {};
 	VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures = {};
 	VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationStructureFeatures = {};
+	VkPhysicalDeviceRayTracingPositionFetchFeaturesKHR positionFetchFeatures = {};
 	if(!!(m_extensions & VulkanExtensions::kKHR_ray_tracing))
 	{
+		if(!(m_extensions & VulkanExtensions::kKHR_ray_tracing_position_fetch))
+		{
+			ANKI_VK_LOGE(VK_KHR_RAY_TRACING_POSITION_FETCH_EXTENSION_NAME " is required");
+			return Error::kFunctionFailed;
+		}
+
 		rtPipelineFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR;
 		rayQueryFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR;
 		accelerationStructureFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR;
+		positionFetchFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR;
 
 		VkPhysicalDeviceFeatures2 features = {};
 		features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
 		features.pNext = &rtPipelineFeatures;
 		rtPipelineFeatures.pNext = &rayQueryFeatures;
 		rayQueryFeatures.pNext = &accelerationStructureFeatures;
+		accelerationStructureFeatures.pNext = &positionFetchFeatures;
 		vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
 
 		if(!rtPipelineFeatures.rayTracingPipeline || !rayQueryFeatures.rayQuery || !accelerationStructureFeatures.accelerationStructure)
@@ -1098,6 +1112,12 @@ Error GrManagerImpl::initDevice()
 			return Error::kFunctionFailed;
 		}
 
+		if(!positionFetchFeatures.rayTracingPositionFetch)
+		{
+			ANKI_VK_LOGE(VK_KHR_RAY_TRACING_POSITION_FETCH_EXTENSION_NAME " should be really really supported");
+			return Error::kFunctionFailed;
+		}
+
 		// Only enable what's necessary
 		rtPipelineFeatures.rayTracingPipelineShaderGroupHandleCaptureReplay = false;
 		rtPipelineFeatures.rayTracingPipelineShaderGroupHandleCaptureReplayMixed = false;
@@ -1109,6 +1129,7 @@ Error GrManagerImpl::initDevice()
 		appendPNextList(ci, &accelerationStructureFeatures);
 		appendPNextList(ci, &rayQueryFeatures);
 		appendPNextList(ci, &rtPipelineFeatures);
+		appendPNextList(ci, &positionFetchFeatures);
 
 		// Get some more stuff
 		VkPhysicalDeviceAccelerationStructurePropertiesKHR props = {};

+ 10 - 3
AnKi/Renderer/RtMaterialFetchDbg.cpp

@@ -151,13 +151,20 @@ void RtMaterialFetchDbg::populateRenderGraph(RenderingContext& ctx)
 			cmdb.bindSrv(6, 2, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(PixelFailedSsr)));
 			cmdb.bindSrv(7, 2, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
 
-			rgraphCtx.bindUav(0, 2, m_runCtx.m_rt);
-			cmdb.bindUav(1, 2, TextureView(getDummyGpuResources().m_texture2DUav.get(), TextureSubresourceDesc::firstSurface()));
-			cmdb.bindUav(2, 2, TextureView(getDummyGpuResources().m_texture2DUav.get(), TextureSubresourceDesc::firstSurface()));
+			for(U32 i = 0; i < 6; ++i)
+			{
+				cmdb.bindUav(i, 2, TextureView(getDummyGpuResources().m_texture3DUav.get(), TextureSubresourceDesc::firstSurface()));
+			}
+
+			rgraphCtx.bindUav(7, 2, m_runCtx.m_rt);
+			cmdb.bindUav(8, 2, TextureView(getDummyGpuResources().m_texture2DUav.get(), TextureSubresourceDesc::firstSurface()));
 
 			cmdb.bindSampler(0, 2, getRenderer().getSamplers().m_trilinearClamp.get());
 			cmdb.bindSampler(1, 2, getRenderer().getSamplers().m_trilinearClampShadow.get());
 
+			Vec4 dummy;
+			cmdb.setFastConstants(&dummy, sizeof(dummy));
+
 			cmdb.traceRays(sbtBuffer, m_sbtRecordSize, GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount(), 1,
 						   getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y(), 1);
 		});

+ 9 - 0
AnKi/ShaderCompiler/ShaderDump.cpp

@@ -23,8 +23,15 @@ void dumpShaderBinary(const ShaderDumpOptions& options, const ShaderBinary& bina
 	{
 		lines.pushBackSprintf(ANKI_TAB "bin%05u \n", count++);
 
+		String reflectionStr;
+		code.m_reflection.toString().join("\n" ANKI_TAB ANKI_TAB, reflectionStr);
+
+		lines.pushBackSprintf(ANKI_TAB ANKI_TAB "%s\n", reflectionStr.cstr());
+
 		if(options.m_writeGlsl)
 		{
+			lines.pushBack(ANKI_TAB ANKI_TAB "----\n");
+
 			spirv_cross::CompilerGLSL::Options options;
 			options.vulkan_semantics = true;
 			options.version = 460;
@@ -47,6 +54,8 @@ void dumpShaderBinary(const ShaderDumpOptions& options, const ShaderBinary& bina
 
 		if(options.m_writeSpirv)
 		{
+			lines.pushBack(ANKI_TAB ANKI_TAB "----\n");
+
 			spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_5);
 
 			const U32 disOptions = SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_NO_HEADER;

+ 22 - 2
AnKi/Shaders/Common.hlsl

@@ -160,13 +160,33 @@ U32 checkStructuredBuffer(T buff, U32 idx)
 
 // Need extra decoration for per-primitive stuff in Vulkan. Remove when https://github.com/microsoft/DirectXShaderCompiler/issues/6862 is fixed
 #if ANKI_GR_BACKEND_VULKAN
-#	define ANKI_PER_PRIMITIVE_VAR [[vk::ext_extension("SPV_EXT_mesh_shader")]] [[vk::ext_capability(5283 /*MeshShadingEXT*/)]]
-#	define ANKI_PER_PRIMITIVE_MEMBER [[vk::ext_decorate(5271 /*PerPrimitiveEXT*/)]]
+#	define SpvCapabilityMeshShadingEXT 5283
+#	define SpvDecorationPerPrimitiveEXT 5271
+
+#	define ANKI_PER_PRIMITIVE_VAR [[vk::ext_extension("SPV_EXT_mesh_shader")]] [[vk::ext_capability(SpvCapabilityMeshShadingEXT)]]
+#	define ANKI_PER_PRIMITIVE_MEMBER \
+		[[vk::ext_extension("SPV_EXT_mesh_shader")]] [[vk::ext_decorate(SpvDecorationPerPrimitiveEXT)]] [[vk::ext_capability( \
+			SpvCapabilityMeshShadingEXT)]]
 #else
 #	define ANKI_PER_PRIMITIVE_VAR
 #	define ANKI_PER_PRIMITIVE_MEMBER
 #endif
 
+#if ANKI_GR_BACKEND_VULKAN && ANKI_CLOSEST_HIT_SHADER
+#	define SpvBuiltInHitTriangleVertexPositionsKHR 5335
+#	define SpvCapabilityRayTracingPositionFetchKHR 5336
+
+[[vk::ext_extension("SPV_KHR_ray_tracing_position_fetch")]] [[vk::ext_capability(SpvCapabilityRayTracingPositionFetchKHR)]] [[vk::ext_builtin_input(
+	SpvBuiltInHitTriangleVertexPositionsKHR)]] const static Vec3 gl_HitTriangleVertexPositions[3];
+#endif
+
+#if ANKI_GR_BACKEND_VULKAN
+#	define SpvDecorationRelaxedPrecision 0
+#	define ANKI_RELAXED_PRECISION [[vk::ext_decorate(SpvDecorationRelaxedPrecision)]]
+#else
+#	define ANKI_RELAXED_PRECISION
+#endif
+
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
 
 template<typename T>

+ 15 - 6
AnKi/Shaders/GBufferGeneric.ankiprog

@@ -139,7 +139,7 @@ struct VertOut
 #endif
 
 #if GBUFFER
-	HVec3 m_normal : NORMAL;
+	ANKI_RELAXED_PRECISION Vec3 m_normal : NORMAL;
 #endif
 
 #if VISUALIZE_MESHLETS
@@ -167,7 +167,7 @@ struct MeshPerVertOut
 #endif
 
 #if GBUFFER
-	HVec3 m_normal : NORMAL;
+	ANKI_RELAXED_PRECISION Vec3 m_normal : NORMAL;
 #endif
 };
 
@@ -612,9 +612,7 @@ GBufferPixelOut main(
 	}
 #		endif
 
-	GBufferPixelOut output;
-	packGBuffer(g, output.m_color0, output.m_color1, output.m_color2, output.m_color3);
-	return output;
+	return packGBuffer(g);
 }
 #	endif
 #endif // ANKI_PIXEL_SHADER
@@ -687,6 +685,8 @@ GBufferPixelOut main(
 // ===========================================================================
 #if ANKI_TECHNIQUE_RtMaterialFetch
 
+#	define USE_POSITION_FETCH_NORMALS ANKI_GR_BACKEND_VULKAN && ANKI_PLATFORM_MOBILE
+
 #	if ANKI_CLOSEST_HIT_SHADER
 [[vk::shader_record_ext]] ConstantBuffer<GpuSceneRenderableInstance> g_gpuSceneRenderable : register(b0); // TODO that won't work on D3D
 
@@ -737,9 +737,18 @@ GBufferPixelOut main(
 	payload.m_emission = emission;
 
 	// Normal
-	const Mat3x4 worldTransform = g_transforms[g_gpuSceneRenderable.m_worldTransformsIndex];
+#		if USE_POSITION_FETCH_NORMALS
+	const Vec3 pos0 = gl_HitTriangleVertexPositions[0];
+	const Vec3 pos1 = gl_HitTriangleVertexPositions[1];
+	const Vec3 pos2 = gl_HitTriangleVertexPositions[2];
 
+	Vec3 normal = cross(pos1 - pos0, pos2 - pos1);
+#		else
 	Vec3 normal = vert0.m_normal * bary.x + vert1.m_normal * bary.y + vert2.m_normal * bary.z;
+#		endif
+
+	const Mat3x4 worldTransform = g_transforms[g_gpuSceneRenderable.m_worldTransformsIndex];
+
 	normal = mul(worldTransform, Vec4(normal, 0.0));
 	normal = normalize(normal);
 

+ 2 - 2
AnKi/Shaders/GBufferGpuParticles.ankiprog

@@ -93,7 +93,7 @@ GBufferPixelOut main(VertOut input)
 	g.m_emission = lerp(localConstants.m_initialEmission, localConstants.m_finalEmission, input.m_lifeFactor);
 	g.m_metallic = localConstants.m_metallic;
 	g.m_velocity = input.m_velocity;
-	packGBuffer(g, output.m_color0, output.m_color1, output.m_color2, output.m_color3);
-	return output;
+
+	return packGBuffer(g);
 }
 #endif // ANKI_PIXEL_SHADER

+ 4 - 6
AnKi/Shaders/GBufferPost.ankiprog

@@ -114,12 +114,10 @@ SamplerState g_linearClampAnySampler : register(s0);
 		gbuffer.m_roughness = roughness;
 		gbuffer.m_metallic = metalness;
 
-		HVec4 rt0, rt1, rt2;
-		Vec2 rt3;
-		packGBuffer(gbuffer, rt0, rt1, rt2, rt3);
+		const GBufferPixelOut gbufferOut = packGBuffer(gbuffer);
 
-		g_gbuffer0Tex[svDispatchThreadId] = rt0;
-		g_gbuffer1Tex[svDispatchThreadId] = rt1;
-		g_gbuffer2Tex[svDispatchThreadId] = rt2;
+		g_gbuffer0Tex[svDispatchThreadId] = gbufferOut.m_rt0;
+		g_gbuffer1Tex[svDispatchThreadId] = gbufferOut.m_rt1;
+		g_gbuffer2Tex[svDispatchThreadId] = gbufferOut.m_rt2;
 	}
 }

+ 5 - 1
AnKi/Shaders/GBufferVisualizeProbe.ankiprog

@@ -178,7 +178,11 @@ PixelOut main(VertOut input)
 	g.m_metallic = (PROBE_TYPE == 0) ? 0.0 : 1.0;
 	g.m_velocity = 1.0;
 
-	packGBuffer(g, output.m_color0, output.m_color1, output.m_color2, output.m_color3);
+	const GBufferPixelOut gbufferOut = packGBuffer(g);
+	output.m_color0 = gbufferOut.m_rt0;
+	output.m_color1 = gbufferOut.m_rt1;
+	output.m_color2 = gbufferOut.m_rt2;
+	output.m_color3 = gbufferOut.m_rt3;
 
 	return output;
 }

+ 0 - 8
AnKi/Shaders/MaterialShadersCommon.hlsl

@@ -61,14 +61,6 @@ Texture2D<Vec4> g_shadowAtlasTex : register(ANKI_REG(t, ANKI_MATERIAL_REGISTER_S
 
 #undef ANKI_REG
 
-struct GBufferPixelOut
-{
-	HVec4 m_color0 : SV_TARGET0;
-	HVec4 m_color1 : SV_TARGET1;
-	HVec4 m_color2 : SV_TARGET2;
-	Vec2 m_color3 : SV_TARGET3;
-};
-
 UnpackedMeshVertex loadVertex(GpuSceneMeshLod mlod, U32 svVertexId, Bool bones)
 {
 	UnpackedMeshVertex v;

+ 17 - 5
AnKi/Shaders/PackFunctions.hlsl

@@ -164,21 +164,33 @@ struct GbufferInfo
 	Vec2 m_velocity;
 };
 
+struct GBufferPixelOut
+{
+	ANKI_RELAXED_PRECISION Vec4 m_rt0 : SV_Target0;
+	ANKI_RELAXED_PRECISION Vec4 m_rt1 : SV_Target1;
+	ANKI_RELAXED_PRECISION Vec4 m_rt2 : SV_Target2;
+	Vec2 m_rt3 : SV_Target3;
+};
+
 // Populate the G buffer
 template<typename T>
-void packGBuffer(GbufferInfo<T> g, out vector<T, 4> rt0, out vector<T, 4> rt1, out vector<T, 4> rt2, out Vec2 rt3)
+GBufferPixelOut packGBuffer(GbufferInfo<T> g)
 {
+	GBufferPixelOut output;
+
 	const T packedSubsurfaceMetallic = packUnorm2ToUnorm1(vector<T, 2>(g.m_subsurface, g.m_metallic));
 
 	const vector<T, 3> tonemappedEmission = reinhardTonemap(g.m_emission);
 
-	rt0 = vector<T, 4>(g.m_diffuse, packedSubsurfaceMetallic);
-	rt1 = vector<T, 4>(g.m_roughness, g.m_f0.x, tonemappedEmission.rb);
+	output.m_rt0 = vector<T, 4>(g.m_diffuse, packedSubsurfaceMetallic);
+	output.m_rt1 = vector<T, 4>(g.m_roughness, g.m_f0.x, tonemappedEmission.rb);
 
 	const vector<T, 3> encNorm = signedOctEncode(g.m_normal);
-	rt2 = vector<T, 4>(tonemappedEmission.g, encNorm);
+	output.m_rt2 = vector<T, 4>(tonemappedEmission.g, encNorm);
+
+	output.m_rt3 = g.m_velocity;
 
-	rt3 = g.m_velocity;
+	return output;
 }
 
 template<typename T>

+ 1 - 1
AnKi/Shaders/RtMaterialFetchDbg.ankiprog

@@ -38,6 +38,6 @@
 	ray.TMax = 100.0; // TODO
 	TraceRay(g_tlas, flags, cullMask, sbtRecordOffset, sbtRecordStride, missIndex, ray, payload);
 
-	const Vec3 col = payload.m_diffuseColor * 1.0 + (payload.m_worldNormal.xyz / 2.0 + 0.5) * 0.0 + payload.m_rayT * 0.0 + payload.m_emission * 0.0;
+	const Vec3 col = payload.m_diffuseColor * 0.0 + (payload.m_worldNormal.xyz / 2.0 + 0.5) * 1.0 + payload.m_rayT * 0.0 + payload.m_emission * 0.0;
 	g_colorAndPdfTex[DispatchRaysIndex().xy] = Vec4(col, 0.0);
 }

BIN
ThirdParty/Dxc/dxc


BIN
ThirdParty/Dxc/dxc.exe


+ 1 - 1
ThirdParty/Dxc/dxcapi.h

@@ -777,7 +777,7 @@ struct IDxcResult : public IDxcOperationResult {
   virtual HRESULT STDMETHODCALLTYPE
   GetOutput(_In_ DXC_OUT_KIND dxcOutKind, _In_ REFIID iid,
             _COM_Outptr_opt_result_maybenull_ void **ppvObject,
-            _COM_Outptr_ IDxcBlobWide **ppOutputName) = 0;
+            _COM_Outptr_opt_result_maybenull_ IDxcBlobWide **ppOutputName) = 0;
 
   /// \brief Retrieves the number of outputs available in this result.
   virtual UINT32 GetNumOutputs() = 0;

BIN
ThirdParty/Dxc/dxcompiler.dll


BIN
ThirdParty/Dxc/dxil.dll


BIN
ThirdParty/Dxc/dxv


BIN
ThirdParty/Dxc/dxv.exe


BIN
ThirdParty/Dxc/libdxcompiler.so


BIN
ThirdParty/Dxc/libdxil.so


+ 15 - 8
ThirdParty/SpirvTools/Android.mk

@@ -27,6 +27,7 @@ SPVTOOLS_SRC_FILES := \
 		source/table.cpp \
 		source/text.cpp \
 		source/text_handler.cpp \
+		source/to_string.cpp \
 		source/util/bit_vector.cpp \
 		source/util/parse_number.cpp \
 		source/util/string_utils.cpp \
@@ -74,6 +75,7 @@ SPVTOOLS_SRC_FILES := \
 		source/val/validate_ray_tracing_reorder.cpp \
 		source/val/validate_scopes.cpp \
 		source/val/validate_small_type_uses.cpp \
+		source/val/validate_tensor_layout.cpp \
 		source/val/validate_type.cpp
 
 SPVTOOLS_OPT_SRC_FILES := \
@@ -128,14 +130,11 @@ SPVTOOLS_OPT_SRC_FILES := \
 		source/opt/inline_pass.cpp \
 		source/opt/inline_exhaustive_pass.cpp \
 		source/opt/inline_opaque_pass.cpp \
-		source/opt/inst_bindless_check_pass.cpp \
-		source/opt/inst_buff_addr_check_pass.cpp \
-		source/opt/inst_debug_printf_pass.cpp \
 		source/opt/instruction.cpp \
 		source/opt/instruction_list.cpp \
-		source/opt/instrument_pass.cpp \
 		source/opt/interface_var_sroa.cpp \
 		source/opt/interp_fixup_pass.cpp \
+		source/opt/invocation_interlock_placement_pass.cpp \
 		source/opt/ir_context.cpp \
 		source/opt/ir_loader.cpp \
 		source/opt/licm_pass.cpp \
@@ -156,7 +155,9 @@ SPVTOOLS_OPT_SRC_FILES := \
 		source/opt/loop_utils.cpp \
 		source/opt/mem_pass.cpp \
 		source/opt/merge_return_pass.cpp \
+		source/opt/modify_maximal_reconvergence.cpp \
 		source/opt/module.cpp \
+		source/opt/opextinst_forward_ref_fixup_pass.cpp \
 		source/opt/optimizer.cpp \
 		source/opt/pass.cpp \
 		source/opt/pass_manager.cpp \
@@ -171,17 +172,22 @@ SPVTOOLS_OPT_SRC_FILES := \
 		source/opt/remove_unused_interface_variables_pass.cpp \
 		source/opt/replace_desc_array_access_using_var_index.cpp \
 		source/opt/replace_invalid_opc.cpp \
+		source/opt/resolve_binding_conflicts_pass.cpp \
 		source/opt/scalar_analysis.cpp \
 		source/opt/scalar_analysis_simplification.cpp \
 		source/opt/scalar_replacement_pass.cpp \
 		source/opt/set_spec_constant_default_value_pass.cpp \
 		source/opt/simplification_pass.cpp \
+		source/opt/split_combined_image_sampler_pass.cpp \
 		source/opt/spread_volatile_semantics.cpp \
 		source/opt/ssa_rewrite_pass.cpp \
 		source/opt/strength_reduction_pass.cpp \
 		source/opt/strip_debug_info_pass.cpp \
 		source/opt/strip_nonsemantic_info_pass.cpp \
 		source/opt/struct_cfg_analysis.cpp \
+		source/opt/struct_packing_pass.cpp \
+		source/opt/switch_descriptorset_pass.cpp \
+		source/opt/trim_capabilities_pass.cpp \
 		source/opt/type_manager.cpp \
 		source/opt/types.cpp \
 		source/opt/unify_const_pass.cpp \
@@ -285,6 +291,7 @@ $(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),spv-amd-shader-bal
 $(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),spv-amd-shader-explicit-vertex-parameter,""))
 $(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),spv-amd-shader-trinary-minmax,""))
 $(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),nonsemantic.clspvreflection,""))
+$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),nonsemantic.vkspreflection,""))
 
 define gen_spvtools_enum_string_mapping
 $(call generate-file-dir,$(1)/extension_enum.inc.inc)
@@ -311,9 +318,9 @@ define gen_spvtools_build_version_inc
 $(call generate-file-dir,$(1)/dummy_filename)
 $(1)/build-version.inc: \
         $(LOCAL_PATH)/utils/update_build_version.py \
-        $(LOCAL_PATH)
+        $(LOCAL_PATH)/CHANGES
 		@$(HOST_PYTHON) $(LOCAL_PATH)/utils/update_build_version.py \
-		                $(LOCAL_PATH) $(1)/build-version.inc
+		                $(LOCAL_PATH)/CHANGES $(1)/build-version.inc
 		@echo "[$(TARGET_ARCH_ABI)] Generate       : build-version.inc <= CHANGES"
 $(LOCAL_PATH)/source/software_version.cpp: $(1)/build-version.inc
 endef
@@ -340,7 +347,7 @@ LOCAL_C_INCLUDES := \
 		$(SPVTOOLS_OUT_PATH)
 LOCAL_EXPORT_C_INCLUDES := \
 		$(LOCAL_PATH)/include
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -Werror
+LOCAL_CXXFLAGS:=-std=c++17 -fno-exceptions -fno-rtti -Werror
 LOCAL_SRC_FILES:= $(SPVTOOLS_SRC_FILES)
 include $(BUILD_STATIC_LIBRARY)
 
@@ -351,7 +358,7 @@ LOCAL_C_INCLUDES := \
 		$(LOCAL_PATH)/source \
 		$(SPVHEADERS_LOCAL_PATH)/include \
 		$(SPVTOOLS_OUT_PATH)
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -Werror
+LOCAL_CXXFLAGS:=-std=c++17 -fno-exceptions -fno-rtti -Werror
 LOCAL_STATIC_LIBRARIES:=SPIRV-Tools
 LOCAL_SRC_FILES:= $(SPVTOOLS_OPT_SRC_FILES)
 include $(BUILD_STATIC_LIBRARY)

+ 72 - 58
ThirdParty/SpirvTools/BUILD.bazel

@@ -58,6 +58,8 @@ generate_vendor_tables(extension = "debuginfo")
 
 generate_vendor_tables(extension = "nonsemantic.clspvreflection")
 
+generate_vendor_tables(extension = "nonsemantic.vkspreflection")
+
 generate_vendor_tables(
     extension = "opencl.debuginfo.100",
     operand_kind_prefix = "CLDEBUG100_",
@@ -94,7 +96,7 @@ genrule(
     outs = ["generators.inc"],
     cmd = "$(location :generate_registry_tables) --xml=$(location @spirv_headers//:spirv_xml_registry) --generator-output=$(location generators.inc)",
     cmd_bat = "$(location :generate_registry_tables) --xml=$(location @spirv_headers//:spirv_xml_registry) --generator-output=$(location generators.inc)",
-    exec_tools = [":generate_registry_tables"],
+    tools = [":generate_registry_tables"],
 )
 
 py_binary(
@@ -104,13 +106,11 @@ py_binary(
 
 genrule(
     name = "build_version_inc",
+    srcs = ["CHANGES"],
     outs = ["build-version.inc"],
-    cmd = "SOURCE_DATE_EPOCH=0 $(location :update_build_version) $(RULEDIR) $(location build-version.inc)",
-    cmd_bat = "set SOURCE_DATE_EPOCH=0  && $(location :update_build_version) $(RULEDIR) $(location build-version.inc)",
-    # This is explicitly tools and not exec_tools because we run it locally (on the host platform) instead of
-    # (potentially remotely) on the execution platform.
+    cmd = "SOURCE_DATE_EPOCH=0 $(location :update_build_version) $(location CHANGES) $(location build-version.inc)",
+    cmd_bat = "set SOURCE_DATE_EPOCH=0  && $(location :update_build_version) $(location CHANGES) $(location build-version.inc)",
     tools = [":update_build_version"],
-    local = True,
 )
 
 # Libraries
@@ -145,15 +145,16 @@ cc_library(
         ":gen_extinst_lang_headers_OpenCLDebugInfo100",
         ":gen_glsl_tables_unified1",
         ":gen_opencl_tables_unified1",
-        ":generators_inc",
         ":gen_vendor_tables_debuginfo",
         ":gen_vendor_tables_nonsemantic_clspvreflection",
+        ":gen_vendor_tables_nonsemantic_vkspreflection",
         ":gen_vendor_tables_nonsemantic_shader_debuginfo_100",
         ":gen_vendor_tables_opencl_debuginfo_100",
         ":gen_vendor_tables_spv_amd_gcn_shader",
         ":gen_vendor_tables_spv_amd_shader_ballot",
         ":gen_vendor_tables_spv_amd_shader_explicit_vertex_parameter",
         ":gen_vendor_tables_spv_amd_shader_trinary_minmax",
+        ":generators_inc",
     ],
     hdrs = [
         "include/spirv-tools/libspirv.h",
@@ -177,7 +178,6 @@ cc_library(
 cc_library(
     name = "spirv_tools_opt",
     hdrs = [
-        "include/spirv-tools/instrument.hpp",
         "include/spirv-tools/optimizer.hpp",
     ],
     copts = COMMON_COPTS,
@@ -195,13 +195,13 @@ cc_library(
         ":gen_vendor_tables_spv_amd_shader_ballot",
     ],
     hdrs = glob(["source/opt/*.h"]) + [
-        "include/spirv-tools/instrument.hpp",
         "include/spirv-tools/optimizer.hpp",
     ],
     copts = COMMON_COPTS,
     deps = [
         ":spirv_tools_internal",
         "@spirv_headers//:spirv_common_headers",
+        "@spirv_headers//:spirv_c_headers",
     ],
 )
 
@@ -270,6 +270,7 @@ cc_library(
 cc_library(
     name = "tools_io",
     hdrs = ["tools/io.h"],
+    srcs = ["tools/io.cpp"],
     copts = COMMON_COPTS,
 )
 
@@ -285,6 +286,7 @@ cc_binary(
     deps = [
         ":spirv_tools_internal",
         ":tools_io",
+        ":tools_util",
     ],
 )
 
@@ -298,6 +300,25 @@ cc_binary(
     deps = [
         ":spirv_tools",
         ":tools_io",
+        ":tools_util",
+    ],
+)
+
+cc_binary(
+    name = "spirv-objdump",
+    srcs = [
+        "tools/objdump/extract_source.cpp",
+        "tools/objdump/extract_source.h",
+        "tools/objdump/objdump.cpp",
+    ],
+    copts = COMMON_COPTS,
+    visibility = ["//visibility:public"],
+    deps = [
+        ":spirv_tools_internal",
+        ":spirv_tools_opt_internal",
+        ":tools_io",
+        ":tools_util",
+        "@spirv_headers//:spirv_cpp_headers",
     ],
 )
 
@@ -357,6 +378,7 @@ cc_binary(
         ":spirv_tools_internal",
         ":spirv_tools_link",
         ":tools_io",
+        ":tools_util",
     ],
 )
 
@@ -387,6 +409,7 @@ cc_binary(
     deps = [
         ":spirv_tools_internal",
         ":tools_io",
+        ":tools_util",
     ],
 )
 
@@ -405,7 +428,7 @@ cc_library(
     copts = TEST_COPTS,
     deps = [
         ":spirv_tools_internal",
-        "@com_google_googletest//:gtest",
+        "@googletest//:gtest",
     ],
 )
 
@@ -416,22 +439,26 @@ cc_library(
     name = "base_{testcase}_test".format(testcase = f[len("test/"):-len("_test.cpp")]),
     size = "small",
     srcs = [f],
-    copts = TEST_COPTS,
+    copts = TEST_COPTS + ["-DTESTING"],
     linkstatic = 1,
     target_compatible_with = {
         "test/timer_test.cpp": incompatible_with(["@bazel_tools//src/conditions:windows"]),
     }.get(f, []),
     deps = [
+        "tools_util",
         ":spirv_tools_internal",
         ":test_lib",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
+        ":tools_io",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
     ],
 ) for f in glob(
-    ["test/*_test.cpp"],
+    [
+        "test/*_test.cpp",
+        "test/tools/*_test.cpp",
+    ],
     exclude = [
         "test/cpp_interface_test.cpp",
-        "test/log_test.cpp",
         "test/pch_test.cpp",
     ],
 )]
@@ -443,8 +470,8 @@ cc_test(
     linkstatic = 1,
     deps = [
         ":spirv_tools_opt_internal",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
         "@spirv_headers//:spirv_cpp11_headers",
     ],
 )
@@ -457,21 +484,8 @@ cc_test(
     linkstatic = 1,
     deps = [
         ":spirv_tools_internal",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
-    ],
-)
-
-cc_test(
-    name = "base_log_test",
-    size = "small",
-    srcs = ["test/log_test.cpp"],
-    copts = TEST_COPTS,
-    linkstatic = 1,
-    deps = [
-        ":spirv_tools_opt_internal",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
     ],
 )
 
@@ -484,8 +498,8 @@ cc_library(
         ":spirv_tools_internal",
         ":spirv_tools_link",
         ":test_lib",
-        "@com_google_effcee//:effcee",
-        "@com_googlesource_code_re2//:re2",
+        "@effcee//:effcee",
+        "@re2//:re2",
     ],
 )
 
@@ -497,8 +511,8 @@ cc_library(
     linkstatic = 1,
     deps = [
         ":link_test_lib",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
     ],
 ) for f in glob(
     ["test/link/*_test.cpp"],
@@ -514,8 +528,8 @@ cc_library(
         ":spirv_tools",
         ":spirv_tools_lint_internal",
         ":spirv_tools_opt_internal",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
     ],
 ) for f in glob(
     ["test/lint/*_test.cpp"],
@@ -538,8 +552,8 @@ cc_library(
     deps = [
         ":spirv_tools_internal",
         ":spirv_tools_opt_internal",
-        "@com_google_effcee//:effcee",
-        "@com_google_googletest//:gtest",
+        "@effcee//:effcee",
+        "@googletest//:gtest",
     ],
 )
 
@@ -554,9 +568,9 @@ cc_library(
         ":spirv_tools_internal",
         ":spirv_tools_opt_internal",
         ":test_lib",
-        "@com_google_effcee//:effcee",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
+        "@effcee//:effcee",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
     ],
 ) for f in glob(["test/opt/*_test.cpp"])]
 
@@ -569,8 +583,8 @@ cc_library(
     deps = [
         ":opt_test_lib",
         ":spirv_tools_opt_internal",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
     ],
 ) for f in glob(
     ["test/opt/dominator_tree/*.cpp"],
@@ -587,9 +601,9 @@ cc_library(
         ":opt_test_lib",
         ":spirv_tools",
         ":spirv_tools_opt_internal",
-        "@com_google_effcee//:effcee",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
+        "@effcee//:effcee",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
     ],
 ) for f in glob(
     ["test/opt/loop_optimizations/*.cpp"],
@@ -610,7 +624,7 @@ cc_library(
         ":spirv_tools_reduce",
         ":test_lib",
         ":tools_io",
-        "@com_google_googletest//:gtest",
+        "@googletest//:gtest",
     ],
 )
 
@@ -625,7 +639,7 @@ cc_library(
         ":spirv_tools_internal",
         ":spirv_tools_opt_internal",
         ":spirv_tools_reduce",
-        "@com_google_googletest//:gtest_main",
+        "@googletest//:gtest_main",
     ],
 ) for f in glob(["test/reduce/*_test.cpp"])]
 
@@ -637,8 +651,8 @@ cc_library(
     linkstatic = 1,
     deps = [
         ":spirv_tools_internal",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
     ],
 ) for f in glob(["test/util/*_test.cpp"])]
 
@@ -669,8 +683,8 @@ cc_library(
         ":spirv_tools_internal",
         ":test_lib",
         ":val_test_lib",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
     ],
 ) for f in glob(
     ["test/val/val_*_test.cpp"],
@@ -691,8 +705,8 @@ cc_test(
         ":spirv_tools_internal",
         ":test_lib",
         ":val_test_lib",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
     ],
 )
 
@@ -708,7 +722,7 @@ cc_test(
     deps = [
         ":test_lib",
         ":val_test_lib",
-        "@com_google_googletest//:gtest",
-        "@com_google_googletest//:gtest_main",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
     ],
 )

+ 67 - 21
ThirdParty/SpirvTools/BUILD.gn

@@ -262,12 +262,12 @@ action("spvtools_generators_inc") {
 action("spvtools_build_version") {
   script = "utils/update_build_version.py"
 
-  repo_path = "."
+  changes_file = "CHANGES"
   inc_file = "${target_gen_dir}/build-version.inc"
 
   outputs = [ inc_file ]
   args = [
-    rebase_path(repo_path, root_build_dir),
+    rebase_path(changes_file, root_build_dir),
     rebase_path(inc_file, root_build_dir),
   ]
 }
@@ -327,6 +327,10 @@ spvtools_vendor_tables = [
     "nonsemantic.clspvreflection",
     "...nil...",
   ],
+  [
+    "nonsemantic.vkspreflection",
+    "...nil...",
+  ],
   [
     "nonsemantic.shader.debuginfo.100",
     "SHDEBUG100_",
@@ -374,11 +378,16 @@ config("spvtools_internal_config") {
     # Make MSVC report the correct value for __cplusplus
     cflags += [ "/Zc:__cplusplus" ]
   }
+
+  if (!is_win) {
+    cflags += [ "-std=c++17" ]
+  } else {
+    cflags += [ "/std:c++17" ]
+  }
 }
 
 source_set("spvtools_headers") {
   sources = [
-    "include/spirv-tools/instrument.hpp",
     "include/spirv-tools/libspirv.h",
     "include/spirv-tools/libspirv.hpp",
     "include/spirv-tools/linker.hpp",
@@ -465,6 +474,8 @@ static_library("spvtools") {
     "source/text.h",
     "source/text_handler.cpp",
     "source/text_handler.h",
+    "source/to_string.cpp",
+    "source/to_string.h",
     "source/util/bit_vector.cpp",
     "source/util/bit_vector.h",
     "source/util/bitutils.h",
@@ -546,6 +557,7 @@ static_library("spvtools_val") {
     "source/val/validate_scopes.cpp",
     "source/val/validate_scopes.h",
     "source/val/validate_small_type_uses.cpp",
+    "source/val/validate_tensor_layout.cpp",
     "source/val/validate_type.cpp",
     "source/val/validation_state.cpp",
     "source/val/validation_state.h",
@@ -671,22 +683,16 @@ static_library("spvtools_opt") {
     "source/opt/inline_opaque_pass.h",
     "source/opt/inline_pass.cpp",
     "source/opt/inline_pass.h",
-    "source/opt/inst_bindless_check_pass.cpp",
-    "source/opt/inst_bindless_check_pass.h",
-    "source/opt/inst_buff_addr_check_pass.cpp",
-    "source/opt/inst_buff_addr_check_pass.h",
-    "source/opt/inst_debug_printf_pass.cpp",
-    "source/opt/inst_debug_printf_pass.h",
     "source/opt/instruction.cpp",
     "source/opt/instruction.h",
     "source/opt/instruction_list.cpp",
     "source/opt/instruction_list.h",
-    "source/opt/instrument_pass.cpp",
-    "source/opt/instrument_pass.h",
     "source/opt/interface_var_sroa.cpp",
     "source/opt/interface_var_sroa.h",
     "source/opt/interp_fixup_pass.cpp",
     "source/opt/interp_fixup_pass.h",
+    "source/opt/invocation_interlock_placement_pass.cpp",
+    "source/opt/invocation_interlock_placement_pass.h",
     "source/opt/ir_builder.h",
     "source/opt/ir_context.cpp",
     "source/opt/ir_context.h",
@@ -729,9 +735,13 @@ static_library("spvtools_opt") {
     "source/opt/mem_pass.h",
     "source/opt/merge_return_pass.cpp",
     "source/opt/merge_return_pass.h",
+    "source/opt/modify_maximal_reconvergence.cpp",
+    "source/opt/modify_maximal_reconvergence.h",
     "source/opt/module.cpp",
     "source/opt/module.h",
     "source/opt/null_pass.h",
+    "source/opt/opextinst_forward_ref_fixup_pass.cpp",
+    "source/opt/opextinst_forward_ref_fixup_pass.h",
     "source/opt/optimizer.cpp",
     "source/opt/pass.cpp",
     "source/opt/pass.h",
@@ -761,6 +771,8 @@ static_library("spvtools_opt") {
     "source/opt/replace_desc_array_access_using_var_index.h",
     "source/opt/replace_invalid_opc.cpp",
     "source/opt/replace_invalid_opc.h",
+    "source/opt/resolve_binding_conflicts_pass.cpp",
+    "source/opt/resolve_binding_conflicts_pass.h",
     "source/opt/scalar_analysis.cpp",
     "source/opt/scalar_analysis.h",
     "source/opt/scalar_analysis_nodes.h",
@@ -771,6 +783,8 @@ static_library("spvtools_opt") {
     "source/opt/set_spec_constant_default_value_pass.h",
     "source/opt/simplification_pass.cpp",
     "source/opt/simplification_pass.h",
+    "source/opt/split_combined_image_sampler_pass.cpp",
+    "source/opt/split_combined_image_sampler_pass.h",
     "source/opt/spread_volatile_semantics.cpp",
     "source/opt/spread_volatile_semantics.h",
     "source/opt/ssa_rewrite_pass.cpp",
@@ -781,9 +795,15 @@ static_library("spvtools_opt") {
     "source/opt/strip_debug_info_pass.h",
     "source/opt/strip_nonsemantic_info_pass.cpp",
     "source/opt/strip_nonsemantic_info_pass.h",
+    "source/opt/struct_packing_pass.cpp",
+    "source/opt/struct_packing_pass.h",
     "source/opt/struct_cfg_analysis.cpp",
     "source/opt/struct_cfg_analysis.h",
+    "source/opt/switch_descriptorset_pass.cpp",
+    "source/opt/switch_descriptorset_pass.h",
     "source/opt/tree_iterator.h",
+    "source/opt/trim_capabilities_pass.cpp",
+    "source/opt/trim_capabilities_pass.h",
     "source/opt/type_manager.cpp",
     "source/opt/type_manager.h",
     "source/opt/types.cpp",
@@ -1361,10 +1381,12 @@ if (build_with_chromium && spvtools_build_executables) {
       "test/fix_word_test.cpp",
       "test/generator_magic_number_test.cpp",
       "test/hex_float_test.cpp",
+      "test/hex_to_text_test.cpp",
       "test/immediate_int_test.cpp",
       "test/libspirv_macros_test.cpp",
       "test/name_mapper_test.cpp",
       "test/named_id_test.cpp",
+      "test/op_unknown_test.cpp",
       "test/opcode_make_test.cpp",
       "test/opcode_require_capabilities_test.cpp",
       "test/opcode_split_test.cpp",
@@ -1398,6 +1420,7 @@ if (build_with_chromium && spvtools_build_executables) {
       "test/text_to_binary.type_declaration_test.cpp",
       "test/text_to_binary_test.cpp",
       "test/text_word_get_test.cpp",
+      "test/to_string_test.cpp",
       "test/unit_spirv.cpp",
       "test/unit_spirv.h",
     ]
@@ -1407,6 +1430,7 @@ if (build_with_chromium && spvtools_build_executables) {
       ":spvtools_language_header_cldebuginfo100",
       ":spvtools_language_header_debuginfo",
       ":spvtools_language_header_vkdebuginfo100",
+      ":spvtools_tools_io",
       ":spvtools_val",
       "//testing/gmock",
       "//testing/gtest",
@@ -1430,8 +1454,18 @@ if (spirv_tools_standalone) {
   }
 }
 
-source_set("spvtools_util_cli_consumer") {
+source_set("spvtools_software_version") {
+  sources = [ "source/software_version.cpp" ]
+  deps = [
+    ":spvtools_build_version",
+    ":spvtools_headers",
+  ]
+  configs += [ ":spvtools_internal_config" ]
+}
+
+source_set("spvtools_tools_util") {
   sources = [
+    "tools/util/flags.cpp",
     "tools/util/cli_consumer.cpp",
     "tools/util/cli_consumer.h",
   ]
@@ -1439,12 +1473,12 @@ source_set("spvtools_util_cli_consumer") {
   configs += [ ":spvtools_internal_config" ]
 }
 
-source_set("spvtools_software_version") {
-  sources = [ "source/software_version.cpp" ]
-  deps = [
-    ":spvtools_build_version",
-    ":spvtools_headers",
+source_set("spvtools_tools_io") {
+  sources = [
+    "tools/io.cpp",
+    "tools/io.h",
   ]
+  deps = [ ":spvtools_headers" ]
   configs += [ ":spvtools_internal_config" ]
 }
 
@@ -1454,6 +1488,8 @@ if (spvtools_build_executables) {
     deps = [
       ":spvtools",
       ":spvtools_software_version",
+      ":spvtools_tools_util",
+      ":spvtools_tools_io",
     ]
     configs += [ ":spvtools_internal_config" ]
   }
@@ -1463,6 +1499,8 @@ if (spvtools_build_executables) {
     deps = [
       ":spvtools",
       ":spvtools_software_version",
+      ":spvtools_tools_util",
+      ":spvtools_tools_io",
     ]
     configs += [ ":spvtools_internal_config" ]
   }
@@ -1472,7 +1510,8 @@ if (spvtools_build_executables) {
     deps = [
       ":spvtools",
       ":spvtools_software_version",
-      ":spvtools_util_cli_consumer",
+      ":spvtools_tools_util",
+      ":spvtools_tools_io",
       ":spvtools_val",
     ]
     configs += [ ":spvtools_internal_config" ]
@@ -1487,6 +1526,8 @@ if (spvtools_build_executables) {
     deps = [
       ":spvtools",
       ":spvtools_software_version",
+      ":spvtools_tools_util",
+      ":spvtools_tools_io",
     ]
     configs += [ ":spvtools_internal_config" ]
   }
@@ -1497,7 +1538,8 @@ if (spvtools_build_executables) {
       ":spvtools",
       ":spvtools_opt",
       ":spvtools_software_version",
-      ":spvtools_util_cli_consumer",
+      ":spvtools_tools_util",
+      ":spvtools_tools_io",
       ":spvtools_val",
     ]
     configs += [ ":spvtools_internal_config" ]
@@ -1510,6 +1552,8 @@ if (spvtools_build_executables) {
       ":spvtools_link",
       ":spvtools_opt",
       ":spvtools_software_version",
+      ":spvtools_tools_util",
+      ":spvtools_tools_io",
       ":spvtools_val",
     ]
     configs += [ ":spvtools_internal_config" ]
@@ -1529,7 +1573,8 @@ if (!is_ios && !spirv_is_winuwp && build_with_chromium && spvtools_build_executa
       ":spvtools_opt",
       ":spvtools_reduce",
       ":spvtools_software_version",
-      ":spvtools_util_cli_consumer",
+      ":spvtools_tools_util",
+      ":spvtools_tools_io",
       ":spvtools_val",
       "//third_party/protobuf:protobuf_full",
     ]
@@ -1548,7 +1593,8 @@ if (!is_ios && !spirv_is_winuwp && spvtools_build_executables) {
       ":spvtools_opt",
       ":spvtools_reduce",
       ":spvtools_software_version",
-      ":spvtools_util_cli_consumer",
+      ":spvtools_tools_util",
+      ":spvtools_tools_io",
       ":spvtools_val",
     ]
     configs += [ ":spvtools_internal_config" ]

+ 230 - 2
ThirdParty/SpirvTools/CHANGES

@@ -1,7 +1,235 @@
 Revision history for SPIRV-Tools
 
-v2023.2-dev 2023-01-17
-   - Start v2023.2-dev
+v2025.1 2025-02-28
+  - General
+    - diff: Fix crash in OpString matching (#5988)
+    - Add SPV_AMDX_shader_enqueue version 2 support (#5838)
+    - add support for SPV_INTEL_subgroup_matrix_multiply_accumulate (#5928)
+    - update cmake_minimum_required to 3.22.1 (#5925)
+    - Add OpImageSampleFootprintNV to IsAllowedSampledImageOperand (#5914)
+    - assembler: ensure progress when seeking the version string (#5910)
+  - Optimizer
+    - opt: keep all OpSource instructions (#5901)
+    - [opt] Fix bug opt::InstructionBuilder::AddVariable (#6007)
+    - [OPT] Add SPV_KHR_ray_tracing to allow list (#5941)
+    - opt: keep all OpSource instructions (#5901)
+  - Validator
+    - spirv-val: Add AllowVulkan32BitBitwise option (#6001)
+    - Fix untyped pointer comparison validation (#6004)
+    - spirv-val: Update VUIDs for 308 header (#5990)
+    - spirv-val: fix env parsing for vk1.1spv1.4 (#5985)
+    - Add validation for SPV_NV_linear_swept_spheres. (#5975)
+    - Add validation SPV_NV_cluster_acceleration_structure. (#5974)
+    - Improve the instruction diagnostic for some access chain errors (#5978)
+    - Update physical storage buffer validation to match SPIR-V 1.6.5 (#5977)
+    - Validate SPV_NV_cooperative_vector (#5972)
+    - Fix layout checks with untyped pointers (#5970)
+    - spirv-val: Update mislabeled VUIDs (#5964)
+    - More explicit layout validation (#5958)
+    - spirv-val: Add VK_KHR_maintenance8 support (#5951)
+    - Add EXT_mesh_shader validation support (#5640)
+    - spirv-val: Remove OpenCL ivec3 req (#5940)
+    - spirv-val: Validate zero product workgroup size (#5407)
+    - Relax DebugLine validation (#5916)
+  - Linker
+    - linker: remove LinkOnceODR decorations when linking executables (#5979)
+    - fix: handle LinkOnceODR correctly (#5938)
+
+v2024.4 2024-12-04
+  - General
+    - Add FPEncoding operand type. (#5726)
+    - Support SPV_KHR_untyped_pointers (#5736)
+    - add support for SPV_INTEL_global_variable_host_access (#5786)
+    - Add support for SPV_KHR_compute_shader_derivative (#5817)
+    - Accept hex representation as binary input (#5870)
+    - Vulkan 1.4 support (#5899)
+  - Optimizer
+    - Add knowledge of cooperative matrices (#5720)
+    - Add struct-packing pass and unit test. (#5778)
+  - Validator
+    - Validate presence of Stride operand to OpCooperativeMatrix{Load,Store}KHR (#5777)
+    - Update sampled image validation (#5789)
+    - Disallow stores according to VUID 06924 (#5368)
+    - Add validation for SPV_NV_tensor_addressing and SPV_NV_cooperative_matrix2 (#5865)
+  - Linker
+    - allow linking functions with different pointer arguments (#5534)
+
+v2024.3 2024-06-20
+  - General
+  - Optimizer
+    - Do not fold mul and adds to generate fmas (#5682)
+    - add OpExtInst forward ref fixup pass (#5708)
+  - Validator
+    - Separate Location check for tess patch (#5654)
+    - Validate MemoryAccessMask of OpCooperativeMatrixStoreKHR (#5668)
+    - OpSampledImage extra validation (#5695)
+    - add support for OpExtInstWithForwardRefs (#5698)A
+  - Disassembler
+    - add decorations to comments (#5675)
+    - Add --nested-indent and --reorder-blocks (#5671)
+
+v2024.2 2024-04-22
+  - General
+    - Add SPIRV_TOOLS_EXPORT to public C++ API (#5591)
+    - Use bazel 7 and bzlmod (#5601)
+  - Optimizer
+    - opt: add GroupNonUniformPartitionedNV capability to trim pass (#5648)
+    - Fix rebuilding types with circular references. (#5637)
+    - Add AliasedPointer decoration (#5635)
+    - add support for vulkan-shader-profiler external passes (#5512)
+  - Validator
+    - A fix to support of SPV_QCOM_image_processing2 (#5646)
+    - spirv-val: Add Vulkan check for Rect Dim in OpTypeImage (#5644)
+    - Validate duplicate decorations and execution modes (#5641)
+    - Validator: Support SPV_NV_raw_access_chains (#5568)
+
+v2024.1 2024-03-06
+  - General
+    - Add tooling support for SPV_KHR_maximal_reconvergence (#5542)
+    - Add support for SPV_KHR_float_controls2 (#5543)
+    - SPV_KHR_quad_control (#5547)
+    - Fold 64-bit int operations (#5561)
+    - update image enum tests to remove Kernel capability (#5562)
+    - Support operand kind for SPV_INTEL_maximum_registers (#5580)
+    - SPV_NV_shader_atomic_fp16_vector (#5581)
+    - Support for SPV_QCOM_image_processing2 (#5582)
+    - Fix access chain struct checks (#5592)
+  - Optimizer
+    - opt: add Int16 and Float16 to capability trim pass (#5519)
+    - Add preserver-interface option to spirv-opt (#5524)
+    - spirv-opt: Fix OpCompositeExtract relaxation with struct operands (#5536)
+    - opt: Add VulkanMemoryModelDeviceScope to trim (#5544)
+    - opt: Add TrimCapabilities pass to spirv-opt tool (#5545)
+    - Add modify-maximal-reconvergence to spirv-opt help (#5546)
+    - opt: add SPV_EXT_mesh_shader to opt allowlist (#5551)
+    - opt: Add OpEntryPoint to DescriptorScalarReplacement pass (#5553)
+    - opt: prevent meld to merge block with MaximalReconvergence (#5557)
+    - [OPT] Use new instruction folder for for all opcodes in spec consti folding (#5569)
+    - [OPT] Identify arrays with unknown length in copy prop arrays (#5570)
+    - [OPT] Add removed unused interface var pass to legalization passes (#5579)
+  - Validator
+    - spirv-val: Re-enable OpControlBarrier VU (#5527)
+    - spirv-val: Add Mesh Primitive Built-In validaiton (#5529)
+    - spirv-val: Validate PhysicalStorageBuffer Stage Interface (#5539)
+    - spirv-val: Multiple interface var with same SC (#5528)
+    - spirv-val: Revert Validate PhysicalStorageBuffer Stage Interface (#5575)
+    - spirv-val: Make Constant evaluation consistent (#5587)
+
+v2023.6 2023-12-18
+  - General
+    - update_build_version.py produce deterministic header. (#5426)
+    - Support missing git in update_build_version.py (#5473)
+  - Optimizer
+    - Add ComputeDerivativeGroup*NV capabilities to trim capabilities pass. (#5430)
+    - Do not crash when tryingto fold unsupported spec constant (#5496)
+    - instrument: Fix handling of gl_InvocationID (#5493)
+    - Fix nullptr argument in MarkInsertChain (#5465)
+    - opt: support 64-bit OpAccessChain index in FixStorageClass (#5446)
+    - opt: add StorageImageReadWithoutFormat to cap trim (#5475)
+    - opt: add PhysicalStorageBufferAddresses to trim (#5476)
+    - Fix array size calculation (#5463
+  - Validator
+    - spirv-val: Loosen restriction on base type of DebugTypePointer and DebugTypeQualifier (#5479)
+    - spirv-val: Add WorkgroupMemoryExplicitLayoutKHR check for Block (#5461)
+
+v2023.5 2023-10-15
+  - General
+    - Support 2 Intel extensions (#5357)
+    - SPV_QCOM_image_processing support (#5223)
+  - Optimizer
+    - opt: fix StorageInputOutput16 trimming. (#5359)
+    - opt: add StoragePushConstant16 to trim pass (#5366)
+    - opt: enable StorageUniform16 (#5371)
+    - opt: add bitmask support for capability trimming (#5372)
+    - opt: Add SwitchDescriptorSetPass (#5375)
+    - opt: add FragmentShader*InterlockEXT to capability trim pass (#5390)
+    - opt: add Int64 capability to trim pass (#5398)
+    - opt: add Float64 capability to trim pass (#5428)
+    - opt: add raytracing/rayquery to trim pass (#5397)
+    - opt: add ImageMSArray capability to trim pass. (#5395)
+    - Add SPV_KHR_physical_storage_buffer to allowlists (#5402)
+    - Add SPV_EXT_fragment_shader_interlock to allow lists (#5393)
+    - Make sure that fragment shader interlock instructions are not removed by DCE (#5400)
+    - instrument: Use Import linkage for instrumentation functions (#5355)
+    - Add a new legalization pass to dedupe invocation interlock instructions (#5409)
+    - instrument: Ensure linking works even of nothing is changed (#5419)
+  - Validator
+    - Move token version/cap/ext checks from parsing to validation (#5370)
+    - val: re-add ImageMSArray validation (#5394)
+  - Linker
+    - linker: Add --use-highest-version option
+
+v2023.4 2023-07-17
+  - General
+    - Set cmake_policy CMP0128 (#5341)
+    - Add python3 requirement for the script (#5326)
+    - Add support for LiteralFloat type (#5323)
+    - SPV_KHR_cooperative_matrix (#5286)
+    - Allow OpTypeBool in UniformConstant (#5237)
+    - Allow physical storage buffer pointer in IO (#5251)
+    - Remove const zero image operands (#5232)
+  - Optimizer
+    - Enable vector constant folding (#4913) (#5272)
+    - Fold negation of integer vectors (#5269)
+    - Add folding rule for OpTranspose (#5241)
+    - Add SPV_NV_bindless_texture to spirv optimizations (#5231)
+    - Fix incorrect half float conversion (#5349)
+    - Add SPV_EXT_shader_atomic_float_add to allow lists (#5348)
+  - Instrument
+    - instrument: Cast gl_VertexIndex and InstanceIndex to uint (#5319)
+    - instrument: Fix buffer address length calculations (#5257)
+    - instrument: Reduce number of inst_bindless_stream_write_6 calls (#5327)
+  - Validator
+    - Validate GroupNonUniform instructions (#5296)
+    - spirv-val: Label SPV_KHR_cooperative_matrix VUID (#5301)
+    - Validate layouts for PhysicalStorageBuffer pointers (#5291)
+    - spirv-val: Remove VUID from 1.3.251 spec (#5244)
+  - Diff
+    - spirv-diff: Update test expectations (#5264)
+    - spirv-diff: Leave undefined ids unpaired. (#5262)
+    - spirv-diff: Properly match SPV_KHR_ray_query types. (#5259)
+    - diff: Don't give up entry point matching too early. (#5224)
+
+v2023.3 2023-05-15
+  - General
+    - Update spirv_headers to include SPV_KHR_ray_tracing_position_fetch (#5205)
+    - spirv-tools: Add support for QNX (#5211)
+    - build: set std=c++17 for BUILD.gn (#5162)
+  - Optimizer
+    - Run ADCE when the printf extension is used. (#5215)
+    - Don't convert struct members to half (#5201)
+    - Apply scalar replacement on vars with Pointer decorations (#5208)
+    - opt: Fix null deref in OpMatrixTimesVector and OpVectorTimesMatrix (#5199)
+    - instrument: Add set and binding to bindless error records (#5204)
+    - instrument: Change descriptor state storage format (#5178)
+    - Fix LICMPass (#5087)
+    - Add Vulkan memory model to allow lists (#5173)
+    - Do not remove control barrier after spv1.3 (#5174)
+  - Validator
+    - spirv-val: Label Interface Location/Component VUIDs (#5221)
+    - Add support for SPV_EXT_shader_tile_image (#5188)
+    - Fix vector OpConstantComposite type validation (#5191)
+    - spirv-val: Label new Vulkan VUID 07951 (#5154)
+  - Fuzz
+    - Do not define GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE if it is already defined. (#5200)
+
+v2023.2 2023-03-10
+  - General
+    - build: move from c++11 to c++17 (#4983)
+    - tools: refactorize tools flags parsing. (#5111)
+    - Add C interface for Optimizer (#5030)
+    - libspirv.cpp: adds c++ api for spvBinaryParse (#5109)
+    - build: change the way we set cxx version for bazel. (#5114)
+  - Optimizer
+    - Fix null pointer in FoldInsertWithConstants. (#5093)
+    - Fix removal of dependent non-semantic instructions (#5122)
+    - Remove duplicate lists of constant and type opcodes (#5106)
+    - opt: fix spirv ABI on Linux again. (#5113)
+  - Validator
+    - Validate decoration of structs with RuntimeArray (#5094)
+    - Validate operand type before operating on it (#5092)
+    - spirv-val: Conditional Branch without an exit is invalid in loop header (#5069)
+    - spirv-val: Initial SPV_EXT_mesh_shader builtins (#5080)
 
 v2023.1 2023-01-17
   - General

+ 39 - 39
ThirdParty/SpirvTools/CMakeLists.txt

@@ -1,4 +1,4 @@
-# Copyright (c) 2015-2016 The Khronos Group Inc.
+# Copyright (c) 2015-2023 The Khronos Group Inc.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,10 +12,20 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-cmake_minimum_required(VERSION 3.17.2)
+cmake_minimum_required(VERSION 3.22.1)
 
 project(spirv-tools)
 
+# Avoid a bug in CMake 3.22.1. By default it will set -std=c++11 for
+# targets in test/*, when those tests need -std=c++17.
+# https://github.com/KhronosGroup/SPIRV-Tools/issues/5340
+# The bug is fixed in CMake 3.22.2
+if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.22.1")
+  if (${CMAKE_VERSION} VERSION_LESS "3.22.2")
+    cmake_policy(SET CMP0128 NEW)
+  endif()
+endif()
+
 set_property(GLOBAL PROPERTY USE_FOLDERS ON)
 
 enable_testing()
@@ -39,33 +49,13 @@ option(ENABLE_RTTI "Enables RTTI" OFF)
 option(SPIRV_ALLOW_TIMERS "Allow timers via clock_gettime on supported platforms" ON)
 
 if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
-  add_definitions(-DSPIRV_LINUX)
   set(SPIRV_TIMER_ENABLED ${SPIRV_ALLOW_TIMERS})
-elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Emscripten")
-    add_definitions(-DSPIRV_EMSCRIPTEN)
 elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
   add_definitions(-DSPIRV_WINDOWS)
 elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
   add_definitions(-DSPIRV_WINDOWS)
-elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
-  add_definitions(-DSPIRV_MAC)
-elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "iOS")
-  add_definitions(-DSPIRV_IOS)
-elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "tvOS")
-  add_definitions(-DSPIRV_TVOS)
 elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
-  add_definitions(-DSPIRV_ANDROID)
   set(SPIRV_TIMER_ENABLED ${SPIRV_ALLOW_TIMERS})
-elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
-  add_definitions(-DSPIRV_FREEBSD)
-elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD")
-  add_definitions(-DSPIRV_OPENBSD)
-elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia")
-  add_definitions(-DSPIRV_FUCHSIA)
-elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "GNU")
-  add_definitions(-DSPIRV_GNU)
-else()
-  message(FATAL_ERROR "Your platform '${CMAKE_SYSTEM_NAME}' is not supported!")
 endif()
 
 if (${SPIRV_TIMER_ENABLED})
@@ -229,7 +219,7 @@ function(spvtools_default_compile_options TARGET)
   # For MinGW cross compile, statically link to the C++ runtime.
   # But it still depends on MSVCRT.dll.
   if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
-    if (${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
+    if (NOT MSVC)
       set_target_properties(${TARGET} PROPERTIES
         LINK_FLAGS -static -static-libgcc -static-libstdc++)
     endif()
@@ -248,7 +238,7 @@ if(NOT COMMAND find_host_program)
 endif()
 
 # Tests require Python3
-find_host_package(PythonInterp 3 REQUIRED)
+find_host_package(Python3 REQUIRED)
 
 # Check for symbol exports on Linux.
 # At the moment, this check will fail on the OSX build machines for the Android NDK.
@@ -257,7 +247,7 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
   macro(spvtools_check_symbol_exports TARGET)
     if (NOT "${SPIRV_SKIP_TESTS}")
       add_test(NAME spirv-tools-symbol-exports-${TARGET}
-               COMMAND ${PYTHON_EXECUTABLE}
+               COMMAND Python3::Interpreter
                ${spirv-tools_SOURCE_DIR}/utils/check_symbol_exports.py "$<TARGET_FILE:${TARGET}>")
     endif()
   endmacro()
@@ -270,7 +260,7 @@ else()
 endif()
 
 if(ENABLE_SPIRV_TOOLS_INSTALL)
-  if(WIN32)
+  if(WIN32 AND NOT MINGW)
     macro(spvtools_config_package_dir TARGET PATH)
       set(${PATH} ${TARGET}/cmake)
     endmacro()
@@ -290,15 +280,21 @@ if(ENABLE_SPIRV_TOOLS_INSTALL)
   endmacro()
 endif()
 
-# Defaults to OFF if the user didn't set it.
-option(SPIRV_SKIP_EXECUTABLES
-  "Skip building the executable and tests along with the library"
-  ON)
-option(SPIRV_SKIP_TESTS
-  "Skip building tests along with the library" ON)
-if ("${SPIRV_SKIP_EXECUTABLES}")
+# Currently iOS and Android are very similar.
+# They both have their own packaging (APP/APK).
+# Which makes regular executables/testing problematic.
+#
+# Currently the only deliverables for these platforms are
+# libraries (either STATIC or SHARED).
+#
+# Furthermore testing is equally problematic.
+set(SPIRV_SKIP_EXECUTABLES ON)
+
+option(SPIRV_SKIP_EXECUTABLES "Skip building the executable and tests along with the library")
+if (SPIRV_SKIP_EXECUTABLES)
   set(SPIRV_SKIP_TESTS ON)
 endif()
+option(SPIRV_SKIP_TESTS "Skip building tests along with the library")
 
 # Defaults to ON.  The checks can be time consuming.
 # Turn off if they take too long.
@@ -349,14 +345,13 @@ if(ENABLE_SPIRV_TOOLS_INSTALL)
       ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/libspirv.hpp
       ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/optimizer.hpp
       ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/linker.hpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/instrument.hpp
     DESTINATION
       ${CMAKE_INSTALL_INCLUDEDIR}/spirv-tools/)
 endif(ENABLE_SPIRV_TOOLS_INSTALL)
 
 if (NOT "${SPIRV_SKIP_TESTS}")
   add_test(NAME spirv-tools-copyrights
-           COMMAND ${PYTHON_EXECUTABLE} utils/check_copyright.py
+           COMMAND Python3::Interpreter utils/check_copyright.py
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 endif()
 
@@ -365,7 +360,8 @@ set(SPIRV_SHARED_LIBRARIES "-lSPIRV-Tools-shared")
 
 # Build pkg-config file
 # Use a first-class target so it's regenerated when relevant files are updated.
-add_custom_target(spirv-tools-pkg-config ALL
+add_custom_command(
+        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc
         COMMAND ${CMAKE_COMMAND}
                       -DCHANGES_FILE=${CMAKE_CURRENT_SOURCE_DIR}/CHANGES
                       -DTEMPLATE_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools.pc.in
@@ -375,8 +371,9 @@ add_custom_target(spirv-tools-pkg-config ALL
                       -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR}
                       -DSPIRV_LIBRARIES=${SPIRV_LIBRARIES}
                       -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
-        DEPENDS "CHANGES" "cmake/SPIRV-Tools.pc.in" "cmake/write_pkg_config.cmake")
-add_custom_target(spirv-tools-shared-pkg-config ALL
+        DEPENDS "CHANGES" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake")
+add_custom_command(
+        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc
         COMMAND ${CMAKE_COMMAND}
                       -DCHANGES_FILE=${CMAKE_CURRENT_SOURCE_DIR}/CHANGES
                       -DTEMPLATE_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools-shared.pc.in
@@ -386,7 +383,10 @@ add_custom_target(spirv-tools-shared-pkg-config ALL
                       -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR}
                       -DSPIRV_SHARED_LIBRARIES=${SPIRV_SHARED_LIBRARIES}
                       -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
-        DEPENDS "CHANGES" "cmake/SPIRV-Tools-shared.pc.in" "cmake/write_pkg_config.cmake")
+        DEPENDS "CHANGES" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools-shared.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake")
+add_custom_target(spirv-tools-pkg-config
+        ALL
+        DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc)
 
 # Install pkg-config file
 if (ENABLE_SPIRV_TOOLS_INSTALL)

+ 45 - 81
ThirdParty/SpirvTools/CONTRIBUTING.md

@@ -2,9 +2,8 @@
 
 ## For users: Reporting bugs and requesting features
 
-We organize known future work in GitHub projects. See [Tracking SPIRV-Tools work
-with GitHub
-projects](https://github.com/KhronosGroup/SPIRV-Tools/blob/master/docs/projects.md)
+We organize known future work in GitHub projects. See
+[Tracking SPIRV-Tools work with GitHub projects](https://github.com/KhronosGroup/SPIRV-Tools/blob/main/docs/projects.md)
 for more.
 
 To report a new bug or request a new feature, please file a GitHub issue. Please
@@ -36,9 +35,9 @@ create a new issue, as with bugs. In the issue provide
 
 ## For developers: Contributing a patch
 
-Before we can use your code, you must sign the [Khronos Open Source Contributor
-License Agreement](https://cla-assistant.io/KhronosGroup/SPIRV-Tools) (CLA),
-which you can do online. The CLA is necessary mainly because you own the
+Before we can use your code, you must sign the
+[Khronos Open Source Contributor License Agreement](https://cla-assistant.io/KhronosGroup/SPIRV-Tools)
+(CLA), which you can do online. The CLA is necessary mainly because you own the
 copyright to your changes, even after your contribution becomes part of our
 codebase, so we need your permission to use and distribute your code. We also
 need to be sure of various other things -- for instance that you'll tell us if
@@ -47,20 +46,20 @@ sign the CLA until after you've submitted your code for review and a member has
 approved it, but you must do it before we can put your code into our codebase.
 
 See
-[README.md](https://github.com/KhronosGroup/SPIRV-Tools/blob/master/README.md)
+[README.md](https://github.com/KhronosGroup/SPIRV-Tools/blob/main/README.md)
 for instruction on how to get, build, and test the source. Once you have made
 your changes:
 
-*   Ensure the code follows the [Google C++ Style
-    Guide](https://google.github.io/styleguide/cppguide.html). Running
-    `clang-format -style=file -i [modified-files]` can help.
+*   Ensure the code follows the
+    [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html).
+    Running `clang-format -style=file -i [modified-files]` can help.
 *   Create a pull request (PR) with your patch.
 *   Make sure the PR description clearly identified the problem, explains the
     solution, and references the issue if applicable.
 *   If your patch completely fixes bug 1234, the commit message should say
-    `Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1234`
-    When you do this, the issue will be closed automatically when the commit
-    goes into master.  Also, this helps us update the [CHANGES](CHANGES) file.
+    `Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1234` When you do
+    this, the issue will be closed automatically when the commit goes into
+    main. Also, this helps us update the [CHANGES](CHANGES) file.
 *   Watch the continuous builds to make sure they pass.
 *   Request a code review.
 
@@ -82,8 +81,8 @@ Instructions for this are given below.
 The formal code reviews are done on GitHub. Reviewers are to look for all of the
 usual things:
 
-*   Coding style follows the [Google C++ Style
-    Guide](https://google.github.io/styleguide/cppguide.html)
+*   Coding style follows the
+    [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)
 *   Identify potential functional problems.
 *   Identify code duplication.
 *   Ensure the unit tests have enough coverage.
@@ -102,84 +101,49 @@ should pay particular attention to:
     updated. For example, a new instruction is added, but the def-use manager is
     not updated. Later on, it is possible that the def-use manager will be used,
     and give wrong results.
+*   If a pass gets the id of a type from the type manager, make sure the type is
+    not a struct or array. It there are two structs that look the same, the type
+    manager can return the wrong one.
 
 ## For maintainers: Merging a PR
 
-We intend to maintain a linear history on the GitHub master branch, and the
+We intend to maintain a linear history on the GitHub main branch, and the
 build and its tests should pass at each commit in that history. A linear
 always-working history is easier to understand and to bisect in case we want to
-find which commit introduced a bug.
+find which commit introduced a bug. The
+[Squash and Merge](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits)
+button on the GitHub web interface. All other ways of merging on the web
+interface have been disabled.
 
-### Initial merge setup
+Before merging, we generally require:
 
-The following steps should be done exactly once (when you are about to merge a
-PR for the first time):
+1.  All tests except for the smoke test pass. See
+    [failing smoke test](#failing-smoke-test).
+1.  The PR is approved by at least one of the maintainers. If the PR modifies
+    different parts of the code, then multiple reviewers might be necessary.
 
-*   It is assumed that upstream points to
-    [[email protected]](mailto:[email protected]):KhronosGroup/SPIRV-Tools.git or
-    https://github.com/KhronosGroup/SPIRV-Tools.git.
+The squash-and-merge button will turn green when these requirements are met.
+Maintainers have the to power to merge even if the button is not green, but that
+is discouraged.
 
-*   Find out the local name for the main github repo in your git configuration.
-    For example, in this configuration, it is labeled `upstream`.
+### Failing smoke test
 
-    ```
-    git remote -v
-    [ ... ]
-    upstream https://github.com/KhronosGroup/SPIRV-Tools.git (fetch)
-    upstream https://github.com/KhronosGroup/SPIRV-Tools.git (push)
-    ```
+The purpose of the smoke test is to let us know if
+[shaderc](https://github.com/google/shaderc) fails to build with the change. If
+it fails, the maintainer needs to determine if the reason for the failure is a
+problem in the current PR or if another repository needs to be changed. Most of
+the time [Glslang](https://github.com/KhronosGroup/glslang) needs to be updated
+to account for the change in SPIR-V Tools.
 
-*   Make sure that the `upstream` remote is set to fetch from the `refs/pull`
-    namespace:
+The PR can still be merged if the problem is not with that PR.
 
-    ```
-    git config --get-all remote.upstream.fetch
-    +refs/heads/*:refs/remotes/upstream/*
-    +refs/pull/*/head:refs/remotes/upstream/pr/*
-    ```
+## For maintainers: Running tests
 
-*   If the line `+refs/pull/*/head:refs/remotes/upstream/pr/*` is not present in
-    your configuration, you can add it with the command:
+For security reasons, not all tests will run automatically. When they do not, a
+maintainer will have to start the tests.
 
-    ```
-    git config --local --add remote.upstream.fetch '+refs/pull/*/head:refs/remotes/upstream/pr/*'
-    ```
+If the Github actions tests do not run on a PR, they can be initiated by closing
+and reopening the PR.
 
-### Merge workflow
-
-The following steps should be done for every PR that you intend to merge:
-
-*   Make sure your local copy of the master branch is up to date:
-
-    ```
-    git checkout master
-    git pull
-    ```
-
-*   Fetch all pull requests refs:
-
-    ```
-    git fetch upstream
-    ```
-
-*   Checkout the particular pull request you are going to review:
-
-    ```
-    git checkout pr/1048
-    ```
-
-*   Rebase the PR on top of the master branch. If there are conflicts, send it
-    back to the author and ask them to rebase. During the interactive rebase be
-    sure to squash all of the commits down to a single commit.
-
-    ```
-    git rebase -i master
-    ```
-
-*   **Build and test the PR.**
-
-*   If all of the tests pass, push the commit `git push upstream HEAD:master`
-
-*   Close the PR and add a comment saying it was push using the commit that you
-    just pushed. See https://github.com/KhronosGroup/SPIRV-Tools/pull/935 as an
-    example.
+If the kokoro tests are not run, they can be run by adding the label
+`kokoro:run` to the PR.

+ 11 - 5
ThirdParty/SpirvTools/DEPS

@@ -3,18 +3,24 @@ use_relative_paths = True
 vars = {
   'github': 'https://github.com',
 
-  'effcee_revision': 'c7b4db79f340f7a9981e8a484f6d5785e24242d1',
+  'abseil_revision': '310e6f4f0f202da13720fdd6cb0095e10a98fe1c',
 
-  'googletest_revision': '750d67d809700ae8fca6d610f7b41b71aa161808',
+  'effcee_revision': '874b47102c57a8979c0f154cf8e0eab53c0a0502',
+
+  'googletest_revision': '3af834740f58ef56058e6f8a1be51f62bc3a6515',
 
   # Use protobufs before they gained the dependency on abseil
-  'protobuf_revision': 'v3.13.0.1',
+  'protobuf_revision': 'v21.12',
+
+  're2_revision': 'c84a140c93352cdabbfb547c531be34515b12228',
 
-  're2_revision': '3a8436ac436124a57a4e22d5c8713a2d42b381d7',
-  'spirv_headers_revision': 'aa331ab0ffcb3a67021caa1a0c1c9017712f2f31',
+  'spirv_headers_revision': 'd5ee9ed2bbe96756a781bffb19c51d62a468049a',
 }
 
 deps = {
+  'external/abseil_cpp':
+      Var('github') + '/abseil/abseil-cpp.git@' + Var('abseil_revision'),
+
   'external/effcee':
       Var('github') + '/google/effcee.git@' + Var('effcee_revision'),
 

+ 33 - 0
ThirdParty/SpirvTools/MODULE.bazel

@@ -0,0 +1,33 @@
+bazel_dep(name = "bazel_skylib", version = "1.5.0")
+
+bazel_dep(name = "googletest", dev_dependency = True)
+local_path_override(
+    module_name = "googletest",
+    path = "external/googletest",
+)
+
+bazel_dep(name = "re2", dev_dependency = True)
+local_path_override(
+    module_name = "re2",
+    path = "external/re2",
+)
+
+bazel_dep(name = "effcee", dev_dependency = True)
+local_path_override(
+    module_name = "effcee",
+    path = "external/effcee",
+)
+
+bazel_dep(name = "rules_python",
+          version = "0.34.0")
+
+# https://rules-python.readthedocs.io/en/stable/toolchains.html#library-modules-with-dev-only-python-usage
+python = use_extension(
+    "@rules_python//python/extensions:python.bzl",
+    "python",
+    dev_dependency = True
+)
+
+python.toolchain(python_version = "3.12",
+                 is_default = True,
+                 ignore_root_user_error = True)

+ 35 - 32
ThirdParty/SpirvTools/README.md

@@ -1,4 +1,5 @@
 # SPIR-V Tools
+[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/KhronosGroup/SPIRV-Tools/badge)](https://securityscorecards.dev/viewer/?uri=github.com/KhronosGroup/SPIRV-Tools)
 
 NEWS 2023-01-11: Development occurs on the `main` branch.
 
@@ -23,9 +24,16 @@ headers, and XML registry.
 
 ## Downloads
 
+The official releases for SPIRV-Tools can be found on LunarG's
+[SDK download page](https://vulkan.lunarg.com/sdk/home).
+
+For convenience, here are also links to the latest builds (HEAD).
+Those are untested automated builds. Those are not official releases, nor
+are guaranteed to work. Official releases builds are in the Vulkan SDK.
+
 <img alt="Linux" src="kokoro/img/linux.png" width="20px" height="20px" hspace="2px"/>[![Linux Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_linux_clang_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_clang_release.html)
 <img alt="MacOS" src="kokoro/img/macos.png" width="20px" height="20px" hspace="2px"/>[![MacOS Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_macos_clang_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_release.html)
-<img alt="Windows" src="kokoro/img/windows.png" width="20px" height="20px" hspace="2px"/>[![Windows Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_windows_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2019_release.html)
+<img alt="Windows" src="kokoro/img/windows.png" width="20px" height="20px" hspace="2px"/>[![Windows Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_windows_vs2022_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2022_release.html)
 
 [More downloads](docs/downloads.md)
 
@@ -48,17 +56,14 @@ version.  An API call reports the software version as a C-style string.
 
 ## Releases
 
-Some versions of SPIRV-Tools are tagged as stable releases (see
-[tags](https://github.com/KhronosGroup/SPIRV-Tools/tags) on github).
-These versions undergo extra testing.
-Releases are not directly related to releases (or versions) of
-[SPIRV-Headers][spirv-headers].
-Releases of SPIRV-Tools are tested against the version of SPIRV-Headers listed
-in the [DEPS](DEPS) file.
-The release generally uses the most recent compatible version of SPIRV-Headers
-available at the time of release.
-No version of SPIRV-Headers other than the one listed in the DEPS file is
-guaranteed to work with the SPIRV-Tools release.
+The official releases for SPIRV-Tools can be found on LunarG's
+[SDK download page](https://vulkan.lunarg.com/sdk/home).
+
+You can find either the prebuilt, and QA tested binaries, or download the
+SDK Config, which lists the commits to use to build the release from scratch.
+
+GitHub releases are deprecated, and we will not publish new releases until
+further notice.
 
 ## Supported features
 
@@ -75,6 +80,8 @@ guaranteed to work with the SPIRV-Tools release.
 * Assembler only does basic syntax checking.  No cross validation of
   IDs or types is performed, except to check literal arguments to
   `OpConstant`, `OpSpecConstant`, and `OpSwitch`.
+* Where tools expect binary input, a hex stream may be provided instead.  See
+  `spirv-dis --help`.
 
 See [`docs/syntax.md`](docs/syntax.md) for the assembly language syntax.
 
@@ -292,16 +299,18 @@ For some kinds of development, you may need the latest sources from the third-pa
     git clone https://github.com/google/googletest.git          spirv-tools/external/googletest
     git clone https://github.com/google/effcee.git              spirv-tools/external/effcee
     git clone https://github.com/google/re2.git                 spirv-tools/external/re2
+    git clone https://github.com/abseil/abseil-cpp.git          spirv-tools/external/abseil_cpp
 
 #### Dependency on Effcee
 
 Some tests depend on the [Effcee][effcee] library for stateful matching.
-Effcee itself depends on [RE2][re2].
+Effcee itself depends on [RE2][re2], and RE2 depends on [Abseil][abseil-cpp].
 
 * If SPIRV-Tools is configured as part of a larger project that already uses
   Effcee, then that project should include Effcee before SPIRV-Tools.
-* Otherwise, SPIRV-Tools expects Effcee sources to appear in `external/effcee`
-  and RE2 sources to appear in `external/re2`.
+* Otherwise, SPIRV-Tools expects Effcee sources to appear in `external/effcee`,
+  RE2 sources to appear in `external/re2`, and Abseil sources to appear in 
+  `external/abseil_cpp`.
 
 ### Source code organization
 
@@ -313,6 +322,9 @@ Effcee itself depends on [RE2][re2].
 * `external/re2`: Location of [RE2][re2] sources, if the `re2` library is not already
   configured by an enclosing project.
   (The Effcee project already requires RE2.)
+* `external/abseil_cpp`: Location of [Abseil][abseil-cpp] sources, if Abseil is
+   not already configured by an enclosing project.
+  (The RE2 project already requires Abseil.)
 * `include/`: API clients should add this directory to the include search path
 * `external/spirv-headers`: Intended location for
   [SPIR-V headers][spirv-headers], not provided
@@ -381,15 +393,8 @@ fuzzer tests.
 ### Build using Bazel
 You can also use [Bazel](https://bazel.build/) to build the project.
 
-On linux:
-```sh
-cd <spirv-dir>
-bazel build --cxxopt=-std=c++17 :all
-```
-
-On windows:
 ```sh
-bazel build --cxxopt=/std:c++17 :all
+bazel build :all
 ```
 
 ### Build a node.js package using Emscripten
@@ -427,7 +432,7 @@ targets, you need to install CMake Version 2.8.12 or later.
 - [Python 3](http://www.python.org/): for utility scripts and running the test
 suite.
 - [Bazel](https://bazel.build/) (optional): if building the source with Bazel,
-you need to install Bazel Version 5.0.0 on your machine. Other versions may
+you need to install Bazel Version 7.0.2 on your machine. Other versions may
 also work, but are not verified.
 - [Emscripten SDK](https://emscripten.org) (optional): if building the
   WebAssembly module.
@@ -435,20 +440,17 @@ also work, but are not verified.
 SPIRV-Tools is regularly tested with the following compilers:
 
 On Linux
-- GCC version 9.3
+- GCC version 9.4
 - Clang version 10.0
 
 On MacOS
-- AppleClang 11.0
+- AppleClang 15.0
 
 On Windows
-- Visual Studio 2017
 - Visual Studio 2019
 - Visual Studio 2022
 
-Note: Visual Studio 2017 has incomplete c++17 support. We might stop
-testing it soon. Other compilers or later versions may work, but they are not
-tested.
+Note: Other compilers or later versions may work, but they are not tested.
 
 ### CMake options
 
@@ -480,12 +482,12 @@ iterator debugging.
 ### Android ndk-build
 
 SPIR-V Tools supports building static libraries `libSPIRV-Tools.a` and
-`libSPIRV-Tools-opt.a` for Android:
+`libSPIRV-Tools-opt.a` for Android.  Using the Android NDK r25c or later:
 
 ```
 cd <spirv-dir>
 
-export ANDROID_NDK=/path/to/your/ndk
+export ANDROID_NDK=/path/to/your/ndk   # NDK r25c or later
 
 mkdir build && cd build
 mkdir libs
@@ -798,6 +800,7 @@ limitations under the License.
 [googletest-issue-610]: https://github.com/google/googletest/issues/610
 [effcee]: https://github.com/google/effcee
 [re2]: https://github.com/google/re2
+[abseil-cpp]: https://github.com/abseil/abseil-cpp
 [CMake]: https://cmake.org/
 [cpp-style-guide]: https://google.github.io/styleguide/cppguide.html
 [clang-sanitizers]: http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation

+ 13 - 0
ThirdParty/SpirvTools/SECURITY.md

@@ -0,0 +1,13 @@
+# Security Policy
+
+## Supported Versions
+
+Security updates are applied only to the latest release.
+
+## Reporting a Vulnerability
+
+If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
+
+Please disclose it at [security advisory](https://github.com/KhronosGroup/SPIRV-Tools/security/advisories/new).
+
+This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.

+ 2 - 12
ThirdParty/SpirvTools/WORKSPACE

@@ -4,16 +4,6 @@ local_repository(
 )
 
 local_repository(
-    name = "com_google_googletest",
-    path = "external/googletest",
-)
-
-local_repository(
-    name = "com_googlesource_code_re2",
-    path = "external/re2",
-)
-
-local_repository(
-    name = "com_google_effcee",
-    path = "external/effcee",
+    name = "abseil-cpp",
+    path = "external/abseil_cpp",
 )

+ 1 - 1
ThirdParty/SpirvTools/android_test/Android.mk

@@ -5,7 +5,7 @@ LOCAL_CPP_EXTENSION := .cc .cpp .cxx
 LOCAL_SRC_FILES:=test.cpp
 LOCAL_MODULE:=spirvtools_test
 LOCAL_LDLIBS:=-landroid
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -Werror
+LOCAL_CXXFLAGS:=-std=c++17 -fno-exceptions -fno-rtti -Werror
 LOCAL_STATIC_LIBRARIES=SPIRV-Tools SPIRV-Tools-opt
 include $(BUILD_SHARED_LIBRARY)
 

+ 1 - 1
ThirdParty/SpirvTools/android_test/jni/Application.mk

@@ -1,5 +1,5 @@
 APP_ABI := all
 APP_BUILD_SCRIPT := Android.mk
 APP_STL := c++_static
-APP_PLATFORM := android-9
+APP_PLATFORM := android-24
 NDK_TOOLCHAIN_VERSION := 4.9

+ 6 - 6
ThirdParty/SpirvTools/build_defs.bzl

@@ -88,7 +88,7 @@ def generate_core_tables(version):
         outs = outs.values(),
         cmd = cmd,
         cmd_bat = cmd,
-        exec_tools = [":generate_grammar_tables"],
+        tools = [":generate_grammar_tables"],
         visibility = ["//visibility:private"],
     )
 
@@ -123,7 +123,7 @@ def generate_enum_string_mapping(version):
         outs = outs.values(),
         cmd = cmd,
         cmd_bat = cmd,
-        exec_tools = [":generate_grammar_tables"],
+        tools = [":generate_grammar_tables"],
         visibility = ["//visibility:private"],
     )
 
@@ -151,7 +151,7 @@ def generate_opencl_tables(version):
         outs = outs.values(),
         cmd = cmd,
         cmd_bat = cmd,
-        exec_tools = [":generate_grammar_tables"],
+        tools = [":generate_grammar_tables"],
         visibility = ["//visibility:private"],
     )
 
@@ -179,7 +179,7 @@ def generate_glsl_tables(version):
         outs = outs.values(),
         cmd = cmd,
         cmd_bat = cmd,
-        exec_tools = [":generate_grammar_tables"],
+        tools = [":generate_grammar_tables"],
         visibility = ["//visibility:private"],
     )
 
@@ -207,7 +207,7 @@ def generate_vendor_tables(extension, operand_kind_prefix = ""):
         outs = outs.values(),
         cmd = cmd,
         cmd_bat = cmd,
-        exec_tools = [":generate_grammar_tables"],
+        tools = [":generate_grammar_tables"],
         visibility = ["//visibility:private"],
     )
 
@@ -229,6 +229,6 @@ def generate_extinst_lang_headers(name, grammar = None):
         outs = outs.values(),
         cmd = cmd,
         cmd_bat = cmd,
-        exec_tools = [":generate_language_headers"],
+        tools = [":generate_language_headers"],
         visibility = ["//visibility:private"],
     )

+ 21 - 18
ThirdParty/SpirvTools/docs/downloads.md

@@ -1,28 +1,31 @@
 # Downloads
 
-## Latest builds
-
-Download the latest builds of the [master](https://github.com/KhronosGroup/SPIRV-Tools/tree/master) branch.
-
-### Release build
-| Windows | Linux | MacOS |
-| --- | --- | --- |
-| [MSVC 2017](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2017_release.html) | [clang](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_clang_release.html) | [clang](https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_release.html) |
-| | [gcc](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_gcc_release.html) | |
-
-### Debug build
-| Windows | Linux | MacOS |
-| --- | --- | --- |
-| [MSVC 2017](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2017_debug.html) | [clang](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_clang_debug.html) | [clang](https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_debug.html) |
-| | [gcc](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_gcc_debug.html) | |
-
-
 ## Vulkan SDK
 
-SPIRV-Tools is published as part of the [LunarG Vulkan SDK](https://www.lunarg.com/vulkan-sdk/).
+The official releases for SPIRV-Tools can be found on LunarG's
+[SDK download page](https://vulkan.lunarg.com/sdk/home).
 The Vulkan SDK is updated approximately every six weeks.
 
 ## Android NDK
 
 SPIRV-Tools host executables, and library sources are published as
 part of the [Android NDK](https://developer.android.com/ndk/downloads).
+
+## Automated builds
+
+For convenience, here are also links to the latest builds (HEAD).
+Those are untested automated builds. Those are not official releases, nor
+are guaranteed to work. Official releases builds are in the Android NDK or
+Vulkan SDK.
+
+Download the latest builds of the [main](https://github.com/KhronosGroup/SPIRV-Tools/tree/main) branch.
+
+| Platform | Processor | Compiler | Release build | Debug build |
+| --- | --- | --- | --- | --- |
+| Windows | x86-64 | VisualStudio 2022 (MSVC v143) | Download: <a href="https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2022_release.html"> <img src="https://storage.googleapis.com/spirv-tools/badges/build_status_windows_vs2022_release.svg" alt="status of VS 2022 release build"></a> | Download: <a href="https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2022_debug.html"> <img src="https://storage.googleapis.com/spirv-tools/badges/build_status_windows_vs2022_debug.svg" alt="status of VS 2022 debug build"></a> |
+| Linux | x86-64 | GCC 9.4 | Download: <a href="https://storage.googleapis.com/spirv-tools/badges/build_link_linux_gcc_release.html"> <img src="https://storage.googleapis.com/spirv-tools/badges/build_status_linux_gcc_release.svg" alt="status of Linux GCC build"></a> | Download: <a href="https://storage.googleapis.com/spirv-tools/badges/build_link_linux_gcc_debug.html"> <img src="https://storage.googleapis.com/spirv-tools/badges/build_status_linux_gcc_debug.svg" alt="status of Linux GCC debug build"></a> |
+| macOS | x86-64 | Clang 15 | Download: <a href="https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_release.html"> <img src="https://storage.googleapis.com/spirv-tools/badges/build_status_macos_clang_release.svg" alt="status of macOS Clang build"></a> | Download: <a href="https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_debug.html"> <img src="https://storage.googleapis.com/spirv-tools/badges/build_status_macos_clang_debug.svg" alt="status of macOS Clang build"></a> |
+
+Note: If you suspect something is wrong with the compiler versions mentioned,
+check the scripts and configurations in the [kokoro](../kokoro) source tree,
+or the results of the checks on the latest commits on the `main` branch.

+ 2 - 2
ThirdParty/SpirvTools/docs/projects.md

@@ -34,7 +34,7 @@ through the project workflow:
   ones.
 * They determine if the work for a card has been completed.
 * Normally they are the person (or persons) who can approve and merge a pull
-  request into the `master` branch.
+  request into the `main` branch.
 
 Our projects organize cards into the following columns:
 * `Ideas`: Work which could be done, captured either as Cards or Notes.
@@ -51,7 +51,7 @@ Our projects organize cards into the following columns:
   claimed by someone.
 * `Done`: Issues which have been resolved, by completing their work.
   * The changes have been applied to the repository, typically by being pushed
-  into the `master` branch.
+  into the `main` branch.
   * Other kinds of work could update repository settings, for example.
 * `Rejected ideas`: Work which has been considered, but which we don't want
   implemented.

+ 44 - 0
ThirdParty/SpirvTools/docs/syntax.md

@@ -215,6 +215,50 @@ Note that this has some interesting consequences, including:
   that named ID being output.  This may be valid SPIR-V, contrary to the
   presumed intention of the writer.
 
+## OpUnknown
+<a name="op-unknown"></a>
+
+HLSL has a feature that allows users to specify an exact SPIR-V type using [the
+`SpirvType` template](https://github.com/microsoft/hlsl-specs/blob/main/proposals/0011-inline-spirv.md#types).
+This feature allows the user to specify a type opcode that the compiler does
+not know. In this case, it will be unable to generate assembly using the
+correct mnemonic.
+
+In order to represent unknown opcodes in assembly format, the `OpUnknown`
+pseudo-instruction may be used. The syntax is:
+
+```
+OpUnknown(<enumerant>, <WordCount>) <operand 1> ...
+```
+
+`enumerant` is the opcode enumerant, and `WordCount` is the number of words in
+the instruction. These will be assembled into a single word representing the
+opcode. Operands will be parsed according to the alternate parsing mode
+described in [Arbitrary Integers](#op-unknown). Named enumerated values cannot
+be handled by this mode and must be represented using the arbitrary integer
+syntax.
+
+It must be used at the beginning of a new instruction, and if there is a result
+ID it must explicitly be passed in as an operand. This is because the physical
+layout of a SPIR-V instruction may include a result type operand before the
+result ID operand, but it depends on the opcode and cannot be inferred for an
+unknown operand.
+
+For example, a 32-bit signed integer type could be represented like this:
+
+```
+OpUnknown(21, 4) %int_t 32 1
+```
+
+An OpStore instruction could be represented as:
+
+```
+OpUnknown(62, 3) %9 %12
+```
+
+The enumerant and word count must be decimal integers.
+
+
 ## Notes
 
 * Some enumerants cannot be used by name, because the target instruction

+ 18 - 6
ThirdParty/SpirvTools/external/CMakeLists.txt

@@ -41,13 +41,11 @@ if (IS_DIRECTORY ${SPIRV_HEADER_DIR})
   # Do this so enclosing projects can use SPIRV-Headers_SOURCE_DIR to find
   # headers to include.
   if (NOT DEFINED SPIRV-Headers_SOURCE_DIR)
-    set(SPIRV_HEADERS_SKIP_INSTALL ON)
-    set(SPIRV_HEADERS_SKIP_EXAMPLES ON)
     add_subdirectory(${SPIRV_HEADER_DIR})
   endif()
 else()
   message(FATAL_ERROR
-    "SPIRV-Headers was not found - please checkout a copy under external/.")
+    "SPIRV-Headers was not found - please checkout a copy at external/spirv-headers.")
 endif()
 
 if (NOT ${SPIRV_SKIP_TESTS})
@@ -56,7 +54,9 @@ if (NOT ${SPIRV_SKIP_TESTS})
   if (TARGET gmock)
     message(STATUS "Google Mock already configured")
   else()
-    set(GMOCK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
+    if (NOT GMOCK_DIR)
+      set(GMOCK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
+    endif()
     if(EXISTS ${GMOCK_DIR})
       if(MSVC)
         # Our tests use ::testing::Combine.  Work around a compiler
@@ -73,7 +73,7 @@ if (NOT ${SPIRV_SKIP_TESTS})
       # gtest requires special defines for building as a shared
       # library, simply always build as static.
       push_variable(BUILD_SHARED_LIBS 0)
-      add_subdirectory(${GMOCK_DIR} EXCLUDE_FROM_ALL)
+      add_subdirectory(${GMOCK_DIR} ${CMAKE_CURRENT_BINARY_DIR}/googletest EXCLUDE_FROM_ALL)
       pop_variable(BUILD_SHARED_LIBS)
     endif()
   endif()
@@ -91,10 +91,22 @@ if (NOT ${SPIRV_SKIP_TESTS})
 
   # Find Effcee and RE2, for testing.
 
+  # RE2 depends on Abseil. We set absl_SOURCE_DIR if it is not already set, so
+  # that effcee can find abseil.
+  if(NOT TARGET absl::base)
+    if (NOT absl_SOURCE_DIR)
+      if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/abseil_cpp)
+        set(absl_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/abseil_cpp" CACHE STRING "Abseil source dir" )
+      endif()
+    endif()
+  endif()
+
   # First find RE2, since Effcee depends on it.
   # If already configured, then use that.  Otherwise, prefer to find it under 're2'
   # in this directory.
   if (NOT TARGET re2)
+
+
     # If we are configuring RE2, then turn off its testing.  It takes a long time and
     # does not add much value for us.  If an enclosing project configured RE2, then it
     # has already chosen whether to enable RE2 testing.
@@ -152,7 +164,7 @@ if(SPIRV_BUILD_FUZZER)
 
   if(NOT TARGET protobuf::libprotobuf OR NOT TARGET protobuf::protoc)
 
-    set(SPIRV_TOOLS_PROTOBUF_DIR ${CMAKE_CURRENT_SOURCE_DIR}/protobuf/cmake)
+    set(SPIRV_TOOLS_PROTOBUF_DIR ${CMAKE_CURRENT_SOURCE_DIR}/protobuf)
     if (NOT IS_DIRECTORY ${SPIRV_TOOLS_PROTOBUF_DIR})
       message(
           FATAL_ERROR

+ 13 - 13
ThirdParty/SpirvTools/external/effcee/BUILD.bazel

@@ -25,7 +25,7 @@ cc_library(
     compatible_with = [
     ],
     deps = [
-        "@com_googlesource_code_re2//:re2",
+        "@re2//:re2",
     ],
 )
 
@@ -60,8 +60,8 @@ cc_test(
     srcs = ["effcee/check_test.cc"],
     deps = [
         ":effcee",
-        "@com_google_googletest//:gtest_main",
-        "@com_google_googletest//:gtest",
+        "@googletest//:gtest_main",
+        "@googletest//:gtest",
     ],
 )
 
@@ -70,8 +70,8 @@ cc_test(
     srcs = ["effcee/cursor_test.cc"],
     deps = [
         ":effcee",
-        "@com_google_googletest//:gtest_main",
-        "@com_google_googletest//:gtest",
+        "@googletest//:gtest_main",
+        "@googletest//:gtest",
     ],
 )
 
@@ -80,8 +80,8 @@ cc_test(
     srcs = ["effcee/diagnostic_test.cc"],
     deps = [
         ":effcee",
-        "@com_google_googletest//:gtest_main",
-        "@com_google_googletest//:gtest",
+        "@googletest//:gtest_main",
+        "@googletest//:gtest",
     ],
 )
 
@@ -90,8 +90,8 @@ cc_test(
     srcs = ["effcee/match_test.cc"],
     deps = [
         ":effcee",
-        "@com_google_googletest//:gtest_main",
-        "@com_google_googletest//:gtest",
+        "@googletest//:gtest_main",
+        "@googletest//:gtest",
     ],
 )
 
@@ -100,8 +100,8 @@ cc_test(
     srcs = ["effcee/options_test.cc"],
     deps = [
         ":effcee",
-        "@com_google_googletest//:gtest_main",
-        "@com_google_googletest//:gtest",
+        "@googletest//:gtest_main",
+        "@googletest//:gtest",
     ],
 )
 
@@ -110,7 +110,7 @@ cc_test(
     srcs = ["effcee/result_test.cc"],
     deps = [
         ":effcee",
-        "@com_google_googletest//:gtest_main",
-        "@com_google_googletest//:gtest",
+        "@googletest//:gtest_main",
+        "@googletest//:gtest",
     ],
 )

+ 6 - 2
ThirdParty/SpirvTools/external/effcee/CHANGES

@@ -1,7 +1,11 @@
 Revision history for Effcee
 
-v2020.0-dev 2020-06-16
- - Start v2020.0-dev
+v2023.0-dev 2020-06-16
+ - Add dependency on Abseil
+ - Set up Kokoro bots
+ - Remove Travis and Appveyor bot support
+ - Avoid hardcoding an exact C++11 requirement at project level.
+ - Avoid subtracting iterators from different string views
 
 v2019.1 2020-06-16
  - Build/CI/release updates

+ 8 - 3
ThirdParty/SpirvTools/external/effcee/CMakeLists.txt

@@ -1,9 +1,14 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.22.1)
 project(effcee C CXX)
 enable_testing()
 
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
+# Require at least C++17
+if(NOT CMAKE_CXX_STANDARD)
+  set(CMAKE_CXX_STANDARD 17)
+endif()
+if(${CMAKE_CXX_STANDARD} LESS 17)
+	message(FATAL_ERROR "Effcee requires C++17 or later, but is configured for C++${CMAKE_CXX_STANDARD})")
+endif()
 
 option(EFFCEE_BUILD_TESTING "Enable testing for Effcee" ON)
 if(${EFFCEE_BUILD_TESTING})

+ 7 - 5
ThirdParty/SpirvTools/external/effcee/README.md

@@ -1,7 +1,5 @@
 # Effcee
 
-[![Linux and OSX Build Status](https://travis-ci.org/google/effcee.svg)](https://travis-ci.org/google/effcee "Linux and OSX Build Status")
-
 Effcee is a C++ library for stateful pattern matching of strings, inspired by
 LLVM's [FileCheck][FileCheck] command.
 
@@ -14,6 +12,7 @@ Effcee:
 -   Has few dependencies:
     -   The C++11 standard library, and
     -   [RE2][RE2] for regular expression matching.
+    -   [Abseil][Abseil] utilities for C++ (via RE2).
 
 ## Example
 
@@ -129,7 +128,9 @@ more information. See also the [`AUTHORS`](AUTHORS) and
 -   `third_party/`: third party open source packages, downloaded separately
 -   [`examples/`](examples): example programs
 
-Effcee depends on the [RE2][RE2] regular expression library.
+Effcee depends on:
+* the [RE2][RE2] regular expression library.
+* the [Abseil][Abseil] utility library for C++.
 
 Effcee tests depend on [Googletest][Googletest] and [Python 3][Python].
 
@@ -145,6 +146,7 @@ git clone https://github.com/google/effcee $SOURCE_DIR
 cd $SOURCE_DIR/third_party
 git clone https://github.com/google/googletest.git
 git clone https://github.com/google/re2.git
+git clone https://github.com/abseil/abseil-cpp.git
 cd $SOURCE_DIR/
 ```
 
@@ -256,8 +258,7 @@ runtime libraries.
 
 On Windows, the following tools should be installed and available on your path:
 
--   Visual Studio 2015 or later. Previous versions of Visual Studio are not
-    usable with RE2 or Googletest.
+-   Visual Studio 2022 or later. Support for VS 2019 is deprecated.
 -   Git - including the associated tools, Bash, `diff`.
 
 ### Build options
@@ -303,4 +304,5 @@ We track bugs using GitHub -- click on the "Issues" button on
 [MinGW]: http://www.mingw.org/
 [Python]: https://www.python.org/
 [RE2]: https://github.com/google/re2
+[Abseil]: https://github.com/abseil/abseil-cpp
 [SPIRV-Tools]: https://github.com/KhronosGroup/SPIRV-Tools

+ 0 - 16
ThirdParty/SpirvTools/external/effcee/WORKSPACE

@@ -1,17 +1 @@
 workspace(name = "effcee")
-
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-
-http_archive(
-    name = "com_google_googletest",
-    strip_prefix = "googletest-release-1.12.1",
-    urls = ["https://github.com/google/googletest/archive/refs/tags/release-1.12.1.zip"],
-    sha256 = "24564e3b712d3eb30ac9a85d92f7d720f60cc0173730ac166f27dda7fed76cb2"
-)
-
-http_archive(
-    name = "com_googlesource_code_re2",
-    strip_prefix = "re2-2022-12-01",
-    urls = ["https://github.com/google/re2/archive/refs/tags/2022-12-01.zip"],
-    sha256 = "0a6cc63356915057f8fceb4224355507e24591dc84eea5c0241b5f57daa02e6f",
-)

+ 3 - 11
ThirdParty/SpirvTools/external/effcee/cmake/setup_build.cmake

@@ -18,7 +18,7 @@ if(NOT COMMAND find_host_package)
   endmacro()
 endif()
 
-find_host_package(PythonInterp 3 REQUIRED)
+find_host_package(Python3)
 
 option(DISABLE_RTTI "Disable RTTI in builds")
 if(DISABLE_RTTI)
@@ -47,15 +47,7 @@ if(WIN32)
 	 "Use the shared CRT with MSVC instead of the static CRT"
 	 ${EFFCEE_ENABLE_SHARED_CRT})
   if (NOT EFFCEE_ENABLE_SHARED_CRT)
-    if(MSVC)
-      # Link executables statically by replacing /MD with /MT everywhere.
-      foreach(flag_var
-	  CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
-	  CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
-	if(${flag_var} MATCHES "/MD")
-	  string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
-	endif(${flag_var} MATCHES "/MD")
-      endforeach(flag_var)
-    endif(MSVC)
+    # Tell MSVC to Link executables statically.
+    set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
   endif(NOT EFFCEE_ENABLE_SHARED_CRT)
 endif(WIN32)

+ 2 - 2
ThirdParty/SpirvTools/external/effcee/cmake/utils.cmake

@@ -49,9 +49,9 @@ endfunction(effcee_default_c_compile_options)
 
 function(effcee_default_compile_options TARGET)
   effcee_default_c_compile_options(${TARGET})
+  # RE2's public header requires C++11.  So publicly require C++11
+  target_compile_features(${TARGET} PUBLIC cxx_std_11)
   if (NOT "${MSVC}")
-    # RE2's public header requires C++11.  So publicly required C++11
-    target_compile_options(${TARGET} PUBLIC -std=c++11)
     if (NOT EFFCEE_ENABLE_SHARED_CRT)
       if (WIN32)
         # For MinGW cross compile, statically link to the C++ runtime.

+ 1 - 0
ThirdParty/SpirvTools/external/effcee/effcee/CMakeLists.txt

@@ -6,6 +6,7 @@ effcee_default_compile_options(effcee)
 target_include_directories(effcee
   PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/.. ${EFFCEE_RE2_DIR})
 target_link_libraries(effcee PUBLIC re2 ${CMAKE_THREADS_LIB_INIT})
+set_target_properties(effcee PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
 
 # TODO(dneto): Avoid installing gtest and gtest_main. ?!
 install(

+ 12 - 4
ThirdParty/SpirvTools/external/effcee/effcee/check.cc

@@ -102,8 +102,15 @@ bool Check::Matches(StringPiece* input, StringPiece* captured,
 
   std::unordered_map<int, std::string> var_def_indices;
 
+  // Construct a regex for the check patterns.  Anchor to the start
+  // of the input string, but also match any prefix. Do this so we
+  // can easily skip over any prefix without having to re-match the
+  // text.
   std::ostringstream consume_regex;
-  int num_captures = 1;  // The outer capture.
+  // Match any minimal prefix, then start a constructed grouping for the
+  // pattern of interest.
+  consume_regex << ".*?(";
+  int num_captures = 2;  // The outer capture, and the constructed capture.
   for (auto& part : parts_) {
     consume_regex << part->Regex(*vars);
     const auto var_def_name = part->VarDefName();
@@ -112,13 +119,14 @@ bool Check::Matches(StringPiece* input, StringPiece* captured,
     }
     num_captures += part->NumCapturingGroups();
   }
+  consume_regex << ")";  // Finish the constructed grouping.
   std::unique_ptr<StringPiece[]> captures(new StringPiece[num_captures]);
   const bool matched = RE2(consume_regex.str())
-                           .Match(*input, 0, input->size(), RE2::UNANCHORED,
+                           .Match(*input, 0, input->size(), RE2::ANCHOR_START,
                                   captures.get(), num_captures);
   if (matched) {
-    *captured = captures[0];
-    input->remove_prefix(captured->end() - input->begin());
+    *captured = captures[1];
+    input->remove_prefix(captures[0].size());
     // Update the variable mapping.
     for (auto& var_def_index : var_def_indices) {
       const int index = var_def_index.first;

+ 3 - 2
ThirdParty/SpirvTools/external/effcee/effcee/cursor.h

@@ -77,13 +77,14 @@ inline std::string LineMessage(StringPiece text, StringPiece subtext,
                                StringPiece message) {
   Cursor c(text);
   StringPiece full_line = c.RestOfLine();
-  while (subtext.end() - full_line.end() > 0) {
+  const auto* subtext_end = subtext.data() + subtext.size();
+  while (subtext_end - (full_line.data() + full_line.size()) > 0) {
     c.AdvanceLine();
     full_line = c.RestOfLine();
   }
   const char* full_line_newline =
       full_line.find('\n') == StringPiece::npos ? "\n" : "";
-  const size_t column = subtext.begin() - full_line.begin();
+  const auto column = size_t(subtext.data() - full_line.data());
 
   std::ostringstream out;
   out << ":" << c.line_num() << ":" << (1 + column) << ": " << message << "\n"

+ 14 - 14
ThirdParty/SpirvTools/external/effcee/effcee/cursor_test.cc

@@ -35,7 +35,7 @@ TEST(Cursor, AdvanceReturnsTheCursorItself) {
 TEST(Cursor, RemainingBeginsEqualToText) {
   const char* original = "The Smiths";
   Cursor c(original);
-  EXPECT_THAT(c.remaining().begin(), Eq(original));
+  EXPECT_THAT(c.remaining().data(), Eq(original));
 }
 
 TEST(Cursor, RemainingDiminishesByPreviousAdvanceCalls) {
@@ -43,13 +43,13 @@ TEST(Cursor, RemainingDiminishesByPreviousAdvanceCalls) {
   Cursor c(original);
   c.Advance(4);
   EXPECT_THAT(c.remaining(), Eq("Smiths are a great 80s band"));
-  EXPECT_THAT(c.remaining().begin(), Eq(original + 4));
+  EXPECT_THAT(c.remaining().data(), Eq(original + 4));
   c.Advance(11);
   EXPECT_THAT(c.remaining(), Eq("a great 80s band"));
-  EXPECT_THAT(c.remaining().begin(), Eq(original + 15));
+  EXPECT_THAT(c.remaining().data(), Eq(original + 15));
   c.Advance(c.remaining().size());
   EXPECT_THAT(c.remaining(), Eq(""));
-  EXPECT_THAT(c.remaining().begin(), Eq(original + 31));
+  EXPECT_THAT(c.remaining().data(), Eq(original + 31));
 }
 
 // Exhausted method
@@ -74,7 +74,7 @@ TEST(Cursor, RestOfLineOnEmptyReturnsEmpty) {
   const char* original = "";
   Cursor c(original);
   EXPECT_THAT(c.RestOfLine(), Eq(""));
-  EXPECT_THAT(c.RestOfLine().begin(), Eq(original));
+  EXPECT_THAT(c.RestOfLine().data(), Eq(original));
 }
 
 TEST(Cursor, RestOfLineWithoutNewline) {
@@ -108,15 +108,15 @@ TEST(Cursor, AdvanceLineWalksThroughTextByLineAndCountsLines) {
   c.AdvanceLine();
   EXPECT_THAT(c.line_num(), Eq(2));
   EXPECT_THAT(c.remaining(), Eq("Of an era\nIs here"));
-  EXPECT_THAT(c.remaining().begin(), Eq(original + 8));
+  EXPECT_THAT(c.remaining().data(), Eq(original + 8));
   c.AdvanceLine();
   EXPECT_THAT(c.line_num(), Eq(3));
   EXPECT_THAT(c.remaining(), Eq("Is here"));
-  EXPECT_THAT(c.remaining().begin(), Eq(original + 18));
+  EXPECT_THAT(c.remaining().data(), Eq(original + 18));
   c.AdvanceLine();
   EXPECT_THAT(c.line_num(), Eq(4));
   EXPECT_THAT(c.remaining(), Eq(""));
-  EXPECT_THAT(c.remaining().begin(), Eq(original + 25));
+  EXPECT_THAT(c.remaining().data(), Eq(original + 25));
 }
 
 TEST(Cursor, AdvanceLineIsNoopAfterEndIsReached) {
@@ -136,42 +136,42 @@ TEST(Cursor, AdvanceLineIsNoopAfterEndIsReached) {
 
 TEST(LineMessage, SubtextIsFirst) {
   StringPiece text("Foo\nBar");
-  StringPiece subtext(text.begin(), 3);
+  StringPiece subtext(text.data(), 3);
   EXPECT_THAT(LineMessage(text, subtext, "loves quiche"),
               Eq(":1:1: loves quiche\nFoo\n^\n"));
 }
 
 TEST(LineMessage, SubtextDoesNotEndInNewline) {
   StringPiece text("Foo\nBar");
-  StringPiece subtext(text.begin()+4, 3);
+  StringPiece subtext(text.data() + 4, 3);
   EXPECT_THAT(LineMessage(text, subtext, "loves quiche"),
               Eq(":2:1: loves quiche\nBar\n^\n"));
 }
 
 TEST(LineMessage, SubtextPartwayThroughItsLine) {
   StringPiece text("Food Life\nBar");
-  StringPiece subtext(text.begin() + 5, 3); // "Lif"
+  StringPiece subtext(text.data() + 5, 3);  // "Lif"
   EXPECT_THAT(LineMessage(text, subtext, "loves quiche"),
               Eq(":1:6: loves quiche\nFood Life\n     ^\n"));
 }
 
 TEST(LineMessage, SubtextOnSubsequentLine) {
   StringPiece text("Food Life\nBar Fight\n");
-  StringPiece subtext(text.begin() + 14, 5); // "Fight"
+  StringPiece subtext(text.data() + 14, 5);  // "Fight"
   EXPECT_THAT(LineMessage(text, subtext, "loves quiche"),
               Eq(":2:5: loves quiche\nBar Fight\n    ^\n"));
 }
 
 TEST(LineMessage, SubtextIsEmptyAndInMiddle) {
   StringPiece text("Food");
-  StringPiece subtext(text.begin() + 2, 0);
+  StringPiece subtext(text.data() + 2, 0);
   EXPECT_THAT(LineMessage(text, subtext, "loves quiche"),
               Eq(":1:3: loves quiche\nFood\n  ^\n"));
 }
 
 TEST(LineMessage, SubtextIsEmptyAndAtVeryEnd) {
   StringPiece text("Food");
-  StringPiece subtext(text.begin() + 4, 0);
+  StringPiece subtext(text.data() + 4, 0);
   EXPECT_THAT(LineMessage(text, subtext, "loves quiche"),
               Eq(":1:5: loves quiche\nFood\n    ^\n"));
 }

+ 1 - 1
ThirdParty/SpirvTools/external/effcee/effcee/effcee.h

@@ -25,7 +25,7 @@ namespace effcee {
 // This does not implement the equivalents of FileCheck options:
 //   --match-full-lines
 //   --strict-whitespace
-//   --implicit-ch3eck-not
+//   --implicit-check-not
 //   --enable-var-scope
 
 using StringPiece = re2::StringPiece;

+ 1 - 1
ThirdParty/SpirvTools/external/effcee/effcee/match.cc

@@ -178,7 +178,7 @@ Result Match(StringPiece input, StringPiece checks, const Options& options) {
               // This must be valid since there was an intervening line.
               const auto non_match =
                   Cursor(input)
-                      .Advance(previous_match_end.begin() - input.begin())
+                      .Advance(previous_match_end.data() - input.data())
                       .AdvanceLine()
                       .RestOfLine();
 

+ 1 - 1
ThirdParty/SpirvTools/external/effcee/examples/CMakeLists.txt

@@ -13,7 +13,7 @@ endif(WIN32 AND NOT MSVC)
 
 if(EFFCEE_BUILD_TESTING)
   add_test(NAME effcee-example
-           COMMAND ${PYTHON_EXECUTABLE}
+                  COMMAND Python3::Interpreter
                   effcee-example-driver.py
                   $<TARGET_FILE:effcee-example>
                   example_data.txt

+ 24 - 0
ThirdParty/SpirvTools/external/effcee/third_party/CMakeLists.txt

@@ -14,6 +14,18 @@ else()
           "Location of googletest source")
 endif()
 
+# Find abseil
+if(absl_SOURCE_DIR)
+  set(EFFCEE_ABSEIL_DIR "${absl_SOURCE_DIR}" CACHE STRING "Location of abseil source" FORCE)
+else()
+  # Allow for abseil-cpp or abseil_cpp
+  if (IS_DIRECTORY "${EFFCEE_THIRD_PARTY_ROOT_DIR}/abseil_cpp")
+    set(EFFCEE_ABSEIL_DIR "${EFFCEE_THIRD_PARTY_ROOT_DIR}/abseil_cpp" CACHE STRING "Location of abseil source")
+  elseif(IS_DIRECTORY "${EFFCEE_THIRD_PARTY_ROOT_DIR}/abseil-cpp")
+    set(EFFCEE_ABSEIL_DIR "${EFFCEE_THIRD_PARTY_ROOT_DIR}/abseil-cpp" CACHE STRING "Location of abseil source")
+  endif()
+endif()
+
 # Find re2
 if(RE2_SOURCE_DIR)
   set(EFFCEE_RE2_DIR "${RE2_SOURCE_DIR}" CACHE STRING "Location of re2 source" FORCE)
@@ -34,6 +46,18 @@ if(EFFCEE_BUILD_TESTING)
   endif()
 endif()
 
+if (NOT TARGET absl::base)
+  if (IS_DIRECTORY ${EFFCEE_ABSEIL_DIR})
+    set(ABSL_INTERNAL_AT_LEAST_CXX17 ON)
+    set(ABSL_PROPAGATE_CXX_STD ON)
+    set(ABSL_ENABLE_INSTALL ON)
+    add_subdirectory(${EFFCEE_ABSEIL_DIR} absl EXCLUDE_FROM_ALL)
+  endif()
+endif()
+if (NOT TARGET absl::base)
+  message(FATAL_ERROR "absl was not found - required for compilation")
+endif()
+
 if (NOT TARGET re2)
   if (IS_DIRECTORY ${EFFCEE_RE2_DIR})
     add_subdirectory(${EFFCEE_RE2_DIR} re2 EXCLUDE_FROM_ALL)

+ 44 - 12
ThirdParty/SpirvTools/external/googletest/BUILD.bazel

@@ -56,6 +56,12 @@ config_setting(
     constraint_values = ["@platforms//os:openbsd"],
 )
 
+# NOTE: Fuchsia is not an officially supported platform.
+config_setting(
+    name = "fuchsia",
+    constraint_values = ["@platforms//os:fuchsia"],
+)
+
 config_setting(
     name = "msvc_compiler",
     flag_values = {
@@ -77,6 +83,10 @@ cc_library(
 )
 
 # Google Test including Google Mock
+
+# For an actual test, use `gtest` and also `gtest_main` if you depend on gtest's
+# main(). For a library, use `gtest_for_library` instead if the library can be
+# testonly.
 cc_library(
     name = "gtest",
     srcs = glob(
@@ -132,23 +142,45 @@ cc_library(
     }),
     deps = select({
         ":has_absl": [
-            "@com_google_absl//absl/debugging:failure_signal_handler",
-            "@com_google_absl//absl/debugging:stacktrace",
-            "@com_google_absl//absl/debugging:symbolize",
-            "@com_google_absl//absl/flags:flag",
-            "@com_google_absl//absl/flags:parse",
-            "@com_google_absl//absl/flags:reflection",
-            "@com_google_absl//absl/flags:usage",
-            "@com_google_absl//absl/strings",
-            "@com_google_absl//absl/types:any",
-            "@com_google_absl//absl/types:optional",
-            "@com_google_absl//absl/types:variant",
-            "@com_googlesource_code_re2//:re2",
+            "@abseil-cpp//absl/container:flat_hash_set",
+            "@abseil-cpp//absl/debugging:failure_signal_handler",
+            "@abseil-cpp//absl/debugging:stacktrace",
+            "@abseil-cpp//absl/debugging:symbolize",
+            "@abseil-cpp//absl/flags:flag",
+            "@abseil-cpp//absl/flags:parse",
+            "@abseil-cpp//absl/flags:reflection",
+            "@abseil-cpp//absl/flags:usage",
+            "@abseil-cpp//absl/strings",
+            "@abseil-cpp//absl/types:any",
+            "@abseil-cpp//absl/types:optional",
+            "@abseil-cpp//absl/types:variant",
+            "@re2//:re2",
+        ],
+        "//conditions:default": [],
+    }) + select({
+        # `gtest-death-test.cc` has `EXPECT_DEATH` that spawns a process,
+        # expects it to crash and inspects its logs with the given matcher,
+        # so that's why these libraries are needed.
+        # Otherwise, builds targeting Fuchsia would fail to compile.
+        ":fuchsia": [
+            "@fuchsia_sdk//pkg/fdio",
+            "@fuchsia_sdk//pkg/syslog",
+            "@fuchsia_sdk//pkg/zx",
         ],
         "//conditions:default": [],
     }),
 )
 
+# `gtest`, but testonly. See guidance on `gtest` for when to use this.
+alias(
+    name = "gtest_for_library",
+    actual = ":gtest",
+    testonly = True,
+)
+
+# Implements main() for tests using gtest. Prefer to depend on `gtest` as well
+# to ensure compliance with the layering_check Bazel feature where only the
+# direct hdrs values are available.
 cc_library(
     name = "gtest_main",
     srcs = ["googlemock/src/gmock_main.cc"],

+ 12 - 15
ThirdParty/SpirvTools/external/googletest/CMakeLists.txt

@@ -1,22 +1,10 @@
 # Note: CMake support is community-based. The maintainers do not use CMake
 # internally.
 
-cmake_minimum_required(VERSION 3.5)
-
-if (POLICY CMP0048)
-  cmake_policy(SET CMP0048 NEW)
-endif (POLICY CMP0048)
-
-if (POLICY CMP0069)
-  cmake_policy(SET CMP0069 NEW)
-endif (POLICY CMP0069)
-
-if (POLICY CMP0077)
-  cmake_policy(SET CMP0077 NEW)
-endif (POLICY CMP0077)
+cmake_minimum_required(VERSION 3.16)
 
 project(googletest-distribution)
-set(GOOGLETEST_VERSION 1.13.0)
+set(GOOGLETEST_VERSION 1.16.0)
 
 if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)
   set(CMAKE_CXX_EXTENSIONS OFF)
@@ -27,11 +15,20 @@ enable_testing()
 include(CMakeDependentOption)
 include(GNUInstallDirs)
 
-#Note that googlemock target already builds googletest
+# Note that googlemock target already builds googletest.
 option(BUILD_GMOCK "Builds the googlemock subproject" ON)
 option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON)
 option(GTEST_HAS_ABSL "Use Abseil and RE2. Requires Abseil and RE2 to be separately added to the build." OFF)
 
+if(GTEST_HAS_ABSL)
+  if(NOT TARGET absl::base)
+    find_package(absl REQUIRED)
+  endif()
+  if(NOT TARGET re2::re2)
+    find_package(re2 REQUIRED)
+  endif()
+endif()
+
 if(BUILD_GMOCK)
   add_subdirectory( googlemock )
 else()

+ 4 - 4
ThirdParty/SpirvTools/external/googletest/CONTRIBUTING.md

@@ -47,11 +47,11 @@ PR is acceptable as an alternative.
 ## The Google Test and Google Mock Communities
 
 The Google Test community exists primarily through the
-[discussion group](http://groups.google.com/group/googletestframework) and the
+[discussion group](https://groups.google.com/group/googletestframework) and the
 GitHub repository. Likewise, the Google Mock community exists primarily through
-their own [discussion group](http://groups.google.com/group/googlemock). You are
-definitely encouraged to contribute to the discussion and you can also help us
-to keep the effectiveness of the group high by following and promoting the
+their own [discussion group](https://groups.google.com/group/googlemock). You
+are definitely encouraged to contribute to the discussion and you can also help
+us to keep the effectiveness of the group high by following and promoting the
 guidelines listed here.
 
 ### Please Be Friendly

+ 1 - 0
ThirdParty/SpirvTools/external/googletest/CONTRIBUTORS

@@ -55,6 +55,7 @@ Russ Cox <[email protected]>
 Russ Rufer <[email protected]>
 Sean Mcafee <[email protected]>
 Sigurður Ásgeirsson <[email protected]>
+Soyeon Kim <[email protected]>
 Sverre Sundsdal <[email protected]>
 Szymon Sobik <[email protected]>
 Takeshi Yoshino <[email protected]>

+ 45 - 23
ThirdParty/SpirvTools/external/googletest/README.md

@@ -8,6 +8,8 @@ GoogleTest now follows the
 [Abseil Live at Head philosophy](https://abseil.io/about/philosophy#upgrade-support).
 We recommend
 [updating to the latest commit in the `main` branch as often as possible](https://github.com/abseil/abseil-cpp/blob/master/FAQ.md#what-is-live-at-head-and-how-do-i-do-it).
+We do publish occasional semantic versions, tagged with
+`v${major}.${minor}.${patch}` (e.g. `v1.16.0`).
 
 #### Documentation Updates
 
@@ -15,25 +17,24 @@ Our documentation is now live on GitHub Pages at
 https://google.github.io/googletest/. We recommend browsing the documentation on
 GitHub Pages rather than directly in the repository.
 
-#### Release 1.13.0
+#### Release 1.16.0
 
-[Release 1.13.0](https://github.com/google/googletest/releases/tag/v1.13.0) is
+[Release 1.16.0](https://github.com/google/googletest/releases/tag/v1.16.0) is
 now available.
 
-The 1.13.x branch requires at least C++14.
+The 1.16.x branch requires at least C++14.
+
+The 1.16.x branch will be the last to support C++14. Future development will
+[require at least C++17](https://opensource.google/documentation/policies/cplusplus-support#c_language_standard).
 
 #### Continuous Integration
 
-We use Google's internal systems for continuous integration. \
-GitHub Actions were added for the convenience of open source contributors. They
-are exclusively maintained by the open source community and not used by the
-GoogleTest team.
+We use Google's internal systems for continuous integration.
 
 #### Coming Soon
 
 *   We are planning to take a dependency on
     [Abseil](https://github.com/abseil/abseil-cpp).
-*   More documentation improvements are planned.
 
 ## Welcome to **GoogleTest**, Google's C++ test framework!
 
@@ -52,16 +53,37 @@ More information about building GoogleTest can be found at
 
 ## Features
 
-*   An [xUnit](https://en.wikipedia.org/wiki/XUnit) test framework.
-*   Test discovery.
-*   A rich set of assertions.
-*   User-defined assertions.
-*   Death tests.
-*   Fatal and non-fatal failures.
-*   Value-parameterized tests.
-*   Type-parameterized tests.
-*   Various options for running the tests.
-*   XML test report generation.
+*   xUnit test framework: \
+    Googletest is based on the [xUnit](https://en.wikipedia.org/wiki/XUnit)
+    testing framework, a popular architecture for unit testing
+*   Test discovery: \
+    Googletest automatically discovers and runs your tests, eliminating the need
+    to manually register your tests
+*   Rich set of assertions: \
+    Googletest provides a variety of assertions, such as equality, inequality,
+    exceptions, and more, making it easy to test your code
+*   User-defined assertions: \
+    You can define your own assertions with Googletest, making it simple to
+    write tests that are specific to your code
+*   Death tests: \
+    Googletest supports death tests, which verify that your code exits in a
+    certain way, making it useful for testing error-handling code
+*   Fatal and non-fatal failures: \
+    You can specify whether a test failure should be treated as fatal or
+    non-fatal with Googletest, allowing tests to continue running even if a
+    failure occurs
+*   Value-parameterized tests: \
+    Googletest supports value-parameterized tests, which run multiple times with
+    different input values, making it useful for testing functions that take
+    different inputs
+*   Type-parameterized tests: \
+    Googletest also supports type-parameterized tests, which run with different
+    data types, making it useful for testing functions that work with different
+    data types
+*   Various options for running tests: \
+    Googletest provides many options for running tests including running
+    individual tests, running tests in a specific order and running tests in
+    parallel
 
 ## Supported Platforms
 
@@ -69,7 +91,7 @@ GoogleTest follows Google's
 [Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support).
 See
 [this table](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md)
-for a list of currently supported versions compilers, platforms, and build
+for a list of currently supported versions of compilers, platforms, and build
 tools.
 
 ## Who Is Using GoogleTest?
@@ -77,12 +99,12 @@ tools.
 In addition to many internal projects at Google, GoogleTest is also used by the
 following notable projects:
 
-*   The [Chromium projects](http://www.chromium.org/) (behind the Chrome browser
-    and Chrome OS).
-*   The [LLVM](http://llvm.org/) compiler.
+*   The [Chromium projects](https://www.chromium.org/) (behind the Chrome
+    browser and Chrome OS).
+*   The [LLVM](https://llvm.org/) compiler.
 *   [Protocol Buffers](https://github.com/google/protobuf), Google's data
     interchange format.
-*   The [OpenCV](http://opencv.org/) computer vision library.
+*   The [OpenCV](https://opencv.org/) computer vision library.
 
 ## Related Open Source Projects
 

+ 49 - 28
ThirdParty/SpirvTools/external/googletest/WORKSPACE

@@ -1,40 +1,61 @@
-workspace(name = "com_google_googletest")
+# Copyright 2024 Google Inc.
+# All Rights Reserved.
+#
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+workspace(name = "googletest")
 
-http_archive(
-    name = "com_google_absl",  # 2023-01-10T21:08:25Z
-    sha256 = "f9a4e749f42c386a32a90fddf0e2913ed408d10c42f7f33ccf4c59ac4f0d1d05",
-    strip_prefix = "abseil-cpp-52835439ca90d86b27bf8cd1708296e95604d724",
-    urls = ["https://github.com/abseil/abseil-cpp/archive/52835439ca90d86b27bf8cd1708296e95604d724.zip"],
-)
+load("//:googletest_deps.bzl", "googletest_deps")
+googletest_deps()
 
-# Note this must use a commit from the `abseil` branch of the RE2 project.
-# https://github.com/google/re2/tree/abseil
-http_archive(
-    name = "com_googlesource_code_re2",  # 2022-12-21T14:29:10Z
-    sha256 = "b9ce3a51beebb38534d11d40f8928d40509b9e18a735f6a4a97ad3d014c87cb5",
-    strip_prefix = "re2-d0b1f8f2ecc2ea74956c7608b6f915175314ff0e",
-    urls = ["https://github.com/google/re2/archive/d0b1f8f2ecc2ea74956c7608b6f915175314ff0e.zip"],
-)
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
 
 http_archive(
-    name = "rules_python",  # 2023-01-10T22:00:51Z
-    sha256 = "5de54486a60ad8948dabe49605bb1c08053e04001a431ab3e96745b4d97a4419",
-    strip_prefix = "rules_python-70cce26432187a60b4e950118791385e6fb3c26f",
-    urls = ["https://github.com/bazelbuild/rules_python/archive/70cce26432187a60b4e950118791385e6fb3c26f.zip"],
+    name = "rules_python",
+    sha256 = "9c6e26911a79fbf510a8f06d8eedb40f412023cf7fa6d1461def27116bff022c",
+    strip_prefix = "rules_python-1.1.0",
+    url = "https://github.com/bazelbuild/rules_python/releases/download/1.1.0/rules_python-1.1.0.tar.gz",
 )
+# https://github.com/bazelbuild/rules_python/releases/tag/1.1.0
+load("@rules_python//python:repositories.bzl", "py_repositories")
+py_repositories()
 
 http_archive(
-    name = "bazel_skylib",  # 2022-11-16T18:29:32Z
-    sha256 = "a22290c26d29d3ecca286466f7f295ac6cbe32c0a9da3a91176a90e0725e3649",
-    strip_prefix = "bazel-skylib-5bfcb1a684550626ce138fe0fe8f5f702b3764c3",
-    urls = ["https://github.com/bazelbuild/bazel-skylib/archive/5bfcb1a684550626ce138fe0fe8f5f702b3764c3.zip"],
+  name = "bazel_skylib",
+  sha256 = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94",
+  urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz"],
 )
 
 http_archive(
-    name = "platforms",  # 2022-11-09T19:18:22Z
-    sha256 = "b4a3b45dc4202e2b3e34e3bc49d2b5b37295fc23ea58d88fb9e01f3642ad9b55",
-    strip_prefix = "platforms-3fbc687756043fb58a407c2ea8c944bc2fe1d922",
-    urls = ["https://github.com/bazelbuild/platforms/archive/3fbc687756043fb58a407c2ea8c944bc2fe1d922.zip"],
+    name = "platforms",
+    urls = [
+        "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.10/platforms-0.0.10.tar.gz",
+        "https://github.com/bazelbuild/platforms/releases/download/0.0.10/platforms-0.0.10.tar.gz",
+    ],
+    sha256 = "218efe8ee736d26a3572663b374a253c012b716d8af0c07e842e82f238a0a7ee",
 )

+ 52 - 29
ThirdParty/SpirvTools/external/googletest/ci/linux-presubmit.sh

@@ -31,39 +31,59 @@
 
 set -euox pipefail
 
-readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20220217"
-readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20220621"
+readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20241218"
+readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20250205"
 
 if [[ -z ${GTEST_ROOT:-} ]]; then
   GTEST_ROOT="$(realpath $(dirname ${0})/..)"
 fi
 
 if [[ -z ${STD:-} ]]; then
-  STD="c++14 c++17 c++20"
+  STD="c++17 c++20"
 fi
 
-# Test the CMake build
-for cc in /usr/local/bin/gcc /opt/llvm/clang/bin/clang; do
-  for cmake_off_on in OFF ON; do
-    time docker run \
-      --volume="${GTEST_ROOT}:/src:ro" \
-      --tmpfs="/build:exec" \
-      --workdir="/build" \
-      --rm \
-      --env="CC=${cc}" \
-      --env=CXXFLAGS="-Werror -Wdeprecated" \
-      ${LINUX_LATEST_CONTAINER} \
-      /bin/bash -c "
-        cmake /src \
-          -DCMAKE_CXX_STANDARD=14 \
-          -Dgtest_build_samples=ON \
-          -Dgtest_build_tests=ON \
-          -Dgmock_build_tests=ON \
-          -Dcxx_no_exception=${cmake_off_on} \
-          -Dcxx_no_rtti=${cmake_off_on} && \
-        make -j$(nproc) && \
-        ctest -j$(nproc) --output-on-failure"
-  done
+# Test CMake + GCC
+for cmake_off_on in OFF ON; do
+  time docker run \
+    --volume="${GTEST_ROOT}:/src:ro" \
+    --tmpfs="/build:exec" \
+    --workdir="/build" \
+    --rm \
+    --env="CC=/usr/local/bin/gcc" \
+    --env=CXXFLAGS="-Werror -Wdeprecated" \
+    ${LINUX_LATEST_CONTAINER} \
+    /bin/bash -c "
+      cmake /src \
+        -DCMAKE_CXX_STANDARD=17 \
+        -Dgtest_build_samples=ON \
+        -Dgtest_build_tests=ON \
+        -Dgmock_build_tests=ON \
+        -Dcxx_no_exception=${cmake_off_on} \
+        -Dcxx_no_rtti=${cmake_off_on} && \
+      make -j$(nproc) && \
+      ctest -j$(nproc) --output-on-failure"
+done
+
+# Test CMake + Clang
+for cmake_off_on in OFF ON; do
+  time docker run \
+    --volume="${GTEST_ROOT}:/src:ro" \
+    --tmpfs="/build:exec" \
+    --workdir="/build" \
+    --rm \
+    --env="CC=/opt/llvm/clang/bin/clang" \
+    --env=CXXFLAGS="-Werror -Wdeprecated --gcc-toolchain=/usr/local" \
+    ${LINUX_LATEST_CONTAINER} \
+    /bin/bash -c "
+      cmake /src \
+        -DCMAKE_CXX_STANDARD=17 \
+        -Dgtest_build_samples=ON \
+        -Dgtest_build_tests=ON \
+        -Dgmock_build_tests=ON \
+        -Dcxx_no_exception=${cmake_off_on} \
+        -Dcxx_no_rtti=${cmake_off_on} && \
+      make -j$(nproc) && \
+      ctest -j$(nproc) --output-on-failure"
 done
 
 # Do one test with an older version of GCC
@@ -72,14 +92,15 @@ time docker run \
   --workdir="/src" \
   --rm \
   --env="CC=/usr/local/bin/gcc" \
-  --env="BAZEL_CXXOPTS=-std=c++14" \
+  --env="BAZEL_CXXOPTS=-std=c++17" \
   ${LINUX_GCC_FLOOR_CONTAINER} \
     /usr/local/bin/bazel test ... \
       --copt="-Wall" \
       --copt="-Werror" \
       --copt="-Wuninitialized" \
+      --copt="-Wundef" \
       --copt="-Wno-error=pragmas" \
-      --distdir="/bazel-distdir" \
+      --enable_bzlmod=false \
       --features=external_include_paths \
       --keep_going \
       --show_timestamps \
@@ -99,8 +120,9 @@ for std in ${STD}; do
         --copt="-Wall" \
         --copt="-Werror" \
         --copt="-Wuninitialized" \
+        --copt="-Wundef" \
         --define="absl=${absl}" \
-        --distdir="/bazel-distdir" \
+        --enable_bzlmod=true \
         --features=external_include_paths \
         --keep_going \
         --show_timestamps \
@@ -123,8 +145,9 @@ for std in ${STD}; do
         --copt="-Wall" \
         --copt="-Werror" \
         --copt="-Wuninitialized" \
+        --copt="-Wundef" \
         --define="absl=${absl}" \
-        --distdir="/bazel-distdir" \
+        --enable_bzlmod=true \
         --features=external_include_paths \
         --keep_going \
         --linkopt="--gcc-toolchain=/usr/local" \

+ 9 - 4
ThirdParty/SpirvTools/external/googletest/ci/macos-presubmit.sh

@@ -31,6 +31,9 @@
 
 set -euox pipefail
 
+# Use Xcode 16.0
+sudo xcode-select -s /Applications/Xcode_16.0.app/Contents/Developer
+
 if [[ -z ${GTEST_ROOT:-} ]]; then
   GTEST_ROOT="$(realpath $(dirname ${0})/..)"
 fi
@@ -40,20 +43,20 @@ for cmake_off_on in OFF ON; do
   BUILD_DIR=$(mktemp -d build_dir.XXXXXXXX)
   cd ${BUILD_DIR}
   time cmake ${GTEST_ROOT} \
-    -DCMAKE_CXX_STANDARD=14 \
+    -DCMAKE_CXX_STANDARD=17 \
     -Dgtest_build_samples=ON \
     -Dgtest_build_tests=ON \
     -Dgmock_build_tests=ON \
     -Dcxx_no_exception=${cmake_off_on} \
     -Dcxx_no_rtti=${cmake_off_on}
-  time make
+  time make -j$(nproc)
   time ctest -j$(nproc) --output-on-failure
 done
 
 # Test the Bazel build
 
 # If we are running on Kokoro, check for a versioned Bazel binary.
-KOKORO_GFILE_BAZEL_BIN="bazel-5.1.1-darwin-x86_64"
+KOKORO_GFILE_BAZEL_BIN="bazel-8.0.0-darwin-x86_64"
 if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]]; then
   BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}"
   chmod +x ${BAZEL_BIN}
@@ -66,8 +69,10 @@ for absl in 0 1; do
   ${BAZEL_BIN} test ... \
     --copt="-Wall" \
     --copt="-Werror" \
-    --cxxopt="-std=c++14" \
+    --copt="-Wundef" \
+    --cxxopt="-std=c++17" \
     --define="absl=${absl}" \
+    --enable_bzlmod=true \
     --features=external_include_paths \
     --keep_going \
     --show_timestamps \

+ 42 - 23
ThirdParty/SpirvTools/external/googletest/ci/windows-presubmit.bat

@@ -1,29 +1,28 @@
 SETLOCAL ENABLEDELAYEDEXPANSION
 
-SET BAZEL_EXE=%KOKORO_GFILE_DIR%\bazel-5.1.1-windows-x86_64.exe
+SET BAZEL_EXE=%KOKORO_GFILE_DIR%\bazel-8.0.0-windows-x86_64.exe
 
-SET PATH=C:\Python37;%PATH%
-SET BAZEL_PYTHON=C:\python37\python.exe
+SET PATH=C:\Python34;%PATH%
+SET BAZEL_PYTHON=C:\python34\python.exe
 SET BAZEL_SH=C:\tools\msys64\usr\bin\bash.exe
-SET CMAKE_BIN="C:\Program Files\CMake\bin\cmake.exe"
-SET CTEST_BIN="C:\Program Files\CMake\bin\ctest.exe"
+SET CMAKE_BIN="cmake.exe"
+SET CTEST_BIN="ctest.exe"
 SET CTEST_OUTPUT_ON_FAILURE=1
+SET CMAKE_BUILD_PARALLEL_LEVEL=16
+SET CTEST_PARALLEL_LEVEL=16
 
-IF EXIST git\googletest (
-  CD git\googletest
-) ELSE IF EXIST github\googletest (
-  CD github\googletest
-)
-
+SET GTEST_ROOT=%~dp0\..
 IF %errorlevel% neq 0 EXIT /B 1
 
 :: ----------------------------------------------------------------------------
-:: CMake Visual Studio 15 2017 Win64
-MKDIR cmake_msvc2017
-CD cmake_msvc2017
+:: CMake
+SET CMAKE_BUILD_PATH=cmake_msvc2022
+MKDIR %CMAKE_BUILD_PATH%
+CD %CMAKE_BUILD_PATH%
 
-%CMAKE_BIN% .. ^
-  -G "Visual Studio 15 2017 Win64" ^
+%CMAKE_BIN% %GTEST_ROOT% ^
+  -G "Visual Studio 17 2022" ^
+  -DCMAKE_CXX_STANDARD=17 ^
   -DPYTHON_EXECUTABLE:FILEPATH=c:\python37\python.exe ^
   -DPYTHON_INCLUDE_DIR:PATH=c:\python37\include ^
   -DPYTHON_LIBRARY:FILEPATH=c:\python37\lib\site-packages\pip ^
@@ -38,18 +37,38 @@ IF %errorlevel% neq 0 EXIT /B 1
 %CTEST_BIN% -C Debug --timeout 600
 IF %errorlevel% neq 0 EXIT /B 1
 
-CD ..
-RMDIR /S /Q cmake_msvc2017
+CD %GTEST_ROOT%
+RMDIR /S /Q %CMAKE_BUILD_PATH%
 
 :: ----------------------------------------------------------------------------
-:: Bazel Visual Studio 15 2017 Win64
+:: Bazel
+
+:: The default home directory on Kokoro is a long path which causes errors
+:: because of Windows limitations on path length.
+:: --output_user_root=C:\tmp causes Bazel to use a shorter path.
+SET BAZEL_VS=C:\Program Files\Microsoft Visual Studio\2022\Community
+
+:: C++17
+%BAZEL_EXE% ^
+  --output_user_root=C:\tmp ^
+  test ... ^
+  --compilation_mode=dbg ^
+  --copt=/std:c++17 ^
+  --copt=/WX ^
+  --enable_bzlmod=true ^
+  --keep_going ^
+  --test_output=errors ^
+  --test_tag_filters=-no_test_msvc2017
+IF %errorlevel% neq 0 EXIT /B 1
 
-SET BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC
-%BAZEL_EXE% test ... ^
+:: C++20
+%BAZEL_EXE% ^
+  --output_user_root=C:\tmp ^
+  test ... ^
   --compilation_mode=dbg ^
-  --copt=/std:c++14 ^
+  --copt=/std:c++20 ^
   --copt=/WX ^
-  --features=external_include_paths ^
+  --enable_bzlmod=true ^
   --keep_going ^
   --test_output=errors ^
   --test_tag_filters=-no_test_msvc2017

+ 203 - 150
ThirdParty/SpirvTools/external/googletest/docs/advanced.md

@@ -1,9 +1,9 @@
-# Advanced googletest Topics
+# Advanced GoogleTest Topics
 
 ## Introduction
 
-Now that you have read the [googletest Primer](primer.md) and learned how to
-write tests using googletest, it's time to learn some new tricks. This document
+Now that you have read the [GoogleTest Primer](primer.md) and learned how to
+write tests using GoogleTest, it's time to learn some new tricks. This document
 will show you more assertions as well as how to construct complex failure
 messages, propagate fatal failures, reuse and speed up your test fixtures, and
 use various flags with your tests.
@@ -25,7 +25,7 @@ Reference.
 
 ### Predicate Assertions for Better Error Messages
 
-Even though googletest has a rich set of assertions, they can never be complete,
+Even though GoogleTest has a rich set of assertions, they can never be complete,
 as it's impossible (nor a good idea) to anticipate all scenarios a user might
 run into. Therefore, sometimes a user has to use `EXPECT_TRUE()` to check a
 complex expression, for lack of a better macro. This has the problem of not
@@ -35,7 +35,7 @@ failure message by themselves, streaming it into `EXPECT_TRUE()`. However, this
 is awkward especially when the expression has side-effects or is expensive to
 evaluate.
 
-googletest gives you three different options to solve this problem:
+GoogleTest gives you three different options to solve this problem:
 
 #### Using an Existing Boolean Function
 
@@ -286,7 +286,7 @@ For example:
 ```c++
 TEST(SkipTest, DoesSkip) {
   GTEST_SKIP() << "Skipping single test";
-  EXPECT_EQ(0, 1);  // Won't fail; it won't be executed
+  FAIL();  // Won't fail; it won't be executed
 }
 
 class SkipFixture : public ::testing::Test {
@@ -298,15 +298,15 @@ class SkipFixture : public ::testing::Test {
 
 // Tests for SkipFixture won't be executed.
 TEST_F(SkipFixture, SkipsOneTest) {
-  EXPECT_EQ(5, 7);  // Won't fail
+  FAIL();  // Won't fail; it won't be executed
 }
 ```
 
 As with assertion macros, you can stream a custom message into `GTEST_SKIP()`.
 
-## Teaching googletest How to Print Your Values
+## Teaching GoogleTest How to Print Your Values
 
-When a test assertion such as `EXPECT_EQ` fails, googletest prints the argument
+When a test assertion such as `EXPECT_EQ` fails, GoogleTest prints the argument
 values to help you debug. It does this using a user-extensible value printer.
 
 This printer knows how to print built-in C++ types, native arrays, STL
@@ -315,73 +315,141 @@ prints the raw bytes in the value and hopes that you the user can figure it out.
 
 As mentioned earlier, the printer is *extensible*. That means you can teach it
 to do a better job at printing your particular type than to dump the bytes. To
-do that, define `<<` for your type:
-
-```c++
-#include <ostream>
+do that, define an `AbslStringify()` overload as a `friend` function template
+for your type:
 
+```cpp
 namespace foo {
 
-class Bar {  // We want googletest to be able to print instances of this.
-...
-  // Create a free inline friend function.
-  friend std::ostream& operator<<(std::ostream& os, const Bar& bar) {
-    return os << bar.DebugString();  // whatever needed to print bar to os
+class Point {  // We want GoogleTest to be able to print instances of this.
+  ...
+  // Provide a friend overload.
+  template <typename Sink>
+  friend void AbslStringify(Sink& sink, const Point& point) {
+    absl::Format(&sink, "(%d, %d)", point.x, point.y);
   }
+
+  int x;
+  int y;
 };
 
 // If you can't declare the function in the class it's important that the
-// << operator is defined in the SAME namespace that defines Bar.  C++'s look-up
-// rules rely on that.
-std::ostream& operator<<(std::ostream& os, const Bar& bar) {
-  return os << bar.DebugString();  // whatever needed to print bar to os
+// AbslStringify overload is defined in the SAME namespace that defines Point.
+// C++'s look-up rules rely on that.
+enum class EnumWithStringify { kMany = 0, kChoices = 1 };
+
+template <typename Sink>
+void AbslStringify(Sink& sink, EnumWithStringify e) {
+  absl::Format(&sink, "%s", e == EnumWithStringify::kMany ? "Many" : "Choices");
 }
 
 }  // namespace foo
 ```
 
-Sometimes, this might not be an option: your team may consider it bad style to
-have a `<<` operator for `Bar`, or `Bar` may already have a `<<` operator that
-doesn't do what you want (and you cannot change it). If so, you can instead
-define a `PrintTo()` function like this:
+{: .callout .note}
+Note: `AbslStringify()` utilizes a generic "sink" buffer to construct its
+string. For more information about supported operations on `AbslStringify()`'s
+sink, see go/abslstringify.
+
+`AbslStringify()` can also use `absl::StrFormat`'s catch-all `%v` type specifier
+within its own format strings to perform type deduction. `Point` above could be
+formatted as `"(%v, %v)"` for example, and deduce the `int` values as `%d`.
+
+Sometimes, `AbslStringify()` might not be an option: your team may wish to print
+types with extra debugging information for testing purposes only. If so, you can
+instead define a `PrintTo()` function like this:
 
 ```c++
 #include <ostream>
 
 namespace foo {
 
-class Bar {
+class Point {
   ...
-  friend void PrintTo(const Bar& bar, std::ostream* os) {
-    *os << bar.DebugString();  // whatever needed to print bar to os
+  friend void PrintTo(const Point& point, std::ostream* os) {
+    *os << "(" << point.x << "," << point.y << ")";
   }
+
+  int x;
+  int y;
 };
 
 // If you can't declare the function in the class it's important that PrintTo()
-// is defined in the SAME namespace that defines Bar.  C++'s look-up rules rely
-// on that.
-void PrintTo(const Bar& bar, std::ostream* os) {
-  *os << bar.DebugString();  // whatever needed to print bar to os
+// is defined in the SAME namespace that defines Point.  C++'s look-up rules
+// rely on that.
+void PrintTo(const Point& point, std::ostream* os) {
+    *os << "(" << point.x << "," << point.y << ")";
 }
 
 }  // namespace foo
 ```
 
-If you have defined both `<<` and `PrintTo()`, the latter will be used when
-googletest is concerned. This allows you to customize how the value appears in
-googletest's output without affecting code that relies on the behavior of its
-`<<` operator.
+If you have defined both `AbslStringify()` and `PrintTo()`, the latter will be
+used by GoogleTest. This allows you to customize how the value appears in
+GoogleTest's output without affecting code that relies on the behavior of
+`AbslStringify()`.
+
+If you have an existing `<<` operator and would like to define an
+`AbslStringify()`, the latter will be used for GoogleTest printing.
 
-If you want to print a value `x` using googletest's value printer yourself, just
+If you want to print a value `x` using GoogleTest's value printer yourself, just
 call `::testing::PrintToString(x)`, which returns an `std::string`:
 
 ```c++
-vector<pair<Bar, int> > bar_ints = GetBarIntVector();
+vector<pair<Point, int> > point_ints = GetPointIntVector();
 
-EXPECT_TRUE(IsCorrectBarIntVector(bar_ints))
-    << "bar_ints = " << testing::PrintToString(bar_ints);
+EXPECT_TRUE(IsCorrectPointIntVector(point_ints))
+    << "point_ints = " << testing::PrintToString(point_ints);
 ```
 
+For more details regarding `AbslStringify()` and its integration with other
+libraries, see go/abslstringify.
+
+## Regular Expression Syntax
+
+When built with Bazel and using Abseil, GoogleTest uses the
+[RE2](https://github.com/google/re2/wiki/Syntax) syntax. Otherwise, for POSIX
+systems (Linux, Cygwin, Mac), GoogleTest uses the
+[POSIX extended regular expression](https://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04)
+syntax. To learn about POSIX syntax, you may want to read this
+[Wikipedia entry](https://en.wikipedia.org/wiki/Regular_expression#POSIX_extended).
+
+On Windows, GoogleTest uses its own simple regular expression implementation. It
+lacks many features. For example, we don't support union (`"x|y"`), grouping
+(`"(xy)"`), brackets (`"[xy]"`), and repetition count (`"x{5,7}"`), among
+others. Below is what we do support (`A` denotes a literal character, period
+(`.`), or a single `\\ ` escape sequence; `x` and `y` denote regular
+expressions.):
+
+Expression | Meaning
+---------- | --------------------------------------------------------------
+`c`        | matches any literal character `c`
+`\\d`      | matches any decimal digit
+`\\D`      | matches any character that's not a decimal digit
+`\\f`      | matches `\f`
+`\\n`      | matches `\n`
+`\\r`      | matches `\r`
+`\\s`      | matches any ASCII whitespace, including `\n`
+`\\S`      | matches any character that's not a whitespace
+`\\t`      | matches `\t`
+`\\v`      | matches `\v`
+`\\w`      | matches any letter, `_`, or decimal digit
+`\\W`      | matches any character that `\\w` doesn't match
+`\\c`      | matches any literal character `c`, which must be a punctuation
+`.`        | matches any single character except `\n`
+`A?`       | matches 0 or 1 occurrences of `A`
+`A*`       | matches 0 or many occurrences of `A`
+`A+`       | matches 1 or many occurrences of `A`
+`^`        | matches the beginning of a string (not that of each line)
+`$`        | matches the end of a string (not that of each line)
+`xy`       | matches `x` followed by `y`
+
+To help you determine which capability is available on your system, GoogleTest
+defines macros to govern which regular expression it is using. The macros are:
+`GTEST_USES_SIMPLE_RE=1` or `GTEST_USES_POSIX_RE=1`. If you want your death
+tests to work in all cases, you can either `#if` on these macros or use the more
+limited syntax only.
+
 ## Death Tests
 
 In many applications, there are assertions that can cause application failure if
@@ -393,7 +461,7 @@ corruption, security holes, or worse. Hence it is vitally important to test that
 such assertion statements work as expected.
 
 Since these precondition checks cause the processes to die, we call such tests
-_death tests_. More generally, any test that checks that a program terminates
+*death tests*. More generally, any test that checks that a program terminates
 (except by throwing an exception) in an expected fashion is also a death test.
 
 Note that if a piece of code throws an exception, we don't consider it "death"
@@ -439,6 +507,12 @@ verifies that:
     exit with exit code 0, and
 *   calling `KillProcess()` kills the process with signal `SIGKILL`.
 
+{: .callout .warning}
+Warning: If your death test contains mocks and is expecting a specific exit
+code, then you must allow the mock objects to be leaked via `Mock::AllowLeak`.
+This is because the mock leak detector will exit with its own error code if it
+detects a leak.
+
 The test function body may contain other assertions and statements as well, if
 necessary.
 
@@ -451,7 +525,7 @@ Note that a death test only cares about three things:
 3.  does the stderr output match `matcher`?
 
 In particular, if `statement` generates an `ASSERT_*` or `EXPECT_*` failure, it
-will **not** cause the death test to fail, as googletest assertions don't abort
+will **not** cause the death test to fail, as GoogleTest assertions don't abort
 the process.
 
 ### Death Test Naming
@@ -480,51 +554,6 @@ TEST_F(FooDeathTest, DoesThat) {
 }
 ```
 
-### Regular Expression Syntax
-
-When built with Bazel and using Abseil, googletest uses the
-[RE2](https://github.com/google/re2/wiki/Syntax) syntax. Otherwise, for POSIX
-systems (Linux, Cygwin, Mac), googletest uses the
-[POSIX extended regular expression](http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04)
-syntax. To learn about POSIX syntax, you may want to read this
-[Wikipedia entry](http://en.wikipedia.org/wiki/Regular_expression#POSIX_extended).
-
-On Windows, googletest uses its own simple regular expression implementation. It
-lacks many features. For example, we don't support union (`"x|y"`), grouping
-(`"(xy)"`), brackets (`"[xy]"`), and repetition count (`"x{5,7}"`), among
-others. Below is what we do support (`A` denotes a literal character, period
-(`.`), or a single `\\ ` escape sequence; `x` and `y` denote regular
-expressions.):
-
-Expression | Meaning
----------- | --------------------------------------------------------------
-`c`        | matches any literal character `c`
-`\\d`      | matches any decimal digit
-`\\D`      | matches any character that's not a decimal digit
-`\\f`      | matches `\f`
-`\\n`      | matches `\n`
-`\\r`      | matches `\r`
-`\\s`      | matches any ASCII whitespace, including `\n`
-`\\S`      | matches any character that's not a whitespace
-`\\t`      | matches `\t`
-`\\v`      | matches `\v`
-`\\w`      | matches any letter, `_`, or decimal digit
-`\\W`      | matches any character that `\\w` doesn't match
-`\\c`      | matches any literal character `c`, which must be a punctuation
-`.`        | matches any single character except `\n`
-`A?`       | matches 0 or 1 occurrences of `A`
-`A*`       | matches 0 or many occurrences of `A`
-`A+`       | matches 1 or many occurrences of `A`
-`^`        | matches the beginning of a string (not that of each line)
-`$`        | matches the end of a string (not that of each line)
-`xy`       | matches `x` followed by `y`
-
-To help you determine which capability is available on your system, googletest
-defines macros to govern which regular expression it is using. The macros are:
-`GTEST_USES_SIMPLE_RE=1` or `GTEST_USES_POSIX_RE=1`. If you want your death
-tests to work in all cases, you can either `#if` on these macros or use the more
-limited syntax only.
-
 ### How It Works
 
 See [Death Assertions](reference/assertions.md#death) in the Assertions
@@ -539,7 +568,7 @@ arrange that kind of environment. For example, statically-initialized modules
 may start threads before main is ever reached. Once threads have been created,
 it may be difficult or impossible to clean them up.
 
-googletest has three features intended to raise awareness of threading issues.
+GoogleTest has three features intended to raise awareness of threading issues.
 
 1.  A warning is emitted if multiple threads are running when a death test is
     encountered.
@@ -562,7 +591,7 @@ The automated testing framework does not set the style flag. You can choose a
 particular style of death tests by setting the flag programmatically:
 
 ```c++
-GTEST_FLAG_SET(death_test_style, "threadsafe")
+GTEST_FLAG_SET(death_test_style, "threadsafe");
 ```
 
 You can do this in `main()` to set the style for all death tests in the binary,
@@ -592,7 +621,7 @@ TEST(MyDeathTest, TestTwo) {
 
 The `statement` argument of `ASSERT_EXIT()` can be any valid C++ statement. If
 it leaves the current function via a `return` statement or by throwing an
-exception, the death test is considered to have failed. Some googletest macros
+exception, the death test is considered to have failed. Some GoogleTest macros
 may return from the current function (e.g. `ASSERT_TRUE()`), so be sure to avoid
 them in `statement`.
 
@@ -704,7 +733,7 @@ Some tips on using `SCOPED_TRACE`:
 ### Propagating Fatal Failures
 
 A common pitfall when using `ASSERT_*` and `FAIL*` is not understanding that
-when they fail they only abort the _current function_, not the entire test. For
+when they fail they only abort the *current function*, not the entire test. For
 example, the following test will segfault:
 
 ```c++
@@ -726,7 +755,7 @@ TEST(FooTest, Bar) {
 }
 ```
 
-To alleviate this, googletest provides three different solutions. You could use
+To alleviate this, GoogleTest provides three different solutions. You could use
 either exceptions, the `(ASSERT|EXPECT)_NO_FATAL_FAILURE` assertions or the
 `HasFatalFailure()` function. They are described in the following two
 subsections.
@@ -760,7 +789,7 @@ in it, the test will continue after the subroutine returns. This may not be what
 you want.
 
 Often people want fatal failures to propagate like exceptions. For that
-googletest offers the following macros:
+GoogleTest offers the following macros:
 
 Fatal assertion                       | Nonfatal assertion                    | Verifies
 ------------------------------------- | ------------------------------------- | --------
@@ -852,7 +881,7 @@ will output XML like this:
 >     needs to be prefixed with `::testing::Test::` if used outside of the
 >     `TEST` body and the test fixture class.
 > *   *`key`* must be a valid XML attribute name, and cannot conflict with the
->     ones already used by googletest (`name`, `status`, `time`, `classname`,
+>     ones already used by GoogleTest (`name`, `status`, `time`, `classname`,
 >     `type_param`, and `value_param`).
 > *   Calling `RecordProperty()` outside of the lifespan of a test is allowed.
 >     If it's called outside of a test but between a test suite's
@@ -863,25 +892,25 @@ will output XML like this:
 
 ## Sharing Resources Between Tests in the Same Test Suite
 
-googletest creates a new test fixture object for each test in order to make
+GoogleTest creates a new test fixture object for each test in order to make
 tests independent and easier to debug. However, sometimes tests use resources
 that are expensive to set up, making the one-copy-per-test model prohibitively
 expensive.
 
 If the tests don't change the resource, there's no harm in their sharing a
-single resource copy. So, in addition to per-test set-up/tear-down, googletest
+single resource copy. So, in addition to per-test set-up/tear-down, GoogleTest
 also supports per-test-suite set-up/tear-down. To use it:
 
 1.  In your test fixture class (say `FooTest` ), declare as `static` some member
     variables to hold the shared resources.
 2.  Outside your test fixture class (typically just below it), define those
     member variables, optionally giving them initial values.
-3.  In the same test fixture class, define a `static void SetUpTestSuite()`
-    function (remember not to spell it as **`SetupTestSuite`** with a small
-    `u`!) to set up the shared resources and a `static void TearDownTestSuite()`
-    function to tear them down.
+3.  In the same test fixture class, define a public member function `static void
+    SetUpTestSuite()` (remember not to spell it as **`SetupTestSuite`** with a
+    small `u`!) to set up the shared resources and a `static void
+    TearDownTestSuite()` function to tear them down.
 
-That's it! googletest automatically calls `SetUpTestSuite()` before running the
+That's it! GoogleTest automatically calls `SetUpTestSuite()` before running the
 *first test* in the `FooTest` test suite (i.e. before creating the first
 `FooTest` object), and calls `TearDownTestSuite()` after running the *last test*
 in it (i.e. after deleting the last `FooTest` object). In between, the tests can
@@ -974,24 +1003,34 @@ class Environment : public ::testing::Environment {
 };
 ```
 
-Then, you register an instance of your environment class with googletest by
+Then, you register an instance of your environment class with GoogleTest by
 calling the `::testing::AddGlobalTestEnvironment()` function:
 
 ```c++
 Environment* AddGlobalTestEnvironment(Environment* env);
 ```
 
-Now, when `RUN_ALL_TESTS()` is called, it first calls the `SetUp()` method of
-each environment object, then runs the tests if none of the environments
-reported fatal failures and `GTEST_SKIP()` was not called. `RUN_ALL_TESTS()`
-always calls `TearDown()` with each environment object, regardless of whether or
-not the tests were run.
+Now, when `RUN_ALL_TESTS()` is invoked, it first calls the `SetUp()` method. The
+tests are then executed, provided that none of the environments have reported
+fatal failures and `GTEST_SKIP()` has not been invoked. Finally, `TearDown()` is
+called.
+
+Note that `SetUp()` and `TearDown()` are only invoked if there is at least one
+test to be performed. Importantly, `TearDown()` is executed even if the test is
+not run due to a fatal failure or `GTEST_SKIP()`.
+
+Calling `SetUp()` and `TearDown()` for each iteration depends on the flag
+`gtest_recreate_environments_when_repeating`. `SetUp()` and `TearDown()` are
+called for each environment object when the object is recreated for each
+iteration. However, if test environments are not recreated for each iteration,
+`SetUp()` is called only on the first iteration, and `TearDown()` is called only
+on the last iteration.
 
 It's OK to register multiple environment objects. In this suite, their `SetUp()`
 will be called in the order they are registered, and their `TearDown()` will be
 called in the reverse order.
 
-Note that googletest takes ownership of the registered environment objects.
+Note that GoogleTest takes ownership of the registered environment objects.
 Therefore **do not delete them** by yourself.
 
 You should call `AddGlobalTestEnvironment()` before `RUN_ALL_TESTS()` is called,
@@ -1043,7 +1082,7 @@ they must be declared **public** rather than **protected** in order to use
 
 ```c++
 class FooTest :
-    public testing::TestWithParam<const char*> {
+    public testing::TestWithParam<absl::string_view> {
   // You can implement all the usual fixture class members here.
   // To access the test parameter, call GetParam() from class
   // TestWithParam<T>.
@@ -1054,7 +1093,7 @@ class BaseTest : public testing::Test {
   ...
 };
 class BarTest : public BaseTest,
-                public testing::WithParamInterface<const char*> {
+                public testing::WithParamInterface<absl::string_view> {
   ...
 };
 ```
@@ -1125,8 +1164,8 @@ with parameter values `"cat"` and `"dog"` using the
 [`ValuesIn`](reference/testing.md#param-generators) parameter generator:
 
 ```c++
-const char* pets[] = {"cat", "dog"};
-INSTANTIATE_TEST_SUITE_P(Pets, FooTest, testing::ValuesIn(pets));
+constexpr absl::string_view kPets[] = {"cat", "dog"};
+INSTANTIATE_TEST_SUITE_P(Pets, FooTest, testing::ValuesIn(kPets));
 ```
 
 The tests from the instantiation above will have these names:
@@ -1501,12 +1540,12 @@ To test them, we use the following special techniques:
 
 ## "Catching" Failures
 
-If you are building a testing utility on top of googletest, you'll want to test
-your utility. What framework would you use to test it? googletest, of course.
+If you are building a testing utility on top of GoogleTest, you'll want to test
+your utility. What framework would you use to test it? GoogleTest, of course.
 
 The challenge is to verify that your testing utility reports failures correctly.
 In frameworks that report a failure by throwing an exception, you could catch
-the exception and assert on it. But googletest doesn't use exceptions, so how do
+the exception and assert on it. But GoogleTest doesn't use exceptions, so how do
 we test that a piece of code generates an expected failure?
 
 `"gtest/gtest-spi.h"` contains some constructs to do this.
@@ -1649,9 +1688,9 @@ particular, you cannot find the test suite name in `SetUpTestSuite()`,
 `TearDownTestSuite()` (where you know the test suite name implicitly), or
 functions called from them.
 
-## Extending googletest by Handling Test Events
+## Extending GoogleTest by Handling Test Events
 
-googletest provides an **event listener API** to let you receive notifications
+GoogleTest provides an **event listener API** to let you receive notifications
 about the progress of a test program and test failures. The events you can
 listen to include the start and end of the test program, a test suite, or a test
 method, among others. You may use this API to augment or replace the standard
@@ -1712,7 +1751,7 @@ Here's an example:
 ### Using Event Listeners
 
 To use the event listener you have defined, add an instance of it to the
-googletest event listener list (represented by class
+GoogleTest event listener list (represented by class
 [`TestEventListeners`](reference/testing.md#TestEventListeners) - note the "s"
 at the end of the name) in your `main()` function, before calling
 `RUN_ALL_TESTS()`:
@@ -1723,7 +1762,7 @@ int main(int argc, char** argv) {
   // Gets hold of the event listener list.
   testing::TestEventListeners& listeners =
       testing::UnitTest::GetInstance()->listeners();
-  // Adds a listener to the end.  googletest takes the ownership.
+  // Adds a listener to the end.  GoogleTest takes the ownership.
   listeners.Append(new MinimalistPrinter);
   return RUN_ALL_TESTS();
 }
@@ -1775,13 +1814,13 @@ See [sample10_unittest.cc] for an example of a failure-raising listener.
 
 ## Running Test Programs: Advanced Options
 
-googletest test programs are ordinary executables. Once built, you can run them
+GoogleTest test programs are ordinary executables. Once built, you can run them
 directly and affect their behavior via the following environment variables
 and/or command line flags. For the flags to work, your programs must call
 `::testing::InitGoogleTest()` before calling `RUN_ALL_TESTS()`.
 
 To see a list of supported flags and their usage, please run your test program
-with the `--help` flag. You can also use `-h`, `-?`, or `/?` for short.
+with the `--help` flag.
 
 If an option is specified both by an environment variable and by a flag, the
 latter takes precedence.
@@ -1808,10 +1847,10 @@ corresponding environment variable for this flag.
 
 #### Running a Subset of the Tests
 
-By default, a googletest program runs all tests the user has defined. Sometimes,
+By default, a GoogleTest program runs all tests the user has defined. Sometimes,
 you want to run only a subset of the tests (e.g. for debugging or quickly
 verifying a change). If you set the `GTEST_FILTER` environment variable or the
-`--gtest_filter` flag to a filter string, googletest will only run the tests
+`--gtest_filter` flag to a filter string, GoogleTest will only run the tests
 whose full names (in the form of `TestSuiteName.TestName`) match the filter.
 
 The format of a filter is a '`:`'-separated list of wildcard patterns (called
@@ -1842,7 +1881,7 @@ For example:
 
 #### Stop test execution upon first failure
 
-By default, a googletest program runs all tests the user has defined. In some
+By default, a GoogleTest program runs all tests the user has defined. In some
 cases (e.g. iterative test development & execution) it may be desirable stop
 test execution upon first failure (trading improved latency for completeness).
 If `GTEST_FAIL_FAST` environment variable or `--gtest_fail_fast` flag is set,
@@ -1859,7 +1898,7 @@ If you need to disable all tests in a test suite, you can either add `DISABLED_`
 to the front of the name of each test, or alternatively add it to the front of
 the test suite name.
 
-For example, the following tests won't be run by googletest, even though they
+For example, the following tests won't be run by GoogleTest, even though they
 will still be compiled:
 
 ```c++
@@ -1874,7 +1913,7 @@ TEST_F(DISABLED_BarTest, DoesXyz) { ... }
 
 {: .callout .note}
 NOTE: This feature should only be used for temporary pain-relief. You still have
-to fix the disabled tests at a later date. As a reminder, googletest will print
+to fix the disabled tests at a later date. As a reminder, GoogleTest will print
 a banner warning you if a test program contains any disabled tests.
 
 {: .callout .tip}
@@ -1890,6 +1929,20 @@ the `--gtest_also_run_disabled_tests` flag or set the
 You can combine this with the `--gtest_filter` flag to further select which
 disabled tests to run.
 
+### Enforcing Having At Least One Test Case
+
+A not uncommon programmer mistake is to write a test program that has no test
+case linked in. This can happen, for example, when you put test case definitions
+in a library and the library is not marked as "always link".
+
+To catch such mistakes, run the test program with the
+`--gtest_fail_if_no_test_linked` flag or set the `GTEST_FAIL_IF_NO_TEST_LINKED`
+environment variable to a value other than `0`. Now the program will fail if no
+test case is linked in.
+
+Note that *any* test case linked in makes the program valid for the purpose of
+this check. In particular, even a disabled test case suffices.
+
 ### Repeating the Tests
 
 Once in a while you'll run into a test whose result is hit-or-miss. Perhaps it
@@ -1932,16 +1985,16 @@ You can specify the `--gtest_shuffle` flag (or set the `GTEST_SHUFFLE`
 environment variable to `1`) to run the tests in a program in a random order.
 This helps to reveal bad dependencies between tests.
 
-By default, googletest uses a random seed calculated from the current time.
+By default, GoogleTest uses a random seed calculated from the current time.
 Therefore you'll get a different order every time. The console output includes
 the random seed value, such that you can reproduce an order-related test failure
 later. To specify the random seed explicitly, use the `--gtest_random_seed=SEED`
 flag (or set the `GTEST_RANDOM_SEED` environment variable), where `SEED` is an
 integer in the range [0, 99999]. The seed value 0 is special: it tells
-googletest to do the default behavior of calculating the seed from the current
+GoogleTest to do the default behavior of calculating the seed from the current
 time.
 
-If you combine this with `--gtest_repeat=N`, googletest will pick a different
+If you combine this with `--gtest_repeat=N`, GoogleTest will pick a different
 random seed and re-shuffle the tests in each iteration.
 
 ### Distributing Test Functions to Multiple Machines
@@ -2000,7 +2053,7 @@ shards, but here's one possible scenario:
 
 #### Colored Terminal Output
 
-googletest can use colors in its terminal output to make it easier to spot the
+GoogleTest can use colors in its terminal output to make it easier to spot the
 important information:
 
 <pre>...
@@ -2025,25 +2078,25 @@ important information:
 
 You can set the `GTEST_COLOR` environment variable or the `--gtest_color`
 command line flag to `yes`, `no`, or `auto` (the default) to enable colors,
-disable colors, or let googletest decide. When the value is `auto`, googletest
+disable colors, or let GoogleTest decide. When the value is `auto`, GoogleTest
 will use colors if and only if the output goes to a terminal and (on non-Windows
 platforms) the `TERM` environment variable is set to `xterm` or `xterm-color`.
 
 #### Suppressing test passes
 
-By default, googletest prints 1 line of output for each test, indicating if it
+By default, GoogleTest prints 1 line of output for each test, indicating if it
 passed or failed. To show only test failures, run the test program with
 `--gtest_brief=1`, or set the GTEST_BRIEF environment variable to `1`.
 
 #### Suppressing the Elapsed Time
 
-By default, googletest prints the time it takes to run each test. To disable
+By default, GoogleTest prints the time it takes to run each test. To disable
 that, run the test program with the `--gtest_print_time=0` command line flag, or
 set the GTEST_PRINT_TIME environment variable to `0`.
 
 #### Suppressing UTF-8 Text Output
 
-In case of assertion failures, googletest prints expected and actual values of
+In case of assertion failures, GoogleTest prints expected and actual values of
 type `string` both as hex-encoded strings as well as in readable UTF-8 text if
 they contain valid non-ASCII UTF-8 characters. If you want to suppress the UTF-8
 text because, for example, you don't have an UTF-8 compatible output medium, run
@@ -2052,7 +2105,7 @@ environment variable to `0`.
 
 #### Generating an XML Report
 
-googletest can emit a detailed XML report to a file in addition to its normal
+GoogleTest can emit a detailed XML report to a file in addition to its normal
 textual output. The report contains the duration of each test, and thus can help
 you identify slow tests.
 
@@ -2063,15 +2116,15 @@ in which case the output can be found in the `test_detail.xml` file in the
 current directory.
 
 If you specify a directory (for example, `"xml:output/directory/"` on Linux or
-`"xml:output\directory\"` on Windows), googletest will create the XML file in
+`"xml:output\directory\"` on Windows), GoogleTest will create the XML file in
 that directory, named after the test executable (e.g. `foo_test.xml` for test
 program `foo_test` or `foo_test.exe`). If the file already exists (perhaps left
-over from a previous run), googletest will pick a different name (e.g.
+over from a previous run), GoogleTest will pick a different name (e.g.
 `foo_test_1.xml`) to avoid overwriting it.
 
 The report is based on the `junitreport` Ant task. Since that format was
 originally intended for Java, a little interpretation is required to make it
-apply to googletest tests, as shown here:
+apply to GoogleTest tests, as shown here:
 
 ```xml
 <testsuites name="AllTests" ...>
@@ -2086,8 +2139,8 @@ apply to googletest tests, as shown here:
 ```
 
 *   The root `<testsuites>` element corresponds to the entire test program.
-*   `<testsuite>` elements correspond to googletest test suites.
-*   `<testcase>` elements correspond to googletest test functions.
+*   `<testsuite>` elements correspond to GoogleTest test suites.
+*   `<testcase>` elements correspond to GoogleTest test functions.
 
 For instance, the following program
 
@@ -2120,7 +2173,7 @@ could generate this report:
 Things to note:
 
 *   The `tests` attribute of a `<testsuites>` or `<testsuite>` element tells how
-    many test functions the googletest program or test suite contains, while the
+    many test functions the GoogleTest program or test suite contains, while the
     `failures` attribute tells how many of them failed.
 
 *   The `time` attribute expresses the duration of the test, test suite, or
@@ -2132,12 +2185,12 @@ Things to note:
 *   The `file` and `line` attributes record the source file location, where the
     test was defined.
 
-*   Each `<failure>` element corresponds to a single failed googletest
+*   Each `<failure>` element corresponds to a single failed GoogleTest
     assertion.
 
 #### Generating a JSON Report
 
-googletest can also emit a JSON report as an alternative format to XML. To
+GoogleTest can also emit a JSON report as an alternative format to XML. To
 generate the JSON report, set the `GTEST_OUTPUT` environment variable or the
 `--gtest_output` flag to the string `"json:path_to_output_file"`, which will
 create the file at the given location. You can also just use the string
@@ -2148,7 +2201,7 @@ The report format conforms to the following JSON Schema:
 
 ```json
 {
-  "$schema": "http://json-schema.org/schema#",
+  "$schema": "https://json-schema.org/schema#",
   "type": "object",
   "definitions": {
     "TestCase": {
@@ -2349,7 +2402,7 @@ IMPORTANT: The exact format of the JSON document is subject to change.
 
 #### Detecting Test Premature Exit
 
-Google Test implements the _premature-exit-file_ protocol for test runners to
+Google Test implements the *premature-exit-file* protocol for test runners to
 catch any kind of unexpected exits of test programs. Upon start, Google Test
 creates the file which will be automatically deleted after all work has been
 finished. Then, the test runner can check if this file exists. In case the file
@@ -2362,7 +2415,7 @@ variable has been set.
 
 When running test programs under a debugger, it's very convenient if the
 debugger can catch an assertion failure and automatically drop into interactive
-mode. googletest's *break-on-failure* mode supports this behavior.
+mode. GoogleTest's *break-on-failure* mode supports this behavior.
 
 To enable it, set the `GTEST_BREAK_ON_FAILURE` environment variable to a value
 other than `0`. Alternatively, you can use the `--gtest_break_on_failure`
@@ -2370,9 +2423,9 @@ command line flag.
 
 #### Disabling Catching Test-Thrown Exceptions
 
-googletest can be used either with or without exceptions enabled. If a test
+GoogleTest can be used either with or without exceptions enabled. If a test
 throws a C++ exception or (on Windows) a structured exception (SEH), by default
-googletest catches it, reports it as a test failure, and continues with the next
+GoogleTest catches it, reports it as a test failure, and continues with the next
 test method. This maximizes the coverage of a test run. Also, on Windows an
 uncaught exception will cause a pop-up window, so catching the exceptions allows
 you to run the tests automatically.
@@ -2410,4 +2463,4 @@ void __tsan_on_report() {
 ```
 
 After compiling your project with one of the sanitizers enabled, if a particular
-test triggers a sanitizer error, googletest will report that it failed.
+test triggers a sanitizer error, GoogleTest will report that it failed.

+ 18 - 39
ThirdParty/SpirvTools/external/googletest/docs/faq.md

@@ -3,7 +3,7 @@
 ## Why should test suite names and test names not contain underscore?
 
 {: .callout .note}
-Note: GoogleTest reserves underscore (`_`) for special purpose keywords, such as
+Note: GoogleTest reserves underscore (`_`) for special-purpose keywords, such as
 [the `DISABLED_` prefix](advanced.md#temporarily-disabling-tests), in addition
 to the following rationale.
 
@@ -33,9 +33,9 @@ contains `_`?
     `TestSuiteName_Bar__Test`, which is invalid.
 
 So clearly `TestSuiteName` and `TestName` cannot start or end with `_`
-(Actually, `TestSuiteName` can start with `_` -- as long as the `_` isn't
-followed by an upper-case letter. But that's getting complicated. So for
-simplicity we just say that it cannot start with `_`.).
+(Actually, `TestSuiteName` can start with `_`—as long as the `_` isn't followed
+by an upper-case letter. But that's getting complicated. So for simplicity we
+just say that it cannot start with `_`.).
 
 It may seem fine for `TestSuiteName` and `TestName` to contain `_` in the
 middle. However, consider this:
@@ -128,30 +128,9 @@ both approaches a try. Practice is a much better way to grasp the subtle
 differences between the two tools. Once you have some concrete experience, you
 can much more easily decide which one to use the next time.
 
-## I got some run-time errors about invalid proto descriptors when using `ProtocolMessageEquals`. Help!
-
-{: .callout .note}
-**Note:** `ProtocolMessageEquals` and `ProtocolMessageEquiv` are *deprecated*
-now. Please use `EqualsProto`, etc instead.
-
-`ProtocolMessageEquals` and `ProtocolMessageEquiv` were redefined recently and
-are now less tolerant of invalid protocol buffer definitions. In particular, if
-you have a `foo.proto` that doesn't fully qualify the type of a protocol message
-it references (e.g. `message<Bar>` where it should be `message<blah.Bar>`), you
-will now get run-time errors like:
-
-```
-... descriptor.cc:...] Invalid proto descriptor for file "path/to/foo.proto":
-... descriptor.cc:...]  blah.MyMessage.my_field: ".Bar" is not defined.
-```
-
-If you see this, your `.proto` file is broken and needs to be fixed by making
-the types fully qualified. The new definition of `ProtocolMessageEquals` and
-`ProtocolMessageEquiv` just happen to reveal your bug.
-
 ## My death test modifies some state, but the change seems lost after the death test finishes. Why?
 
-Death tests (`EXPECT_DEATH`, etc) are executed in a sub-process s.t. the
+Death tests (`EXPECT_DEATH`, etc.) are executed in a sub-process s.t. the
 expected crash won't kill the test program (i.e. the parent process). As a
 result, any in-memory side effects they incur are observable in their respective
 sub-processes, but not in the parent process. You can think of them as running
@@ -192,16 +171,16 @@ class Foo {
 };
 ```
 
-You also need to define it *outside* of the class body in `foo.cc`:
+you also need to define it *outside* of the class body in `foo.cc`:
 
 ```c++
 const int Foo::kBar;  // No initializer here.
 ```
 
 Otherwise your code is **invalid C++**, and may break in unexpected ways. In
-particular, using it in GoogleTest comparison assertions (`EXPECT_EQ`, etc) will
-generate an "undefined reference" linker error. The fact that "it used to work"
-doesn't mean it's valid. It just means that you were lucky. :-)
+particular, using it in GoogleTest comparison assertions (`EXPECT_EQ`, etc.)
+will generate an "undefined reference" linker error. The fact that "it used to
+work" doesn't mean it's valid. It just means that you were lucky. :-)
 
 If the declaration of the static data member is `constexpr` then it is
 implicitly an `inline` definition, and a separate definition in `foo.cc` is not
@@ -311,7 +290,7 @@ a **fresh** test fixture object, immediately call `SetUp()`, run the test body,
 call `TearDown()`, and then delete the test fixture object.
 
 When you need to write per-test set-up and tear-down logic, you have the choice
-between using the test fixture constructor/destructor or `SetUp()/TearDown()`.
+between using the test fixture constructor/destructor or `SetUp()`/`TearDown()`.
 The former is usually preferred, as it has the following benefits:
 
 *   By initializing a member variable in the constructor, we have the option to
@@ -352,7 +331,7 @@ You may still want to use `SetUp()/TearDown()` in the following cases:
     GoogleTest assertions in a destructor if your code could run on such a
     platform.
 
-## The compiler complains "no matching function to call" when I use ASSERT_PRED*. How do I fix it?
+## The compiler complains "no matching function to call" when I use `ASSERT_PRED*`. How do I fix it?
 
 See details for [`EXPECT_PRED*`](reference/assertions.md#EXPECT_PRED) in the
 Assertions Reference.
@@ -410,7 +389,7 @@ C++ is case-sensitive. Did you spell it as `Setup()`?
 Similarly, sometimes people spell `SetUpTestSuite()` as `SetupTestSuite()` and
 wonder why it's never called.
 
-## I have several test suites which share the same test fixture logic, do I have to define a new test fixture class for each of them? This seems pretty tedious.
+## I have several test suites which share the same test fixture logic; do I have to define a new test fixture class for each of them? This seems pretty tedious.
 
 You don't have to. Instead of
 
@@ -545,7 +524,7 @@ The new NPTL thread library doesn't suffer from this problem, as it doesn't
 create a manager thread. However, if you don't control which machine your test
 runs on, you shouldn't depend on this.
 
-## Why does GoogleTest require the entire test suite, instead of individual tests, to be named *DeathTest when it uses ASSERT_DEATH?
+## Why does GoogleTest require the entire test suite, instead of individual tests, to be named `*DeathTest` when it uses `ASSERT_DEATH`?
 
 GoogleTest does not interleave tests from different test suites. That is, it
 runs all tests in one test suite first, and then runs all tests in the next test
@@ -570,7 +549,7 @@ interleave tests from different test suites, we need to run all tests in the
 `FooTest` case before running any test in the `BarTest` case. This contradicts
 with the requirement to run `BarTest.DefDeathTest` before `FooTest.Uvw`.
 
-## But I don't like calling my entire test suite \*DeathTest when it contains both death tests and non-death tests. What do I do?
+## But I don't like calling my entire test suite `*DeathTest` when it contains both death tests and non-death tests. What do I do?
 
 You don't have to, but if you like, you may split up the test suite into
 `FooTest` and `FooDeathTest`, where the names make it clear that they are
@@ -607,7 +586,7 @@ defined such that we can print a value of `FooType`.
 
 In addition, if `FooType` is declared in a name space, the `<<` operator also
 needs to be defined in the *same* name space. See
-[Tip of the Week #49](http://abseil.io/tips/49) for details.
+[Tip of the Week #49](https://abseil.io/tips/49) for details.
 
 ## How do I suppress the memory leak messages on Windows?
 
@@ -628,10 +607,10 @@ mistake in production. Such cleverness also leads to
 advise against the practice, and GoogleTest doesn't provide a way to do it.
 
 In general, the recommended way to cause the code to behave differently under
-test is [Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection). You can inject
+test is [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection). You can inject
 different functionality from the test and from the production code. Since your
 production code doesn't link in the for-test logic at all (the
-[`testonly`](http://docs.bazel.build/versions/master/be/common-definitions.html#common.testonly) attribute for BUILD targets helps to ensure
+[`testonly`](https://docs.bazel.build/versions/master/be/common-definitions.html#common.testonly) attribute for BUILD targets helps to ensure
 that), there is no danger in accidentally running it.
 
 However, if you *really*, *really*, *really* have no choice, and if you follow
@@ -654,7 +633,7 @@ the `--gtest_also_run_disabled_tests` flag.
 Yes.
 
 The rule is **all test methods in the same test suite must use the same fixture
-class.** This means that the following is **allowed** because both tests use the
+class**. This means that the following is **allowed** because both tests use the
 same fixture class (`::testing::Test`).
 
 ```c++

+ 1 - 1
ThirdParty/SpirvTools/external/googletest/docs/gmock_cheat_sheet.md

@@ -20,7 +20,7 @@ class Foo {
 (note that `~Foo()` **must** be virtual) we can define its mock as
 
 ```cpp
-#include "gmock/gmock.h"
+#include <gmock/gmock.h>
 
 class MockFoo : public Foo {
  public:

+ 127 - 62
ThirdParty/SpirvTools/external/googletest/docs/gmock_cook_book.md

@@ -177,7 +177,7 @@ class StackInterface {
 template <typename Elem>
 class MockStack : public StackInterface<Elem> {
   ...
-  MOCK_METHOD(int, GetSize, (), (override));
+  MOCK_METHOD(int, GetSize, (), (const, override));
   MOCK_METHOD(void, Push, (const Elem& x), (override));
 };
 ```
@@ -697,9 +697,9 @@ TEST(AbcTest, Xyz) {
   EXPECT_CALL(foo, DoThat(_, _));
 
   int n = 0;
-  EXPECT_EQ('+', foo.DoThis(5));  // FakeFoo::DoThis() is invoked.
+  EXPECT_EQ(foo.DoThis(5), '+');  // FakeFoo::DoThis() is invoked.
   foo.DoThat("Hi", &n);  // FakeFoo::DoThat() is invoked.
-  EXPECT_EQ(2, n);
+  EXPECT_EQ(n, 2);
 }
 ```
 
@@ -936,8 +936,8 @@ casts a matcher `m` to type `Matcher<T>`. To ensure safety, gMock checks that
     floating-point numbers), the conversion from `T` to `U` is not lossy (in
     other words, any value representable by `T` can also be represented by `U`);
     and
-3.  When `U` is a reference, `T` must also be a reference (as the underlying
-    matcher may be interested in the address of the `U` value).
+3.  When `U` is a non-const reference, `T` must also be a reference (as the
+    underlying matcher may be interested in the address of the `U` value).
 
 The code won't compile if any of these conditions isn't met.
 
@@ -1129,11 +1129,11 @@ using STL's `<functional>` header is just painful). For example, here's a
 predicate that's satisfied by any number that is >= 0, <= 100, and != 50:
 
 ```cpp
-using testing::AllOf;
-using testing::Ge;
-using testing::Le;
-using testing::Matches;
-using testing::Ne;
+using ::testing::AllOf;
+using ::testing::Ge;
+using ::testing::Le;
+using ::testing::Matches;
+using ::testing::Ne;
 ...
 Matches(AllOf(Ge(0), Le(100), Ne(50)))
 ```
@@ -1861,7 +1861,7 @@ error. So, what shall you do?
 Though you may be tempted, DO NOT use `std::ref()`:
 
 ```cpp
-using testing::Return;
+using ::testing::Return;
 
 class MockFoo : public Foo {
  public:
@@ -1873,7 +1873,7 @@ class MockFoo : public Foo {
   EXPECT_CALL(foo, GetValue())
       .WillRepeatedly(Return(std::ref(x)));  // Wrong!
   x = 42;
-  EXPECT_EQ(42, foo.GetValue());
+  EXPECT_EQ(foo.GetValue(), 42);
 ```
 
 Unfortunately, it doesn't work here. The above code will fail with error:
@@ -1895,14 +1895,14 @@ the expectation is set, and `Return(std::ref(x))` will always return 0.
 returns the value pointed to by `pointer` at the time the action is *executed*:
 
 ```cpp
-using testing::ReturnPointee;
+using ::testing::ReturnPointee;
 ...
   int x = 0;
   MockFoo foo;
   EXPECT_CALL(foo, GetValue())
       .WillRepeatedly(ReturnPointee(&x));  // Note the & here.
   x = 42;
-  EXPECT_EQ(42, foo.GetValue());  // This will succeed now.
+  EXPECT_EQ(foo.GetValue(), 42);  // This will succeed now.
 ```
 
 ### Combining Actions
@@ -1927,6 +1927,12 @@ class MockFoo : public Foo {
                       action_n));
 ```
 
+The return value of the last action **must** match the return type of the mocked
+method. In the example above, `action_n` could be `Return(true)`, or a lambda
+that returns a `bool`, but not `SaveArg`, which returns `void`. Otherwise the
+signature of `DoAll` would not match the signature expected by `WillOnce`, which
+is the signature of the mocked method, and it wouldn't compile.
+
 ### Verifying Complex Arguments {#SaveArgVerify}
 
 If you want to verify that a method is called with a particular argument but the
@@ -2264,7 +2270,7 @@ TEST_F(FooTest, Test) {
 
   EXPECT_CALL(foo, DoThis(2))
       .WillOnce(Invoke(NewPermanentCallback(SignOfSum, 5)));
-  EXPECT_EQ('+', foo.DoThis(2));  // Invokes SignOfSum(5, 2).
+  EXPECT_EQ(foo.DoThis(2), '+');  // Invokes SignOfSum(5, 2).
 }
 ```
 
@@ -2640,8 +2646,8 @@ action will exhibit different behaviors. Example:
       .WillRepeatedly(IncrementCounter(0));
   foo.DoThis();  // Returns 1.
   foo.DoThis();  // Returns 2.
-  foo.DoThat();  // Returns 1 - Blah() uses a different
-                 // counter than Bar()'s.
+  foo.DoThat();  // Returns 1 - DoThat() uses a different
+                 // counter than DoThis()'s.
 ```
 
 versus
@@ -2771,36 +2777,33 @@ returns a null `unique_ptr`, that’s what you’ll get if you don’t specify a
 action:
 
 ```cpp
+using ::testing::IsNull;
+...
   // Use the default action.
   EXPECT_CALL(mock_buzzer_, MakeBuzz("hello"));
 
   // Triggers the previous EXPECT_CALL.
-  EXPECT_EQ(nullptr, mock_buzzer_.MakeBuzz("hello"));
+  EXPECT_THAT(mock_buzzer_.MakeBuzz("hello"), IsNull());
 ```
 
 If you are not happy with the default action, you can tweak it as usual; see
 [Setting Default Actions](#OnCall).
 
-If you just need to return a pre-defined move-only value, you can use the
-`Return(ByMove(...))` action:
+If you just need to return a move-only value, you can use it in combination with
+`WillOnce`. For example:
 
 ```cpp
-  // When this fires, the unique_ptr<> specified by ByMove(...) will
-  // be returned.
-  EXPECT_CALL(mock_buzzer_, MakeBuzz("world"))
-      .WillOnce(Return(ByMove(std::make_unique<Buzz>(AccessLevel::kInternal))));
-
-  EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("world"));
+  EXPECT_CALL(mock_buzzer_, MakeBuzz("hello"))
+      .WillOnce(Return(std::make_unique<Buzz>(AccessLevel::kInternal)));
+  EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("hello"));
 ```
 
-Note that `ByMove()` is essential here - if you drop it, the code won’t compile.
-
-Quiz time! What do you think will happen if a `Return(ByMove(...))` action is
-performed more than once (e.g. you write `...
-.WillRepeatedly(Return(ByMove(...)));`)? Come think of it, after the first time
-the action runs, the source value will be consumed (since it’s a move-only
-value), so the next time around, there’s no value to move from -- you’ll get a
-run-time error that `Return(ByMove(...))` can only be run once.
+Quiz time! What do you think will happen if a `Return` action is performed more
+than once (e.g. you write `... .WillRepeatedly(Return(std::move(...)));`)? Come
+think of it, after the first time the action runs, the source value will be
+consumed (since it’s a move-only value), so the next time around, there’s no
+value to move from -- you’ll get a run-time error that `Return(std::move(...))`
+can only be run once.
 
 If you need your mock method to do more than just moving a pre-defined value,
 remember that you can always use a lambda or a callable object, which can do
@@ -2817,7 +2820,7 @@ pretty much anything you want:
 ```
 
 Every time this `EXPECT_CALL` fires, a new `unique_ptr<Buzz>` will be created
-and returned. You cannot do this with `Return(ByMove(...))`.
+and returned. You cannot do this with `Return(std::make_unique<...>(...))`.
 
 That covers returning move-only values; but how do we work with methods
 accepting move-only arguments? The answer is that they work normally, although
@@ -3197,11 +3200,11 @@ You can unlock this power by running your test with the `--gmock_verbose=info`
 flag. For example, given the test program:
 
 ```cpp
-#include "gmock/gmock.h"
+#include <gmock/gmock.h>
 
-using testing::_;
-using testing::HasSubstr;
-using testing::Return;
+using ::testing::_;
+using ::testing::HasSubstr;
+using ::testing::Return;
 
 class MockFoo {
  public:
@@ -3309,7 +3312,7 @@ For convenience, we allow the description string to be empty (`""`), in which
 case gMock will use the sequence of words in the matcher name as the
 description.
 
-For example:
+#### Basic Example
 
 ```cpp
 MATCHER(IsDivisibleBy7, "") { return (arg % 7) == 0; }
@@ -3347,6 +3350,8 @@ If the above assertions fail, they will print something like:
 where the descriptions `"is divisible by 7"` and `"not (is divisible by 7)"` are
 automatically calculated from the matcher name `IsDivisibleBy7`.
 
+#### Adding Custom Failure Messages
+
 As you may have noticed, the auto-generated descriptions (especially those for
 the negation) may not be so great. You can always override them with a `string`
 expression of your own:
@@ -3380,21 +3385,48 @@ With this definition, the above assertion will give a better message:
     Actual: 27 (the remainder is 6)
 ```
 
+#### Using EXPECT_ Statements in Matchers
+
+You can also use `EXPECT_...` statements inside custom matcher definitions. In
+many cases, this allows you to write your matcher more concisely while still
+providing an informative error message. For example:
+
+```cpp
+MATCHER(IsDivisibleBy7, "") {
+  const auto remainder = arg % 7;
+  EXPECT_EQ(remainder, 0);
+  return true;
+}
+```
+
+If you write a test that includes the line `EXPECT_THAT(27, IsDivisibleBy7());`,
+you will get an error something like the following:
+
+```shell
+Expected equality of these values:
+  remainder
+    Which is: 6
+  0
+```
+
+#### `MatchAndExplain`
+
 You should let `MatchAndExplain()` print *any additional information* that can
 help a user understand the match result. Note that it should explain why the
 match succeeds in case of a success (unless it's obvious) - this is useful when
 the matcher is used inside `Not()`. There is no need to print the argument value
 itself, as gMock already prints it for you.
 
-{: .callout .note}
-NOTE: The type of the value being matched (`arg_type`) is determined by the
-context in which you use the matcher and is supplied to you by the compiler, so
-you don't need to worry about declaring it (nor can you). This allows the
-matcher to be polymorphic. For example, `IsDivisibleBy7()` can be used to match
-any type where the value of `(arg % 7) == 0` can be implicitly converted to a
-`bool`. In the `Bar(IsDivisibleBy7())` example above, if method `Bar()` takes an
-`int`, `arg_type` will be `int`; if it takes an `unsigned long`, `arg_type` will
-be `unsigned long`; and so on.
+#### Argument Types
+
+The type of the value being matched (`arg_type`) is determined by the context in
+which you use the matcher and is supplied to you by the compiler, so you don't
+need to worry about declaring it (nor can you). This allows the matcher to be
+polymorphic. For example, `IsDivisibleBy7()` can be used to match any type where
+the value of `(arg % 7) == 0` can be implicitly converted to a `bool`. In the
+`Bar(IsDivisibleBy7())` example above, if method `Bar()` takes an `int`,
+`arg_type` will be `int`; if it takes an `unsigned long`, `arg_type` will be
+`unsigned long`; and so on.
 
 ### Writing New Parameterized Matchers Quickly
 
@@ -3535,10 +3567,15 @@ just based on the number of parameters).
 
 ### Writing New Monomorphic Matchers
 
-A matcher of argument type `T` implements the matcher interface for `T` and does
-two things: it tests whether a value of type `T` matches the matcher, and can
-describe what kind of values it matches. The latter ability is used for
-generating readable error messages when expectations are violated.
+A matcher of type `testing::Matcher<T>` implements the matcher interface for `T`
+and does two things: it tests whether a value of type `T` matches the matcher,
+and can describe what kind of values it matches. The latter ability is used for
+generating readable error messages when expectations are violated. Some matchers
+can even explain why it matches or doesn't match a certain value, which can be
+helpful when the reason isn't obvious.
+
+Because a matcher of type `testing::Matcher<T>` for a particular type `T` can
+only be used to match a value of type `T`, we call it "monomorphic."
 
 A matcher of `T` must declare a typedef like:
 
@@ -3630,8 +3667,16 @@ instead of `std::ostream*`.
 
 ### Writing New Polymorphic Matchers
 
-Expanding what we learned above to *polymorphic* matchers is now just as simple
-as adding templates in the right place.
+Unlike a monomorphic matcher, which can only be used to match a value of a
+particular type, a *polymorphic* matcher is one that can be used to match values
+of multiple types. For example, `Eq(5)` is a polymorhpic matcher as it can be
+used to match an `int`, a `double`, a `float`, and so on. You should think of a
+polymorphic matcher as a *matcher factory* as opposed to a
+`testing::Matcher<SomeType>` - itself is not an actual matcher, but can be
+implicitly converted to a `testing::Matcher<SomeType>` depending on the context.
+
+Expanding what we learned above to polymorphic matchers is now as simple as
+adding templates in the right place.
 
 ```cpp
 
@@ -3757,6 +3802,26 @@ virtual.
 Like in a monomorphic matcher, you may explain the match result by streaming
 additional information to the `listener` argument in `MatchAndExplain()`.
 
+### Implementing Composite Matchers {#CompositeMatchers}
+
+Sometimes we want to define a matcher that takes other matchers as parameters.
+For example, `DistanceFrom(target, m)` is a polymorphic matcher that takes a
+matcher `m` as a parameter. It tests that the distance from `target` to the
+value being matched satisfies sub-matcher `m`.
+
+If you are implementing such a composite matcher, you'll need to generate the
+description of the matcher based on the description(s) of its sub-matcher(s).
+You can see the implementation of `DistanceFrom()` in
+`googlemock/include/gmock/gmock-matchers.h` for an example. In particular, pay
+attention to `DistanceFromMatcherImpl`. Notice that it stores the sub-matcher as
+a `const Matcher<const Distance&> distance_matcher_` instead of a polymorphic
+matcher - this allows it to call `distance_matcher_.DescribeTo(os)` to describe
+the sub-matcher. If the sub-matcher is stored as a polymorphic matcher instead,
+it would not be possible to get its description as in general polymorphic
+matchers don't know how to describe themselves - they are matcher factories
+instead of actual matchers; only after being converted to `Matcher<SomeType>`
+can they be described.
+
 ### Writing New Cardinalities
 
 A cardinality is used in `Times()` to tell gMock how many times you expect a
@@ -3822,15 +3887,15 @@ If the built-in actions don't work for you, you can easily define your own one.
 All you need is a call operator with a signature compatible with the mocked
 function. So you can use a lambda:
 
-```
+```cpp
 MockFunction<int(int)> mock;
 EXPECT_CALL(mock, Call).WillOnce([](const int input) { return input * 7; });
-EXPECT_EQ(14, mock.AsStdFunction()(2));
+EXPECT_EQ(mock.AsStdFunction()(2), 14);
 ```
 
 Or a struct with a call operator (even a templated one):
 
-```
+```cpp
 struct MultiplyBy {
   template <typename T>
   T operator()(T arg) { return arg * multiplier; }
@@ -3845,16 +3910,16 @@ struct MultiplyBy {
 It's also fine for the callable to take no arguments, ignoring the arguments
 supplied to the mock function:
 
-```
+```cpp
 MockFunction<int(int)> mock;
 EXPECT_CALL(mock, Call).WillOnce([] { return 17; });
-EXPECT_EQ(17, mock.AsStdFunction()(0));
+EXPECT_EQ(mock.AsStdFunction()(0), 17);
 ```
 
 When used with `WillOnce`, the callable can assume it will be called at most
 once and is allowed to be a move-only type:
 
-```
+```cpp
 // An action that contains move-only types and has an &&-qualified operator,
 // demanding in the type system that it be called at most once. This can be
 // used with WillOnce, but the compiler will reject it if handed to
@@ -4298,7 +4363,7 @@ particular type than to dump the bytes.
 ### Mock std::function {#MockFunction}
 
 `std::function` is a general function type introduced in C++11. It is a
-preferred way of passing callbacks to new interfaces. Functions are copiable,
+preferred way of passing callbacks to new interfaces. Functions are copyable,
 and are not usually passed around by pointer, which makes them tricky to mock.
 But fear not - `MockFunction` can help you with that.
 

+ 7 - 5
ThirdParty/SpirvTools/external/googletest/docs/gmock_for_dummies.md

@@ -90,14 +90,14 @@ gMock is bundled with googletest.
 ## A Case for Mock Turtles
 
 Let's look at an example. Suppose you are developing a graphics program that
-relies on a [LOGO](http://en.wikipedia.org/wiki/Logo_programming_language)-like
+relies on a [LOGO](https://en.wikipedia.org/wiki/Logo_programming_language)-like
 API for drawing. How would you test that it does the right thing? Well, you can
 run it and compare the screen with a golden screen snapshot, but let's admit it:
 tests like this are expensive to run and fragile (What if you just upgraded to a
 shiny new graphics card that has better anti-aliasing? Suddenly you have to
 update all your golden images.). It would be too painful if all your tests are
 like this. Fortunately, you learned about
-[Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection) and know the right thing
+[Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) and know the right thing
 to do: instead of having your application talk to the system API directly, wrap
 the API in an interface (say, `Turtle`) and code to that interface:
 
@@ -164,7 +164,7 @@ follow:
 After the process, you should have something like:
 
 ```cpp
-#include "gmock/gmock.h"  // Brings in gMock.
+#include <gmock/gmock.h>  // Brings in gMock.
 
 class MockTurtle : public Turtle {
  public:
@@ -224,8 +224,8 @@ Here's an example:
 
 ```cpp
 #include "path/to/mock-turtle.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
 
 using ::testing::AtLeast;                         // #1
 
@@ -261,6 +261,8 @@ happen. Therefore it's a good idea to turn on the heap checker in your tests
 when you allocate mocks on the heap. You get that automatically if you use the
 `gtest_main` library already.
 
+###### Expectation Ordering
+
 **Important note:** gMock requires expectations to be set **before** the mock
 functions are called, otherwise the behavior is **undefined**. Do not alternate
 between calls to `EXPECT_CALL()` and calls to the mock functions, and do not set

+ 5 - 9
ThirdParty/SpirvTools/external/googletest/docs/pkgconfig.md

@@ -19,19 +19,15 @@ examples here we assume you want to compile the sample
 Using `pkg-config` in CMake is fairly easy:
 
 ```cmake
-cmake_minimum_required(VERSION 3.0)
-
-cmake_policy(SET CMP0048 NEW)
-project(my_gtest_pkgconfig VERSION 0.0.1 LANGUAGES CXX)
-
 find_package(PkgConfig)
 pkg_search_module(GTEST REQUIRED gtest_main)
 
-add_executable(testapp samples/sample3_unittest.cc)
-target_link_libraries(testapp ${GTEST_LDFLAGS})
-target_compile_options(testapp PUBLIC ${GTEST_CFLAGS})
+add_executable(testapp)
+target_sources(testapp PRIVATE samples/sample3_unittest.cc)
+target_link_libraries(testapp PRIVATE ${GTEST_LDFLAGS})
+target_compile_options(testapp PRIVATE ${GTEST_CFLAGS})
 
-include(CTest)
+enable_testing()
 add_test(first_and_only_test testapp)
 ```
 

+ 6 - 33
ThirdParty/SpirvTools/external/googletest/docs/platforms.md

@@ -1,35 +1,8 @@
 # Supported Platforms
 
-GoogleTest requires a codebase and compiler compliant with the C++11 standard or
-newer.
-
-The GoogleTest code is officially supported on the following platforms.
-Operating systems or tools not listed below are community-supported. For
-community-supported platforms, patches that do not complicate the code may be
-considered.
-
-If you notice any problems on your platform, please file an issue on the
-[GoogleTest GitHub Issue Tracker](https://github.com/google/googletest/issues).
-Pull requests containing fixes are welcome!
-
-### Operating systems
-
-*   Linux
-*   macOS
-*   Windows
-
-### Compilers
-
-*   gcc 5.0+
-*   clang 5.0+
-*   MSVC 2015+
-
-**macOS users:** Xcode 9.3+ provides clang 5.0+.
-
-### Build systems
-
-*   [Bazel](https://bazel.build/)
-*   [CMake](https://cmake.org/)
-
-Bazel is the build system used by the team internally and in tests. CMake is
-supported on a best-effort basis and by the community.
+GoogleTest follows Google's
+[Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support).
+See
+[this table](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md)
+for a list of currently supported versions compilers, platforms, and build
+tools.

+ 65 - 66
ThirdParty/SpirvTools/external/googletest/docs/primer.md

@@ -1,84 +1,84 @@
-# Googletest Primer
+# GoogleTest Primer
 
-## Introduction: Why googletest?
+## Introduction: Why GoogleTest?
 
-*googletest* helps you write better C++ tests.
+*GoogleTest* helps you write better C++ tests.
 
-googletest is a testing framework developed by the Testing Technology team with
+GoogleTest is a testing framework developed by the Testing Technology team with
 Google's specific requirements and constraints in mind. Whether you work on
-Linux, Windows, or a Mac, if you write C++ code, googletest can help you. And it
+Linux, Windows, or a Mac, if you write C++ code, GoogleTest can help you. And it
 supports *any* kind of tests, not just unit tests.
 
-So what makes a good test, and how does googletest fit in? We believe:
+So what makes a good test, and how does GoogleTest fit in? We believe:
 
 1.  Tests should be *independent* and *repeatable*. It's a pain to debug a test
-    that succeeds or fails as a result of other tests. googletest isolates the
+    that succeeds or fails as a result of other tests. GoogleTest isolates the
     tests by running each of them on a different object. When a test fails,
-    googletest allows you to run it in isolation for quick debugging.
+    GoogleTest allows you to run it in isolation for quick debugging.
 2.  Tests should be well *organized* and reflect the structure of the tested
-    code. googletest groups related tests into test suites that can share data
+    code. GoogleTest groups related tests into test suites that can share data
     and subroutines. This common pattern is easy to recognize and makes tests
     easy to maintain. Such consistency is especially helpful when people switch
     projects and start to work on a new code base.
 3.  Tests should be *portable* and *reusable*. Google has a lot of code that is
-    platform-neutral; its tests should also be platform-neutral. googletest
+    platform-neutral; its tests should also be platform-neutral. GoogleTest
     works on different OSes, with different compilers, with or without
-    exceptions, so googletest tests can work with a variety of configurations.
+    exceptions, so GoogleTest tests can work with a variety of configurations.
 4.  When tests fail, they should provide as much *information* about the problem
-    as possible. googletest doesn't stop at the first test failure. Instead, it
+    as possible. GoogleTest doesn't stop at the first test failure. Instead, it
     only stops the current test and continues with the next. You can also set up
     tests that report non-fatal failures after which the current test continues.
     Thus, you can detect and fix multiple bugs in a single run-edit-compile
     cycle.
 5.  The testing framework should liberate test writers from housekeeping chores
-    and let them focus on the test *content*. googletest automatically keeps
+    and let them focus on the test *content*. GoogleTest automatically keeps
     track of all tests defined, and doesn't require the user to enumerate them
     in order to run them.
-6.  Tests should be *fast*. With googletest, you can reuse shared resources
+6.  Tests should be *fast*. With GoogleTest, you can reuse shared resources
     across tests and pay for the set-up/tear-down only once, without making
     tests depend on each other.
 
-Since googletest is based on the popular xUnit architecture, you'll feel right
+Since GoogleTest is based on the popular xUnit architecture, you'll feel right
 at home if you've used JUnit or PyUnit before. If not, it will take you about 10
 minutes to learn the basics and get started. So let's go!
 
-## Beware of the nomenclature
+## Beware of the Nomenclature
 
 {: .callout .note}
-_Note:_ There might be some confusion arising from different definitions of the
-terms _Test_, _Test Case_ and _Test Suite_, so beware of misunderstanding these.
+*Note:* There might be some confusion arising from different definitions of the
+terms *Test*, *Test Case* and *Test Suite*, so beware of misunderstanding these.
 
-Historically, googletest started to use the term _Test Case_ for grouping
+Historically, GoogleTest started to use the term *Test Case* for grouping
 related tests, whereas current publications, including International Software
-Testing Qualifications Board ([ISTQB](http://www.istqb.org/)) materials and
+Testing Qualifications Board ([ISTQB](https://www.istqb.org/)) materials and
 various textbooks on software quality, use the term
-_[Test Suite][istqb test suite]_ for this.
+*[Test Suite][istqb test suite]* for this.
 
-The related term _Test_, as it is used in googletest, corresponds to the term
-_[Test Case][istqb test case]_ of ISTQB and others.
+The related term *Test*, as it is used in GoogleTest, corresponds to the term
+*[Test Case][istqb test case]* of ISTQB and others.
 
-The term _Test_ is commonly of broad enough sense, including ISTQB's definition
-of _Test Case_, so it's not much of a problem here. But the term _Test Case_ as
+The term *Test* is commonly of broad enough sense, including ISTQB's definition
+of *Test Case*, so it's not much of a problem here. But the term *Test Case* as
 was used in Google Test is of contradictory sense and thus confusing.
 
-googletest recently started replacing the term _Test Case_ with _Test Suite_.
+GoogleTest recently started replacing the term *Test Case* with *Test Suite*.
 The preferred API is *TestSuite*. The older TestCase API is being slowly
 deprecated and refactored away.
 
 So please be aware of the different definitions of the terms:
 
 
-Meaning                                                                              | googletest Term         | [ISTQB](http://www.istqb.org/) Term
+Meaning                                                                              | GoogleTest Term         | [ISTQB](https://www.istqb.org/) Term
 :----------------------------------------------------------------------------------- | :---------------------- | :----------------------------------
 Exercise a particular program path with specific input values and verify the results | [TEST()](#simple-tests) | [Test Case][istqb test case]
 
 
-[istqb test case]: http://glossary.istqb.org/en/search/test%20case
-[istqb test suite]: http://glossary.istqb.org/en/search/test%20suite
+[istqb test case]: https://glossary.istqb.org/en_US/term/test-case
+[istqb test suite]: https://glossary.istqb.org/en_US/term/test-suite
 
 ## Basic Concepts
 
-When using googletest, you start by writing *assertions*, which are statements
+When using GoogleTest, you start by writing *assertions*, which are statements
 that check whether a condition is true. An assertion's result can be *success*,
 *nonfatal failure*, or *fatal failure*. If a fatal failure occurs, it aborts the
 current function; otherwise the program continues normally.
@@ -98,11 +98,11 @@ assertion level and building up to tests and test suites.
 
 ## Assertions
 
-googletest assertions are macros that resemble function calls. You test a class
+GoogleTest assertions are macros that resemble function calls. You test a class
 or function by making assertions about its behavior. When an assertion fails,
-googletest prints the assertion's source file and line number location, along
+GoogleTest prints the assertion's source file and line number location, along
 with a failure message. You may also supply a custom failure message which will
-be appended to googletest's message.
+be appended to GoogleTest's message.
 
 The assertions come in pairs that test the same thing but have different effects
 on the current function. `ASSERT_*` versions generate fatal failures when they
@@ -149,7 +149,7 @@ To create a test:
 1.  Use the `TEST()` macro to define and name a test function. These are
     ordinary C++ functions that don't return a value.
 2.  In this function, along with any valid C++ statements you want to include,
-    use the various googletest assertions to check values.
+    use the various GoogleTest assertions to check values.
 3.  The test's result is determined by the assertions; if any assertion in the
     test fails (either fatally or non-fatally), or if the test crashes, the
     entire test fails. Otherwise, it succeeds.
@@ -190,7 +190,7 @@ TEST(FactorialTest, HandlesPositiveInput) {
 }
 ```
 
-googletest groups the test results by test suites, so logically related tests
+GoogleTest groups the test results by test suites, so logically related tests
 should be in the same test suite; in other words, the first argument to their
 `TEST()` should be the same. In the above example, we have two tests,
 `HandlesZeroInput` and `HandlesPositiveInput`, that belong to the same test
@@ -210,7 +210,7 @@ objects for several different tests.
 
 To create a fixture:
 
-1.  Derive a class from `::testing::Test` . Start its body with `protected:`, as
+1.  Derive a class from `testing::Test` . Start its body with `protected:`, as
     we'll want to access fixture members from sub-classes.
 2.  Inside the class, declare any objects you plan to use.
 3.  If necessary, write a default constructor or `SetUp()` function to prepare
@@ -227,14 +227,14 @@ When using a fixture, use `TEST_F()` instead of `TEST()` as it allows you to
 access objects and subroutines in the test fixture:
 
 ```c++
-TEST_F(TestFixtureName, TestName) {
+TEST_F(TestFixtureClassName, TestName) {
   ... test body ...
 }
 ```
 
-Like `TEST()`, the first argument is the test suite name, but for `TEST_F()`
-this must be the name of the test fixture class. You've probably guessed: `_F`
-is for fixture.
+Unlike `TEST()`, in `TEST_F()` the first argument must be the name of the test
+fixture class. (`_F` stands for "Fixture"). No test suite name is specified for
+this macro.
 
 Unfortunately, the C++ macro system does not allow us to create a single macro
 that can handle both types of tests. Using the wrong macro causes a compiler
@@ -244,12 +244,12 @@ Also, you must first define a test fixture class before using it in a
 `TEST_F()`, or you'll get the compiler error "`virtual outside class
 declaration`".
 
-For each test defined with `TEST_F()`, googletest will create a *fresh* test
+For each test defined with `TEST_F()`, GoogleTest will create a *fresh* test
 fixture at runtime, immediately initialize it via `SetUp()`, run the test, clean
 up by calling `TearDown()`, and then delete the test fixture. Note that
 different tests in the same test suite have different test fixture objects, and
-googletest always deletes a test fixture before it creates the next one.
-googletest does **not** reuse the same test fixture for multiple tests. Any
+GoogleTest always deletes a test fixture before it creates the next one.
+GoogleTest does **not** reuse the same test fixture for multiple tests. Any
 changes one test makes to the fixture do not affect other tests.
 
 As an example, let's write tests for a FIFO queue class named `Queue`, which has
@@ -271,16 +271,16 @@ First, define a fixture class. By convention, you should give it the name
 `FooTest` where `Foo` is the class being tested.
 
 ```c++
-class QueueTest : public ::testing::Test {
+class QueueTest : public testing::Test {
  protected:
-  void SetUp() override {
+  QueueTest() {
      // q0_ remains empty
      q1_.Enqueue(1);
      q2_.Enqueue(2);
      q2_.Enqueue(3);
   }
 
-  // void TearDown() override {}
+  // ~QueueTest() override = default;
 
   Queue<int> q0_;
   Queue<int> q1_;
@@ -288,8 +288,9 @@ class QueueTest : public ::testing::Test {
 };
 ```
 
-In this case, `TearDown()` is not needed since we don't have to clean up after
-each test, other than what's already done by the destructor.
+In this case, we don't need to define a destructor or a `TearDown()` method,
+because the implicit destructor generated by the compiler will perform all of
+the necessary cleanup.
 
 Now we'll write tests using `TEST_F()` and this fixture.
 
@@ -325,19 +326,17 @@ would lead to a segfault when `n` is `NULL`.
 
 When these tests run, the following happens:
 
-1.  googletest constructs a `QueueTest` object (let's call it `t1`).
-2.  `t1.SetUp()` initializes `t1`.
-3.  The first test (`IsEmptyInitially`) runs on `t1`.
-4.  `t1.TearDown()` cleans up after the test finishes.
-5.  `t1` is destructed.
-6.  The above steps are repeated on another `QueueTest` object, this time
+1.  GoogleTest constructs a `QueueTest` object (let's call it `t1`).
+2.  The first test (`IsEmptyInitially`) runs on `t1`.
+3.  `t1` is destructed.
+4.  The above steps are repeated on another `QueueTest` object, this time
     running the `DequeueWorks` test.
 
 **Availability**: Linux, Windows, Mac.
 
 ## Invoking the Tests
 
-`TEST()` and `TEST_F()` implicitly register their tests with googletest. So,
+`TEST()` and `TEST_F()` implicitly register their tests with GoogleTest. So,
 unlike with many other C++ testing frameworks, you don't have to re-list all
 your defined tests in order to run them.
 
@@ -348,7 +347,7 @@ test suites, or even different source files.
 
 When invoked, the `RUN_ALL_TESTS()` macro:
 
-*   Saves the state of all googletest flags.
+*   Saves the state of all GoogleTest flags.
 
 *   Creates a test fixture object for the first test.
 
@@ -360,7 +359,7 @@ When invoked, the `RUN_ALL_TESTS()` macro:
 
 *   Deletes the fixture.
 
-*   Restores the state of all googletest flags.
+*   Restores the state of all GoogleTest flags.
 
 *   Repeats the above steps for the next test, until all tests have run.
 
@@ -374,14 +373,14 @@ If a fatal failure happens the subsequent steps will be skipped.
 > return the value of `RUN_ALL_TESTS()`.
 >
 > Also, you should call `RUN_ALL_TESTS()` only **once**. Calling it more than
-> once conflicts with some advanced googletest features (e.g., thread-safe
+> once conflicts with some advanced GoogleTest features (e.g., thread-safe
 > [death tests](advanced.md#death-tests)) and thus is not supported.
 
 **Availability**: Linux, Windows, Mac.
 
 ## Writing the main() Function
 
-Most users should _not_ need to write their own `main` function and instead link
+Most users should *not* need to write their own `main` function and instead link
 with `gtest_main` (as opposed to with `gtest`), which defines a suitable entry
 point. See the end of this section for details. The remainder of this section
 should only apply when you need to do something custom before the tests run that
@@ -395,14 +394,14 @@ You can start from this boilerplate:
 ```c++
 #include "this/package/foo.h"
 
-#include "gtest/gtest.h"
+#include <gtest/gtest.h>
 
 namespace my {
 namespace project {
 namespace {
 
 // The fixture for testing class Foo.
-class FooTest : public ::testing::Test {
+class FooTest : public testing::Test {
  protected:
   // You can remove any or all of the following functions if their bodies would
   // be empty.
@@ -450,14 +449,14 @@ TEST_F(FooTest, DoesXyz) {
 }  // namespace my
 
 int main(int argc, char **argv) {
-  ::testing::InitGoogleTest(&argc, argv);
+  testing::InitGoogleTest(&argc, argv);
   return RUN_ALL_TESTS();
 }
 ```
 
-The `::testing::InitGoogleTest()` function parses the command line for
-googletest flags, and removes all recognized flags. This allows the user to
-control a test program's behavior via various flags, which we'll cover in the
+The `testing::InitGoogleTest()` function parses the command line for GoogleTest
+flags, and removes all recognized flags. This allows the user to control a test
+program's behavior via various flags, which we'll cover in the
 [AdvancedGuide](advanced.md). You **must** call this function before calling
 `RUN_ALL_TESTS()`, or the flags won't be properly initialized.
 
@@ -476,7 +475,7 @@ NOTE: `ParseGUnitFlags()` is deprecated in favor of `InitGoogleTest()`.
 
 *   Google Test is designed to be thread-safe. The implementation is thread-safe
     on systems where the `pthreads` library is available. It is currently
-    _unsafe_ to use Google Test assertions from two threads concurrently on
+    *unsafe* to use Google Test assertions from two threads concurrently on
     other systems (e.g. Windows). In most tests this is not an issue as usually
     the assertions are done in the main thread. If you want to help, you can
     volunteer to implement the necessary synchronization primitives in

+ 30 - 30
ThirdParty/SpirvTools/external/googletest/docs/quickstart-bazel.md

@@ -10,8 +10,8 @@ To complete this tutorial, you'll need:
 
 *   A compatible operating system (e.g. Linux, macOS, Windows).
 *   A compatible C++ compiler that supports at least C++14.
-*   [Bazel](https://bazel.build/), the preferred build system used by the
-    GoogleTest team.
+*   [Bazel](https://bazel.build/) 7.0 or higher, the preferred build system used
+    by the GoogleTest team.
 
 See [Supported Platforms](platforms.md) for more information about platforms
 compatible with GoogleTest.
@@ -28,7 +28,7 @@ A
 [Bazel workspace](https://docs.bazel.build/versions/main/build-ref.html#workspace)
 is a directory on your filesystem that you use to manage source files for the
 software you want to build. Each workspace directory has a text file named
-`WORKSPACE` which may be empty, or may contain references to external
+`MODULE.bazel` which may be empty, or may contain references to external
 dependencies required to build the outputs.
 
 First, create a directory for your workspace:
@@ -37,30 +37,20 @@ First, create a directory for your workspace:
 $ mkdir my_workspace && cd my_workspace
 ```
 
-Next, you’ll create the `WORKSPACE` file to specify dependencies. A common and
-recommended way to depend on GoogleTest is to use a
-[Bazel external dependency](https://docs.bazel.build/versions/main/external.html)
-via the
-[`http_archive` rule](https://docs.bazel.build/versions/main/repo/http.html#http_archive).
-To do this, in the root directory of your workspace (`my_workspace/`), create a
-file named `WORKSPACE` with the following contents:
+Next, you’ll create the `MODULE.bazel` file to specify dependencies. As of Bazel
+7.0, the recommended way to consume GoogleTest is through the
+[Bazel Central Registry](https://registry.bazel.build/modules/googletest). To do
+this, create a `MODULE.bazel` file in the root directory of your Bazel workspace
+with the following content:
 
 ```
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+# MODULE.bazel
 
-http_archive(
-  name = "com_google_googletest",
-  urls = ["https://github.com/google/googletest/archive/5ab508a01f9eb089207ee87fd547d290da39d015.zip"],
-  strip_prefix = "googletest-5ab508a01f9eb089207ee87fd547d290da39d015",
-)
+# Choose the most recent version available at
+# https://registry.bazel.build/modules/googletest
+bazel_dep(name = "googletest", version = "1.15.2")
 ```
 
-The above configuration declares a dependency on GoogleTest which is downloaded
-as a ZIP archive from GitHub. In the above example,
-`5ab508a01f9eb089207ee87fd547d290da39d015` is the Git commit hash of the
-GoogleTest version to use; we recommend updating the hash often to point to the
-latest version. Use a recent hash on the `main` branch.
-
 Now you're ready to build C++ code that uses GoogleTest.
 
 ## Create and run a binary
@@ -92,23 +82,33 @@ following contents:
 
 ```
 cc_test(
-  name = "hello_test",
-  size = "small",
-  srcs = ["hello_test.cc"],
-  deps = ["@com_google_googletest//:gtest_main"],
+    name = "hello_test",
+    size = "small",
+    srcs = ["hello_test.cc"],
+    deps = [
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
+    ],
 )
 ```
 
 This `cc_test` rule declares the C++ test binary you want to build, and links to
-GoogleTest (`//:gtest_main`) using the prefix you specified in the `WORKSPACE`
-file (`@com_google_googletest`). For more information about Bazel `BUILD` files,
-see the
+the GoogleTest library (`@googletest//:gtest"`) and the GoogleTest `main()`
+function (`@googletest//:gtest_main`). For more information about Bazel `BUILD`
+files, see the
 [Bazel C++ Tutorial](https://docs.bazel.build/versions/main/tutorial/cpp.html).
 
+{: .callout .note}
+NOTE: In the example below, we assume Clang or GCC and set `--cxxopt=-std=c++14`
+to ensure that GoogleTest is compiled as C++14 instead of the compiler's default
+setting (which could be C++11). For MSVC, the equivalent would be
+`--cxxopt=/std:c++14`. See [Supported Platforms](platforms.md) for more details
+on supported language versions.
+
 Now you can build and run your test:
 
 <pre>
-<strong>my_workspace$ bazel test --test_output=all //:hello_test</strong>
+<strong>$ bazel test --cxxopt=-std=c++14 --test_output=all //:hello_test</strong>
 INFO: Analyzed target //:hello_test (26 packages loaded, 362 targets configured).
 INFO: Found 1 test target...
 INFO: From Testing //:hello_test:

+ 1 - 0
ThirdParty/SpirvTools/external/googletest/docs/quickstart-cmake.md

@@ -54,6 +54,7 @@ project(my_project)
 
 # GoogleTest requires at least C++14
 set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
 include(FetchContent)
 FetchContent_Declare(

+ 2 - 1
ThirdParty/SpirvTools/external/googletest/docs/reference/actions.md

@@ -24,7 +24,8 @@ provided by GoogleTest. All actions are defined in the `::testing` namespace.
 | :--------------------------------- | :-------------------------------------- |
 | `Assign(&variable, value)` | Assign `value` to variable. |
 | `DeleteArg<N>()` | Delete the `N`-th (0-based) argument, which must be a pointer. |
-| `SaveArg<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer`. |
+| `SaveArg<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer` by copy-assignment. |
+| `SaveArgByMove<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer` by move-assignment. |
 | `SaveArgPointee<N>(pointer)` | Save the value pointed to by the `N`-th (0-based) argument to `*pointer`. |
 | `SetArgReferee<N>(value)` | Assign `value` to the variable referenced by the `N`-th (0-based) argument. |
 | `SetArgPointee<N>(value)` | Assign `value` to the variable pointed by the `N`-th (0-based) argument. |

+ 12 - 5
ThirdParty/SpirvTools/external/googletest/docs/reference/assertions.md

@@ -1,7 +1,7 @@
 # Assertions Reference
 
 This page lists the assertion macros provided by GoogleTest for verifying code
-behavior. To use them, include the header `gtest/gtest.h`.
+behavior. To use them, add `#include <gtest/gtest.h>`.
 
 The majority of the macros listed below come as a pair with an `EXPECT_` variant
 and an `ASSERT_` variant. Upon failure, `EXPECT_` macros generate nonfatal
@@ -88,7 +88,7 @@ For example, the following code verifies that the string `value1` starts with
 10:
 
 ```cpp
-#include "gmock/gmock.h"
+#include <gmock/gmock.h>
 
 using ::testing::AllOf;
 using ::testing::Gt;
@@ -276,7 +276,8 @@ Units in the Last Place (ULPs). To learn more about ULPs, see the article
 `ASSERT_FLOAT_EQ(`*`val1`*`,`*`val2`*`)`
 
 Verifies that the two `float` values *`val1`* and *`val2`* are approximately
-equal, to within 4 ULPs from each other.
+equal, to within 4 ULPs from each other. Infinity and the largest finite float
+value are considered to be one ULP apart.
 
 ### EXPECT_DOUBLE_EQ {#EXPECT_DOUBLE_EQ}
 
@@ -284,7 +285,8 @@ equal, to within 4 ULPs from each other.
 `ASSERT_DOUBLE_EQ(`*`val1`*`,`*`val2`*`)`
 
 Verifies that the two `double` values *`val1`* and *`val2`* are approximately
-equal, to within 4 ULPs from each other.
+equal, to within 4 ULPs from each other. Infinity and the largest finite double
+value are considered to be one ULP apart.
 
 ### EXPECT_NEAR {#EXPECT_NEAR}
 
@@ -294,6 +296,11 @@ equal, to within 4 ULPs from each other.
 Verifies that the difference between *`val1`* and *`val2`* does not exceed the
 absolute error bound *`abs_error`*.
 
+If *`val`* and *`val2`* are both infinity of the same sign, the difference is
+considered to be 0. Otherwise, if either value is infinity, the difference is
+considered to be infinity. All non-NaN values (including infinity) are
+considered to not exceed an *`abs_error`* of infinity.
+
 ## Exception Assertions {#exceptions}
 
 The following assertions verify that a piece of code throws, or does not throw,
@@ -515,7 +522,7 @@ Verifies that *`expression`* is a success `HRESULT`.
 ### EXPECT_HRESULT_FAILED {#EXPECT_HRESULT_FAILED}
 
 `EXPECT_HRESULT_FAILED(`*`expression`*`)` \
-`EXPECT_HRESULT_FAILED(`*`expression`*`)`
+`ASSERT_HRESULT_FAILED(`*`expression`*`)`
 
 Verifies that *`expression`* is a failure `HRESULT`.
 

+ 7 - 4
ThirdParty/SpirvTools/external/googletest/docs/reference/matchers.md

@@ -42,6 +42,8 @@ Matcher                     | Description
 | `Lt(value)`            | `argument < value`                                  |
 | `Ne(value)`            | `argument != value`                                 |
 | `IsFalse()`            | `argument` evaluates to `false` in a Boolean context. |
+| `DistanceFrom(target, m)` | The distance between `argument` and `target` (computed by `abs(argument - target)`) matches `m`. |
+| `DistanceFrom(target, get_distance, m)` | The distance between `argument` and `target` (computed by `get_distance(argument, target)`) matches `m`. |
 | `IsTrue()`             | `argument` evaluates to `true` in a Boolean context. |
 | `IsNull()`             | `argument` is a `NULL` pointer (raw or smart).      |
 | `NotNull()`            | `argument` is a non-null pointer (raw or smart).    |
@@ -171,6 +173,11 @@ messages, you can use:
 | `Property(&class::property, m)` | `argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. The method `property()` must take no argument and be declared as `const`. |
 | `Property(property_name, &class::property, m)` | The same as the two-parameter version, but provides a better error message.
 
+{: .callout .warning}
+Warning: Don't use `Property()` against member functions that you do not own,
+because taking addresses of functions is fragile and generally not part of the
+contract of the function.
+
 **Notes:**
 
 *   You can use `FieldsAre()` to match any type that supports structured
@@ -189,10 +196,6 @@ messages, you can use:
     EXPECT_THAT(s, FieldsAre(42, "aloha"));
     ```
 
-*   Don't use `Property()` against member functions that you do not own, because
-    taking addresses of functions is fragile and generally not part of the
-    contract of the function.
-
 ## Matching the Result of a Function, Functor, or Callback
 
 | Matcher          | Description                                       |

+ 1 - 2
ThirdParty/SpirvTools/external/googletest/docs/reference/mocking.md

@@ -1,8 +1,7 @@
 # Mocking Reference
 
 This page lists the facilities provided by GoogleTest for creating and working
-with mock objects. To use them, include the header
-`gmock/gmock.h`.
+with mock objects. To use them, add `#include <gmock/gmock.h>`.
 
 ## Macros {#macros}
 

+ 159 - 40
ThirdParty/SpirvTools/external/googletest/docs/reference/testing.md

@@ -3,7 +3,7 @@
 <!--* toc_depth: 3 *-->
 
 This page lists the facilities provided by GoogleTest for writing test programs.
-To use them, include the header `gtest/gtest.h`.
+To use them, add `#include <gtest/gtest.h>`.
 
 ## Macros
 
@@ -94,7 +94,8 @@ Instantiates the value-parameterized test suite *`TestSuiteName`* (defined with
 The argument *`InstantiationName`* is a unique name for the instantiation of the
 test suite, to distinguish between multiple instantiations. In test output, the
 instantiation name is added as a prefix to the test suite name
-*`TestSuiteName`*.
+*`TestSuiteName`*. If *`InstantiationName`* is empty
+(`INSTANTIATE_TEST_SUITE_P(, ...)`), no prefix is added.
 
 The argument *`param_generator`* is one of the following GoogleTest-provided
 functions that generate the test parameters, all defined in the `::testing`
@@ -109,7 +110,8 @@ namespace:
 | `ValuesIn(container)` or `ValuesIn(begin,end)` | Yields values from a C-style array, an STL-style container, or an iterator range `[begin, end)`. |
 | `Bool()`                     | Yields sequence `{false, true}`.            |
 | `Combine(g1, g2, ..., gN)`   | Yields as `std::tuple` *n*-tuples all combinations (Cartesian product) of the values generated by the given *n* generators `g1`, `g2`, ..., `gN`. |
-| `ConvertGenerator<T>(g)`     | Yields values generated by generator `g`, `static_cast` to `T`. |
+| `ConvertGenerator<T>(g)` or `ConvertGenerator(g, func)`    | Yields values generated by generator `g`, `static_cast` from `T`. (Note: `T` might not be what you expect. See [*Using ConvertGenerator*](#using-convertgenerator) below.) The second overload uses `func` to perform the conversion. |
+
 The optional last argument *`name_generator`* is a function or functor that
 generates custom test name suffixes based on the test parameters. The function
 must accept an argument of type
@@ -121,8 +123,8 @@ custom function can be used for more control:
 ```cpp
 INSTANTIATE_TEST_SUITE_P(
     MyInstantiation, MyTestSuite,
-    ::testing::Values(...),
-    [](const ::testing::TestParamInfo<MyTestSuite::ParamType>& info) {
+    testing::Values(...),
+    [](const testing::TestParamInfo<MyTestSuite::ParamType>& info) {
       // Can use info.param here to generate the test suffix
       std::string name = ...
       return name;
@@ -135,9 +137,107 @@ For more information, see
 See also
 [`GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST`](#GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST).
 
+###### Using `ConvertGenerator`
+
+The functions listed in the table above appear to return generators that create
+values of the desired types, but this is not generally the case. Rather, they
+typically return factory objects that convert to the the desired generators.
+This affords some flexibility in allowing you to specify values of types that
+are different from, yet implicitly convertible to, the actual parameter type
+required by your fixture class.
+
+For example, you can do the following with a fixture that requires an `int`
+parameter:
+
+```cpp
+INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
+    testing::Values(1, 1.2));  // Yes, Values() supports heterogeneous argument types.
+```
+
+It might seem obvious that `1.2` &mdash; a `double` &mdash; will be converted to
+an `int` but in actuality it requires some template gymnastics involving the
+indirection described in the previous paragraph.
+
+What if your parameter type is not implicitly convertible from the generated
+type but is *explicitly* convertible? There will be no automatic conversion, but
+you can force it by applying `ConvertGenerator<T>`. The compiler can
+automatically deduce the target type (your fixture's parameter type), but
+because of the aforementioned indirection it cannot decide what the generated
+type should be. You need to tell it, by providing the type `T` explicitly. Thus
+`T` should not be your fixture's parameter type, but rather an intermediate type
+that is supported by the factory object, and which can be `static_cast` to the
+fixture's parameter type:
+
+```cpp
+// The fixture's parameter type.
+class MyParam {
+ public:
+  // Explicit converting ctor.
+  explicit MyParam(const std::tuple<int, bool>& t);
+  ...
+};
+
+INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
+    ConvertGenerator<std::tuple<int, bool>>(Combine(Values(0.1, 1.2), Bool())));
+```
+
+In this example `Combine` supports the generation of `std::tuple<int, bool>>`
+objects (even though the provided values for the first tuple element are
+`double`s) and those `tuple`s get converted into `MyParam` objects by virtue of
+the call to `ConvertGenerator`.
+
+For parameter types that are not convertible from the generated types you can
+provide a callable that does the conversion. The callable accepts an object of
+the generated type and returns an object of the fixture's parameter type. The
+generated type can often be deduced by the compiler from the callable's call
+signature so you do not usually need specify it explicitly (but see a caveat
+below).
+
+```cpp
+// The fixture's parameter type.
+class MyParam {
+ public:
+  MyParam(int, bool);
+  ...
+};
+
+INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
+    ConvertGenerator(Combine(Values(1, 1.2), Bool()),
+        [](const std::tuple<int i, bool>& t){
+          const auto [i, b] = t;
+          return MyParam(i, b);
+        }));
+```
+
+The callable may be anything that can be used to initialize a `std::function`
+with the appropriate call signature. Note the callable's return object gets
+`static_cast` to the fixture's parameter type, so it does not have to be of that
+exact type, only convertible to it.
+
+**Caveat:** Consider the following example.
+
+```cpp
+INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
+    ConvertGenerator(Values(std::string("s")), [](std::string_view s) { ... }));
+```
+
+The `string` argument gets copied into the factory object returned by `Values`.
+Then, because the generated type deduced from the lambda is `string_view`, the
+factory object spawns a generator that holds a `string_view` referencing that
+`string`. Unfortunately, by the time this generator gets invoked, the factory
+object is gone and the `string_view` is dangling.
+
+To overcome this problem you can specify the generated type explicitly:
+`ConvertGenerator<std::string>(Values(std::string("s")), [](std::string_view s)
+{ ... })`. Alternatively, you can change the lambda's signature to take a
+`std::string` or a `const std::string&` (the latter will not leave you with a
+dangling reference because the type deduction strips off the reference and the
+`const`).
+
 ### TYPED_TEST_SUITE {#TYPED_TEST_SUITE}
 
 `TYPED_TEST_SUITE(`*`TestFixtureName`*`,`*`Types`*`)`
+`TYPED_TEST_SUITE(`*`TestFixtureName`*`,`*`Types`*`,`*`NameGenerator`*`)`
 
 Defines a typed test suite based on the test fixture *`TestFixtureName`*. The
 test suite name is *`TestFixtureName`*.
@@ -147,7 +247,7 @@ type, for example:
 
 ```cpp
 template <typename T>
-class MyFixture : public ::testing::Test {
+class MyFixture : public testing::Test {
  public:
   ...
   using List = std::list<T>;
@@ -167,6 +267,22 @@ TYPED_TEST_SUITE(MyFixture, MyTypes);
 The type alias (`using` or `typedef`) is necessary for the `TYPED_TEST_SUITE`
 macro to parse correctly.
 
+The optional third argument *`NameGenerator`* allows specifying a class that
+exposes a templated static function `GetName(int)`. For example:
+
+```cpp
+class NameGenerator {
+ public:
+  template <typename T>
+  static std::string GetName(int) {
+    if constexpr (std::is_same_v<T, char>) return "char";
+    if constexpr (std::is_same_v<T, int>) return "int";
+    if constexpr (std::is_same_v<T, unsigned int>) return "unsignedInt";
+  }
+};
+TYPED_TEST_SUITE(MyFixture, MyTypes, NameGenerator);
+```
+
 See also [`TYPED_TEST`](#TYPED_TEST) and
 [Typed Tests](../advanced.md#typed-tests) for more information.
 
@@ -276,7 +392,8 @@ must be registered with
 The argument *`InstantiationName`* is a unique name for the instantiation of the
 test suite, to distinguish between multiple instantiations. In test output, the
 instantiation name is added as a prefix to the test suite name
-*`TestSuiteName`*.
+*`TestSuiteName`*. If *`InstantiationName`* is empty
+(`INSTANTIATE_TYPED_TEST_SUITE_P(, ...)`), no prefix is added.
 
 The argument *`Types`* is a [`Types`](#Types) object representing the list of
 types to run the tests on, for example:
@@ -323,7 +440,7 @@ Then the test code should look like:
 ```cpp
 namespace my_namespace {
 
-class MyClassTest : public ::testing::Test {
+class MyClassTest : public testing::Test {
   ...
 };
 
@@ -386,7 +503,7 @@ GoogleTest defines the following classes and types to help with writing tests.
 
 ### AssertionResult {#AssertionResult}
 
-`::testing::AssertionResult`
+`testing::AssertionResult`
 
 A class for indicating whether an assertion was successful.
 
@@ -400,14 +517,14 @@ To create an instance of this class, use one of the factory functions
 
 ### AssertionException {#AssertionException}
 
-`::testing::AssertionException`
+`testing::AssertionException`
 
 Exception which can be thrown from
 [`TestEventListener::OnTestPartResult`](#TestEventListener::OnTestPartResult).
 
 ### EmptyTestEventListener {#EmptyTestEventListener}
 
-`::testing::EmptyTestEventListener`
+`testing::EmptyTestEventListener`
 
 Provides an empty implementation of all methods in the
 [`TestEventListener`](#TestEventListener) interface, such that a subclass only
@@ -415,7 +532,7 @@ needs to override the methods it cares about.
 
 ### Environment {#Environment}
 
-`::testing::Environment`
+`testing::Environment`
 
 Represents a global test environment. See
 [Global Set-Up and Tear-Down](../advanced.md#global-set-up-and-tear-down).
@@ -436,7 +553,7 @@ Override this to define how to tear down the environment.
 
 ### ScopedTrace {#ScopedTrace}
 
-`::testing::ScopedTrace`
+`testing::ScopedTrace`
 
 An instance of this class causes a trace to be included in every test failure
 message generated by code in the scope of the lifetime of the `ScopedTrace`
@@ -452,7 +569,7 @@ ScopedTrace(const char* file, int line, const T& message)
 Example usage:
 
 ```cpp
-::testing::ScopedTrace trace("file.cc", 123, "message");
+testing::ScopedTrace trace("file.cc", 123, "message");
 ```
 
 The resulting trace includes the given source file path and line number, and the
@@ -463,7 +580,7 @@ See also [`SCOPED_TRACE`](#SCOPED_TRACE).
 
 ### Test {#Test}
 
-`::testing::Test`
+`testing::Test`
 
 The abstract class that all tests inherit from. `Test` is not copyable.
 
@@ -551,7 +668,7 @@ after running each individual test.
 
 ### TestWithParam {#TestWithParam}
 
-`::testing::TestWithParam<T>`
+`testing::TestWithParam<T>`
 
 A convenience class which inherits from both [`Test`](#Test) and
 [`WithParamInterface<T>`](#WithParamInterface).
@@ -671,7 +788,7 @@ during execution of `SetUpTestSuite` and `TearDownTestSuite`.
 
 ### TestInfo {#TestInfo}
 
-`::testing::TestInfo`
+`testing::TestInfo`
 
 Stores information about a test.
 
@@ -750,7 +867,7 @@ Returns the result of the test. See [`TestResult`](#TestResult).
 
 ### TestParamInfo {#TestParamInfo}
 
-`::testing::TestParamInfo<T>`
+`testing::TestParamInfo<T>`
 
 Describes a parameter to a value-parameterized test. The type `T` is the type of
 the parameter.
@@ -760,7 +877,7 @@ and its integer index respectively.
 
 ### UnitTest {#UnitTest}
 
-`::testing::UnitTest`
+`testing::UnitTest`
 
 This class contains information about the test program.
 
@@ -928,7 +1045,7 @@ GoogleTest. See [`TestEventListeners`](#TestEventListeners).
 
 ### TestEventListener {#TestEventListener}
 
-`::testing::TestEventListener`
+`testing::TestEventListener`
 
 The interface for tracing execution of tests. The methods below are listed in
 the order the corresponding events are fired.
@@ -1026,7 +1143,7 @@ Fired after all test activities have ended.
 
 ### TestEventListeners {#TestEventListeners}
 
-`::testing::TestEventListeners`
+`testing::TestEventListeners`
 
 Lets users add listeners to track events in GoogleTest.
 
@@ -1071,7 +1188,7 @@ the caller and makes this function return `NULL` the next time.
 
 ### TestPartResult {#TestPartResult}
 
-`::testing::TestPartResult`
+`testing::TestPartResult`
 
 A copyable object representing the result of a test part (i.e. an assertion or
 an explicit `FAIL()`, `ADD_FAILURE()`, or `SUCCESS()`).
@@ -1153,7 +1270,7 @@ Returns true if and only if the test part failed.
 
 ### TestProperty {#TestProperty}
 
-`::testing::TestProperty`
+`testing::TestProperty`
 
 A copyable object representing a user-specified test property which can be
 output as a key/value string pair.
@@ -1180,7 +1297,7 @@ Sets a new value, overriding the previous one.
 
 ### TestResult {#TestResult}
 
-`::testing::TestResult`
+`testing::TestResult`
 
 Contains information about the result of a single test.
 
@@ -1261,20 +1378,20 @@ range, aborts the program.
 
 ### TimeInMillis {#TimeInMillis}
 
-`::testing::TimeInMillis`
+`testing::TimeInMillis`
 
 An integer type representing time in milliseconds.
 
 ### Types {#Types}
 
-`::testing::Types<T...>`
+`testing::Types<T...>`
 
 Represents a list of types for use in typed tests and type-parameterized tests.
 
 The template argument `T...` can be any number of types, for example:
 
 ```
-::testing::Types<char, int, unsigned int>
+testing::Types<char, int, unsigned int>
 ```
 
 See [Typed Tests](../advanced.md#typed-tests) and
@@ -1283,7 +1400,7 @@ information.
 
 ### WithParamInterface {#WithParamInterface}
 
-`::testing::WithParamInterface<T>`
+`testing::WithParamInterface<T>`
 
 The pure interface class that all value-parameterized tests inherit from.
 
@@ -1309,14 +1426,16 @@ tests.
 
 ### InitGoogleTest {#InitGoogleTest}
 
-`void ::testing::InitGoogleTest(int* argc, char** argv)` \
-`void ::testing::InitGoogleTest(int* argc, wchar_t** argv)` \
-`void ::testing::InitGoogleTest()`
+`void testing::InitGoogleTest(int* argc, char** argv)` \
+`void testing::InitGoogleTest(int* argc, wchar_t** argv)` \
+`void testing::InitGoogleTest()`
 
 Initializes GoogleTest. This must be called before calling
 [`RUN_ALL_TESTS()`](#RUN_ALL_TESTS). In particular, it parses the command line
 for the flags that GoogleTest recognizes. Whenever a GoogleTest flag is seen, it
-is removed from `argv`, and `*argc` is decremented.
+is removed from `argv`, and `*argc` is decremented. Keep in mind that `argv`
+must terminate with a `NULL` pointer (i.e. `argv[argc]` is `NULL`), which is
+already the case with the default `argv` passed to `main`.
 
 No value is returned. Instead, the GoogleTest flag variables are updated.
 
@@ -1328,7 +1447,7 @@ platforms where there is no `argc`/`argv`.
 
 ### AddGlobalTestEnvironment {#AddGlobalTestEnvironment}
 
-`Environment* ::testing::AddGlobalTestEnvironment(Environment* env)`
+`Environment* testing::AddGlobalTestEnvironment(Environment* env)`
 
 Adds a test environment to the test program. Must be called before
 [`RUN_ALL_TESTS()`](#RUN_ALL_TESTS) is called. See
@@ -1341,7 +1460,7 @@ See also [`Environment`](#Environment).
 
 ```cpp
 template <typename Factory>
-TestInfo* ::testing::RegisterTest(const char* test_suite_name, const char* test_name,
+TestInfo* testing::RegisterTest(const char* test_suite_name, const char* test_name,
                                   const char* type_param, const char* value_param,
                                   const char* file, int line, Factory factory)
 ```
@@ -1380,27 +1499,27 @@ an all-caps name.
 
 ### AssertionSuccess {#AssertionSuccess}
 
-`AssertionResult ::testing::AssertionSuccess()`
+`AssertionResult testing::AssertionSuccess()`
 
 Creates a successful assertion result. See
 [`AssertionResult`](#AssertionResult).
 
 ### AssertionFailure {#AssertionFailure}
 
-`AssertionResult ::testing::AssertionFailure()`
+`AssertionResult testing::AssertionFailure()`
 
 Creates a failed assertion result. Use the `<<` operator to store a failure
 message:
 
 ```cpp
-::testing::AssertionFailure() << "My failure message";
+testing::AssertionFailure() << "My failure message";
 ```
 
 See [`AssertionResult`](#AssertionResult).
 
 ### StaticAssertTypeEq {#StaticAssertTypeEq}
 
-`::testing::StaticAssertTypeEq<T1, T2>()`
+`testing::StaticAssertTypeEq<T1, T2>()`
 
 Compile-time assertion for type equality. Compiles if and only if `T1` and `T2`
 are the same type. The value it returns is irrelevant.
@@ -1409,7 +1528,7 @@ See [Type Assertions](../advanced.md#type-assertions) for more information.
 
 ### PrintToString {#PrintToString}
 
-`std::string ::testing::PrintToString(x)`
+`std::string testing::PrintToString(x)`
 
 Prints any value `x` using GoogleTest's value printer.
 
@@ -1419,7 +1538,7 @@ for more information.
 
 ### PrintToStringParamName {#PrintToStringParamName}
 
-`std::string ::testing::PrintToStringParamName(TestParamInfo<T>& info)`
+`std::string testing::PrintToStringParamName(TestParamInfo<T>& info)`
 
 A built-in parameterized test name generator which returns the result of
 [`PrintToString`](#PrintToString) called on `info.param`. Does not work when the

+ 24 - 32
ThirdParty/SpirvTools/external/googletest/googlemock/CMakeLists.txt

@@ -5,7 +5,7 @@
 # CMake build script for Google Mock.
 #
 # To run the tests for Google Mock itself on Linux, use 'make test' or
-# ctest.  You can select which tests to run using 'ctest -R regex'.
+# ctest. You can select which tests to run using 'ctest -R regex'.
 # For more options, run 'ctest --help'.
 
 option(gmock_build_tests "Build all of Google Mock's own tests." OFF)
@@ -36,8 +36,7 @@ endif()
 # as ${gmock_SOURCE_DIR} and to the root binary directory as
 # ${gmock_BINARY_DIR}.
 # Language "C" is required for find_package(Threads).
-cmake_minimum_required(VERSION 3.5)
-cmake_policy(SET CMP0048 NEW)
+cmake_minimum_required(VERSION 3.13)
 project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
 
 if (COMMAND set_up_hermetic_build)
@@ -45,7 +44,7 @@ if (COMMAND set_up_hermetic_build)
 endif()
 
 # Instructs CMake to process Google Test's CMakeLists.txt and add its
-# targets to the current scope.  We are placing Google Test's binary
+# targets to the current scope. We are placing Google Test's binary
 # directory in a subdirectory of our own as VC compilation may break
 # if they are the same (the default).
 add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/${gtest_dir}")
@@ -61,25 +60,26 @@ else()
 endif()
 
 # Although Google Test's CMakeLists.txt calls this function, the
-# changes there don't affect the current scope.  Therefore we have to
+# changes there don't affect the current scope. Therefore we have to
 # call it again here.
-config_compiler_and_linker()  # from ${gtest_dir}/cmake/internal_utils.cmake
+config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake
 
 # Adds Google Mock's and Google Test's header directories to the search path.
+# Get Google Test's include dirs from the target, gtest_SOURCE_DIR is broken
+# when using fetch-content with the name "GTest".
+get_target_property(gtest_include_dirs gtest INCLUDE_DIRECTORIES)
 set(gmock_build_include_dirs
   "${gmock_SOURCE_DIR}/include"
   "${gmock_SOURCE_DIR}"
-  "${gtest_SOURCE_DIR}/include"
-  # This directory is needed to build directly from Google Test sources.
-  "${gtest_SOURCE_DIR}")
+  "${gtest_include_dirs}")
 include_directories(${gmock_build_include_dirs})
 
 ########################################################################
 #
-# Defines the gmock & gmock_main libraries.  User tests should link
+# Defines the gmock & gmock_main libraries. User tests should link
 # with one of them.
 
-# Google Mock libraries.  We build them using more strict warnings than what
+# Google Mock libraries. We build them using more strict warnings than what
 # are used for other targets, to ensure that Google Mock can be compiled by
 # a user aggressive about warnings.
 if (MSVC)
@@ -101,22 +101,18 @@ else()
   target_link_libraries(gmock_main PUBLIC gmock)
   set_target_properties(gmock_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
 endif()
-# If the CMake version supports it, attach header directory information
-# to the targets for when we are part of a parent build (ie being pulled
-# in via add_subdirectory() rather than being a standalone build).
-if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
-  string(REPLACE ";" "$<SEMICOLON>" dirs "${gmock_build_include_dirs}")
-  target_include_directories(gmock SYSTEM INTERFACE
-    "$<BUILD_INTERFACE:${dirs}>"
-    "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
-  target_include_directories(gmock_main SYSTEM INTERFACE
-    "$<BUILD_INTERFACE:${dirs}>"
-    "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
-endif()
+
+string(REPLACE ";" "$<SEMICOLON>" dirs "${gmock_build_include_dirs}")
+target_include_directories(gmock SYSTEM INTERFACE
+  "$<BUILD_INTERFACE:${dirs}>"
+  "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
+target_include_directories(gmock_main SYSTEM INTERFACE
+  "$<BUILD_INTERFACE:${dirs}>"
+  "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
 
 ########################################################################
 #
-# Install rules
+# Install rules.
 install_project(gmock gmock_main)
 
 ########################################################################
@@ -126,8 +122,8 @@ install_project(gmock gmock_main)
 # You can skip this section if you aren't interested in testing
 # Google Mock itself.
 #
-# The tests are not built by default.  To build them, set the
-# gmock_build_tests option to ON.  You can do it by running ccmake
+# The tests are not built by default. To build them, set the
+# gmock_build_tests option to ON. You can do it by running ccmake
 # or specifying the -Dgmock_build_tests=ON flag when running cmake.
 
 if (gmock_build_tests)
@@ -136,11 +132,7 @@ if (gmock_build_tests)
   enable_testing()
 
   if (MINGW OR CYGWIN)
-    if (CMAKE_VERSION VERSION_LESS "2.8.12")
-      add_compile_options("-Wa,-mbig-obj")
-    else()
-      add_definitions("-Wa,-mbig-obj")
-    endif()
+    add_compile_options("-Wa,-mbig-obj")
   endif()
 
   ############################################################
@@ -196,7 +188,7 @@ if (gmock_build_tests)
   cxx_shared_library(shared_gmock_main "${cxx_default}"
     "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
 
-  # Tests that a binary can be built with Google Mock as a shared library.  On
+  # Tests that a binary can be built with Google Mock as a shared library. On
   # some system configurations, it may not possible to run the binary without
   # knowing more details about the system configurations. We do not try to run
   # this binary. To get a more robust shared library coverage, configure with

+ 3 - 3
ThirdParty/SpirvTools/external/googletest/googlemock/README.md

@@ -8,8 +8,8 @@ derive better designs of your system and write better tests.
 It is inspired by:
 
 *   [jMock](http://www.jmock.org/)
-*   [EasyMock](http://www.easymock.org/)
-*   [Hamcrest](http://code.google.com/p/hamcrest/)
+*   [EasyMock](https://easymock.org/)
+*   [Hamcrest](https://code.google.com/p/hamcrest/)
 
 It is designed with C++'s specifics in mind.
 
@@ -36,5 +36,5 @@ Details and examples can be found here:
 *   [gMock Cheat Sheet](https://google.github.io/googletest/gmock_cheat_sheet.html)
 
 GoogleMock is a part of
-[GoogleTest C++ testing framework](http://github.com/google/googletest/) and a
+[GoogleTest C++ testing framework](https://github.com/google/googletest/) and a
 subject to the same requirements.

+ 113 - 33
ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-actions.h

@@ -135,6 +135,7 @@
 #endif
 
 #include <algorithm>
+#include <exception>
 #include <functional>
 #include <memory>
 #include <string>
@@ -175,9 +176,15 @@ struct BuiltInDefaultValueGetter<T, false> {
   static T Get() {
     Assert(false, __FILE__, __LINE__,
            "Default action undefined for the function return type.");
-    return internal::Invalid<T>();
+#if defined(__GNUC__) || defined(__clang__)
+    __builtin_unreachable();
+#elif defined(_MSC_VER)
+    __assume(0);
+#else
+    return Invalid<T>();
     // The above statement will never be reached, but is required in
     // order for this function to compile.
+#endif
   }
 };
 
@@ -611,7 +618,7 @@ class DefaultValue {
  private:
   class ValueProducer {
    public:
-    virtual ~ValueProducer() {}
+    virtual ~ValueProducer() = default;
     virtual T Produce() = 0;
   };
 
@@ -699,8 +706,8 @@ class ActionInterface {
   typedef typename internal::Function<F>::Result Result;
   typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
 
-  ActionInterface() {}
-  virtual ~ActionInterface() {}
+  ActionInterface() = default;
+  virtual ~ActionInterface() = default;
 
   // Performs the action.  This method is not const, as in general an
   // action can have side effects and be stateful.  For example, a
@@ -749,7 +756,7 @@ class Action<R(Args...)> {
 
   // Constructs a null Action.  Needed for storing Action objects in
   // STL containers.
-  Action() {}
+  Action() = default;
 
   // Construct an Action from a specified callable.
   // This cannot take std::function directly, because then Action would not be
@@ -1273,7 +1280,7 @@ class AssignAction {
   const T2 value_;
 };
 
-#if !GTEST_OS_WINDOWS_MOBILE
+#ifndef GTEST_OS_WINDOWS_MOBILE
 
 // Implements the SetErrnoAndReturn action to simulate return from
 // various system calls and libc functions.
@@ -1486,6 +1493,7 @@ class DoAllAction<FinalAction> {
   // providing a call operator because even with a particular set of arguments
   // they don't have a fixed return type.
 
+  // We support conversion to OnceAction whenever the sub-action does.
   template <typename R, typename... Args,
             typename std::enable_if<
                 std::is_convertible<FinalAction, OnceAction<R(Args...)>>::value,
@@ -1494,6 +1502,21 @@ class DoAllAction<FinalAction> {
     return std::move(final_action_);
   }
 
+  // We also support conversion to OnceAction whenever the sub-action supports
+  // conversion to Action (since any Action can also be a OnceAction).
+  template <
+      typename R, typename... Args,
+      typename std::enable_if<
+          conjunction<
+              negation<
+                  std::is_convertible<FinalAction, OnceAction<R(Args...)>>>,
+              std::is_convertible<FinalAction, Action<R(Args...)>>>::value,
+          int>::type = 0>
+  operator OnceAction<R(Args...)>() && {  // NOLINT
+    return Action<R(Args...)>(std::move(final_action_));
+  }
+
+  // We support conversion to Action whenever the sub-action does.
   template <
       typename R, typename... Args,
       typename std::enable_if<
@@ -1573,16 +1596,16 @@ class DoAllAction<InitialAction, OtherActions...>
       : Base({}, std::forward<U>(other_actions)...),
         initial_action_(std::forward<T>(initial_action)) {}
 
-  template <typename R, typename... Args,
-            typename std::enable_if<
-                conjunction<
-                    // Both the initial action and the rest must support
-                    // conversion to OnceAction.
-                    std::is_convertible<
-                        InitialAction,
-                        OnceAction<void(InitialActionArgType<Args>...)>>,
-                    std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
-                int>::type = 0>
+  // We support conversion to OnceAction whenever both the initial action and
+  // the rest support conversion to OnceAction.
+  template <
+      typename R, typename... Args,
+      typename std::enable_if<
+          conjunction<std::is_convertible<
+                          InitialAction,
+                          OnceAction<void(InitialActionArgType<Args>...)>>,
+                      std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
+          int>::type = 0>
   operator OnceAction<R(Args...)>() && {  // NOLINT
     // Return an action that first calls the initial action with arguments
     // filtered through InitialActionArgType, then forwards arguments directly
@@ -1605,12 +1628,34 @@ class DoAllAction<InitialAction, OtherActions...>
     };
   }
 
+  // We also support conversion to OnceAction whenever the initial action
+  // supports conversion to Action (since any Action can also be a OnceAction).
+  //
+  // The remaining sub-actions must also be compatible, but we don't need to
+  // special case them because the base class deals with them.
+  template <
+      typename R, typename... Args,
+      typename std::enable_if<
+          conjunction<
+              negation<std::is_convertible<
+                  InitialAction,
+                  OnceAction<void(InitialActionArgType<Args>...)>>>,
+              std::is_convertible<InitialAction,
+                                  Action<void(InitialActionArgType<Args>...)>>,
+              std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
+          int>::type = 0>
+  operator OnceAction<R(Args...)>() && {  // NOLINT
+    return DoAll(
+        Action<void(InitialActionArgType<Args>...)>(std::move(initial_action_)),
+        std::move(static_cast<Base&>(*this)));
+  }
+
+  // We support conversion to Action whenever both the initial action and the
+  // rest support conversion to Action.
   template <
       typename R, typename... Args,
       typename std::enable_if<
           conjunction<
-              // Both the initial action and the rest must support conversion to
-              // Action.
               std::is_convertible<const InitialAction&,
                                   Action<void(InitialActionArgType<Args>...)>>,
               std::is_convertible<const Base&, Action<R(Args...)>>>::value,
@@ -1658,8 +1703,9 @@ template <size_t k>
 struct ReturnArgAction {
   template <typename... Args,
             typename = typename std::enable_if<(k < sizeof...(Args))>::type>
-  auto operator()(Args&&... args) const -> decltype(std::get<k>(
-      std::forward_as_tuple(std::forward<Args>(args)...))) {
+  auto operator()(Args&&... args) const
+      -> decltype(std::get<k>(
+          std::forward_as_tuple(std::forward<Args>(args)...))) {
     return std::get<k>(std::forward_as_tuple(std::forward<Args>(args)...));
   }
 };
@@ -1674,6 +1720,16 @@ struct SaveArgAction {
   }
 };
 
+template <size_t k, typename Ptr>
+struct SaveArgByMoveAction {
+  Ptr pointer;
+
+  template <typename... Args>
+  void operator()(Args&&... args) const {
+    *pointer = std::move(std::get<k>(std::tie(args...)));
+  }
+};
+
 template <size_t k, typename Ptr>
 struct SaveArgPointeeAction {
   Ptr pointer;
@@ -1740,6 +1796,13 @@ struct ThrowAction {
     return [copy](Args...) -> R { throw copy; };
   }
 };
+struct RethrowAction {
+  std::exception_ptr exception;
+  template <typename R, typename... Args>
+  operator Action<R(Args...)>() const {  // NOLINT
+    return [ex = exception](Args...) -> R { std::rethrow_exception(ex); };
+  }
+};
 #endif  // GTEST_HAS_EXCEPTIONS
 
 }  // namespace internal
@@ -1926,7 +1989,7 @@ PolymorphicAction<internal::AssignAction<T1, T2>> Assign(T1* ptr, T2 val) {
   return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));
 }
 
-#if !GTEST_OS_WINDOWS_MOBILE
+#ifndef GTEST_OS_WINDOWS_MOBILE
 
 // Creates an action that sets errno and returns the appropriate error.
 template <typename T>
@@ -2017,6 +2080,13 @@ internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {
   return {pointer};
 }
 
+// Action SaveArgByMove<k>(pointer) moves the k-th (0-based) argument of the
+// mock function into *pointer.
+template <size_t k, typename Ptr>
+internal::SaveArgByMoveAction<k, Ptr> SaveArgByMove(Ptr pointer) {
+  return {pointer};
+}
+
 // Action SaveArgPointee<k>(pointer) saves the value pointed to
 // by the k-th (0-based) argument of the mock function to *pointer.
 template <size_t k, typename Ptr>
@@ -2056,13 +2126,23 @@ internal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) {
   return {pointer};
 }
 
-// Action Throw(exception) can be used in a mock function of any type
-// to throw the given exception.  Any copyable value can be thrown.
 #if GTEST_HAS_EXCEPTIONS
+// Action Throw(exception) can be used in a mock function of any type
+// to throw the given exception.  Any copyable value can be thrown,
+// except for std::exception_ptr, which is likely a mistake if
+// thrown directly.
 template <typename T>
-internal::ThrowAction<typename std::decay<T>::type> Throw(T&& exception) {
+typename std::enable_if<
+    !std::is_base_of<std::exception_ptr, typename std::decay<T>::type>::value,
+    internal::ThrowAction<typename std::decay<T>::type>>::type
+Throw(T&& exception) {
   return {std::forward<T>(exception)};
 }
+// Action Rethrow(exception_ptr) can be used in a mock function of any type
+// to rethrow any exception_ptr. Note that the same object is thrown each time.
+inline internal::RethrowAction Rethrow(std::exception_ptr exception) {
+  return {std::move(exception)};
+}
 #endif  // GTEST_HAS_EXCEPTIONS
 
 namespace internal {
@@ -2111,13 +2191,13 @@ struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {
   R operator()(Args&&... arg) const {
     static constexpr size_t kMaxArgs =
         sizeof...(Args) <= 10 ? sizeof...(Args) : 10;
-    return Apply(MakeIndexSequence<kMaxArgs>{},
-                 MakeIndexSequence<10 - kMaxArgs>{},
+    return Apply(std::make_index_sequence<kMaxArgs>{},
+                 std::make_index_sequence<10 - kMaxArgs>{},
                  args_type{std::forward<Args>(arg)...});
   }
 
   template <std::size_t... arg_id, std::size_t... excess_id>
-  R Apply(IndexSequence<arg_id...>, IndexSequence<excess_id...>,
+  R Apply(std::index_sequence<arg_id...>, std::index_sequence<excess_id...>,
           const args_type& args) const {
     // Impl need not be specific to the signature of action being implemented;
     // only the implementing function body needs to have all of the specific
@@ -2150,9 +2230,9 @@ template <typename F, typename Impl>
 }
 
 #define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
-  , const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_
-#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_                 \
-  const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \
+  , [[maybe_unused]] const arg##i##_type& arg##i
+#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_          \
+  [[maybe_unused]] const args_type& args GMOCK_PP_REPEAT( \
       GMOCK_INTERNAL_ARG_UNUSED, , 10)
 
 #define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
@@ -2217,8 +2297,8 @@ template <typename F, typename Impl>
     std::shared_ptr<const gmock_Impl> impl_;                                   \
   };                                                                           \
   template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \
-  inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name(                    \
-      GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) GTEST_MUST_USE_RESULT_;        \
+  [[nodiscard]] inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name(      \
+      GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params));                               \
   template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \
   inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name(                    \
       GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) {                              \
@@ -2253,7 +2333,7 @@ template <typename F, typename Impl>
       return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
     };                                                                        \
   };                                                                          \
-  inline name##Action name() GTEST_MUST_USE_RESULT_;                          \
+  [[nodiscard]] inline name##Action name();                                   \
   inline name##Action name() { return name##Action(); }                       \
   template <typename function_type, typename return_type, typename args_type, \
             GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>                                \

+ 2 - 2
ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-cardinalities.h

@@ -65,7 +65,7 @@ namespace testing {
 // The implementation of a cardinality.
 class CardinalityInterface {
  public:
-  virtual ~CardinalityInterface() {}
+  virtual ~CardinalityInterface() = default;
 
   // Conservative estimate on the lower/upper bound of the number of
   // calls allowed.
@@ -92,7 +92,7 @@ class GTEST_API_ Cardinality {
  public:
   // Constructs a null cardinality.  Needed for storing Cardinality
   // objects in STL containers.
-  Cardinality() {}
+  Cardinality() = default;
 
   // Constructs a Cardinality from its implementation.
   explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}

+ 5 - 4
ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-function-mocker.h

@@ -37,6 +37,7 @@
 #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
 #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
 
+#include <cstddef>
 #include <type_traits>  // IWYU pragma: keep
 #include <utility>      // IWYU pragma: keep
 
@@ -69,22 +70,22 @@ constexpr bool PrefixOf(const char* a, const char* b) {
   return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1));
 }
 
-template <int N, int M>
+template <size_t N, size_t M>
 constexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) {
   return N <= M && internal::PrefixOf(prefix, str);
 }
 
-template <int N, int M>
+template <size_t N, size_t M>
 constexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) {
   return N <= M && internal::PrefixOf(suffix, str + M - N);
 }
 
-template <int N, int M>
+template <size_t N, size_t M>
 constexpr bool Equals(const char (&a)[N], const char (&b)[M]) {
   return N == M && internal::PrefixOf(a, b);
 }
 
-template <int N>
+template <size_t N>
 constexpr bool ValidateSpec(const char (&spec)[N]) {
   return internal::Equals("const", spec) ||
          internal::Equals("override", spec) ||

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 400 - 159
ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-matchers.h


+ 12 - 11
ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-more-actions.h

@@ -521,9 +521,8 @@
         GMOCK_INTERNAL_DECL_##value_params)                                    \
         GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params),    \
                     = default;                                                 \
-                    ,                                                          \
-                    : impl_(std::make_shared<gmock_Impl>(                      \
-                        GMOCK_INTERNAL_LIST_##value_params)){})                \
+                    , : impl_(std::make_shared<gmock_Impl>(                    \
+                          GMOCK_INTERNAL_LIST_##value_params)){})              \
             GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \
                 name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_      \
         ##value_params                                                         \
@@ -551,10 +550,10 @@
   };                                                                           \
   template <GMOCK_INTERNAL_DECL_##template_params                              \
                 GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \
-  GMOCK_ACTION_CLASS_(                                                         \
+  [[nodiscard]] GMOCK_ACTION_CLASS_(                                           \
       name, value_params)<GMOCK_INTERNAL_LIST_##template_params                \
                               GMOCK_INTERNAL_LIST_TYPE_##value_params>         \
-      name(GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_;         \
+      name(GMOCK_INTERNAL_DECL_##value_params);                                \
   template <GMOCK_INTERNAL_DECL_##template_params                              \
                 GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \
   inline GMOCK_ACTION_CLASS_(                                                  \
@@ -592,21 +591,23 @@ namespace internal {
 // Overloads for other custom-callables are provided in the
 // internal/custom/gmock-generated-actions.h header.
 template <typename F, typename... Args>
-auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) {
-  return f(args...);
+auto InvokeArgument(F &&f,
+                    Args... args) -> decltype(std::forward<F>(f)(args...)) {
+  return std::forward<F>(f)(args...);
 }
 
 template <std::size_t index, typename... Params>
 struct InvokeArgumentAction {
   template <typename... Args,
             typename = typename std::enable_if<(index < sizeof...(Args))>::type>
-  auto operator()(Args &&...args) const -> decltype(internal::InvokeArgument(
-      std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
-      std::declval<const Params &>()...)) {
+  auto operator()(Args &&...args) const
+      -> decltype(internal::InvokeArgument(
+          std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
+          std::declval<const Params &>()...)) {
     internal::FlatTuple<Args &&...> args_tuple(FlatTupleConstructTag{},
                                                std::forward<Args>(args)...);
     return params.Apply([&](const Params &...unpacked_params) {
-      auto &&callable = args_tuple.template Get<index>();
+      auto &&callable = std::move(args_tuple.template Get<index>());
       return internal::InvokeArgument(
           std::forward<decltype(callable)>(callable), unpacked_params...);
     });

+ 1 - 1
ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-nice-strict.h

@@ -98,7 +98,7 @@ constexpr bool HasStrictnessModifier() {
 // deregistration. This guarantees that MockClass's constructor and destructor
 // run with the same level of strictness as its instance methods.
 
-#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW && \
+#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) && \
     (defined(_MSC_VER) || defined(__clang__))
 // We need to mark these classes with this declspec to ensure that
 // the empty base class optimization is performed.

+ 56 - 21
ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock-spec-builders.h

@@ -204,6 +204,9 @@ class GTEST_API_ UntypedFunctionMockerBase {
 
   using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>;
 
+  struct UninterestingCallCleanupHandler;
+  struct FailureCleanupHandler;
+
   // Returns an Expectation object that references and co-owns exp,
   // which must be an expectation on this mock function.
   Expectation GetHandleOf(ExpectationBase* exp);
@@ -563,7 +566,7 @@ class ExpectationSet {
   typedef Expectation::Set::value_type value_type;
 
   // Constructs an empty set.
-  ExpectationSet() {}
+  ExpectationSet() = default;
 
   // This single-argument ctor must not be explicit, in order to support the
   //   ExpectationSet es = EXPECT_CALL(...);
@@ -865,7 +868,7 @@ class GTEST_API_ ExpectationBase {
   Clause last_clause_;
   mutable bool action_count_checked_;  // Under mutex_.
   mutable Mutex mutex_;                // Protects action_count_checked_.
-};                                     // class ExpectationBase
+};  // class ExpectationBase
 
 template <typename F>
 class TypedExpectation;
@@ -1396,6 +1399,41 @@ class Cleanup final {
   std::function<void()> f_;
 };
 
+struct UntypedFunctionMockerBase::UninterestingCallCleanupHandler {
+  CallReaction reaction;
+  std::stringstream& ss;
+
+  ~UninterestingCallCleanupHandler() {
+    ReportUninterestingCall(reaction, ss.str());
+  }
+};
+
+struct UntypedFunctionMockerBase::FailureCleanupHandler {
+  std::stringstream& ss;
+  std::stringstream& why;
+  std::stringstream& loc;
+  const ExpectationBase* untyped_expectation;
+  bool found;
+  bool is_excessive;
+
+  ~FailureCleanupHandler() {
+    ss << "\n" << why.str();
+
+    if (!found) {
+      // No expectation matches this call - reports a failure.
+      Expect(false, nullptr, -1, ss.str());
+    } else if (is_excessive) {
+      // We had an upper-bound violation and the failure message is in ss.
+      Expect(false, untyped_expectation->file(), untyped_expectation->line(),
+             ss.str());
+    } else {
+      // We had an expected call and the matching expectation is
+      // described in ss.
+      Log(kInfo, loc.str() + ss.str(), 2);
+    }
+  }
+};
+
 template <typename F>
 class FunctionMocker;
 
@@ -1408,7 +1446,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
   using ArgumentTuple = std::tuple<Args...>;
   using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
 
-  FunctionMocker() {}
+  FunctionMocker() = default;
 
   // There is no generally useful and implementable semantics of
   // copying a mock object, so copying a mock is usually a user error.
@@ -1794,8 +1832,14 @@ R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)
     //
     // We use RAII to do the latter in case R is void or a non-moveable type. In
     // either case we can't assign it to a local variable.
-    const Cleanup report_uninteresting_call(
-        [&] { ReportUninterestingCall(reaction, ss.str()); });
+    //
+    // Note that std::bind() is essential here.
+    // We *don't* use any local callback types (like lambdas).
+    // Doing so slows down compilation dramatically because the *constructor* of
+    // std::function<T> is re-instantiated with different template
+    // parameters each time.
+    const UninterestingCallCleanupHandler report_uninteresting_call = {reaction,
+                                                                       ss};
 
     return PerformActionAndPrintResult(nullptr, std::move(args), ss.str(), ss);
   }
@@ -1839,22 +1883,13 @@ R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)
   //
   // We use RAII to do the latter in case R is void or a non-moveable type. In
   // either case we can't assign it to a local variable.
-  const Cleanup handle_failures([&] {
-    ss << "\n" << why.str();
-
-    if (!found) {
-      // No expectation matches this call - reports a failure.
-      Expect(false, nullptr, -1, ss.str());
-    } else if (is_excessive) {
-      // We had an upper-bound violation and the failure message is in ss.
-      Expect(false, untyped_expectation->file(), untyped_expectation->line(),
-             ss.str());
-    } else {
-      // We had an expected call and the matching expectation is
-      // described in ss.
-      Log(kInfo, loc.str() + ss.str(), 2);
-    }
-  });
+  //
+  // Note that we *don't* use any local callback types (like lambdas) here.
+  // Doing so slows down compilation dramatically because the *constructor* of
+  // std::function<T> is re-instantiated with different template
+  // parameters each time.
+  const FailureCleanupHandler handle_failures = {
+      ss, why, loc, untyped_expectation, found, is_excessive};
 
   return PerformActionAndPrintResult(untyped_action, std::move(args), ss.str(),
                                      ss);

+ 8 - 7
ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/gmock.h

@@ -53,13 +53,14 @@
 //
 // where all clauses are optional and WillOnce() can be repeated.
 
-#include "gmock/gmock-actions.h"
-#include "gmock/gmock-cardinalities.h"
-#include "gmock/gmock-function-mocker.h"
-#include "gmock/gmock-matchers.h"
-#include "gmock/gmock-more-actions.h"
-#include "gmock/gmock-more-matchers.h"
-#include "gmock/gmock-nice-strict.h"
+#include "gmock/gmock-actions.h"  // IWYU pragma: export
+#include "gmock/gmock-cardinalities.h"  // IWYU pragma: export
+#include "gmock/gmock-function-mocker.h"  // IWYU pragma: export
+#include "gmock/gmock-matchers.h"  // IWYU pragma: export
+#include "gmock/gmock-more-actions.h"  // IWYU pragma: export
+#include "gmock/gmock-more-matchers.h"  // IWYU pragma: export
+#include "gmock/gmock-nice-strict.h"  // IWYU pragma: export
+#include "gmock/gmock-spec-builders.h"  // IWYU pragma: export
 #include "gmock/internal/gmock-internal-utils.h"
 #include "gmock/internal/gmock-port.h"
 

+ 11 - 11
ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h

@@ -44,6 +44,7 @@
 #include <ostream>  // NOLINT
 #include <string>
 #include <type_traits>
+#include <utility>
 #include <vector>
 
 #include "gmock/internal/gmock-port.h"
@@ -224,7 +225,7 @@ class FailureReporterInterface {
   // The type of a failure (either non-fatal or fatal).
   enum FailureType { kNonfatal, kFatal };
 
-  virtual ~FailureReporterInterface() {}
+  virtual ~FailureReporterInterface() = default;
 
   // Reports a failure that occurred at the given source file location.
   virtual void ReportFailure(FailureType type, const char* file, int line,
@@ -311,7 +312,8 @@ GTEST_API_ WithoutMatchers GetWithoutMatchers();
 // crashes).
 template <typename T>
 inline T Invalid() {
-  Assert(false, "", -1, "Internal error: attempt to return invalid value");
+  Assert(/*condition=*/false, /*file=*/"", /*line=*/-1,
+         "Internal error: attempt to return invalid value");
 #if defined(__GNUC__) || defined(__clang__)
   __builtin_unreachable();
 #elif defined(_MSC_VER)
@@ -419,7 +421,7 @@ struct RemoveConstFromKey<std::pair<const K, V> > {
 GTEST_API_ void IllegalDoDefault(const char* file, int line);
 
 template <typename F, typename Tuple, size_t... Idx>
-auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
+auto ApplyImpl(F&& f, Tuple&& args, std::index_sequence<Idx...>)
     -> decltype(std::forward<F>(f)(
         std::get<Idx>(std::forward<Tuple>(args))...)) {
   return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
@@ -427,12 +429,13 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
 
 // Apply the function to a tuple of arguments.
 template <typename F, typename Tuple>
-auto Apply(F&& f, Tuple&& args) -> decltype(ApplyImpl(
-    std::forward<F>(f), std::forward<Tuple>(args),
-    MakeIndexSequence<std::tuple_size<
-        typename std::remove_reference<Tuple>::type>::value>())) {
+auto Apply(F&& f, Tuple&& args)
+    -> decltype(ApplyImpl(
+        std::forward<F>(f), std::forward<Tuple>(args),
+        std::make_index_sequence<std::tuple_size<
+            typename std::remove_reference<Tuple>::type>::value>())) {
   return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
-                   MakeIndexSequence<std::tuple_size<
+                   std::make_index_sequence<std::tuple_size<
                        typename std::remove_reference<Tuple>::type>::value>());
 }
 
@@ -464,9 +467,6 @@ struct Function<R(Args...)> {
   using MakeResultIgnoredValue = IgnoredValue(Args...);
 };
 
-template <typename R, typename... Args>
-constexpr size_t Function<R(Args...)>::ArgumentCount;
-
 // Workaround for MSVC error C2039: 'type': is not a member of 'std'
 // when std::tuple_element is used.
 // See: https://github.com/google/googletest/issues/3931

+ 5 - 4
ThirdParty/SpirvTools/external/googletest/googlemock/include/gmock/internal/gmock-port.h

@@ -42,6 +42,7 @@
 
 #include <assert.h>
 #include <stdlib.h>
+
 #include <cstdint>
 #include <iostream>
 
@@ -56,7 +57,7 @@
 #include "gmock/internal/custom/gmock-port.h"
 #include "gtest/internal/gtest-port.h"
 
-#ifdef GTEST_HAS_ABSL
+#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
 #include "absl/flags/declare.h"
 #include "absl/flags/flag.h"
 #endif
@@ -73,7 +74,7 @@
 #define GMOCK_FLAG(name) FLAGS_gmock_##name
 
 // Pick a command line flags implementation.
-#ifdef GTEST_HAS_ABSL
+#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
 
 // Macros for defining flags.
 #define GMOCK_DEFINE_bool_(name, default_val, doc) \
@@ -95,7 +96,7 @@
 #define GMOCK_FLAG_SET(name, value) \
   (void)(::absl::SetFlag(&GMOCK_FLAG(name), value))
 
-#else  // GTEST_HAS_ABSL
+#else  // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
 
 // Macros for defining flags.
 #define GMOCK_DEFINE_bool_(name, default_val, doc)  \
@@ -134,6 +135,6 @@
 #define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
 #define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
 
-#endif  // GTEST_HAS_ABSL
+#endif  // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
 
 #endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_

+ 4 - 4
ThirdParty/SpirvTools/external/googletest/googlemock/src/gmock-cardinalities.cc

@@ -53,12 +53,12 @@ class BetweenCardinalityImpl : public CardinalityInterface {
       : min_(min >= 0 ? min : 0), max_(max >= min_ ? max : min_) {
     std::stringstream ss;
     if (min < 0) {
-      ss << "The invocation lower bound must be >= 0, "
-         << "but is actually " << min << ".";
+      ss << "The invocation lower bound must be >= 0, " << "but is actually "
+         << min << ".";
       internal::Expect(false, __FILE__, __LINE__, ss.str());
     } else if (max < 0) {
-      ss << "The invocation upper bound must be >= 0, "
-         << "but is actually " << max << ".";
+      ss << "The invocation upper bound must be >= 0, " << "but is actually "
+         << max << ".";
       internal::Expect(false, __FILE__, __LINE__, ss.str());
     } else if (min > max) {
       ss << "The invocation upper bound (" << max

+ 5 - 3
ThirdParty/SpirvTools/external/googletest/googlemock/src/gmock-internal-utils.cc

@@ -41,8 +41,10 @@
 #include <cctype>
 #include <cstdint>
 #include <cstring>
+#include <iostream>
 #include <ostream>  // NOLINT
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "gmock/gmock.h"
@@ -87,7 +89,7 @@ GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) {
                                  (!IsDigit(prev_char) && IsDigit(*p));
 
     if (IsAlNum(*p)) {
-      if (starts_new_word && result != "") result += ' ';
+      if (starts_new_word && !result.empty()) result += ' ';
       result += ToLower(*p);
     }
   }
@@ -210,14 +212,14 @@ constexpr char UnBase64Impl(char c, const char* const base64, char carry) {
 }
 
 template <size_t... I>
-constexpr std::array<char, 256> UnBase64Impl(IndexSequence<I...>,
+constexpr std::array<char, 256> UnBase64Impl(std::index_sequence<I...>,
                                              const char* const base64) {
   return {
       {UnBase64Impl(UndoWebSafeEncoding(static_cast<char>(I)), base64, 0)...}};
 }
 
 constexpr std::array<char, 256> UnBase64(const char* const base64) {
-  return UnBase64Impl(MakeIndexSequence<256>{}, base64);
+  return UnBase64Impl(std::make_index_sequence<256>{}, base64);
 }
 
 static constexpr char kBase64[] =

+ 15 - 16
ThirdParty/SpirvTools/external/googletest/googlemock/src/gmock-matchers.cc

@@ -53,7 +53,7 @@ GTEST_API_ std::string FormatMatcherDescription(
     bool negation, const char* matcher_name,
     const std::vector<const char*>& param_names, const Strings& param_values) {
   std::string result = ConvertIdentifierNameToWords(matcher_name);
-  if (param_values.size() >= 1) {
+  if (!param_values.empty()) {
     result += " " + JoinAsKeyValueTuple(param_names, param_values);
   }
   return negation ? "not (" + result + ")" : result;
@@ -120,7 +120,7 @@ GTEST_API_ std::string FormatMatcherDescription(
 //   [1] Cormen, et al (2001). "Section 26.2: The Ford-Fulkerson method".
 //       "Introduction to Algorithms (Second ed.)", pp. 651-664.
 //   [2] "Ford-Fulkerson algorithm", Wikipedia,
-//       'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
+//       'https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
 class MaxBipartiteMatchState {
  public:
   explicit MaxBipartiteMatchState(const MatchMatrix& graph)
@@ -236,9 +236,8 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
   os << "{";
   const char* sep = "";
   for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
-    os << sep << "\n  ("
-       << "element #" << it->first << ", "
-       << "matcher #" << it->second << ")";
+    os << sep << "\n  (" << "element #" << it->first << ", " << "matcher #"
+       << it->second << ")";
     sep = ",";
   }
   os << "\n}";
@@ -374,20 +373,20 @@ bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
     return true;
   }
 
-  if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
-    if (matrix.LhsSize() != matrix.RhsSize()) {
-      // The element count doesn't match.  If the container is empty,
-      // there's no need to explain anything as Google Mock already
-      // prints the empty container. Otherwise we just need to show
-      // how many elements there actually are.
-      if (matrix.LhsSize() != 0 && listener->IsInterested()) {
-        *listener << "which has " << Elements(matrix.LhsSize());
-      }
-      return false;
+  const bool is_exact_match_with_size_discrepency =
+      match_flags() == UnorderedMatcherRequire::ExactMatch &&
+      matrix.LhsSize() != matrix.RhsSize();
+  if (is_exact_match_with_size_discrepency) {
+    // The element count doesn't match.  If the container is empty,
+    // there's no need to explain anything as Google Mock already
+    // prints the empty container. Otherwise we just need to show
+    // how many elements there actually are.
+    if (matrix.LhsSize() != 0 && listener->IsInterested()) {
+      *listener << "which has " << Elements(matrix.LhsSize()) << "\n";
     }
   }
 
-  bool result = true;
+  bool result = !is_exact_match_with_size_discrepency;
   ::std::vector<char> element_matched(matrix.LhsSize(), 0);
   ::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
 

+ 11 - 9
ThirdParty/SpirvTools/external/googletest/googlemock/src/gmock-spec-builders.cc

@@ -40,6 +40,7 @@
 #include <map>
 #include <memory>
 #include <set>
+#include <sstream>
 #include <string>
 #include <unordered_map>
 #include <vector>
@@ -48,10 +49,10 @@
 #include "gtest/gtest.h"
 #include "gtest/internal/gtest-port.h"
 
-#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
+#if defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC)
 #include <unistd.h>  // NOLINT
 #endif
-#if GTEST_OS_QURT
+#ifdef GTEST_OS_QURT
 #include <qurt_event.h>
 #endif
 
@@ -95,7 +96,7 @@ ExpectationBase::ExpectationBase(const char* a_file, int a_line,
       action_count_checked_(false) {}
 
 // Destructs an ExpectationBase object.
-ExpectationBase::~ExpectationBase() {}
+ExpectationBase::~ExpectationBase() = default;
 
 // Explicitly specifies the cardinality of this expectation.  Used by
 // the subclasses to implement the .Times() clause.
@@ -308,7 +309,7 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
 UntypedFunctionMockerBase::UntypedFunctionMockerBase()
     : mock_obj_(nullptr), name_("") {}
 
-UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
+UntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default;
 
 // Sets the mock object this mock method belongs to, and registers
 // this information in the global mock registry.  Will be called
@@ -489,6 +490,7 @@ class MockObjectRegistry {
   // failure, unless the user explicitly asked us to ignore it.
   ~MockObjectRegistry() {
     if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
+    internal::MutexLock l(&internal::g_gmock_mutex);
 
     int leaked_count = 0;
     for (StateMap::const_iterator it = states_.begin(); it != states_.end();
@@ -503,7 +505,7 @@ class MockObjectRegistry {
       std::cout << internal::FormatFileLocation(state.first_used_file,
                                                 state.first_used_line);
       std::cout << " ERROR: this mock object";
-      if (state.first_used_test != "") {
+      if (!state.first_used_test.empty()) {
         std::cout << " (used in test " << state.first_used_test_suite << "."
                   << state.first_used_test << ")";
       }
@@ -526,10 +528,10 @@ class MockObjectRegistry {
       // RUN_ALL_TESTS() has already returned when this destructor is
       // called.  Therefore we cannot use the normal Google Test
       // failure reporting mechanism.
-#if GTEST_OS_QURT
+#ifdef GTEST_OS_QURT
       qurt_exception_raise_fatal();
 #else
-      _exit(1);  // We cannot call exit() as it is not reentrant and
+      _Exit(1);  // We cannot call exit() as it is not reentrant and
                  // may already have been called.
 #endif
     }
@@ -745,13 +747,13 @@ void Mock::ClearDefaultActionsLocked(void* mock_obj)
   // needed by VerifyAndClearExpectationsLocked().
 }
 
-Expectation::Expectation() {}
+Expectation::Expectation() = default;
 
 Expectation::Expectation(
     const std::shared_ptr<internal::ExpectationBase>& an_expectation_base)
     : expectation_base_(an_expectation_base) {}
 
-Expectation::~Expectation() {}
+Expectation::~Expectation() = default;
 
 // Adds an expectation to a sequence.
 void Sequence::AddExpectation(const Expectation& expectation) const {

+ 2 - 0
ThirdParty/SpirvTools/external/googletest/googlemock/src/gmock.cc

@@ -29,6 +29,8 @@
 
 #include "gmock/gmock.h"
 
+#include <string>
+
 #include "gmock/internal/gmock-port.h"
 
 GMOCK_DEFINE_bool_(catch_leaked_mocks, true,

+ 5 - 4
ThirdParty/SpirvTools/external/googletest/googlemock/src/gmock_main.cc

@@ -32,8 +32,9 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-#if GTEST_OS_ESP8266 || GTEST_OS_ESP32
-#if GTEST_OS_ESP8266
+#if defined(GTEST_OS_ESP8266) || defined(GTEST_OS_ESP32) || \
+    (defined(GTEST_OS_NRF52) && defined(ARDUINO))
+#ifdef GTEST_OS_ESP8266
 extern "C" {
 #endif
 void setup() {
@@ -43,7 +44,7 @@ void setup() {
   testing::InitGoogleMock();
 }
 void loop() { RUN_ALL_TESTS(); }
-#if GTEST_OS_ESP8266
+#ifdef GTEST_OS_ESP8266
 }
 #endif
 
@@ -55,7 +56,7 @@ void loop() { RUN_ALL_TESTS(); }
 // Windows. See the following link to track the current status of this bug:
 // https://web.archive.org/web/20170912203238/connect.microsoft.com/VisualStudio/feedback/details/394464/wmain-link-error-in-the-static-library
 // // NOLINT
-#if GTEST_OS_WINDOWS_MOBILE
+#ifdef GTEST_OS_WINDOWS_MOBILE
 #include <tchar.h>  // NOLINT
 
 GTEST_API_ int _tmain(int argc, TCHAR** argv) {

+ 66 - 17
ThirdParty/SpirvTools/external/googletest/googlemock/test/gmock-actions_test.cc

@@ -37,14 +37,18 @@
 #include <functional>
 #include <iterator>
 #include <memory>
+#include <sstream>
 #include <string>
+#include <tuple>
 #include <type_traits>
+#include <utility>
 #include <vector>
 
 #include "gmock/gmock.h"
 #include "gmock/internal/gmock-port.h"
 #include "gtest/gtest-spi.h"
 #include "gtest/gtest.h"
+#include "gtest/internal/gtest-port.h"
 
 // Silence C4100 (unreferenced formal parameter) and C4503 (decorated name
 // length exceeded) for MSVC.
@@ -218,7 +222,8 @@ TEST(TypeTraits, IsInvocableRV) {
   // In C++17 and above, where it's guaranteed that functions can return
   // non-moveable objects, everything should work fine for non-moveable rsult
   // types too.
-#if defined(__cplusplus) && __cplusplus >= 201703L
+  // TODO(b/396121064) - Fix this test under MSVC
+#ifndef _MSC_VER
   {
     struct NonMoveable {
       NonMoveable() = default;
@@ -239,7 +244,7 @@ TEST(TypeTraits, IsInvocableRV) {
     static_assert(!internal::is_callable_r<int, Callable>::value);
     static_assert(!internal::is_callable_r<NonMoveable, Callable, int>::value);
   }
-#endif  // C++17 and above
+#endif  // _MSC_VER
 
   // Nothing should choke when we try to call other arguments besides directly
   // callable objects, but they should not show up as callable.
@@ -436,15 +441,15 @@ TEST(DefaultValueDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
 
   EXPECT_EQ(0, DefaultValue<int>::Get());
 
-  EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<MyNonDefaultConstructible>::Get(); },
-                            "");
+  EXPECT_DEATH_IF_SUPPORTED(
+      { DefaultValue<MyNonDefaultConstructible>::Get(); }, "");
 }
 
 TEST(DefaultValueTest, GetWorksForMoveOnlyIfSet) {
   EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists());
   EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Get() == nullptr);
   DefaultValue<std::unique_ptr<int>>::SetFactory(
-      [] { return std::unique_ptr<int>(new int(42)); });
+      [] { return std::make_unique<int>(42); });
   EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists());
   std::unique_ptr<int> i = DefaultValue<std::unique_ptr<int>>::Get();
   EXPECT_EQ(42, *i);
@@ -500,8 +505,8 @@ TEST(DefaultValueOfReferenceDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
   EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet());
 
   EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<int&>::Get(); }, "");
-  EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<MyNonDefaultConstructible>::Get(); },
-                            "");
+  EXPECT_DEATH_IF_SUPPORTED(
+      { DefaultValue<MyNonDefaultConstructible>::Get(); }, "");
 }
 
 // Tests that ActionInterface can be implemented by defining the
@@ -982,7 +987,7 @@ TEST(ReturnRoundRobinTest, WorksForVector) {
 
 class MockClass {
  public:
-  MockClass() {}
+  MockClass() = default;
 
   MOCK_METHOD1(IntFunc, int(bool flag));  // NOLINT
   MOCK_METHOD0(Foo, MyNonDefaultConstructible());
@@ -1472,6 +1477,54 @@ TEST(DoAll, SupportsTypeErasedActions) {
   }
 }
 
+// A DoAll action should be convertible to a OnceAction, even when its component
+// sub-actions are user-provided types that define only an Action conversion
+// operator. If they supposed being called more than once then they also support
+// being called at most once.
+TEST(DoAll, ConvertibleToOnceActionWithUserProvidedActionConversion) {
+  // Simplest case: only one sub-action.
+  struct CustomFinal final {
+    operator Action<int()>() {  // NOLINT
+      return Return(17);
+    }
+
+    operator Action<int(int, char)>() {  // NOLINT
+      return Return(19);
+    }
+  };
+
+  {
+    OnceAction<int()> action = DoAll(CustomFinal{});
+    EXPECT_EQ(17, std::move(action).Call());
+  }
+
+  {
+    OnceAction<int(int, char)> action = DoAll(CustomFinal{});
+    EXPECT_EQ(19, std::move(action).Call(0, 0));
+  }
+
+  // It should also work with multiple sub-actions.
+  struct CustomInitial final {
+    operator Action<void()>() {  // NOLINT
+      return [] {};
+    }
+
+    operator Action<void(int, char)>() {  // NOLINT
+      return [] {};
+    }
+  };
+
+  {
+    OnceAction<int()> action = DoAll(CustomInitial{}, CustomFinal{});
+    EXPECT_EQ(17, std::move(action).Call());
+  }
+
+  {
+    OnceAction<int(int, char)> action = DoAll(CustomInitial{}, CustomFinal{});
+    EXPECT_EQ(19, std::move(action).Call(0, 0));
+  }
+}
+
 // Tests using WithArgs and with an action that takes 1 argument.
 TEST(WithArgsTest, OneArg) {
   Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary));  // NOLINT
@@ -1592,7 +1645,7 @@ TEST(WithArgsTest, RefQualifiedInnerAction) {
   EXPECT_EQ(19, mock.AsStdFunction()(0, 17));
 }
 
-#if !GTEST_OS_WINDOWS_MOBILE
+#ifndef GTEST_OS_WINDOWS_MOBILE
 
 class SetErrnoAndReturnTest : public testing::Test {
  protected:
@@ -1751,9 +1804,7 @@ TEST(ReturnNewTest, ConstructorThatTakes10Arguments) {
   delete c;
 }
 
-std::unique_ptr<int> UniquePtrSource() {
-  return std::unique_ptr<int>(new int(19));
-}
+std::unique_ptr<int> UniquePtrSource() { return std::make_unique<int>(19); }
 
 std::vector<std::unique_ptr<int>> VectorUniquePtrSource() {
   std::vector<std::unique_ptr<int>> out;
@@ -1802,7 +1853,7 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
 
   // Check default value
   DefaultValue<std::unique_ptr<int>>::SetFactory(
-      [] { return std::unique_ptr<int>(new int(42)); });
+      [] { return std::make_unique<int>(42); });
   EXPECT_EQ(42, *mock.MakeUnique());
 
   EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(Invoke(UniquePtrSource));
@@ -1822,7 +1873,7 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
 
 TEST(MockMethodTest, CanTakeMoveOnlyValue) {
   MockClass mock;
-  auto make = [](int i) { return std::unique_ptr<int>(new int(i)); };
+  auto make = [](int i) { return std::make_unique<int>(i); };
 
   EXPECT_CALL(mock, TakeUnique(_)).WillRepeatedly([](std::unique_ptr<int> i) {
     return *i;
@@ -2053,9 +2104,7 @@ struct Double {
   }
 };
 
-std::unique_ptr<int> UniqueInt(int i) {
-  return std::unique_ptr<int>(new int(i));
-}
+std::unique_ptr<int> UniqueInt(int i) { return std::make_unique<int>(i); }
 
 TEST(FunctorActionTest, ActionFromFunction) {
   Action<int(int, int&, int*)> a = &Add;

+ 3 - 1
ThirdParty/SpirvTools/external/googletest/googlemock/test/gmock-cardinalities_test.cc

@@ -31,6 +31,8 @@
 //
 // This file tests the built-in cardinalities.
 
+#include <ostream>
+
 #include "gmock/gmock.h"
 #include "gtest/gtest-spi.h"
 #include "gtest/gtest.h"
@@ -50,7 +52,7 @@ using testing::MakeCardinality;
 
 class MockFoo {
  public:
-  MockFoo() {}
+  MockFoo() = default;
   MOCK_METHOD0(Bar, int());  // NOLINT
 
  private:

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác