Convert `@location` to store expression internally.

This CL updates the internal storage for a `@location` attribute
to store the `Expression` instead of a raw `uint32_t`. The current
parser is updated to generate an `IntLiteralExpression` so we still
parse as a `uint32_t` at the moment.

Bug: tint:1633
Change-Id: I2b9684754a657b39554160c81727cf1541bee96c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/101461
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index 8775168..82a047c 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -640,7 +640,17 @@
 
         std::optional<uint32_t> location;
         if (auto* attr = ast::GetAttribute<ast::LocationAttribute>(var->attributes)) {
-            location = attr->value;
+            auto* materialize = Materialize(Expression(attr->value));
+            if (!materialize) {
+                return nullptr;
+            }
+            auto* c = materialize->ConstantValue();
+            if (!c) {
+                // TODO(crbug.com/tint/1633): Add error message about invalid materialization
+                // when location can be an expression.
+                return nullptr;
+            }
+            location = c->As<uint32_t>();
         }
 
         sem = builder_->create<sem::GlobalVariable>(
@@ -725,7 +735,17 @@
 
     std::optional<uint32_t> location;
     if (auto* l = ast::GetAttribute<ast::LocationAttribute>(param->attributes)) {
-        location = l->value;
+        auto* materialize = Materialize(Expression(l->value));
+        if (!materialize) {
+            return nullptr;
+        }
+        auto* c = materialize->ConstantValue();
+        if (!c) {
+            // TODO(crbug.com/tint/1633): Add error message about invalid materialization when
+            // location can be an expression.
+            return nullptr;
+        }
+        location = c->As<uint32_t>();
     }
 
     auto* sem = builder_->create<sem::Parameter>(
@@ -924,7 +944,17 @@
         Mark(attr);
 
         if (auto* a = attr->As<ast::LocationAttribute>()) {
-            return_location = a->value;
+            auto* materialize = Materialize(Expression(a->value));
+            if (!materialize) {
+                return nullptr;
+            }
+            auto* c = materialize->ConstantValue();
+            if (!c) {
+                // TODO(crbug.com/tint/1633): Add error message about invalid materialization when
+                // location can be an expression.
+                return nullptr;
+            }
+            return_location = c->As<uint32_t>();
         }
     }
     if (!validator_.NoDuplicateAttributes(decl->attributes)) {
@@ -2808,7 +2838,17 @@
                 size = s->size;
                 has_size_attr = true;
             } else if (auto* l = attr->As<ast::LocationAttribute>()) {
-                location = l->value;
+                auto* materialize = Materialize(Expression(l->value));
+                if (!materialize) {
+                    return nullptr;
+                }
+                auto* c = materialize->ConstantValue();
+                if (!c) {
+                    // TODO(crbug.com/tint/1633): Add error message about invalid materialization
+                    // when location can be an expression.
+                    return nullptr;
+                }
+                location = c->As<uint32_t>();
             }
         }