Support OpenCL.DebugInfo.100 extended instruction set (#3080)

* Clone opencl.debuginfo.100 grammar from debuginfo grammar

Update version number to 200 revision 2

* Apply content from OpenCL.DebugInfo.100 extension text

* Rename grammar file

* Support OpenCL.DebugInfo.100 extended instructions

Add support for prefixing operand type names, to disambiguate
them between different instruction sets.

* Add tests for OpenCL.DebugInfo.100

* Support lookup of OpenCL.DebugInfo.100 extinst

* Add tests for enum values

* Recognize 2017-2019 as copyright date range

* Android.mk: support OpenCL.DebugInfo.100 extended instruction set

Also, stop generating core instruction tables for non-unified1 versions
of the grammar.

* Imported entity operand type is concrete

* Bazel: Suppoort OpenCL.DebugInfo.100

* BUILD.gn: Support OpenCL.DebugInfo.100

diff --git a/Android.mk b/Android.mk
index cb7062c..7794c76 100644
--- a/Android.mk
+++ b/Android.mk
@@ -178,73 +178,43 @@
 
 # Locations of grammar files.
 #
-# TODO(dneto): Build a single set of tables that embeds versioning differences on
-# a per-item basis.  That must happen before SPIR-V 1.4, etc.
-# https://github.com/KhronosGroup/SPIRV-Tools/issues/1195
-SPV_CORE10_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.0/spirv.core.grammar.json
-SPV_CORE11_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.1/spirv.core.grammar.json
-SPV_CORE12_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.2/spirv.core.grammar.json
 SPV_COREUNIFIED1_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/unified1/spirv.core.grammar.json
-SPV_CORELATEST_GRAMMAR=$(SPV_COREUNIFIED1_GRAMMAR)
 SPV_GLSL_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.2/extinst.glsl.std.450.grammar.json
 SPV_OPENCL_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.2/extinst.opencl.std.100.grammar.json
 # TODO(dneto): I expect the DebugInfo grammar file to eventually migrate to SPIRV-Headers
 SPV_DEBUGINFO_GRAMMAR=$(LOCAL_PATH)/source/extinst.debuginfo.grammar.json
+SPV_CLDEBUGINFO100_GRAMMAR=$(LOCAL_PATH)/source/extinst.opencl.debuginfo.100.grammar.json
 
 define gen_spvtools_grammar_tables
-$(call generate-file-dir,$(1)/core.insts-1.0.inc)
-$(1)/core.insts-1.0.inc $(1)/operand.kinds-1.0.inc $(1)/glsl.std.450.insts.inc $(1)/opencl.std.insts.inc: \
+$(call generate-file-dir,$(1)/core.insts-unified1.inc)
+$(1)/core.insts-unified1.inc $(1)/operand.kinds-unified1.inc \
+$(1)/glsl.std.450.insts.inc \
+$(1)/opencl.std.insts.inc \
+: \
         $(LOCAL_PATH)/utils/generate_grammar_tables.py \
-        $(SPV_CORE10_GRAMMAR) \
+        $(SPV_COREUNIFIED1_GRAMMAR) \
         $(SPV_GLSL_GRAMMAR) \
-        $(SPV_OPENCL_GRAMMAR) \
-        $(SPV_DEBUGINFO_GRAMMAR)
+        $(SPV_OpenCL_GRAMMAR) \
+        $(SPV_DEBUGINFO_GRAMMAR) \
+        $(SPV_CLDEBUGINFO100_GRAMMAR)
 		@$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \
-		                --spirv-core-grammar=$(SPV_CORE10_GRAMMAR) \
+		                --spirv-core-grammar=$(SPV_COREUNIFIED1_GRAMMAR) \
 		                --extinst-glsl-grammar=$(SPV_GLSL_GRAMMAR) \
 		                --extinst-opencl-grammar=$(SPV_OPENCL_GRAMMAR) \
 		                --extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \
-		                --core-insts-output=$(1)/core.insts-1.0.inc \
+		                --extinst-cldebuginfo100-grammar=$(SPV_CLDEBUGINFO100_GRAMMAR) \
+		                --core-insts-output=$(1)/core.insts-unified1.inc \
 		                --glsl-insts-output=$(1)/glsl.std.450.insts.inc \
 		                --opencl-insts-output=$(1)/opencl.std.insts.inc \
-		                --operand-kinds-output=$(1)/operand.kinds-1.0.inc
-		@echo "[$(TARGET_ARCH_ABI)] Grammar v1.0   : instructions & operands <= grammar JSON files"
-$(1)/core.insts-1.1.inc $(1)/operand.kinds-1.1.inc: \
-        $(LOCAL_PATH)/utils/generate_grammar_tables.py \
-        $(SPV_CORE11_GRAMMAR) \
-        $(SPV_DEBUGINFO_GRAMMAR)
-		@$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \
-		                --spirv-core-grammar=$(SPV_CORE11_GRAMMAR) \
-		                --extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \
-		                --core-insts-output=$(1)/core.insts-1.1.inc \
-		                --operand-kinds-output=$(1)/operand.kinds-1.1.inc
-		@echo "[$(TARGET_ARCH_ABI)] Grammar v1.1   : instructions & operands <= grammar JSON files"
-$(1)/core.insts-1.2.inc $(1)/operand.kinds-1.2.inc: \
-        $(LOCAL_PATH)/utils/generate_grammar_tables.py \
-        $(SPV_CORE12_GRAMMAR) \
-        $(SPV_DEBUGINFO_GRAMMAR)
-		@$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \
-		                --spirv-core-grammar=$(SPV_CORE12_GRAMMAR) \
-		                --extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \
-		                --core-insts-output=$(1)/core.insts-1.2.inc \
-		                --operand-kinds-output=$(1)/operand.kinds-1.2.inc
-		@echo "[$(TARGET_ARCH_ABI)] Grammar v1.2   : instructions & operands <= grammar JSON files"
-$(1)/core.insts-unified1.inc $(1)/operand.kinds-unified1.inc: \
-        $(LOCAL_PATH)/utils/generate_grammar_tables.py \
-        $(SPV_COREUNIFIED1_GRAMMAR) \
-        $(SPV_DEBUGINFO_GRAMMAR)
-		@$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \
-		                --spirv-core-grammar=$(SPV_COREUNIFIED1_GRAMMAR) \
-		                --extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \
-		                --core-insts-output=$(1)/core.insts-unified1.inc \
 		                --operand-kinds-output=$(1)/operand.kinds-unified1.inc
-		@echo "[$(TARGET_ARCH_ABI)] Grammar v1.3 (from unified1)  : instructions & operands <= grammar JSON files"
-$(LOCAL_PATH)/source/opcode.cpp: $(1)/core.insts-1.0.inc $(1)/core.insts-1.1.inc $(1)/core.insts-1.2.inc $(1)/core.insts-unified1.inc
-$(LOCAL_PATH)/source/operand.cpp: $(1)/operand.kinds-1.0.inc $(1)/operand.kinds-1.1.inc $(1)/operand.kinds-1.2.inc $(1)/operand.kinds-unified1.inc
+		@echo "[$(TARGET_ARCH_ABI)] Grammar (from unified1)  : instructions & operands <= grammar JSON files"
+$(LOCAL_PATH)/source/opcode.cpp: $(1)/core.insts-unified1.inc
+$(LOCAL_PATH)/source/operand.cpp: $(1)/operand.kinds-unified1.inc
 $(LOCAL_PATH)/source/ext_inst.cpp: \
 	$(1)/glsl.std.450.insts.inc \
 	$(1)/opencl.std.insts.inc \
 	$(1)/debuginfo.insts.inc \
+	$(1)/opencl.debuginfo.100.insts.inc \
 	$(1)/spv-amd-gcn-shader.insts.inc \
 	$(1)/spv-amd-shader-ballot.insts.inc \
 	$(1)/spv-amd-shader-explicit-vertex-parameter.insts.inc \
@@ -271,8 +241,9 @@
 		@echo "[$(TARGET_ARCH_ABI)] Generate language specific header for $(2): headers <= grammar"
 $(LOCAL_PATH)/source/ext_inst.cpp: $(1)/$(2).h
 endef
-# We generate language-specific headers for DebugInfo
+# We generate language-specific headers for DebugInfo and OpenCL.DebugInfo.100
 $(eval $(call gen_spvtools_lang_headers,$(SPVTOOLS_OUT_PATH),DebugInfo,$(SPV_DEBUGINFO_GRAMMAR)))
+$(eval $(call gen_spvtools_lang_headers,$(SPVTOOLS_OUT_PATH),OpenCLDebugInfo100,$(SPV_CLDEBUGINFO100_GRAMMAR)))
 
 
 define gen_spvtools_vendor_tables
@@ -282,22 +253,28 @@
         $(LOCAL_PATH)/source/extinst.$(2).grammar.json
 		@$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \
 		    --extinst-vendor-grammar=$(LOCAL_PATH)/source/extinst.$(2).grammar.json \
-		    --vendor-insts-output=$(1)/$(2).insts.inc
+		    --vendor-insts-output=$(1)/$(2).insts.inc \
+		    --vendor-operand-kind-prefix=$(3)
 		@echo "[$(TARGET_ARCH_ABI)] Vendor extended instruction set: $(2) tables <= grammar"
 $(LOCAL_PATH)/source/ext_inst.cpp: $(1)/$(2).insts.inc
 endef
-# Vendor extended instruction sets, with grammars from SPIRV-Tools source tree.
-SPV_NONSTANDARD_EXTINST_GRAMMARS=$(foreach F,$(wildcard $(LOCAL_PATH)/source/extinst.*.grammar.json),$(patsubst extinst.%.grammar.json,%,$(notdir $F)))
-$(foreach E,$(SPV_NONSTANDARD_EXTINST_GRAMMARS),$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),$E)))
+# Vendor and debug extended instruction sets, with grammars from SPIRV-Tools source tree.
+$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),debuginfo,""))
+$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),opencl.debuginfo.100,"CLDEBUG100_"))
+$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),spv-amd-gcn-shader,""))
+$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),spv-amd-shader-ballot,""))
+$(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,""))
 
 define gen_spvtools_enum_string_mapping
 $(call generate-file-dir,$(1)/extension_enum.inc.inc)
 $(1)/extension_enum.inc $(1)/enum_string_mapping.inc: \
         $(LOCAL_PATH)/utils/generate_grammar_tables.py \
-        $(SPV_CORELATEST_GRAMMAR)
+        $(SPV_COREUNIFIED1_GRAMMAR)
 		@$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \
-		                --spirv-core-grammar=$(SPV_CORELATEST_GRAMMAR) \
+		                --spirv-core-grammar=$(SPV_COREUNIFIED1_GRAMMAR) \
 		                --extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \
+		                --extinst-cldebuginfo100-grammar=$(SPV_CLDEBUGINFO100_GRAMMAR) \
 		                --extension-enum-output=$(1)/extension_enum.inc \
 		                --enum-string-mapping-output=$(1)/enum_string_mapping.inc
 		@echo "[$(TARGET_ARCH_ABI)] Generate enum<->string mapping <= grammar JSON files"
diff --git a/BUILD.bazel b/BUILD.bazel
index dc1ca60..3046781 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -2,6 +2,7 @@
     ":build_defs.bzl",
     "COMMON_COPTS",
     "DEBUGINFO_GRAMMAR_JSON_FILE",
+    "CLDEBUGINFO100_GRAMMAR_JSON_FILE",
     "TEST_COPTS",
     "base_test",
     "generate_core_tables",
@@ -38,12 +39,6 @@
     srcs = ["utils/generate_language_headers.py"],
 )
 
-generate_core_tables("1.0")
-
-generate_core_tables("1.1")
-
-generate_core_tables("1.2")
-
 generate_core_tables("unified1")
 
 generate_enum_string_mapping("unified1")
@@ -62,8 +57,12 @@
 
 generate_vendor_tables("debuginfo")
 
+generate_vendor_tables("opencl.debuginfo.100", "CLDEBUG100_")
+
 generate_extinst_lang_headers("DebugInfo", DEBUGINFO_GRAMMAR_JSON_FILE)
 
