Fix MSVC warnings on enum class switches
diff --git a/src/backend/InputState.cpp b/src/backend/InputState.cpp
index 5bfba91..902e082 100644
--- a/src/backend/InputState.cpp
+++ b/src/backend/InputState.cpp
@@ -27,6 +27,8 @@
                 return sizeof(uint16_t);
             case nxt::IndexFormat::Uint32:
                 return sizeof(uint32_t);
+            default:
+                UNREACHABLE();
         }
     }
 
@@ -40,6 +42,8 @@
                 return 2;
             case nxt::VertexFormat::FloatR32:
                 return 1;
+            default:
+                UNREACHABLE();
         }
     }
 
@@ -50,6 +54,8 @@
             case nxt::VertexFormat::FloatR32G32:
             case nxt::VertexFormat::FloatR32:
                 return VertexFormatNumComponents(format) * sizeof(float);
+            default:
+                UNREACHABLE();
         }
     }
 
diff --git a/src/backend/Texture.cpp b/src/backend/Texture.cpp
index c28951c..a7c378b 100644
--- a/src/backend/Texture.cpp
+++ b/src/backend/Texture.cpp
@@ -23,6 +23,8 @@
         switch (format) {
             case nxt::TextureFormat::R8G8B8A8Unorm:
                 return 4;
+            default:
+                UNREACHABLE();
         }
     }
 
@@ -97,6 +99,8 @@
         switch (format) {
             case nxt::TextureFormat::R8G8B8A8Unorm:
                 return false;
+            default:
+                UNREACHABLE();
         }
     }
 
diff --git a/src/backend/d3d12/CommandBufferD3D12.cpp b/src/backend/d3d12/CommandBufferD3D12.cpp
index 352d487..4a9a637 100644
--- a/src/backend/d3d12/CommandBufferD3D12.cpp
+++ b/src/backend/d3d12/CommandBufferD3D12.cpp
@@ -38,6 +38,8 @@
                     return DXGI_FORMAT_R16_UINT;
                 case nxt::IndexFormat::Uint32:
                     return DXGI_FORMAT_R32_UINT;
+                default:
+                    UNREACHABLE();
             }
         }
 
diff --git a/src/backend/d3d12/InputStateD3D12.cpp b/src/backend/d3d12/InputStateD3D12.cpp
index 5a9e559..73b3acb 100644
--- a/src/backend/d3d12/InputStateD3D12.cpp
+++ b/src/backend/d3d12/InputStateD3D12.cpp
@@ -27,6 +27,8 @@
                 return DXGI_FORMAT_R32G32_FLOAT;
             case nxt::VertexFormat::FloatR32:
                 return DXGI_FORMAT_R32_FLOAT;
+            default:
+                UNREACHABLE();
         }
     }
 
@@ -36,6 +38,8 @@
                 return D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
             case nxt::InputStepMode::Instance:
                 return D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
+            default:
+                UNREACHABLE();
         }
     }
 
diff --git a/src/backend/d3d12/TextureD3D12.cpp b/src/backend/d3d12/TextureD3D12.cpp
index f17950b..432b5b8 100644
--- a/src/backend/d3d12/TextureD3D12.cpp
+++ b/src/backend/d3d12/TextureD3D12.cpp
@@ -66,6 +66,8 @@
             switch (dimension) {
                 case nxt::TextureDimension::e2D:
                     return D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+                default:
+                    UNREACHABLE();
             }
         }
 
@@ -73,6 +75,8 @@
             switch (format) {
                 case nxt::TextureFormat::R8G8B8A8Unorm:
                     return DXGI_FORMAT_R8G8B8A8_UNORM;
+                default:
+                    UNREACHABLE();
             }
         }
     }
diff --git a/src/backend/opengl/CommandBufferGL.cpp b/src/backend/opengl/CommandBufferGL.cpp
index 3e968c5..27a7568 100644
--- a/src/backend/opengl/CommandBufferGL.cpp
+++ b/src/backend/opengl/CommandBufferGL.cpp
@@ -41,6 +41,8 @@
                 return GL_UNSIGNED_SHORT;
             case nxt::IndexFormat::Uint32:
                 return GL_UNSIGNED_INT;
+            default:
+                UNREACHABLE();
         }
     }
 
@@ -51,6 +53,8 @@
             case nxt::VertexFormat::FloatR32G32:
             case nxt::VertexFormat::FloatR32:
                 return GL_FLOAT;
+            default:
+                UNREACHABLE();
         }
     }
 
