reader/wgsl: Add support for [[override]]

The Resolver, Inspector, and backends already handle this form of the
attribute correctly, so this is straightforward.

Fixed: tint:755
Change-Id: I8c394f1e58d64827d8a53b81402e30a472ca5441
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/50844
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index 663cf47..ae8c14d 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -3101,13 +3101,20 @@
 
   if (s == kOverrideDecoration) {
     const char* use = "override decoration";
-    return expect_paren_block(use, [&]() -> Result {
-      auto val = expect_positive_sint(use);
-      if (val.errored)
-        return Failure::kErrored;
 
-      return create<ast::OverrideDecoration>(t.source(), val.value);
-    });
+    if (peek().IsParenLeft()) {
+      // [[override(x)]]
+      return expect_paren_block(use, [&]() -> Result {
+        auto val = expect_positive_sint(use);
+        if (val.errored)
+          return Failure::kErrored;
+
+        return create<ast::OverrideDecoration>(t.source(), val.value);
+      });
+    } else {
+      // [[override]]
+      return create<ast::OverrideDecoration>(t.source());
+    }
   }
 
   return Failure::kNoMatch;
diff --git a/src/reader/wgsl/parser_impl_global_constant_decl_test.cc b/src/reader/wgsl/parser_impl_global_constant_decl_test.cc
index 5f27155..f8fd1d5 100644
--- a/src/reader/wgsl/parser_impl_global_constant_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_global_constant_decl_test.cc
@@ -112,9 +112,42 @@
   ASSERT_NE(e->constructor(), nullptr);
   EXPECT_TRUE(e->constructor()->Is<ast::ConstructorExpression>());
 
-  EXPECT_TRUE(
-      ast::HasDecoration<ast::OverrideDecoration>(e.value->decorations()));
-  EXPECT_EQ(e.value->constant_id(), 7u);
+  auto* override_deco =
+      ast::GetDecoration<ast::OverrideDecoration>(e.value->decorations());
+  ASSERT_NE(override_deco, nullptr);
+  EXPECT_TRUE(override_deco->HasValue());
+  EXPECT_EQ(override_deco->value(), 7u);
+}
+
+TEST_F(ParserImplTest, GlobalConstantDec_Override_WithoutId) {
+  auto p = parser("[[override]] let a : f32 = 1.");
+  auto decos = p->decoration_list();
+  EXPECT_FALSE(decos.errored);
+  EXPECT_TRUE(decos.matched);
+
+  auto e = p->global_constant_decl(decos.value);
+  EXPECT_FALSE(p->has_error()) << p->error();
+  EXPECT_TRUE(e.matched);
+  EXPECT_FALSE(e.errored);
+  ASSERT_NE(e.value, nullptr);
+
+  EXPECT_TRUE(e->is_const());
+  EXPECT_EQ(e->symbol(), p->builder().Symbols().Get("a"));
+  ASSERT_NE(e->type(), nullptr);
+  EXPECT_TRUE(e->type()->Is<ast::F32>());
+
+  EXPECT_EQ(e->source().range.begin.line, 1u);
+  EXPECT_EQ(e->source().range.begin.column, 18u);
+  EXPECT_EQ(e->source().range.end.line, 1u);
+  EXPECT_EQ(e->source().range.end.column, 19u);
+
+  ASSERT_NE(e->constructor(), nullptr);
+  EXPECT_TRUE(e->constructor()->Is<ast::ConstructorExpression>());
+
+  auto* override_deco =
+      ast::GetDecoration<ast::OverrideDecoration>(e.value->decorations());
+  ASSERT_NE(override_deco, nullptr);
+  EXPECT_FALSE(override_deco->HasValue());
 }
 
 TEST_F(ParserImplTest, GlobalConstantDec_Override_MissingId) {