+generate_extinst_lang_headers("OpenCLDebugInfo100", CLDEBUGINFO100_GRAMMAR_JSON_FILE)
+
 py_binary(
     name = "generate_registry_tables",
     srcs = ["utils/generate_registry_tables.py"],
@@ -96,16 +95,15 @@
     name = "generated_headers",
     hdrs = [
         ":gen_build_version",
-        ":gen_core_tables_1.0",
-        ":gen_core_tables_1.1",
-        ":gen_core_tables_1.2",
         ":gen_core_tables_unified1",
         ":gen_enum_string_mapping",
         ":gen_extinst_lang_headers_DebugInfo",
+        ":gen_extinst_lang_headers_OpenCLDebugInfo100",
         ":gen_glsl_tables_unified1",
         ":gen_opencl_tables_unified1",
         ":gen_registry_tables",
         ":gen_vendor_tables_debuginfo",
+        ":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",
diff --git a/BUILD.gn b/BUILD.gn
index 5c8eb9a..3c85c4e 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -32,7 +32,8 @@
         "${spirv_headers}/include/spirv/$version/spirv.core.grammar.json"
     core_insts_file = "${target_gen_dir}/core.insts-$version.inc"
     operand_kinds_file = "${target_gen_dir}/operand.kinds-$version.inc"
-    extinst_file = "source/extinst.debuginfo.grammar.json"
+    debuginfo_insts_file = "source/extinst.debuginfo.grammar.json"
+    cldebuginfo100_insts_file = "source/extinst.opencl.debuginfo.100.grammar.json"
 
     sources = [
       core_json_file,
@@ -47,7 +48,9 @@
       "--core-insts-output",
       rebase_path(core_insts_file, root_build_dir),
       "--extinst-debuginfo-grammar",
-      rebase_path(extinst_file, root_build_dir),
+      rebase_path(debuginfo_insts_file, root_build_dir),
+      "--extinst-cldebuginfo100-grammar",
+      rebase_path(cldebuginfo100_insts_file, root_build_dir),
       "--operand-kinds-output",
       rebase_path(operand_kinds_file, root_build_dir),
     ]
@@ -64,7 +67,8 @@
 
     core_json_file =
         "${spirv_headers}/include/spirv/$version/spirv.core.grammar.json"
-    debug_insts_file = "source/extinst.debuginfo.grammar.json"
+    debuginfo_insts_file = "source/extinst.debuginfo.grammar.json"
+    cldebuginfo100_insts_file = "source/extinst.opencl.debuginfo.100.grammar.json"
     extension_enum_file = "${target_gen_dir}/extension_enum.inc"
     extension_map_file = "${target_gen_dir}/enum_string_mapping.inc"
 
@@ -72,7 +76,9 @@
       "--spirv-core-grammar",
       rebase_path(core_json_file, root_build_dir),
       "--extinst-debuginfo-grammar",
-      rebase_path(debug_insts_file, root_build_dir),
+      rebase_path(debuginfo_insts_file, root_build_dir),
+      "--extinst-cldebuginfo100-grammar",
+      rebase_path(cldebuginfo100_insts_file, root_build_dir),
       "--extension-enum-output",
       rebase_path(extension_enum_file, root_build_dir),
       "--enum-string-mapping-output",
@@ -100,7 +106,6 @@
         "${spirv_headers}/include/spirv/$version/spirv.core.grammar.json"
     glsl_json_file = "${spirv_headers}/include/spirv/${version}/extinst.glsl.std.450.grammar.json"
     glsl_insts_file = "${target_gen_dir}/glsl.std.450.insts.inc"
-    debug_insts_file = "source/extinst.debuginfo.grammar.json"
 
     args = [
       "--spirv-core-grammar",
@@ -109,8 +114,6 @@
       rebase_path(glsl_json_file, root_build_dir),
       "--glsl-insts-output",
       rebase_path(glsl_insts_file, root_build_dir),
-      "--extinst-debuginfo-grammar",
-      rebase_path(debug_insts_file, root_build_dir),
     ]
     inputs = [
       core_json_file,
@@ -134,7 +137,6 @@
         "${spirv_headers}/include/spirv/$version/spirv.core.grammar.json"
     opengl_json_file = "${spirv_headers}/include/spirv/${version}/extinst.opencl.std.100.grammar.json"
     opencl_insts_file = "${target_gen_dir}/opencl.std.insts.inc"
-    debug_insts_file = "source/extinst.debuginfo.grammar.json"
 
     args = [
       "--spirv-core-grammar",
@@ -143,8 +145,6 @@
       rebase_path(opengl_json_file, root_build_dir),
       "--opencl-insts-output",
       rebase_path(opencl_insts_file, root_build_dir),
-      "--extinst-debuginfo-grammar",
-      rebase_path(debug_insts_file, root_build_dir),
     ]
     inputs = [
       core_json_file,
@@ -164,13 +164,12 @@
 
     name = invoker.name
     extinst_output_base = "${target_gen_dir}/${name}"
-    debug_insts_file = "source/extinst.debuginfo.grammar.json"
 
     args = [
       "--extinst-name",
       "${name}",
       "--extinst-grammar",
-      rebase_path(debug_insts_file, root_build_dir),
+      rebase_path(invoker.grammar_file, root_build_dir),
       "--extinst-output-base",
       rebase_path(extinst_output_base, root_build_dir),
     ]
@@ -198,6 +197,8 @@
       rebase_path(extinst_vendor_grammar, root_build_dir),
       "--vendor-insts-output",
       rebase_path(extinst_file, root_build_dir),
+      "--vendor-operand-kind-prefix",
+      invoker.operand_kind_prefix
     ]
     inputs = [
       extinst_vendor_grammar,
@@ -256,21 +257,28 @@
 spvtools_opencl_tables("opencl1-0") {
   version = "1.0"
 }
-spvtools_language_header("unified1") {
+spvtools_language_header("debuginfo") {
   name = "DebugInfo"
+  grammar_file = "source/extinst.debuginfo.grammar.json"
+}
+spvtools_language_header("cldebuginfo100") {
+  name = "OpenCLDebugInfo100"
+  grammar_file = "source/extinst.opencl.debuginfo.100.grammar.json"
 }
 
 spvtools_vendor_tables = [
-  "spv-amd-shader-explicit-vertex-parameter",
-  "spv-amd-shader-trinary-minmax",
-  "spv-amd-gcn-shader",
-  "spv-amd-shader-ballot",
-  "debuginfo",
+  ["spv-amd-shader-explicit-vertex-parameter", ""],
+  ["spv-amd-shader-trinary-minmax", ""],
+  ["spv-amd-gcn-shader", ""],
+  ["spv-amd-shader-ballot", ""],
+  ["debuginfo", ""],
+  ["opencl.debuginfo.100", "CLDEBUG100_"],
 ]
 
-foreach(table, spvtools_vendor_tables) {
+foreach(table_def, spvtools_vendor_tables) {
   spvtools_vendor_table(table) {
-    name = table
+    name = table_def[0]
+    operand_kind_prefix = table_def[1]
   }
 }
 
@@ -320,10 +328,12 @@
     ":spvtools_core_tables_unified1",
     ":spvtools_generators_inc",
     ":spvtools_glsl_tables_glsl1-0",
-    ":spvtools_language_header_unified1",
+    ":spvtools_language_header_debuginfo",
+    ":spvtools_language_header_cldebuginfo100",
     ":spvtools_opencl_tables_opencl1-0",
   ]
-  foreach(target_name, spvtools_vendor_tables) {
+  foreach(table_def, spvtools_vendor_tables) {
+    target_name = table_def[0]
     deps += [ ":spvtools_vendor_tables_$target_name" ]
   }
 
@@ -818,6 +828,7 @@
       "test/ext_inst.debuginfo_test.cpp",
       "test/ext_inst.glsl_test.cpp",
       "test/ext_inst.opencl_test.cpp",
+      "test/ext_inst.cldebug100_test.cpp",
       "test/fix_word_test.cpp",
       "test/generator_magic_number_test.cpp",
       "test/hex_float_test.cpp",
@@ -864,7 +875,8 @@
 
     deps = [
       ":spvtools",
-      ":spvtools_language_header_unified1",
+      ":spvtools_language_header_debuginfo",
+      ":spvtools_language_header_cldebuginfo100",
       ":spvtools_val",
       "//testing/gmock",
       "//testing/gtest",
diff --git a/build_defs.bzl b/build_defs.bzl
index 483fd2a..5d913a1 100644
--- a/build_defs.bzl
+++ b/build_defs.bzl
@@ -40,6 +40,7 @@
 })
 
 DEBUGINFO_GRAMMAR_JSON_FILE = "source/extinst.debuginfo.grammar.json"
+CLDEBUGINFO100_GRAMMAR_JSON_FILE = "source/extinst.opencl.debuginfo.100.grammar.json"
 
 def generate_core_tables(version = None):
     if not version:
@@ -47,6 +48,7 @@
     grammars = [
         "@spirv_headers//:spirv_core_grammar_" + version,
         DEBUGINFO_GRAMMAR_JSON_FILE,
+        CLDEBUGINFO100_GRAMMAR_JSON_FILE,
     ]
     outs = [
         "core.insts-{}.inc".format(version),
@@ -61,8 +63,9 @@
             "$(location :generate_grammar_tables) " +
             "--spirv-core-grammar=$(location {0}) " +
             "--extinst-debuginfo-grammar=$(location {1}) " +
-            "--core-insts-output=$(location {2}) " +
-            "--operand-kinds-output=$(location {3})"
+            "--extinst-cldebuginfo100-grammar=$(location {2}) " +
+            "--core-insts-output=$(location {3}) " +
+            "--operand-kinds-output=$(location {4})"
         ).format(*fmtargs),
         tools = [":generate_grammar_tables"],
         visibility = ["//visibility:private"],
@@ -74,6 +77,7 @@
     grammars = [
         "@spirv_headers//:spirv_core_grammar_" + version,
         DEBUGINFO_GRAMMAR_JSON_FILE,
+        CLDEBUGINFO100_GRAMMAR_JSON_FILE,
     ]
     outs = [
         "extension_enum.inc",
@@ -88,8 +92,9 @@
             "$(location :generate_grammar_tables) " +
             "--spirv-core-grammar=$(location {0}) " +
             "--extinst-debuginfo-grammar=$(location {1}) " +
-            "--extension-enum-output=$(location {2}) " +
-            "--enum-string-mapping-output=$(location {3})"
+            "--extinst-cldebuginfo100-grammar=$(location {2}) " +
+            "--extension-enum-output=$(location {3}) " +
+            "--enum-string-mapping-output=$(location {4})"
         ).format(*fmtargs),
         tools = [":generate_grammar_tables"],
         visibility = ["//visibility:private"],
@@ -137,13 +142,14 @@
         visibility = ["//visibility:private"],
     )
 
-def generate_vendor_tables(extension = None):
+def generate_vendor_tables(extension, operand_kind_prefix = ""):
     if not extension:
         fail("Must specify extension", "extension")
-    extension_rule = extension.replace("-", "_")
+    extension_rule = extension.replace("-", "_").replace(".", "_")
     grammars = ["source/extinst.{}.grammar.json".format(extension)]
     outs = ["{}.insts.inc".format(extension)]
-    fmtargs = grammars + outs
+    prefices = [operand_kind_prefix]
+    fmtargs = grammars + outs + prefices
     native.genrule(
         name = "gen_vendor_tables_" + extension_rule,
         srcs = grammars,
@@ -151,7 +157,8 @@
         cmd = (
             "$(location :generate_grammar_tables) " +
             "--extinst-vendor-grammar=$(location {0}) " +
-            "--vendor-insts-output=$(location {1})"
+            "--vendor-insts-output=$(location {1}) " +
+            "--vendor-operand-kind-prefix={2}"
         ).format(*fmtargs),
         tools = [":generate_grammar_tables"],
         visibility = ["//visibility:private"],
diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h
index 723de05..5dcb81a 100644
--- a/include/spirv-tools/libspirv.h
+++ b/include/spirv-tools/libspirv.h
@@ -225,13 +225,23 @@
   // A sequence of zero or more pairs of (Id, Literal integer)
   LAST_VARIABLE(SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER),
 
-  // The following are concrete enum types.
+  // The following are concrete enum types from the DebugInfo extended
+  // instruction set.
   SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS,  // DebugInfo Sec 3.2.  A mask.
   SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING,  // DebugInfo Sec 3.3
   SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE,                // DebugInfo Sec 3.4
   SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER,                // DebugInfo Sec 3.5
   SPV_OPERAND_TYPE_DEBUG_OPERATION,                     // DebugInfo Sec 3.6
 
+  // The following are concrete enum types from the OpenCL.DebugInfo.100
+  // extended instruction set.
+  SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS,  // Sec 3.2. A Mask
+  SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING,  // Sec 3.3
+  SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE,                // Sec 3.4
+  SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER,                // Sec 3.5
+  SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION,                     // Sec 3.6
+  SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY,               // Sec 3.7
+
   // This is a sentinel value, and does not represent an operand type.
   // It should come last.
   SPV_OPERAND_TYPE_NUM_OPERAND_TYPES,
@@ -248,6 +258,7 @@
   SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER,
   SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT,
   SPV_EXT_INST_TYPE_DEBUGINFO,
+  SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100,
 
   // Multiple distinct extended instruction set types could return this
   // value, if they are prefixed with NonSemantic. and are otherwise
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index f3b5942..4e7e10c 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -20,6 +20,7 @@
 # For now, assume the DebugInfo grammar file is in the current directory.
 # It might migrate to SPIRV-Headers.
 set(DEBUGINFO_GRAMMAR_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/extinst.debuginfo.grammar.json")
+set(CLDEBUGINFO100_GRAMMAR_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/extinst.opencl.debuginfo.100.grammar.json")
 
 # macro() definitions are used in the following because we need to append .inc
 # file paths into some global lists (*_CPP_DEPENDS). And those global lists are
@@ -33,9 +34,13 @@
     COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
       --spirv-core-grammar=${GRAMMAR_JSON_FILE}
       --extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE}
+      --extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE}
       --core-insts-output=${GRAMMAR_INSTS_INC_FILE}
       --operand-kinds-output=${GRAMMAR_KINDS_INC_FILE}
-    DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${GRAMMAR_JSON_FILE} ${DEBUGINFO_GRAMMAR_JSON_FILE}
+    DEPENDS ${GRAMMAR_PROCESSING_SCRIPT}
+            ${GRAMMAR_JSON_FILE}
+            ${DEBUGINFO_GRAMMAR_JSON_FILE}
+            ${CLDEBUGINFO100_GRAMMAR_JSON_FILE}
     COMMENT "Generate info tables for SPIR-V v${CONFIG_VERSION} core instructions and operands.")
   list(APPEND OPCODE_CPP_DEPENDS ${GRAMMAR_INSTS_INC_FILE})
   list(APPEND OPERAND_CPP_DEPENDS ${GRAMMAR_KINDS_INC_FILE})
@@ -50,9 +55,13 @@
     COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
       --spirv-core-grammar=${GRAMMAR_JSON_FILE}
       --extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE}
+      --extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE}
       --extension-enum-output=${GRAMMAR_EXTENSION_ENUM_INC_FILE}
       --enum-string-mapping-output=${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE}
-    DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${GRAMMAR_JSON_FILE} ${DEBUGINFO_GRAMMAR_JSON_FILE}
+    DEPENDS ${GRAMMAR_PROCESSING_SCRIPT}
+            ${GRAMMAR_JSON_FILE}
+            ${DEBUGINFO_GRAMMAR_JSON_FILE}
+            ${CLDEBUGINFO100_GRAMMAR_JSON_FILE}
     COMMENT "Generate enum-string mapping for SPIR-V v${CONFIG_VERSION}.")
   list(APPEND EXTENSION_H_DEPENDS ${GRAMMAR_EXTENSION_ENUM_INC_FILE})
   list(APPEND ENUM_STRING_MAPPING_CPP_DEPENDS ${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE})
@@ -101,13 +110,14 @@
   list(APPEND EXTINST_CPP_DEPENDS ${GRAMMAR_INC_FILE})
 endmacro(spvtools_opencl_tables)
 
-macro(spvtools_vendor_tables VENDOR_TABLE SHORT_NAME)
+macro(spvtools_vendor_tables VENDOR_TABLE SHORT_NAME OPERAND_KIND_PREFIX)
   set(INSTS_FILE "${spirv-tools_BINARY_DIR}/${VENDOR_TABLE}.insts.inc")
   set(GRAMMAR_FILE "${spirv-tools_SOURCE_DIR}/source/extinst.${VENDOR_TABLE}.grammar.json")
   add_custom_command(OUTPUT ${INSTS_FILE}
     COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
       --extinst-vendor-grammar=${GRAMMAR_FILE}
       --vendor-insts-output=${INSTS_FILE}
+      --vendor-operand-kind-prefix=${OPERAND_KIND_PREFIX}
     DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${GRAMMAR_FILE}
     COMMENT "Generate extended instruction tables for ${VENDOR_TABLE}.")
   add_custom_target(spv-tools-${SHORT_NAME} DEPENDS ${INSTS_FILE})
@@ -134,12 +144,14 @@
 spvtools_enum_string_mapping("unified1")
 spvtools_opencl_tables("unified1")
 spvtools_glsl_tables("unified1")
-spvtools_vendor_tables("spv-amd-shader-explicit-vertex-parameter" "spv-amd-sevp")
-spvtools_vendor_tables("spv-amd-shader-trinary-minmax" "spv-amd-stm")
-spvtools_vendor_tables("spv-amd-gcn-shader" "spv-amd-gs")
-spvtools_vendor_tables("spv-amd-shader-ballot" "spv-amd-sb")
-spvtools_vendor_tables("debuginfo" "debuginfo")
+spvtools_vendor_tables("spv-amd-shader-explicit-vertex-parameter" "spv-amd-sevp" "")
+spvtools_vendor_tables("spv-amd-shader-trinary-minmax" "spv-amd-stm" "")
+spvtools_vendor_tables("spv-amd-gcn-shader" "spv-amd-gs" "")
+spvtools_vendor_tables("spv-amd-shader-ballot" "spv-amd-sb" "")
+spvtools_vendor_tables("debuginfo" "debuginfo" "")
+spvtools_vendor_tables("opencl.debuginfo.100" "cldi100" "CLDEBUG100_")
 spvtools_extinst_lang_headers("DebugInfo" ${DEBUGINFO_GRAMMAR_JSON_FILE})
+spvtools_extinst_lang_headers("OpenCLDebugInfo100" ${CLDEBUGINFO100_GRAMMAR_JSON_FILE})
 
 spvtools_vimsyntax("unified1" "1.0")
 add_custom_target(spirv-tools-vimsyntax DEPENDS ${VIMSYNTAX_FILE})
diff --git a/source/binary.cpp b/source/binary.cpp
index 8229e53..0463061 100644
--- a/source/binary.cpp
+++ b/source/binary.cpp
@@ -636,7 +636,12 @@
     case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
     case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
     case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
-    case SPV_OPERAND_TYPE_DEBUG_OPERATION: {
+    case SPV_OPERAND_TYPE_DEBUG_OPERATION:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY: {
       // A single word that is a plain enum value.
 
       // Map an optional operand type to its corresponding concrete type.
@@ -660,6 +665,7 @@
     case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
     case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
     case SPV_OPERAND_TYPE_SELECTION_CONTROL:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
     case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: {
       // This operand is a mask.
 
diff --git a/source/disassemble.cpp b/source/disassemble.cpp
index 2ba0d3d..4b3972b 100644
--- a/source/disassemble.cpp
+++ b/source/disassemble.cpp
@@ -280,7 +280,12 @@
     case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
     case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
     case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
-    case SPV_OPERAND_TYPE_DEBUG_OPERATION: {
+    case SPV_OPERAND_TYPE_DEBUG_OPERATION:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY: {
       spv_operand_desc entry;
       if (grammar_.lookupOperand(operand.type, word, &entry))
         assert(false && "should have caught this earlier");
@@ -293,6 +298,7 @@
     case SPV_OPERAND_TYPE_MEMORY_ACCESS:
     case SPV_OPERAND_TYPE_SELECTION_CONTROL:
     case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
       EmitMaskOperand(operand.type, word);
       break;
     default:
diff --git a/source/ext_inst.cpp b/source/ext_inst.cpp
index 6ac5756..e332f0d 100644
--- a/source/ext_inst.cpp
+++ b/source/ext_inst.cpp
@@ -28,6 +28,7 @@
 
 #include "debuginfo.insts.inc"
 #include "glsl.std.450.insts.inc"
+#include "opencl.debuginfo.100.insts.inc"
 #include "opencl.std.insts.inc"
 
 #include "spirv-tools/libspirv.h"
@@ -51,6 +52,8 @@
      ARRAY_SIZE(spv_amd_shader_ballot_entries), spv_amd_shader_ballot_entries},
     {SPV_EXT_INST_TYPE_DEBUGINFO, ARRAY_SIZE(debuginfo_entries),
      debuginfo_entries},
+    {SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100,
+     ARRAY_SIZE(opencl_debuginfo_100_entries), opencl_debuginfo_100_entries},
 };
 
 static const spv_ext_inst_table_t kTable_1_0 = {ARRAY_SIZE(kGroups_1_0),
@@ -116,6 +119,9 @@
   if (!strcmp("DebugInfo", name)) {
     return SPV_EXT_INST_TYPE_DEBUGINFO;
   }
+  if (!strcmp("OpenCL.DebugInfo.100", name)) {
+    return SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100;
+  }
   // ensure to add any known non-semantic extended instruction sets
   // above this point, and update spvExtInstIsNonSemantic()
   if (!strncmp("NonSemantic.", name, 12)) {
diff --git a/source/extinst.opencl.debuginfo.100.grammar.json b/source/extinst.opencl.debuginfo.100.grammar.json
new file mode 100644
index 0000000..08062be
--- /dev/null
+++ b/source/extinst.opencl.debuginfo.100.grammar.json
@@ -0,0 +1,632 @@
+{
+  "copyright" : [
+    "Copyright (c) 2018 The Khronos Group Inc.",
+    "",
+    "Permission is hereby granted, free of charge, to any person obtaining a copy",
+    "of this software and/or associated documentation files (the \"Materials\"),",
+    "to deal in the Materials without restriction, including without limitation",
+    "the rights to use, copy, modify, merge, publish, distribute, sublicense,",
+    "and/or sell copies of the Materials, and to permit persons to whom the",
+    "Materials are furnished to do so, subject to the following conditions:",
+    "",
+    "The above copyright notice and this permission notice shall be included in",
+    "all copies or substantial portions of the Materials.",
+    "",
+    "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS",
+    "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND",
+    "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ",
+    "",
+    "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS",
+    "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
+    "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL",
+    "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
+    "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING",
+    "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS",
+    "IN THE MATERIALS."
+  ],
+  "version" : 200,
+  "revision" : 2,
+  "instructions" : [
+    {
+      "opname" : "DebugInfoNone",
+      "opcode" : 0
+    },
+    {
+      "opname" : "DebugCompilationUnit",
+      "opcode" : 1,
+      "operands" : [
+        { "kind" : "LiteralInteger", "name" : "'Version'" },
+        { "kind" : "LiteralInteger", "name" : "'DWARF Version'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "SourceLanguage", "name" : "'Language'" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeBasic",
+      "opcode" : 2,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "IdRef", "name" : "'Size'" },
+        { "kind" : "DebugBaseTypeAttributeEncoding", "name" : "'Encoding'" }
+      ]
+    },
+    {
+      "opname" : "DebugTypePointer",
+      "opcode" : 3,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Base Type'" },
+        { "kind" : "StorageClass", "name" : "'Storage Class'" },
+        { "kind" : "DebugInfoFlags", "name" : "'Flags'" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeQualifier",
+      "opcode" : 4,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Base Type'" },
+        { "kind" : "DebugTypeQualifier", "name" : "'Type Qualifier'" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeArray",
+      "opcode" : 5,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Base Type'" },
+        { "kind" : "IdRef", "name" : "'Component Counts'", "quantifier" : "*" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeVector",
+      "opcode" : 6,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Base Type'" },
+        { "kind" : "LiteralInteger", "name" : "'Component Count'" }
+      ]
+    },
+    {
+      "opname" : "DebugTypedef",
+      "opcode" : 7,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "IdRef", "name" : "'Base Type'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" },
+        { "kind" : "IdRef", "name" : "'Parent'" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeFunction",
+      "opcode" : 8,
+      "operands" : [
+        { "kind" : "DebugInfoFlags", "name" : "'Flags'" },
+        { "kind" : "IdRef", "name" : "'Return Type'" },
+        { "kind" : "IdRef", "name" : "'Parameter Types'", "quantifier" : "*" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeEnum",
+      "opcode" : 9,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "IdRef", "name" : "'Underlying Type'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" },
+        { "kind" : "IdRef", "name" : "'Parent'" },
+        { "kind" : "IdRef", "name" : "'Size'" },
+        { "kind" : "DebugInfoFlags", "name" : "'Flags'" },
+        { "kind" : "PairIdRefIdRef", "name" : "'Value, Name, Value, Name, ...'", "quantifier" : "*" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeComposite",
+      "opcode" : 10,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "DebugCompositeType", "name" : "'Tag'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" },
+        { "kind" : "IdRef", "name" : "'Parent'" },
+        { "kind" : "IdRef", "name" : "'Linkage Name'" },
+        { "kind" : "IdRef", "name" : "'Size'" },
+        { "kind" : "DebugInfoFlags", "name" : "'Flags'" },
+        { "kind" : "IdRef", "name" : "'Members'", "quantifier" : "*" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeMember",
+      "opcode" : 11,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "IdRef", "name" : "'Type'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" },
+        { "kind" : "IdRef", "name" : "'Parent'" },
+        { "kind" : "IdRef", "name" : "'Offset'" },
+        { "kind" : "IdRef", "name" : "'Size'" },
+        { "kind" : "DebugInfoFlags", "name" : "'Flags'" },
+        { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeInheritance",
+      "opcode" : 12,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Child'" },
+        { "kind" : "IdRef", "name" : "'Parent'" },
+        { "kind" : "IdRef", "name" : "'Offset'" },
+        { "kind" : "IdRef", "name" : "'Size'" },
+        { "kind" : "DebugInfoFlags", "name" : "'Flags'" }
+      ]
+    },
+    {
+      "opname" : "DebugTypePtrToMember",
+      "opcode" : 13,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Member Type'" },
+        { "kind" : "IdRef", "name" : "'Parent'" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeTemplate",
+      "opcode" : 14,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Target'" },
+        { "kind" : "IdRef", "name" : "'Parameters'", "quantifier" : "*" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeTemplateParameter",
+      "opcode" : 15,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "IdRef", "name" : "'Actual Type'" },
+        { "kind" : "IdRef", "name" : "'Value'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeTemplateTemplateParameter",
+      "opcode" : 16,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "IdRef", "name" : "'Template Name'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" }
+      ]
+    },
+    {
+      "opname" : "DebugTypeTemplateParameterPack",
+      "opcode" : 17,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" },
+        { "kind" : "IdRef", "name" : "'Template Parameters'", "quantifier" : "*" }
+      ]
+    },
+    {
+      "opname" : "DebugGlobalVariable",
+      "opcode" : 18,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "IdRef", "name" : "'Type'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" },
+        { "kind" : "IdRef", "name" : "'Parent'" },
+        { "kind" : "IdRef", "name" : "'Linkage Name'" },
+        { "kind" : "IdRef", "name" : "'Variable'" },
+        { "kind" : "DebugInfoFlags", "name" : "'Flags'" },
+        { "kind" : "IdRef", "name" : "'Static Member Declaration'", "quantifier" : "?" }
+      ]
+    },
+    {
+      "opname" : "DebugFunctionDeclaration",
+      "opcode" : 19,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "IdRef", "name" : "'Type'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" },
+        { "kind" : "IdRef", "name" : "'Parent'" },
+        { "kind" : "IdRef", "name" : "'Linkage Name'" },
+        { "kind" : "DebugInfoFlags", "name" : "'Flags'" }
+      ]
+    },
+    {
+      "opname" : "DebugFunction",
+      "opcode" : 20,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "IdRef", "name" : "'Type'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" },
+        { "kind" : "IdRef", "name" : "'Parent'" },
+        { "kind" : "IdRef", "name" : "'Linkage Name'" },
+        { "kind" : "DebugInfoFlags", "name" : "'Flags'" },
+        { "kind" : "LiteralInteger", "name" : "'Scope Line'" },
+        { "kind" : "IdRef", "name" : "'Function'" },
+        { "kind" : "IdRef", "name" : "'Declaration'", "quantifier" : "?" }
+      ]
+    },
+    {
+      "opname" : "DebugLexicalBlock",
+      "opcode" : 21,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" },
+        { "kind" : "IdRef", "name" : "'Parent'" },
+        { "kind" : "IdRef", "name" : "'Name'", "quantifier" : "?" }
+      ]
+    },
+    {
+      "opname" : "DebugLexicalBlockDiscriminator",
+      "opcode" : 22,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Discriminator'" },
+        { "kind" : "IdRef", "name" : "'Parent'" }
+      ]
+    },
+    {
+      "opname" : "DebugScope",
+      "opcode" : 23,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Scope'" },
+        { "kind" : "IdRef", "name" : "'Inlined At'", "quantifier" : "?" }
+      ]
+    },
+    {
+      "opname" : "DebugNoScope",
+      "opcode" : 24
+    },
+    {
+      "opname" : "DebugInlinedAt",
+      "opcode" : 25,
+      "operands" : [
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "IdRef", "name" : "'Scope'" },
+        { "kind" : "IdRef", "name" : "'Inlined'", "quantifier" : "?" }
+      ]
+    },
+    {
+      "opname" : "DebugLocalVariable",
+      "opcode" : 26,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "IdRef", "name" : "'Type'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" },
+        { "kind" : "IdRef", "name" : "'Parent'" },
+        { "kind" : "DebugInfoFlags", "name" : "'Flags'" },
+        { "kind" : "LiteralInteger", "name" : "'Arg Number'", "quantifier" : "?" }
+      ]
+    },
+    {
+      "opname" : "DebugInlinedVariable",
+      "opcode" : 27,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Variable'" },
+        { "kind" : "IdRef", "name" : "'Inlined'" }
+      ]
+    },
+    {
+      "opname" : "DebugDeclare",
+      "opcode" : 28,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Local Variable'" },
+        { "kind" : "IdRef", "name" : "'Variable'" },
+        { "kind" : "IdRef", "name" : "'Expression'" }
+      ]
+    },
+    {
+      "opname" : "DebugValue",
+      "opcode" : 29,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Local Variable'" },
+        { "kind" : "IdRef", "name" : "'Value'" },
+        { "kind" : "IdRef", "name" : "'Expression'" },
+        { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" }
+      ]
+    },
+    {
+      "opname" : "DebugOperation",
+      "opcode" : 30,
+      "operands" : [
+        { "kind" : "DebugOperation", "name" : "'OpCode'" },
+        { "kind" : "LiteralInteger", "name" : "'Operands ...'", "quantifier" : "*" }
+      ]
+    },
+    {
+      "opname" : "DebugExpression",
+      "opcode" : 31,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Operands ...'", "quantifier" : "*" }
+      ]
+    },
+    {
+      "opname" : "DebugMacroDef",
+      "opcode" : 32,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" }
+      ]
+    },
+    {
+      "opname" : "DebugMacroUndef",
+      "opcode" : 33,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "IdRef", "name" : "'Macro'" }
+      ]
+    },
+    {
+      "opname" : "DebugImportedEntity",
+      "opcode" : 34,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'Name'" },
+        { "kind" : "DebugImportedEntity", "name" : "'Tag'" },
+        { "kind" : "IdRef", "name" : "'Source'" },
+        { "kind" : "IdRef", "name" : "'Entity'" },
+        { "kind" : "LiteralInteger", "name" : "'Line'" },
+        { "kind" : "LiteralInteger", "name" : "'Column'" },
+        { "kind" : "IdRef", "name" : "'Parent'" }
+      ]
+    },
+    {
+      "opname" : "DebugSource",
+      "opcode" : 35,
+      "operands" : [
+        { "kind" : "IdRef", "name" : "'File'" },
+        { "kind" : "IdRef", "name" : "'Text'", "quantifier" : "?" }
+      ]
+    }
+  ],
+  "operand_kinds" : [
+    {
+      "category" : "BitEnum",
+      "kind" : "DebugInfoFlags",
+      "enumerants" : [
+        {
+          "enumerant" : "FlagIsProtected",
+          "value" : "0x01"
+        },
+        {
+          "enumerant" : "FlagIsPrivate",
+          "value" : "0x02"
+        },
+        {
+          "enumerant" : "FlagIsPublic",
+          "value" : "0x03"
+        },
+        {
+          "enumerant" : "FlagIsLocal",
+          "value" : "0x04"
+        },
+        {
+          "enumerant" : "FlagIsDefinition",
+          "value" : "0x08"
+        },
+        {
+          "enumerant" : "FlagFwdDecl",
+          "value" : "0x10"
+        },
+        {
+          "enumerant" : "FlagArtificial",
+          "value" : "0x20"
+        },
+        {
+          "enumerant" : "FlagExplicit",
+          "value" : "0x40"
+        },
+        {
+          "enumerant" : "FlagPrototyped",
+          "value" : "0x80"
+        },
+        {
+          "enumerant" : "FlagObjectPointer",
+          "value" : "0x100"
+        },
+        {
+          "enumerant" : "FlagStaticMember",
+          "value" : "0x200"
+        },
+        {
+          "enumerant" : "FlagIndirectVariable",
+          "value" : "0x400"
+        },
+        {
+          "enumerant" : "FlagLValueReference",
+          "value" : "0x800"
+        },
+        {
+          "enumerant" : "FlagRValueReference",
+          "value" : "0x1000"
+        },
+        {
+          "enumerant" : "FlagIsOptimized",
+          "value" : "0x2000"
+        },
+        {
+          "enumerant" : "FlagIsEnumClass",
+          "value" : "0x4000"
+        },
+        {
+          "enumerant" : "FlagTypePassByValue",
+          "value" : "0x8000"
+        },
+        {
+          "enumerant" : "FlagTypePassByReference",
+          "value" : "0x10000"
+        }
+      ]
+    },
+    {
+      "category" : "ValueEnum",
+      "kind" : "DebugBaseTypeAttributeEncoding",
+      "enumerants" : [
+        {
+          "enumerant" : "Unspecified",
+          "value" : "0"
+        },
+        {
+          "enumerant" : "Address",
+          "value" : "1"
+        },
+        {
+          "enumerant" : "Boolean",
+          "value" : "2"
+        },
+        {
+          "enumerant" : "Float",
+          "value" : "3"
+        },
+        {
+          "enumerant" : "Signed",
+          "value" : "4"
+        },
+        {
+          "enumerant" : "SignedChar",
+          "value" : "5"
+        },
+        {
+          "enumerant" : "Unsigned",
+          "value" : "6"
+        },
+        {
+          "enumerant" : "UnsignedChar",
+          "value" : "7"
+        }
+      ]
+    },
+    {
+      "category" : "ValueEnum",
+      "kind" : "DebugCompositeType",
+      "enumerants" : [
+        {
+          "enumerant" : "Class",
+          "value" : "0"
+        },
+        {
+          "enumerant" : "Structure",
+          "value" : "1"
+        },
+        {
+          "enumerant" : "Union",
+          "value" : "2"
+        }
+      ]
+    },
+    {
+      "category" : "ValueEnum",
+      "kind" : "DebugTypeQualifier",
+      "enumerants" : [
+        {
+          "enumerant" : "ConstType",
+          "value" : "0"
+        },
+        {
+          "enumerant" : "VolatileType",
+          "value" : "1"
+        },
+        {
+          "enumerant" : "RestrictType",
+          "value" : "2"
+        },
+        {
+          "enumerant" : "AtomicType",
+          "value" : "3"
+        }
+      ]
+    },
+    {
+      "category" : "ValueEnum",
+      "kind" : "DebugOperation",
+      "enumerants" : [
+        {
+          "enumerant" : "Deref",
+          "value" : "0"
+        },
+        {
+          "enumerant" : "Plus",
+          "value" : "1"
+        },
+        {
+          "enumerant" : "Minus",
+          "value" : "2"
+        },
+        {
+          "enumerant" : "PlusUconst",
+          "value" : "3",
+          "parameters" : [
+             { "kind" : "LiteralInteger" }
+          ]
+        },
+        {
+          "enumerant" : "BitPiece",
+          "value" : "4",
+          "parameters" : [
+             { "kind" : "LiteralInteger" },
+             { "kind" : "LiteralInteger" }
+          ]
+        },
+        {
+          "enumerant" : "Swap",
+          "value" : "5"
+        },
+        {
+          "enumerant" : "Xderef",
+          "value" : "6"
+        },
+        {
+          "enumerant" : "StackValue",
+          "value" : "7"
+        },
+        {
+          "enumerant" : "Constu",
+          "value" : "8",
+          "parameters" : [
+             { "kind" : "LiteralInteger" }
+          ]
+        },
+        {
+          "enumerant" : "Fragment",
+          "value" : "9",
+          "parameters" : [
+             { "kind" : "LiteralInteger" },
+             { "kind" : "LiteralInteger" }
+          ]
+        }
+      ]
+    },
+    {
+      "category" : "ValueEnum",
+      "kind" : "DebugImportedEntity",
+      "enumerants" : [
+        {
+          "enumerant" : "ImportedModule",
+          "value" : "0"
+        },
+        {
+          "enumerant" : "ImportedDeclaration",
+          "value" : "1"
+	}
+      ]
+    }
+  ]
+}
diff --git a/source/operand.cpp b/source/operand.cpp
index cd26a3d..39d17a6 100644
--- a/source/operand.cpp
+++ b/source/operand.cpp
@@ -29,6 +29,7 @@
 // per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195
 
 #include "operand.kinds-unified1.inc"
