Update HasResultAndType code generation to skip duplicate enum values. There weren't any until SPIR-V 1.4 release, now there are two.
diff --git a/include/spirv/unified1/spirv.h b/include/spirv/unified1/spirv.h
index 9eb4ed7..66093e3 100644
--- a/include/spirv/unified1/spirv.h
+++ b/include/spirv/unified1/spirv.h
@@ -1743,9 +1743,7 @@
     case SpvOpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break;
     case SpvOpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
     case SpvOpDecorateString: *hasResult = false; *hasResultType = false; break;
-    case SpvOpDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
     case SpvOpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
-    case SpvOpMemberDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
     case SpvOpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
     case SpvOpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break;
     case SpvOpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break;
diff --git a/include/spirv/unified1/spirv.hpp b/include/spirv/unified1/spirv.hpp
index 5297fd3..d8318d3 100644
--- a/include/spirv/unified1/spirv.hpp
+++ b/include/spirv/unified1/spirv.hpp
@@ -1739,9 +1739,7 @@
     case OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break;
     case OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
     case OpDecorateString: *hasResult = false; *hasResultType = false; break;
-    case OpDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
     case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
-    case OpMemberDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
     case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
     case OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break;
     case OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break;
diff --git a/include/spirv/unified1/spirv.hpp11 b/include/spirv/unified1/spirv.hpp11
index 3427b37..54f861f 100644
--- a/include/spirv/unified1/spirv.hpp11
+++ b/include/spirv/unified1/spirv.hpp11
@@ -1739,9 +1739,7 @@
     case Op::OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break;
     case Op::OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
     case Op::OpDecorateString: *hasResult = false; *hasResultType = false; break;
-    case Op::OpDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
     case Op::OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
-    case Op::OpMemberDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
     case Op::OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
     case Op::OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break;
     case Op::OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break;
diff --git a/tools/buildHeaders/header.cpp b/tools/buildHeaders/header.cpp
index f579eaf..e1e05d0 100644
--- a/tools/buildHeaders/header.cpp
+++ b/tools/buildHeaders/header.cpp
@@ -42,6 +42,7 @@
 #include <cctype>
 #include <vector>
 #include <utility>
+#include <set>
 
 #include "jsoncpp/dist/json/json.h"
 
@@ -503,6 +504,8 @@
         {
             const Json::Value& enums = spvRoot["spv"]["enum"];
 
+            std::set<unsigned> seenValues;
+
             for (auto opClass = enums.begin(); opClass != enums.end(); ++opClass) {
                 const auto opName   = (*opClass)["Name"].asString();
                 if (opName != "Op") {
@@ -516,6 +519,14 @@
                 out << "    default: /* unknown opcode */ break;" << std::endl;
 
                 for (auto& inst : spv::InstructionDesc) {
+
+                    // Filter out duplicate enum values, which would break the switch statement.
+                    // These are probably just extension enums promoted to core.
+                    if (seenValues.find(inst.value) != seenValues.end()) {
+                        continue;
+                    }
+                    seenValues.insert(inst.value);
+
                     std::string name = inst.name;
                     out << "    case " << fmtEnumUse("Op", name) << ": *hasResult = " << (inst.hasResult() ? "true" : "false") << "; *hasResultType = " << (inst.hasType() ? "true" : "false") << "; break;" << std::endl;
                 }