[ast] Add constant id helper.

This CL adds constant id helper methods to the decorated variable class.

Bug: tint:150
Change-Id: Icfdc516f37d4f2680d2b990879bff722085cf732
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/29082
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/decorated_variable.cc b/src/ast/decorated_variable.cc
index 8588b99..d9e5130 100644
--- a/src/ast/decorated_variable.cc
+++ b/src/ast/decorated_variable.cc
@@ -14,6 +14,10 @@
 
 #include "src/ast/decorated_variable.h"
 
+#include <cassert>
+
+#include "src/ast/constant_id_decoration.h"
+
 namespace tint {
 namespace ast {
 
@@ -44,6 +48,25 @@
   return false;
 }
 
+bool DecoratedVariable::HasConstantIdDecoration() const {
+  for (const auto& deco : decorations_) {
+    if (deco->IsConstantId()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+uint32_t DecoratedVariable::constant_id() const {
+  assert(HasConstantIdDecoration());
+  for (const auto& deco : decorations_) {
+    if (deco->IsConstantId()) {
+      return deco->AsConstantId()->value();
+    }
+  }
+  return 0;
+}
+
 bool DecoratedVariable::IsDecorated() const {
   return true;
 }
diff --git a/src/ast/decorated_variable.h b/src/ast/decorated_variable.h
index 489dcbc..54f8b07 100644
--- a/src/ast/decorated_variable.h
+++ b/src/ast/decorated_variable.h
@@ -49,6 +49,12 @@
   bool HasLocationDecoration() const;
   /// @returns true if the deocrations include a BuiltinDecoration
   bool HasBuiltinDecoration() const;
+  /// @returns true if the decorations include a ConstantIdDecoration
+  bool HasConstantIdDecoration() const;
+
+  /// @returns the constant_id value for the variable. Assumes that
+  /// |HasConstantIdDecoration| has been called first.
+  uint32_t constant_id() const;
 
   /// @returns true if this is a decorated variable
   bool IsDecorated() const override;
diff --git a/src/ast/decorated_variable_test.cc b/src/ast/decorated_variable_test.cc
index 01d39f0..6b035ad 100644
--- a/src/ast/decorated_variable_test.cc
+++ b/src/ast/decorated_variable_test.cc
@@ -16,7 +16,10 @@
 
 #include "gtest/gtest.h"
 #include "src/ast/binding_decoration.h"
+#include "src/ast/builtin_decoration.h"
+#include "src/ast/constant_id_decoration.h"
 #include "src/ast/identifier_expression.h"
+#include "src/ast/location_decoration.h"
 #include "src/ast/set_decoration.h"
 #include "src/ast/type/f32_type.h"
 #include "src/ast/type/i32_type.h"
@@ -54,6 +57,44 @@
   EXPECT_EQ(dv.column(), 4u);
 }
 
+TEST_F(DecoratedVariableTest, NoDecorations) {
+  type::I32Type t;
+  auto var = std::make_unique<Variable>("my_var", StorageClass::kFunction, &t);
+  DecoratedVariable dv(std::move(var));
+  EXPECT_FALSE(dv.HasLocationDecoration());
+  EXPECT_FALSE(dv.HasBuiltinDecoration());
+  EXPECT_FALSE(dv.HasConstantIdDecoration());
+}
+
+TEST_F(DecoratedVariableTest, WithDecorations) {
+  type::F32Type t;
+  auto var = std::make_unique<Variable>("my_var", StorageClass::kFunction, &t);
+  DecoratedVariable dv(std::move(var));
+
+  VariableDecorationList decos;
+  decos.push_back(std::make_unique<LocationDecoration>(1));
+  decos.push_back(std::make_unique<BuiltinDecoration>(ast::Builtin::kPosition));
+  decos.push_back(std::make_unique<ConstantIdDecoration>(1200));
+
+  dv.set_decorations(std::move(decos));
+
+  EXPECT_TRUE(dv.HasLocationDecoration());
+  EXPECT_TRUE(dv.HasBuiltinDecoration());
+  EXPECT_TRUE(dv.HasConstantIdDecoration());
+}
+
+TEST_F(DecoratedVariableTest, ConstantId) {
+  type::F32Type t;
+  auto var = std::make_unique<Variable>("my_var", StorageClass::kFunction, &t);
+  DecoratedVariable dv(std::move(var));
+
+  VariableDecorationList decos;
+  decos.push_back(std::make_unique<ConstantIdDecoration>(1200));
+  dv.set_decorations(std::move(decos));
+
+  EXPECT_EQ(dv.constant_id(), 1200u);
+}
+
 TEST_F(DecoratedVariableTest, IsValid) {
   type::I32Type t;
   auto var = std::make_unique<Variable>("my_var", StorageClass::kNone, &t);