+#include "spirv-tools/libspirv.h"
 
 static const spv_operand_table_t kOperandTable = {
     ARRAY_SIZE(pygen_variable_OperandInfoTable),
@@ -228,6 +229,18 @@
       return "debug type qualifier";
     case SPV_OPERAND_TYPE_DEBUG_OPERATION:
       return "debug operation";
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
+      return "OpenCL.DebugInfo.100 debug info flags";
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
+      return "OpenCL.DebugInfo.100 debug base type encoding";
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
+      return "OpenCL.DebugInfo.100 debug composite type";
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
+      return "OpenCL.DebugInfo.100 debug type qualifier";
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
+      return "OpenCL.DebugInfo.100 debug operation";
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
+      return "OpenCL.DebugInfo.100 debug imported entity";
 
     // The next values are for values returned from an instruction, not actually
     // an operand.  So the specific strings don't matter.  But let's add them
@@ -312,6 +325,11 @@
     case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
     case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
     case SPV_OPERAND_TYPE_DEBUG_OPERATION:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
       return true;
     default:
       break;
@@ -328,6 +346,7 @@
     case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
     case SPV_OPERAND_TYPE_MEMORY_ACCESS:
     case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
       return true;
     default:
       break;
diff --git a/source/text.cpp b/source/text.cpp
index fb475d8..88a8e8f 100644
--- a/source/text.cpp
+++ b/source/text.cpp
@@ -400,7 +400,8 @@
     case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
     case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
     case SPV_OPERAND_TYPE_SELECTION_CONTROL:
-    case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: {
+    case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
+    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: {
       uint32_t value;
       if (grammar.parseMaskOperand(type, textValue, &value)) {
         return context->diagnostic() << "Invalid " << spvOperandTypeStr(type)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index e6857e0..70999f9 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -100,6 +100,7 @@
   diagnostic_test.cpp
   enum_string_mapping_test.cpp
   enum_set_test.cpp
+  ext_inst.cldebug100_test.cpp
   ext_inst.debuginfo_test.cpp
   ext_inst.glsl_test.cpp
   ext_inst.non_semantic_test.cpp
diff --git a/test/ext_inst.cldebug100_test.cpp b/test/ext_inst.cldebug100_test.cpp
new file mode 100644
index 0000000..4f1e106
--- /dev/null
+++ b/test/ext_inst.cldebug100_test.cpp
@@ -0,0 +1,1070 @@
+// Copyright (c) 2017-2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string>
+#include <vector>
+
+#include "OpenCLDebugInfo100.h"
+#include "gmock/gmock.h"
+#include "source/util/string_utils.h"
+#include "spirv/unified1/spirv.h"
+#include "test/test_fixture.h"
+#include "test/unit_spirv.h"
+
+// This file tests the correctness of encoding and decoding of instructions
+// involving the OpenCL.DebugInfo.100 extended instruction set.
+// Validation is not checked here.
+
+namespace spvtools {
+namespace {
+
+using spvtest::Concatenate;
+using spvtest::MakeInstruction;
+using testing::Eq;
+using utils::MakeVector;
+
+// Test values of enums vs. what is written in the spec.
+
+TEST(ExtInstCLDebugInfo, InstructionValues) {
+  EXPECT_EQ(0, OpenCLDebugInfo100DebugInfoNone);
+  EXPECT_EQ(1, OpenCLDebugInfo100DebugCompilationUnit);
+  EXPECT_EQ(2, OpenCLDebugInfo100DebugTypeBasic);
+  EXPECT_EQ(3, OpenCLDebugInfo100DebugTypePointer);
+  EXPECT_EQ(4, OpenCLDebugInfo100DebugTypeQualifier);
+  EXPECT_EQ(5, OpenCLDebugInfo100DebugTypeArray);
+  EXPECT_EQ(6, OpenCLDebugInfo100DebugTypeVector);
+  EXPECT_EQ(7, OpenCLDebugInfo100DebugTypedef);
+  EXPECT_EQ(8, OpenCLDebugInfo100DebugTypeFunction);
+  EXPECT_EQ(9, OpenCLDebugInfo100DebugTypeEnum);
+  EXPECT_EQ(10, OpenCLDebugInfo100DebugTypeComposite);
+  EXPECT_EQ(11, OpenCLDebugInfo100DebugTypeMember);
+  EXPECT_EQ(12, OpenCLDebugInfo100DebugTypeInheritance);
+  EXPECT_EQ(13, OpenCLDebugInfo100DebugTypePtrToMember);
+  EXPECT_EQ(14, OpenCLDebugInfo100DebugTypeTemplate);
+  EXPECT_EQ(15, OpenCLDebugInfo100DebugTypeTemplateParameter);
+  EXPECT_EQ(16, OpenCLDebugInfo100DebugTypeTemplateTemplateParameter);
+  EXPECT_EQ(17, OpenCLDebugInfo100DebugTypeTemplateParameterPack);
+  EXPECT_EQ(18, OpenCLDebugInfo100DebugGlobalVariable);
+  EXPECT_EQ(19, OpenCLDebugInfo100DebugFunctionDeclaration);
+  EXPECT_EQ(20, OpenCLDebugInfo100DebugFunction);
+  EXPECT_EQ(21, OpenCLDebugInfo100DebugLexicalBlock);
+  EXPECT_EQ(22, OpenCLDebugInfo100DebugLexicalBlockDiscriminator);
+  EXPECT_EQ(23, OpenCLDebugInfo100DebugScope);
+  EXPECT_EQ(24, OpenCLDebugInfo100DebugNoScope);
+  EXPECT_EQ(25, OpenCLDebugInfo100DebugInlinedAt);
+  EXPECT_EQ(26, OpenCLDebugInfo100DebugLocalVariable);
+  EXPECT_EQ(27, OpenCLDebugInfo100DebugInlinedVariable);
+  EXPECT_EQ(28, OpenCLDebugInfo100DebugDeclare);
+  EXPECT_EQ(29, OpenCLDebugInfo100DebugValue);
+  EXPECT_EQ(30, OpenCLDebugInfo100DebugOperation);
+  EXPECT_EQ(31, OpenCLDebugInfo100DebugExpression);
+  EXPECT_EQ(32, OpenCLDebugInfo100DebugMacroDef);
+  EXPECT_EQ(33, OpenCLDebugInfo100DebugMacroUndef);
+  EXPECT_EQ(34, OpenCLDebugInfo100DebugImportedEntity);
+  EXPECT_EQ(35, OpenCLDebugInfo100DebugSource);
+}
+
+TEST(ExtInstCLDebugInfo, InfoFlagValues) {
+  EXPECT_EQ(1 << 0, OpenCLDebugInfo100FlagIsProtected);
+  EXPECT_EQ(1 << 1, OpenCLDebugInfo100FlagIsPrivate);
+  EXPECT_EQ(((1 << 0) | (1 << 1)), OpenCLDebugInfo100FlagIsPublic);
+  EXPECT_EQ(1 << 2, OpenCLDebugInfo100FlagIsLocal);
+  EXPECT_EQ(1 << 3, OpenCLDebugInfo100FlagIsDefinition);
+  EXPECT_EQ(1 << 4, OpenCLDebugInfo100FlagFwdDecl);
+  EXPECT_EQ(1 << 5, OpenCLDebugInfo100FlagArtificial);
+  EXPECT_EQ(1 << 6, OpenCLDebugInfo100FlagExplicit);
+  EXPECT_EQ(1 << 7, OpenCLDebugInfo100FlagPrototyped);
+  EXPECT_EQ(1 << 8, OpenCLDebugInfo100FlagObjectPointer);
+  EXPECT_EQ(1 << 9, OpenCLDebugInfo100FlagStaticMember);
+  EXPECT_EQ(1 << 10, OpenCLDebugInfo100FlagIndirectVariable);
+  EXPECT_EQ(1 << 11, OpenCLDebugInfo100FlagLValueReference);
+  EXPECT_EQ(1 << 12, OpenCLDebugInfo100FlagRValueReference);
+  EXPECT_EQ(1 << 13, OpenCLDebugInfo100FlagIsOptimized);
+  EXPECT_EQ(1 << 14, OpenCLDebugInfo100FlagIsEnumClass);
+  EXPECT_EQ(1 << 15, OpenCLDebugInfo100FlagTypePassByValue);
+  EXPECT_EQ(1 << 16, OpenCLDebugInfo100FlagTypePassByReference);
+}
+
+TEST(ExtInstCLDebugInfo, BaseTypeAttributeEndodingValues) {
+  EXPECT_EQ(0, OpenCLDebugInfo100Unspecified);
+  EXPECT_EQ(1, OpenCLDebugInfo100Address);
+  EXPECT_EQ(2, OpenCLDebugInfo100Boolean);
+  EXPECT_EQ(3, OpenCLDebugInfo100Float);
+  EXPECT_EQ(4, OpenCLDebugInfo100Signed);
+  EXPECT_EQ(5, OpenCLDebugInfo100SignedChar);
+  EXPECT_EQ(6, OpenCLDebugInfo100Unsigned);
+  EXPECT_EQ(7, OpenCLDebugInfo100UnsignedChar);
+}
+
+TEST(ExtInstCLDebugInfo, CompositeTypeValues) {
+  EXPECT_EQ(0, OpenCLDebugInfo100Class);
+  EXPECT_EQ(1, OpenCLDebugInfo100Structure);
+  EXPECT_EQ(2, OpenCLDebugInfo100Union);
+}
+
+TEST(ExtInstCLDebugInfo, TypeQualifierValues) {
+  EXPECT_EQ(0, OpenCLDebugInfo100ConstType);
+  EXPECT_EQ(1, OpenCLDebugInfo100VolatileType);
+  EXPECT_EQ(2, OpenCLDebugInfo100RestrictType);
+  EXPECT_EQ(3, OpenCLDebugInfo100AtomicType);
+}
+
+TEST(ExtInstCLDebugInfo, DebugOperationValues) {
+  EXPECT_EQ(0, OpenCLDebugInfo100Deref);
+  EXPECT_EQ(1, OpenCLDebugInfo100Plus);
+  EXPECT_EQ(2, OpenCLDebugInfo100Minus);
+  EXPECT_EQ(3, OpenCLDebugInfo100PlusUconst);
+  EXPECT_EQ(4, OpenCLDebugInfo100BitPiece);
+  EXPECT_EQ(5, OpenCLDebugInfo100Swap);
+  EXPECT_EQ(6, OpenCLDebugInfo100Xderef);
+  EXPECT_EQ(7, OpenCLDebugInfo100StackValue);
+  EXPECT_EQ(8, OpenCLDebugInfo100Constu);
+  EXPECT_EQ(9, OpenCLDebugInfo100Fragment);
+}
+
+TEST(ExtInstCLDebugInfo, ImportedEntityValues) {
+  EXPECT_EQ(0, OpenCLDebugInfo100ImportedModule);
+  EXPECT_EQ(1, OpenCLDebugInfo100ImportedDeclaration);
+}
+
+// Test round trip through assembler and disassembler.
+
+struct InstructionCase {
+  uint32_t opcode;
+  std::string name;
+  std::string operands;
+  std::vector<uint32_t> expected_operands;
+};
+
+using ExtInstCLDebugInfo100RoundTripTest =
+    spvtest::TextToBinaryTestBase<::testing::TestWithParam<InstructionCase>>;
+using ExtInstCLDebugInfo100RoundTripTestExplicit = spvtest::TextToBinaryTest;
+
+TEST_P(ExtInstCLDebugInfo100RoundTripTest, ParameterizedExtInst) {
+  const std::string input =
+      "%1 = OpExtInstImport \"OpenCL.DebugInfo.100\"\n"
+      "%3 = OpExtInst %2 %1 " +
+      GetParam().name + GetParam().operands + "\n";
+  // First make sure it assembles correctly.
+  std::cout << input << std::endl;
+  EXPECT_THAT(CompiledInstructions(input),
+              Eq(Concatenate(
+                  {MakeInstruction(SpvOpExtInstImport, {1},
+                                   MakeVector("OpenCL.DebugInfo.100")),
+                   MakeInstruction(SpvOpExtInst, {2, 3, 1, GetParam().opcode},
+                                   GetParam().expected_operands)})))
+      << input;
+  // Now check the round trip through the disassembler.
+  EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input) << input;
+}
+
+#define EPREFIX "Debug"
+
+#define CASE_0(Enum)                                               \
+  {                                                                \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, "", {} \
+  }
+
+#define CASE_ILL(Enum, L0, L1)                              \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 " #L0 " " #L1, {                               \
+      4, L0, L1                                             \
+    }                                                       \
+  }
+
+#define CASE_IL(Enum, L0)                                                 \
+  {                                                                       \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 " #L0, { \
+      4, L0                                                               \
+    }                                                                     \
+  }
+
+#define CASE_I(Enum)                                                     \
+  {                                                                      \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4", { 4 } \
+  }
+
+#define CASE_II(Enum)                                                          \
+  {                                                                            \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 %5", { 4, 5 } \
+  }
+
+#define CASE_III(Enum)                                                     \
+  {                                                                        \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 %5 %6", { \
+      4, 5, 6                                                              \
+    }                                                                      \
+  }
+
+#define CASE_IIII(Enum)                                                       \
+  {                                                                           \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 %5 %6 %7", { \
+      4, 5, 6, 7                                                              \
+    }                                                                         \
+  }
+
+#define CASE_IIIII(Enum)                                                       \
+  {                                                                            \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 %5 %6 %7 %8", \
+    {                                                                          \
+      4, 5, 6, 7, 8                                                            \
+    }                                                                          \
+  }
+
+#define CASE_IIIIII(Enum)                                   \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 %6 %7 %8 %9", {                             \
+      4, 5, 6, 7, 8, 9                                      \
+    }                                                       \
+  }
+
+#define CASE_IIIIIII(Enum)                                  \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 %6 %7 %8 %9 %10", {                         \
+      4, 5, 6, 7, 8, 9, 10                                  \
+    }                                                       \
+  }
+
+#define CASE_IIILLI(Enum, L0, L1)                           \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 %6 " #L0 " " #L1 " %7", {                   \
+      4, 5, 6, L0, L1, 7                                    \
+    }                                                       \
+  }
+
+#define CASE_IIILLIF(Enum, L0, L1, Fstr, Fnum)              \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 %6 " #L0 " " #L1 " %7 " Fstr, {             \
+      4, 5, 6, L0, L1, 7, Fnum                              \
+    }                                                       \
+  }
+
+#define CASE_IIILLIFL(Enum, L0, L1, Fstr, Fnum, L2)         \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 %6 " #L0 " " #L1 " %7 " Fstr " " #L2, {     \
+      4, 5, 6, L0, L1, 7, Fnum, L2                          \
+    }                                                       \
+  }
+
+#define CASE_IIILLIL(Enum, L0, L1, L2)                      \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 %6 " #L0 " " #L1 " %7 " #L2, {              \
+      4, 5, 6, L0, L1, 7, L2                                \
+    }                                                       \
+  }
+
+#define CASE_IE(Enum, E0)                                                 \
+  {                                                                       \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 " #E0, { \
+      4, uint32_t(OpenCLDebugInfo100##E0)                                 \
+    }                                                                     \
+  }
+
+#define CASE_IEIILLI(Enum, E0, L1, L2)                      \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 " #E0 " %5 %6 " #L1 " " #L2 " %7", {           \
+      4, uint32_t(OpenCLDebugInfo100##E0), 5, 6, L1, L2, 7  \
+    }                                                       \
+  }
+
+#define CASE_IIE(Enum, E0)                                                   \
+  {                                                                          \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 %5 " #E0, { \
+      4, 5, uint32_t(OpenCLDebugInfo100##E0)                                 \
+    }                                                                        \
+  }
+
+#define CASE_ISF(Enum, S0, Fstr, Fnum)                      \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 " #S0 " " Fstr, {                              \
+      4, uint32_t(SpvStorageClass##S0), Fnum                \
+    }                                                       \
+  }
+
+#define CASE_LII(Enum, L0)                                                    \
+  {                                                                           \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " " #L0 " %4 %5", \
+    {                                                                         \
+      L0, 4, 5                                                                \
+    }                                                                         \
+  }
+
+#define CASE_LLIe(Enum, L0, L1, RawEnumName, RawEnumValue)  \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " " #L0 " " #L1 " %4 " RawEnumName, {               \
+      L0, L1, 4, RawEnumValue                               \
+    }                                                       \
+  }
+
+#define CASE_ILI(Enum, L0)                                                    \
+  {                                                                           \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 " #L0 " %5", \
+    {                                                                         \
+      4, L0, 5                                                                \
+    }                                                                         \
+  }
+
+#define CASE_ILII(Enum, L0)                                 \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 " #L0 " %5 %6", {                              \
+      4, L0, 5, 6                                           \
+    }                                                       \
+  }
+
+#define CASE_ILLII(Enum, L0, L1)                            \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 " #L0 " " #L1 " %5 %6", {                      \
+      4, L0, L1, 5, 6                                       \
+    }                                                       \
+  }
+
+#define CASE_IIILLIIF(Enum, L0, L1, Fstr, Fnum)             \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr, {          \
+      4, 5, 6, L0, L1, 7, 8, Fnum                           \
+    }                                                       \
+  }
+
+#define CASE_IIILLIIFII(Enum, L0, L1, Fstr, Fnum)            \
+  {                                                          \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum,  \
+        " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " %9 %10", { \
+      4, 5, 6, L0, L1, 7, 8, Fnum, 9, 10                     \
+    }                                                        \
+  }
+
+#define CASE_IIILLIIFIIII(Enum, L0, L1, Fstr, Fnum)                  \
+  {                                                                  \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum,          \
+        " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " %9 %10 %11 %12", { \
+      4, 5, 6, L0, L1, 7, 8, Fnum, 9, 10, 11, 12                     \
+    }                                                                \
+  }
+
+#define CASE_IIILLIIFIIIIII(Enum, L0, L1, Fstr, Fnum)                        \
+  {                                                                          \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum,                  \
+        " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " %9 %10 %11 %12 %13 %14", { \
+      4, 5, 6, L0, L1, 7, 8, Fnum, 9, 10, 11, 12, 13, 14                     \
+    }                                                                        \
+  }
+
+#define CASE_IEILLIIIF(Enum, E0, L0, L1, Fstr, Fnum)                \
+  {                                                                 \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum,         \
+        " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 %8 " Fstr, {          \
+      4, uint32_t(OpenCLDebugInfo100##E0), 5, L0, L1, 6, 7, 8, Fnum \
+    }                                                               \
+  }
+
+#define CASE_IEILLIIIFI(Enum, E0, L0, L1, Fstr, Fnum)                  \
+  {                                                                    \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum,            \
+        " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 %8 " Fstr " %9", {       \
+      4, uint32_t(OpenCLDebugInfo100##E0), 5, L0, L1, 6, 7, 8, Fnum, 9 \
+    }                                                                  \
+  }
+
+#define CASE_IEILLIIIFII(Enum, E0, L0, L1, Fstr, Fnum)                     \
+  {                                                                        \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum,                \
+        " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 %8 " Fstr " %9 %10", {       \
+      4, uint32_t(OpenCLDebugInfo100##E0), 5, L0, L1, 6, 7, 8, Fnum, 9, 10 \
+    }                                                                      \
+  }
+
+#define CASE_IEILLIIIFIII(Enum, E0, L0, L1, Fstr, Fnum)                        \
+  {                                                                            \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum,                    \
+        " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 %8 " Fstr " %9 %10 %11", {       \
+      4, uint32_t(OpenCLDebugInfo100##E0), 5, L0, L1, 6, 7, 8, Fnum, 9, 10, 11 \
+    }                                                                          \
+  }
+
+#define CASE_IEILLIIIFIIII(Enum, E0, L0, L1, Fstr, Fnum)                     \
+  {                                                                          \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum,                  \
+        " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 %8 " Fstr " %9 %10 %11 %12", { \
+      4, uint32_t(OpenCLDebugInfo100##E0), 5, L0, L1, 6, 7, 8, Fnum, 9, 10,  \
+          11, 12                                                             \
+    }                                                                        \
+  }
+
+#define CASE_IIILLIIIF(Enum, L0, L1, Fstr, Fnum)            \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 %6 " #L0 " " #L1 " %7 %8 %9 " Fstr, {       \
+      4, 5, 6, L0, L1, 7, 8, 9, Fnum                        \
+    }                                                       \
+  }
+
+#define CASE_IIILLIIIFI(Enum, L0, L1, Fstr, Fnum)            \
+  {                                                          \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum,  \
+        " %4 %5 %6 " #L0 " " #L1 " %7 %8 %9 " Fstr " %10", { \
+      4, 5, 6, L0, L1, 7, 8, 9, Fnum, 10                     \
+    }                                                        \
+  }
+
+#define CASE_IIIIF(Enum, Fstr, Fnum)                        \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 %6 %7 " Fstr, {                             \
+      4, 5, 6, 7, Fnum                                      \
+    }                                                       \
+  }
+
+#define CASE_IIILL(Enum, L0, L1)                            \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 %6 " #L0 " " #L1, {                         \
+      4, 5, 6, L0, L1                                       \
+    }                                                       \
+  }
+
+#define CASE_IIIILL(Enum, L0, L1)                           \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 %6 %7 " #L0 " " #L1, {                      \
+      4, 5, 6, 7, L0, L1                                    \
+    }                                                       \
+  }
+
+#define CASE_IILLI(Enum, L0, L1)                            \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 " #L0 " " #L1 " %6", {                      \
+      4, 5, L0, L1, 6                                       \
+    }                                                       \
+  }
+
+#define CASE_IILLII(Enum, L0, L1)                           \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 " #L0 " " #L1 " %6 %7", {                   \
+      4, 5, L0, L1, 6, 7                                    \
+    }                                                       \
+  }
+
+#define CASE_IILLIII(Enum, L0, L1)                          \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 " #L0 " " #L1 " %6 %7 %8", {                \
+      4, 5, L0, L1, 6, 7, 8                                 \
+    }                                                       \
+  }
+
+#define CASE_IILLIIII(Enum, L0, L1)                         \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " %4 %5 " #L0 " " #L1 " %6 %7 %8 %9", {             \
+      4, 5, L0, L1, 6, 7, 8, 9                              \
+    }                                                       \
+  }
+
+#define CASE_IIILLIIFLI(Enum, L0, L1, Fstr, Fnum, L2)            \
+  {                                                              \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum,      \
+        " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " " #L2 " %9", { \
+      4, 5, 6, L0, L1, 7, 8, Fnum, L2, 9                         \
+    }                                                            \
+  }
+
+#define CASE_IIILLIIFLII(Enum, L0, L1, Fstr, Fnum, L2)               \
+  {                                                                  \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum,          \
+        " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " " #L2 " %9 %10", { \
+      4, 5, 6, L0, L1, 7, 8, Fnum, L2, 9, 10                         \
+    }                                                                \
+  }
+
+#define CASE_E(Enum, E0)                                               \
+  {                                                                    \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " " #E0, { \
+      uint32_t(OpenCLDebugInfo100##E0)                                 \
+    }                                                                  \
+  }
+
+#define CASE_EI(Enum, E0)                                                    \
+  {                                                                          \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " " #E0 " %4", { \
+      uint32_t(OpenCLDebugInfo100##E0), 4                                    \
+    }                                                                        \
+  }
+
+#define CASE_EII(Enum, E0)                                                    \
+  {                                                                           \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " " #E0 " %4 %5", \
+    {                                                                         \
+      uint32_t(OpenCLDebugInfo100##E0), 4, 5                                  \
+    }                                                                         \
+  }
+
+#define CASE_EIII(Enum, E0)                                 \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " " #E0 " %4 %5 %6", {                              \
+      uint32_t(OpenCLDebugInfo100##E0), 4, 5, 6             \
+    }                                                       \
+  }
+
+#define CASE_EIIII(Enum, E0)                                \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " " #E0 " %4 %5 %6 %7", {                           \
+      uint32_t(OpenCLDebugInfo100##E0), 4, 5, 6, 7          \
+    }                                                       \
+  }
+
+#define CASE_EIIIII(Enum, E0)                               \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " " #E0 " %4 %5 %6 %7 %8", {                        \
+      uint32_t(OpenCLDebugInfo100##E0), 4, 5, 6, 7, 8       \
+    }                                                       \
+  }
+
+#define CASE_EL(Enum, E0, L0)                                                  \
+  {                                                                            \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " " #E0 " " #L0, { \
+      uint32_t(OpenCLDebugInfo100##E0), L0                                     \
+    }                                                                          \
+  }
+
+#define CASE_ELL(Enum, E0, L0, L1)                          \
+  {                                                         \
+    uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \
+        " " #E0 " " #L0 " " #L1, {                          \
+      uint32_t(OpenCLDebugInfo100##E0), L0, L1              \
+    }                                                       \
+  }
+
+// OpenCL.DebugInfo.100 4.1 Missing Debugging Information
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugInfoNone,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_0(InfoNone),  // enum value 0
+                         })));
+
+// OpenCL.DebugInfo.100 4.2 Compilation Unit
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugCompilationUnit, ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+        CASE_LLIe(CompilationUnit, 100, 42, "HLSL", SpvSourceLanguageHLSL),
+    })));
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugSource, ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+        // TODO(dneto): Should this be a list of sourc texts,
+        // to accomodate length limits?
+        CASE_I(Source),
+        CASE_II(Source),
+    })));
+
+// OpenCL.DebugInfo.100 4.3 Type instructions
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeBasic,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_IIE(TypeBasic, Unspecified),
+                             CASE_IIE(TypeBasic, Address),
+                             CASE_IIE(TypeBasic, Boolean),
+                             CASE_IIE(TypeBasic, Float),
+                             CASE_IIE(TypeBasic, Signed),
+                             CASE_IIE(TypeBasic, SignedChar),
+                             CASE_IIE(TypeBasic, Unsigned),
+                             CASE_IIE(TypeBasic, UnsignedChar),
+                         })));
+
+// The FlagIsPublic is value is (1 << 0) | (1 << 2) which is the same
+// as the bitwise-OR of FlagIsProtected and FlagIsPrivate.
+// The disassembler will emit the compound expression instead.
+// There is no simple fix for this.  This enum is not really a mask
+// for the bottom two bits.
+TEST_F(ExtInstCLDebugInfo100RoundTripTestExplicit, FlagIsPublic) {
+  const std::string prefix =
+      "%1 = OpExtInstImport \"DebugInfo\"\n"
+      "%3 = OpExtInst %2 %1 DebugTypePointer %4 Private ";
+  const std::string input = prefix + "FlagIsPublic\n";
+  const std::string expected = prefix + "FlagIsProtected|FlagIsPrivate\n";
+  // First make sure it assembles correctly.
+  EXPECT_THAT(
+      CompiledInstructions(input),
+      Eq(Concatenate(
+          {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("DebugInfo")),
+           MakeInstruction(SpvOpExtInst,
+                           {2, 3, 1, OpenCLDebugInfo100DebugTypePointer, 4,
+                            uint32_t(SpvStorageClassPrivate),
+                            OpenCLDebugInfo100FlagIsPublic})})))
+      << input;
+  // Now check the round trip through the disassembler.
+  EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(expected)) << input;
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugTypePointer, ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+
+        //// Use each flag independently.
+        CASE_ISF(TypePointer, Private, "FlagIsProtected",
+                 uint32_t(OpenCLDebugInfo100FlagIsProtected)),
+        CASE_ISF(TypePointer, Private, "FlagIsPrivate",
+                 uint32_t(OpenCLDebugInfo100FlagIsPrivate)),
+
+        // FlagIsPublic is tested above.
+
+        CASE_ISF(TypePointer, Private, "FlagIsLocal",
+                 uint32_t(OpenCLDebugInfo100FlagIsLocal)),
+        CASE_ISF(TypePointer, Private, "FlagIsDefinition",
+                 uint32_t(OpenCLDebugInfo100FlagIsDefinition)),
+        CASE_ISF(TypePointer, Private, "FlagFwdDecl",
+                 uint32_t(OpenCLDebugInfo100FlagFwdDecl)),
+        CASE_ISF(TypePointer, Private, "FlagArtificial",
+                 uint32_t(OpenCLDebugInfo100FlagArtificial)),
+        CASE_ISF(TypePointer, Private, "FlagExplicit",
+                 uint32_t(OpenCLDebugInfo100FlagExplicit)),
+        CASE_ISF(TypePointer, Private, "FlagPrototyped",
+                 uint32_t(OpenCLDebugInfo100FlagPrototyped)),
+        CASE_ISF(TypePointer, Private, "FlagObjectPointer",
+                 uint32_t(OpenCLDebugInfo100FlagObjectPointer)),
+        CASE_ISF(TypePointer, Private, "FlagStaticMember",
+                 uint32_t(OpenCLDebugInfo100FlagStaticMember)),
+        CASE_ISF(TypePointer, Private, "FlagIndirectVariable",
+                 uint32_t(OpenCLDebugInfo100FlagIndirectVariable)),
+        CASE_ISF(TypePointer, Private, "FlagLValueReference",
+                 uint32_t(OpenCLDebugInfo100FlagLValueReference)),
+        CASE_ISF(TypePointer, Private, "FlagIsOptimized",
+                 uint32_t(OpenCLDebugInfo100FlagIsOptimized)),
+        CASE_ISF(TypePointer, Private, "FlagIsEnumClass",
+                 uint32_t(OpenCLDebugInfo100FlagIsEnumClass)),
+        CASE_ISF(TypePointer, Private, "FlagTypePassByValue",
+                 uint32_t(OpenCLDebugInfo100FlagTypePassByValue)),
+        CASE_ISF(TypePointer, Private, "FlagTypePassByReference",
+                 uint32_t(OpenCLDebugInfo100FlagTypePassByReference)),
+
+        //// Use flags in combination, and try different storage classes.
+        CASE_ISF(TypePointer, Function, "FlagIsProtected|FlagIsPrivate",
+                 uint32_t(OpenCLDebugInfo100FlagIsProtected) |
+                     uint32_t(OpenCLDebugInfo100FlagIsPrivate)),
+        CASE_ISF(
+            TypePointer, Workgroup,
+            "FlagIsPrivate|FlagFwdDecl|FlagIndirectVariable|FlagIsOptimized",
+            uint32_t(OpenCLDebugInfo100FlagIsPrivate) |
+                uint32_t(OpenCLDebugInfo100FlagFwdDecl) |
+                uint32_t(OpenCLDebugInfo100FlagIndirectVariable) |
+                uint32_t(OpenCLDebugInfo100FlagIsOptimized)),
+
+    })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeQualifier,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_IE(TypeQualifier, ConstType),
+                             CASE_IE(TypeQualifier, VolatileType),
+                             CASE_IE(TypeQualifier, RestrictType),
+                             CASE_IE(TypeQualifier, AtomicType),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeArray,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_II(TypeArray),
+                             CASE_III(TypeArray),
+                             CASE_IIII(TypeArray),
+                             CASE_IIIII(TypeArray),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeVector,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_IL(TypeVector, 2),
+                             CASE_IL(TypeVector, 3),
+                             CASE_IL(TypeVector, 4),
+                             CASE_IL(TypeVector, 16),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypedef,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_IIILLI(Typedef, 12, 13),
+                             CASE_IIILLI(Typedef, 14, 99),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeFunction,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_EI(TypeFunction, FlagIsProtected),
+                             CASE_EII(TypeFunction, FlagIsDefinition),
+                             CASE_EIII(TypeFunction, FlagArtificial),
+                             CASE_EIIII(TypeFunction, FlagExplicit),
+                             CASE_EIIIII(TypeFunction, FlagIsPrivate),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugTypeEnum, ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+        CASE_IIILLIIFII(
+            TypeEnum, 12, 13,
+            "FlagIsPrivate|FlagFwdDecl|FlagIndirectVariable|FlagIsOptimized",
+            uint32_t(OpenCLDebugInfo100FlagIsPrivate) |
+                uint32_t(OpenCLDebugInfo100FlagFwdDecl) |
+                uint32_t(OpenCLDebugInfo100FlagIndirectVariable) |
+                uint32_t(OpenCLDebugInfo100FlagIsOptimized)),
+        CASE_IIILLIIFIIII(TypeEnum, 17, 18, "FlagStaticMember",
+                          uint32_t(OpenCLDebugInfo100FlagStaticMember)),
+        CASE_IIILLIIFIIIIII(TypeEnum, 99, 1, "FlagStaticMember",
+                            uint32_t(OpenCLDebugInfo100FlagStaticMember)),
+    })));
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugTypeComposite, ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+        CASE_IEILLIIIF(
+            TypeComposite, Class, 12, 13,
+            "FlagIsPrivate|FlagFwdDecl|FlagIndirectVariable|FlagIsOptimized",
+            uint32_t(OpenCLDebugInfo100FlagIsPrivate) |
+                uint32_t(OpenCLDebugInfo100FlagFwdDecl) |
+                uint32_t(OpenCLDebugInfo100FlagIndirectVariable) |
+                uint32_t(OpenCLDebugInfo100FlagIsOptimized)),
+        // Cover all tag values: Class, Structure, Union
+        CASE_IEILLIIIF(TypeComposite, Class, 12, 13, "FlagIsPrivate",
+                       uint32_t(OpenCLDebugInfo100FlagIsPrivate)),
+        CASE_IEILLIIIF(TypeComposite, Structure, 12, 13, "FlagIsPrivate",
+                       uint32_t(OpenCLDebugInfo100FlagIsPrivate)),
+        CASE_IEILLIIIF(TypeComposite, Union, 12, 13, "FlagIsPrivate",
+                       uint32_t(OpenCLDebugInfo100FlagIsPrivate)),
+        // Now add members
+        CASE_IEILLIIIFI(TypeComposite, Class, 9, 10, "FlagIsPrivate",
+                        uint32_t(OpenCLDebugInfo100FlagIsPrivate)),
+        CASE_IEILLIIIFII(TypeComposite, Class, 9, 10, "FlagIsPrivate",
+                         uint32_t(OpenCLDebugInfo100FlagIsPrivate)),
+        CASE_IEILLIIIFIII(TypeComposite, Class, 9, 10, "FlagIsPrivate",
+                          uint32_t(OpenCLDebugInfo100FlagIsPrivate)),
+        CASE_IEILLIIIFIIII(TypeComposite, Class, 9, 10, "FlagIsPrivate",
+                           uint32_t(OpenCLDebugInfo100FlagIsPrivate)),
+    })));
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugTypeMember, ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+        CASE_IIILLIIIF(TypeMember, 12, 13, "FlagIsPrivate",
+                       uint32_t(OpenCLDebugInfo100FlagIsPrivate)),
+        CASE_IIILLIIIF(TypeMember, 99, 100, "FlagIsPrivate|FlagFwdDecl",
+                       uint32_t(OpenCLDebugInfo100FlagIsPrivate) |
+                           uint32_t(OpenCLDebugInfo100FlagFwdDecl)),
+        // Add the optional Id argument.
+        CASE_IIILLIIIFI(TypeMember, 12, 13, "FlagIsPrivate",
+                        uint32_t(OpenCLDebugInfo100FlagIsPrivate)),
+    })));
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugTypeInheritance, ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+        CASE_IIIIF(TypeInheritance, "FlagIsPrivate",
+                   uint32_t(OpenCLDebugInfo100FlagIsPrivate)),
+        CASE_IIIIF(TypeInheritance, "FlagIsPrivate|FlagFwdDecl",
+                   uint32_t(OpenCLDebugInfo100FlagIsPrivate) |
+                       uint32_t(OpenCLDebugInfo100FlagFwdDecl)),
+    })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypePtrToMember,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_II(TypePtrToMember),
+                         })));
+
+// OpenCL.DebugInfo.100 4.4 Templates
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeTemplate,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_II(TypeTemplate),
+                             CASE_III(TypeTemplate),
+                             CASE_IIII(TypeTemplate),
+                             CASE_IIIII(TypeTemplate),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeTemplateParameter,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_IIIILL(TypeTemplateParameter, 1, 2),
+                             CASE_IIIILL(TypeTemplateParameter, 99, 102),
+                             CASE_IIIILL(TypeTemplateParameter, 10, 7),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeTemplateTemplateParameter,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_IIILL(TypeTemplateTemplateParameter, 1, 2),
+                             CASE_IIILL(TypeTemplateTemplateParameter, 99, 102),
+                             CASE_IIILL(TypeTemplateTemplateParameter, 10, 7),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeTemplateParameterPack,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_IILLI(TypeTemplateParameterPack, 1, 2),
+                             CASE_IILLII(TypeTemplateParameterPack, 99, 102),
+                             CASE_IILLIII(TypeTemplateParameterPack, 10, 7),
+                             CASE_IILLIIII(TypeTemplateParameterPack, 10, 7),
+                         })));
+
+// OpenCL.DebugInfo.100 4.5 Global Variables
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugGlobalVariable, ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+        CASE_IIILLIIIF(GlobalVariable, 1, 2, "FlagIsOptimized",
+                       uint32_t(OpenCLDebugInfo100FlagIsOptimized)),
+        CASE_IIILLIIIF(GlobalVariable, 42, 43, "FlagIsOptimized",
+                       uint32_t(OpenCLDebugInfo100FlagIsOptimized)),
+        CASE_IIILLIIIFI(GlobalVariable, 1, 2, "FlagIsOptimized",
+                        uint32_t(OpenCLDebugInfo100FlagIsOptimized)),
+        CASE_IIILLIIIFI(GlobalVariable, 42, 43, "FlagIsOptimized",
+                        uint32_t(OpenCLDebugInfo100FlagIsOptimized)),
+    })));
+
+// OpenCL.DebugInfo.100 4.6 Functions
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugFunctionDeclaration,
+    ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+        CASE_IIILLIIF(FunctionDeclaration, 1, 2, "FlagIsOptimized",
+                      uint32_t(OpenCLDebugInfo100FlagIsOptimized)),
+        CASE_IIILLIIF(FunctionDeclaration, 42, 43, "FlagFwdDecl",
+                      uint32_t(OpenCLDebugInfo100FlagFwdDecl)),
+    })));
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugFunction, ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+        CASE_IIILLIIFLI(Function, 1, 2, "FlagIsOptimized",
+                        uint32_t(OpenCLDebugInfo100FlagIsOptimized), 3),
+        CASE_IIILLIIFLI(Function, 42, 43, "FlagFwdDecl",
+                        uint32_t(OpenCLDebugInfo100FlagFwdDecl), 44),
+        // Add the optional declaration Id.
+        CASE_IIILLIIFLII(Function, 1, 2, "FlagIsOptimized",
+                         uint32_t(OpenCLDebugInfo100FlagIsOptimized), 3),
+        CASE_IIILLIIFLII(Function, 42, 43, "FlagFwdDecl",
+                         uint32_t(OpenCLDebugInfo100FlagFwdDecl), 44),
+    })));
+
+// OpenCL.DebugInfo.100 4.7 Local Information
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugLexicalBlock,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_ILLII(LexicalBlock, 1, 2),
+                             CASE_ILLII(LexicalBlock, 42, 43),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugLexicalBlockDiscriminator,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_ILI(LexicalBlockDiscriminator, 1),
+                             CASE_ILI(LexicalBlockDiscriminator, 42),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugScope,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_I(Scope),
+                             CASE_II(Scope),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugNoScope,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_0(NoScope),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugInlinedAt,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_LII(InlinedAt, 1),
+                             CASE_LII(InlinedAt, 42),
+                         })));
+
+// OpenCL.DebugInfo.100 4.8 Local Variables
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugLocalVariable, ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+        CASE_IIILLIF(LocalVariable, 1, 2, "FlagIsPrivate",
+                     OpenCLDebugInfo100FlagIsPrivate),
+        CASE_IIILLIF(LocalVariable, 4, 5, "FlagIsProtected",
+                     OpenCLDebugInfo100FlagIsProtected),
+        CASE_IIILLIFL(LocalVariable, 9, 99, "FlagIsProtected",
+                      OpenCLDebugInfo100FlagIsProtected, 195),
+        CASE_IIILLIFL(LocalVariable, 19, 199, "FlagIsPrivate",
+                      OpenCLDebugInfo100FlagIsPrivate, 195),
+    })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugInlinedVariable,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_II(InlinedVariable),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugDebugDeclare,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_III(Declare),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugDebugValue, ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+        CASE_IIII(Value),
+        CASE_IIIII(Value),
+        CASE_IIIIII(Value),
+        // Test up to 3 id parameters. We can always try more.
+        CASE_IIIIIII(Value),
+    })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugDebugOperation,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_E(Operation, Deref),
+                             CASE_E(Operation, Plus),
+                             CASE_E(Operation, Minus),
+                             CASE_EL(Operation, PlusUconst, 1),
+                             CASE_EL(Operation, PlusUconst, 42),
+                             CASE_ELL(Operation, BitPiece, 1, 2),
+                             CASE_ELL(Operation, BitPiece, 4, 5),
+                             CASE_E(Operation, Swap),
+                             CASE_E(Operation, Xderef),
+                             CASE_E(Operation, StackValue),
+                             CASE_EL(Operation, Constu, 1),
+                             CASE_EL(Operation, Constu, 42),
+                             CASE_ELL(Operation, Fragment, 100, 200),
+                             CASE_ELL(Operation, Fragment, 8, 9),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugDebugExpression,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_0(Expression),
+                             CASE_I(Expression),
+                             CASE_II(Expression),
+                             CASE_III(Expression),
+                             CASE_IIII(Expression),
+                             CASE_IIIII(Expression),
+                             CASE_IIIIII(Expression),
+                             CASE_IIIIIII(Expression),
+                         })));
+
+// OpenCL.DebugInfo.100 4.9 Macros
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugMacroDef,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_ILI(MacroDef, 1),
+                             CASE_ILI(MacroDef, 42),
+                             CASE_ILII(MacroDef, 1),
+                             CASE_ILII(MacroDef, 42),
+                         })));
+
+INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugMacroUndef,
+                         ExtInstCLDebugInfo100RoundTripTest,
+                         ::testing::ValuesIn(std::vector<InstructionCase>({
+                             CASE_ILI(MacroUndef, 1),
+                             CASE_ILI(MacroUndef, 42),
+                         })));
+
+// OpenCL.DebugInfo.100 4.10 Imported Entities
+
+INSTANTIATE_TEST_SUITE_P(
+    OpenCLDebugInfo100DebugImportedEntity, ExtInstCLDebugInfo100RoundTripTest,
+    ::testing::ValuesIn(std::vector<InstructionCase>({
+        // ID Name
+        // Literal Tag
+        // ID Source
+        // ID Entity
+        // Literal Number Line
+        // Literal Number Column
+        // ID Parent
+        CASE_IEIILLI(ImportedEntity, ImportedModule, 67, 68),
+        CASE_IEIILLI(ImportedEntity, ImportedDeclaration, 42, 43),
+    })));
+
+#undef EPREFIX
+#undef CASE_0
+#undef CASE_ILL
+#undef CASE_IL
+#undef CASE_I
+#undef CASE_II
+#undef CASE_III
+#undef CASE_IIII
+#undef CASE_IIIII
+#undef CASE_IIIIII
+#undef CASE_IIIIIII
+#undef CASE_IIILLI
+#undef CASE_IIILLIL
+#undef CASE_IE
+#undef CASE_IEIILLI
+#undef CASE_IIE
+#undef CASE_ISF
+#undef CASE_LII
+#undef CASE_LLIe
+#undef CASE_ILI
+#undef CASE_ILII
+#undef CASE_ILLII
+#undef CASE_IIILLIF
+#undef CASE_IIILLIFL
+#undef CASE_IIILLIIF
+#undef CASE_IIILLIIFII
+#undef CASE_IIILLIIFIIII
+#undef CASE_IIILLIIFIIIIII
+#undef CASE_IEILLIIIF
+#undef CASE_IEILLIIIFI
+#undef CASE_IEILLIIIFII
+#undef CASE_IEILLIIIFIII
+#undef CASE_IEILLIIIFIIII
+#undef CASE_IIILLIIIF
+#undef CASE_IIILLIIIFI
+#undef CASE_IIIIF
+#undef CASE_IIILL
+#undef CASE_IIIILL
+#undef CASE_IILLI
+#undef CASE_IILLII
+#undef CASE_IILLIII
+#undef CASE_IILLIIII
+#undef CASE_IIILLIIFLI
+#undef CASE_IIILLIIFLII
+#undef CASE_E
+#undef CASE_EI
+#undef CASE_EII
+#undef CASE_EIII
+#undef CASE_EIIII
+#undef CASE_EIIIII
+#undef CASE_EL
+#undef CASE_ELL
+
+}  // namespace
+}  // namespace spvtools
diff --git a/utils/check_copyright.py b/utils/check_copyright.py
index cfeef80..969371d 100755
--- a/utils/check_copyright.py
+++ b/utils/check_copyright.py
@@ -34,7 +34,7 @@
            'Samsung Inc']
 CURRENT_YEAR='2019'
 