diff --git a/src/backend/opengl/DepthStencilStateGL.cpp b/src/backend/opengl/DepthStencilStateGL.cpp
index 97d1830..4fb287d 100644
--- a/src/backend/opengl/DepthStencilStateGL.cpp
+++ b/src/backend/opengl/DepthStencilStateGL.cpp
@@ -16,6 +16,7 @@
 
 #include "backend/opengl/OpenGLBackend.h"
 #include "backend/opengl/PersistentPipelineStateGL.h"
+#include "common/Assert.h"
 
 namespace backend {
 namespace opengl {
@@ -39,6 +40,8 @@
                     return GL_EQUAL;
                 case nxt::CompareFunction::Always:
                     return GL_ALWAYS;
+                default:
+                    UNREACHABLE();
             }
         }
 
@@ -60,6 +63,8 @@
                     return GL_INCR_WRAP;
                 case nxt::StencilOperation::DecrementWrap:
                     return GL_DECR_WRAP;
+                default:
+                    UNREACHABLE();
             }
         }
     }
diff --git a/src/backend/opengl/PipelineGL.cpp b/src/backend/opengl/PipelineGL.cpp
index 01cbfee..1fb4746 100644
--- a/src/backend/opengl/PipelineGL.cpp
+++ b/src/backend/opengl/PipelineGL.cpp
@@ -36,6 +36,8 @@
                     return GL_FRAGMENT_SHADER;
                 case nxt::ShaderStage::Compute:
                     return GL_COMPUTE_SHADER;
+                default:
+                    UNREACHABLE();
             }
         }
 
diff --git a/src/backend/opengl/SamplerGL.cpp b/src/backend/opengl/SamplerGL.cpp
index 35489c5..742603f 100644
--- a/src/backend/opengl/SamplerGL.cpp
+++ b/src/backend/opengl/SamplerGL.cpp
@@ -14,6 +14,8 @@
 
 #include "backend/opengl/SamplerGL.h"
 
+#include "common/Assert.h"
+
 namespace backend {
 namespace opengl {
 
@@ -24,6 +26,8 @@
                     return GL_NEAREST;
                 case nxt::FilterMode::Linear:
                     return GL_LINEAR;
+                default:
+                    UNREACHABLE();
             }
         }
 
@@ -35,6 +39,8 @@
                             return GL_NEAREST_MIPMAP_NEAREST;
                         case nxt::FilterMode::Linear:
                             return GL_NEAREST_MIPMAP_LINEAR;
+                        default:
+                            UNREACHABLE();
                     }
                 case nxt::FilterMode::Linear:
                     switch (mipMapFilter) {
@@ -42,7 +48,11 @@
                             return GL_LINEAR_MIPMAP_NEAREST;
                         case nxt::FilterMode::Linear:
                             return GL_LINEAR_MIPMAP_LINEAR;
+                        default:
+                            UNREACHABLE();
                     }
+                default:
+                    UNREACHABLE();
             }
         }
     }
diff --git a/src/backend/opengl/TextureGL.cpp b/src/backend/opengl/TextureGL.cpp
index 6605d6a..f0eb89d 100644
--- a/src/backend/opengl/TextureGL.cpp
+++ b/src/backend/opengl/TextureGL.cpp
@@ -14,6 +14,8 @@
 
 #include "backend/opengl/TextureGL.h"
 
+#include "common/Assert.h"
+
 #include <algorithm>
 #include <vector>
 
@@ -26,6 +28,8 @@
             switch (dimension) {
                 case nxt::TextureDimension::e2D:
                     return GL_TEXTURE_2D;
+                default:
+                    UNREACHABLE();
             }
         }
 
@@ -33,6 +37,8 @@
             switch (format) {
                 case nxt::TextureFormat::R8G8B8A8Unorm:
                     return {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE};
+                default:
+                    UNREACHABLE();
             }
         }
 
diff --git a/src/common/Assert.h b/src/common/Assert.h
index 1e2cad1..9a24b3f 100644
--- a/src/common/Assert.h
+++ b/src/common/Assert.h
@@ -35,7 +35,7 @@
 
 // MSVC triggers a warning in /W4 for do {} while(0). SDL worked around this by using
 // // (0,0) and points out that it looks like an owl face.
-#if defined(_MSC_VER)
+#if defined(NXT_COMPILER_MSVC)
     #define NXT_ASSERT_LOOP_CONDITION (0,0)
 #else
     #define NXT_ASSERT_LOOP_CONDITION (0)
@@ -51,10 +51,10 @@
             } \
         } while(NXT_ASSERT_LOOP_CONDITION)
 #else
-    #if defined(_MSC_VER)
+    #if defined(NXT_COMPILER_MSVC)
         #define NXT_ASSERT_CALLSITE_HELPER(file, func, line, condition) \
                 __assume(condition)
