Support reflecting if pipeline overrideable constants has numeric ID specified

Bug: tint:1155
Change-Id: I362adf36a84ed470fa1bf7ab2c9a1fbe0a54da5a
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/67602
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Shrek Shao <shrekshao@google.com>
diff --git a/src/inspector/entry_point.h b/src/inspector/entry_point.h
index cf386a1..12cb4da 100644
--- a/src/inspector/entry_point.h
+++ b/src/inspector/entry_point.h
@@ -93,6 +93,9 @@
   /// Name of the constant
   std::string name;
 
+  /// ID of the constant
+  uint16_t numeric_id;
+
   /// Type of the scalar
   enum class Type {
     kBool,
@@ -106,6 +109,10 @@
 
   /// Does this pipeline overridable constant have an initializer?
   bool is_initialized = false;
+
+  /// Does this pipeline overridable constant have a numeric ID specified
+  /// explicitly?
+  bool is_numeric_id_specified = false;
 };
 
 /// Reflection data for an entry point in the shader.
diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc
index ca2a968..19cf595 100644
--- a/src/inspector/inspector.cc
+++ b/src/inspector/inspector.cc
@@ -197,6 +197,7 @@
       if (global && global->IsPipelineConstant()) {
         OverridableConstant overridable_constant;
         overridable_constant.name = name;
+        overridable_constant.numeric_id = global->ConstantId();
         auto* type = var->Type();
         TINT_ASSERT(Inspector, type->is_scalar());
         if (type->is_bool_scalar_or_vector()) {
@@ -213,6 +214,10 @@
 
         overridable_constant.is_initialized =
             global->Declaration()->constructor;
+        auto* override_deco = ast::GetDecoration<ast::OverrideDecoration>(
+            global->Declaration()->decorations);
+        overridable_constant.is_numeric_id_specified =
+            override_deco ? override_deco->has_value : false;
 
         entry_point.overridable_constants.push_back(overridable_constant);
       }
diff --git a/src/inspector/inspector_test.cc b/src/inspector/inspector_test.cc
index 2c84340..e2c0eae 100644
--- a/src/inspector/inspector_test.cc
+++ b/src/inspector/inspector_test.cc
@@ -612,6 +612,7 @@
   ASSERT_EQ(1u, result.size());
   ASSERT_EQ(1u, result[0].overridable_constants.size());
   EXPECT_EQ("foo", result[0].overridable_constants[0].name);
+  EXPECT_EQ(1, result[0].overridable_constants[0].numeric_id);
 }
 
 TEST_F(InspectorGetEntryPointTest, OverridableConstantTypes) {
@@ -682,6 +683,31 @@
   EXPECT_FALSE(result[0].overridable_constants[0].is_initialized);
 }
 
+TEST_F(InspectorGetEntryPointTest, OverridableConstantNumericIDSpecified) {
+  AddOverridableConstantWithoutID("foo_no_id", ty.f32(), nullptr);
+  AddOverridableConstantWithID("foo_id", 1234, ty.f32(), nullptr);
+
+  MakePlainGlobalReferenceBodyFunction("no_id_func", "foo_no_id", ty.f32(), {});
+  MakePlainGlobalReferenceBodyFunction("id_func", "foo_id", ty.f32(), {});
+
+  MakeCallerBodyFunction(
+      "ep_func", {"no_id_func", "id_func"},
+      {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+
+  Inspector& inspector = Build();
+
+  auto result = inspector.GetEntryPoints();
+
+  ASSERT_EQ(1u, result.size());
+  ASSERT_EQ(2u, result[0].overridable_constants.size());
+  EXPECT_EQ("foo_no_id", result[0].overridable_constants[0].name);
+  EXPECT_EQ("foo_id", result[0].overridable_constants[1].name);
+  EXPECT_EQ(1234, result[0].overridable_constants[1].numeric_id);
+
+  EXPECT_FALSE(result[0].overridable_constants[0].is_numeric_id_specified);
+  EXPECT_TRUE(result[0].overridable_constants[1].is_numeric_id_specified);
+}
+
 TEST_F(InspectorGetEntryPointTest, NonOverridableConstantSkipped) {
   auto* foo_struct_type = MakeUniformBufferType("foo_type", {ty.i32()});
   AddUniformBuffer("foo_ub", ty.Of(foo_struct_type), 0, 0);