-YEARS = '(2014-2016|2015-2016|2016|2016-2017|2017|2018|2019)'
+YEARS = '(2014-2016|2015-2016|2016|2016-2017|2017|2017-2019|2018|2019)'
 COPYRIGHT_RE = re.compile(
         'Copyright \(c\) {} ({})'.format(YEARS, '|'.join(AUTHORS)))
 
diff --git a/utils/generate_grammar_tables.py b/utils/generate_grammar_tables.py
index f6c671e..06fcf94 100755
--- a/utils/generate_grammar_tables.py
+++ b/utils/generate_grammar_tables.py
@@ -360,14 +360,22 @@
     return '{}\n\n{}\n\n{}'.format(caps_arrays, exts_arrays, '\n'.join(insts))
 
 
-def generate_extended_instruction_table(inst_table, set_name):
+def generate_extended_instruction_table(json_grammar, set_name, operand_kind_prefix=""):
     """Returns the info table containing all SPIR-V extended instructions,
     sorted by opcode, and prefixed by capability arrays.
 
     Arguments:
       - inst_table: a list containing all SPIR-V instructions.
       - set_name: the name of the extended instruction set.
+      - operand_kind_prefix: the prefix, if any, to add to the front
+        of operand kind names.
     """
+    if operand_kind_prefix:
+        prefix_operand_kind_names(operand_kind_prefix, json_grammar)
+
+    inst_table = json_grammar["instructions"]
+    set_name = set_name.replace(".", "_")
+
     inst_table = sorted(inst_table, key=lambda k: k['opcode'])
     caps = [inst.get('capabilities', []) for inst in inst_table]
     caps_arrays = generate_capability_arrays(caps)