-    #elif defined(__clang__) && defined(__builtin_assume)
+    #elif defined(NXT_COMPILER_CLANG) && defined(__builtin_assume)
         #define NXT_ASSERT_CALLSITE_HELPER(file, func, line, condition) \
                 __builtin_assume(condition)
     #else
@@ -66,9 +66,14 @@
 #endif
 
 #define NXT_ASSERT(condition) NXT_ASSERT_CALLSITE_HELPER(__FILE__, __func__, __LINE__, condition)
+#define NXT_UNREACHABLE() \
+    do { \
+        NXT_ASSERT(false && "Unreachable code hit"); NXT_BUILTIN_UNREACHABLE(); \
+    } while(NXT_ASSERT_LOOP_CONDITION)
 
 #if !defined(NXT_SKIP_ASSERT_SHORTHANDS)
     #define ASSERT NXT_ASSERT
+    #define UNREACHABLE NXT_UNREACHABLE
 #endif
 
 #endif // COMMON_ASSERT_H_
diff --git a/src/common/Compiler.h b/src/common/Compiler.h
index 7ee3a02..a6d84ae 100644
--- a/src/common/Compiler.h
+++ b/src/common/Compiler.h
@@ -16,10 +16,17 @@
 #define COMMON_COMPILER_H_
 
 // Defines macros for compiler-specific functionality
+//  - NXT_COMPILER_[CLANG|GCC|MSVC]: Compiler detection
 //  - NXT_BREAKPOINT(): Raises an exception and breaks in the debugger
+//  - NXT_BUILTIN_UNREACHABLE(): Hints the compiler that a code path is unreachable
 
 // Clang and GCC
 #ifdef __GNUC__
+    #if defined(__clang__)
+        #define NXT_COMPILER_CLANG
+    #else
+        #define NXT_COMPILER_GCC
+    #endif
 
     #if defined(__i386__) || defined(__x86_64__)
         #define NXT_BREAKPOINT() __asm__ __volatile__("int $3\n\t")
@@ -27,11 +34,17 @@
         #error "Implement BREAKPOINT on your platform"
     #endif
 
+    #define NXT_BUILTIN_UNREACHABLE() __builtin_unreachable()
+
 // MSVC
 #elif defined(_MSC_VER)
+    #define NXT_COMPILER_MSVC
+
     extern void __cdecl __debugbreak(void);
     #define NXT_BREAKPOINT() __debugbreak()
 
+    #define NXT_BUILTIN_UNREACHABLE() __assume(false)
+
 #else
     #error "Unsupported compiler"
 #endif
diff --git a/src/tests/end2end/InputStateTests.cpp b/src/tests/end2end/InputStateTests.cpp
index c0de37d..ea05ee8 100644
--- a/src/tests/end2end/InputStateTests.cpp
+++ b/src/tests/end2end/InputStateTests.cpp
@@ -14,6 +14,7 @@
 
 #include "tests/NXTTest.h"
 
+#include "common/Assert.h"
 #include "utils/NXTHelpers.h"
 
 using nxt::InputStepMode;
@@ -72,6 +73,8 @@
                     return component >= 2;
                 case VertexFormat::FloatR32:
                     return component >= 1;
+                default:
+                    NXT_UNREACHABLE();
             }
         }
 
diff --git a/src/utils/BackendBinding.cpp b/src/utils/BackendBinding.cpp
index 917c4d6..db19eb3 100644
--- a/src/utils/BackendBinding.cpp
+++ b/src/utils/BackendBinding.cpp
@@ -14,6 +14,8 @@
 
 #include "utils/BackendBinding.h"
 
+#include "common/Assert.h"
+
 namespace utils {
 
     BackendBinding* CreateD3D12Binding();
@@ -50,6 +52,9 @@
 
             case BackendType::Vulkan:
                 return nullptr; // TODO(cwallez@chromium.org) change it to CreateVulkanBinding();
+
+            default:
+                UNREACHABLE();
         }
     }
 
diff --git a/src/utils/NXTHelpers.cpp b/src/utils/NXTHelpers.cpp
index cecdb36..595d073 100644
--- a/src/utils/NXTHelpers.cpp
+++ b/src/utils/NXTHelpers.cpp
@@ -14,6 +14,8 @@
 
 #include "utils/NXTHelpers.h"
 
+#include "common/Assert.h"
+
 #include <shaderc/shaderc.hpp>
 
 #include <cstring>
@@ -38,6 +40,8 @@
             case nxt::ShaderStage::Compute:
                 kind = shaderc_glsl_compute_shader;
                 break;
+            default:
+                UNREACHABLE();
         }
 
         auto result = compiler.CompileGlslToSpv(source, strlen(source), kind, "myshader?", options);