@@ -452,6 +460,7 @@
 
 def generate_enum_operand_kind(enum, synthetic_exts_list):
     """Returns the C definition for the given operand kind.
+    It's a static const named array of spv_operand_desc_t.
 
     Also appends to |synthetic_exts_list| a list of extension lists
     used.
@@ -681,6 +690,26 @@
     return operand_kinds
 
 
+def prefix_operand_kind_names(prefix, json_dict):
+    """Modifies json_dict, by prefixing all the operand kind names
+    with the given prefix.  Also modifies their uses in the instructions
+    to match.
+    """
+
+    old_to_new = {}
+    for operand_kind in json_dict["operand_kinds"]:
+        old_name = operand_kind["kind"]
+        new_name = prefix + old_name
+        operand_kind["kind"] = new_name
+        old_to_new[old_name] = new_name
+
+    for instruction in json_dict["instructions"]:
+        for operand in instruction.get("operands", []):
+            replacement = old_to_new.get(operand["kind"])
+            if replacement is not None:
+                operand["kind"] = replacement
+
+
 def main():
     import argparse
     parser = argparse.ArgumentParser(description='Generate SPIR-V info tables')
@@ -693,6 +722,10 @@
                         type=str, required=False, default=None,
                         help='input JSON grammar file for DebugInfo extended '
                         'instruction set')
+    parser.add_argument('--extinst-cldebuginfo100-grammar', metavar='<path>',
+                        type=str, required=False, default=None,
+                        help='input JSON grammar file for OpenCL.DebugInfo.100 '
+                        'extended instruction set')
     parser.add_argument('--extinst-glsl-grammar', metavar='<path>',
                         type=str, required=False, default=None,
                         help='input JSON grammar file for GLSL extended '
@@ -727,6 +760,9 @@
     parser.add_argument('--vendor-insts-output', metavar='<path>',
                         type=str, required=False, default=None,
                         help='output file for vendor extended instruction set')
+    parser.add_argument('--vendor-operand-kind-prefix', metavar='<string>',
+                        type=str, required=False, default=None,
+                        help='prefix for operand kinds (to disambiguate operand type enums)')
     args = parser.parse_args()
 
     if (args.core_insts_output is None) != \
@@ -734,9 +770,12 @@
         print('error: --core-insts-output and --operand-kinds-output '
               'should be specified together.')
         exit(1)
-    if args.operand_kinds_output and not (args.spirv_core_grammar and args.extinst_debuginfo_grammar):
+    if args.operand_kinds_output and not (args.spirv_core_grammar and
+         args.extinst_debuginfo_grammar and
+         args.extinst_cldebuginfo100_grammar):
         print('error: --operand-kinds-output requires --spirv-core-grammar '
-              'and --exinst-debuginfo-grammar')
+              'and --exinst-debuginfo-grammar '
+              'and --exinst-cldebuginfo100-grammar')
         exit(1)
     if (args.glsl_insts_output is None) != \
             (args.extinst_glsl_grammar is None):
@@ -767,14 +806,19 @@
             core_grammar = json.loads(json_file.read())
             with open(args.extinst_debuginfo_grammar) as debuginfo_json_file:
                 debuginfo_grammar = json.loads(debuginfo_json_file.read())
-                instructions = []
-                instructions.extend(core_grammar['instructions'])
-                instructions.extend(debuginfo_grammar['instructions'])
-                operand_kinds = []
-                operand_kinds.extend(core_grammar['operand_kinds'])
-                operand_kinds.extend(debuginfo_grammar['operand_kinds'])
-                extensions = get_extension_list(instructions, operand_kinds)
-                operand_kinds = precondition_operand_kinds(operand_kinds)
+                with open(args.extinst_cldebuginfo100_grammar) as cldebuginfo100_json_file:
+                    cldebuginfo100_grammar = json.loads(cldebuginfo100_json_file.read())
+                    prefix_operand_kind_names("CLDEBUG100_", cldebuginfo100_grammar)
+                    instructions = []
+                    instructions.extend(core_grammar['instructions'])
+                    instructions.extend(debuginfo_grammar['instructions'])
+                    instructions.extend(cldebuginfo100_grammar['instructions'])
+                    operand_kinds = []
+                    operand_kinds.extend(core_grammar['operand_kinds'])
+                    operand_kinds.extend(debuginfo_grammar['operand_kinds'])
+                    operand_kinds.extend(cldebuginfo100_grammar['operand_kinds'])
+                    extensions = get_extension_list(instructions, operand_kinds)
+                    operand_kinds = precondition_operand_kinds(operand_kinds)
         if args.core_insts_output is not None:
             make_path_to_file(args.core_insts_output)
             make_path_to_file(args.operand_kinds_output)
@@ -799,7 +843,7 @@
             make_path_to_file(args.glsl_insts_output)
             with open(args.glsl_insts_output, 'w') as f:
                 f.write(generate_extended_instruction_table(
-                    grammar['instructions'], 'glsl'))
+                    grammar, 'glsl'))
 
     if args.extinst_opencl_grammar is not None:
         with open(args.extinst_opencl_grammar) as json_file:
@@ -807,7 +851,7 @@
             make_path_to_file(args.opencl_insts_output)
             with open(args.opencl_insts_output, 'w') as f:
                 f.write(generate_extended_instruction_table(
-                    grammar['instructions'], 'opencl'))
+                    grammar, 'opencl'))
 
     if args.extinst_vendor_grammar is not None:
         with open(args.extinst_vendor_grammar) as json_file:
@@ -818,7 +862,7 @@
             name = name[start:-len('.grammar.json')].replace('-', '_')
             with open(args.vendor_insts_output, 'w') as f:
                 f.write(generate_extended_instruction_table(
-                    grammar['instructions'], name))
+                    grammar, name, args.vendor_operand_kind_prefix))
 
 
 if __name__ == '__main__':