Replace FunctionDecoration::(Is|As)Workgroup with Castable

Change-Id: Ia365504fd745579b3bd7bef0b6eda73d3164f539
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/34312
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/function.cc b/src/ast/function.cc
index 5348b62..b636559 100644
--- a/src/ast/function.cc
+++ b/src/ast/function.cc
@@ -55,8 +55,8 @@
 
 std::tuple<uint32_t, uint32_t, uint32_t> Function::workgroup_size() const {
   for (auto* deco : decorations_) {
-    if (deco->IsWorkgroup()) {
-      return deco->AsWorkgroup()->values();
+    if (auto* workgroup = deco->As<WorkgroupDecoration>()) {
+      return workgroup->values();
     }
   }
   return {1, 1, 1};
diff --git a/src/ast/function_decoration.cc b/src/ast/function_decoration.cc
index 0b746be..25476a5 100644
--- a/src/ast/function_decoration.cc
+++ b/src/ast/function_decoration.cc
@@ -14,10 +14,6 @@
 
 #include "src/ast/function_decoration.h"
 
-#include <assert.h>
-
-#include "src/ast/workgroup_decoration.h"
-
 namespace tint {
 namespace ast {
 
@@ -31,14 +27,5 @@
   return Kind;
 }
 
-bool FunctionDecoration::IsWorkgroup() const {
-  return false;
-}
-
-const WorkgroupDecoration* FunctionDecoration::AsWorkgroup() const {
-  assert(IsWorkgroup());
-  return static_cast<const WorkgroupDecoration*>(this);
-}
-
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/function_decoration.h b/src/ast/function_decoration.h
index fe1a9dd..556a0d9 100644
--- a/src/ast/function_decoration.h
+++ b/src/ast/function_decoration.h
@@ -24,8 +24,6 @@
 namespace tint {
 namespace ast {
 
-class WorkgroupDecoration;
-
 /// A decoration attached to a function
 class FunctionDecoration : public Castable<FunctionDecoration, Decoration> {
  public:
@@ -37,12 +35,6 @@
   /// @return the decoration kind
   DecorationKind GetKind() const override;
 
-  /// @returns true if this is a workgroup decoration
-  virtual bool IsWorkgroup() const;
-
-  /// @returns the decoration as a workgroup decoration
-  const WorkgroupDecoration* AsWorkgroup() const;
-
  protected:
   /// Constructor
   /// @param source the source of this decoration
diff --git a/src/ast/stage_decoration_test.cc b/src/ast/stage_decoration_test.cc
index 5adb97e..83acb5b 100644
--- a/src/ast/stage_decoration_test.cc
+++ b/src/ast/stage_decoration_test.cc
@@ -17,6 +17,7 @@
 #include <sstream>
 
 #include "src/ast/test_helper.h"
+#include "src/ast/workgroup_decoration.h"
 
 namespace tint {
 namespace ast {
@@ -32,8 +33,8 @@
 TEST_F(StageDecorationTest, Is) {
   StageDecoration sd{ast::PipelineStage::kFragment, Source{}};
   Decoration* d = &sd;
-  EXPECT_FALSE(sd.IsWorkgroup());
-  EXPECT_TRUE(d->Is<ast::StageDecoration>());
+  EXPECT_FALSE(d->Is<WorkgroupDecoration>());
+  EXPECT_TRUE(d->Is<StageDecoration>());
 }
 
 TEST_F(StageDecorationTest, ToStr) {
diff --git a/src/ast/workgroup_decoration.cc b/src/ast/workgroup_decoration.cc
index 248718b..f32d09a 100644
--- a/src/ast/workgroup_decoration.cc
+++ b/src/ast/workgroup_decoration.cc
@@ -33,10 +33,6 @@
 
 WorkgroupDecoration::~WorkgroupDecoration() = default;
 
-bool WorkgroupDecoration::IsWorkgroup() const {
-  return true;
-}
-
 void WorkgroupDecoration::to_str(std::ostream& out, size_t indent) const {
   make_indent(out, indent);
   out << "WorkgroupDecoration{" << x_ << " " << y_ << " " << z_ << "}"
diff --git a/src/ast/workgroup_decoration.h b/src/ast/workgroup_decoration.h
index 47cc51a..2345b53 100644
--- a/src/ast/workgroup_decoration.h
+++ b/src/ast/workgroup_decoration.h
@@ -45,9 +45,6 @@
   WorkgroupDecoration(uint32_t x, uint32_t y, uint32_t z, const Source& source);
   ~WorkgroupDecoration() override;
 
-  /// @returns true if this is a workgroup decoration
-  bool IsWorkgroup() const override;
-
   /// @returns the workgroup dimensions
   std::tuple<uint32_t, uint32_t, uint32_t> values() const {
     return {x_, y_, z_};
diff --git a/src/ast/workgroup_decoration_test.cc b/src/ast/workgroup_decoration_test.cc
index 1d722f3..e285d35 100644
--- a/src/ast/workgroup_decoration_test.cc
+++ b/src/ast/workgroup_decoration_test.cc
@@ -60,7 +60,7 @@
 TEST_F(WorkgroupDecorationTest, Is) {
   WorkgroupDecoration wd{2, 4, 6, Source{}};
   Decoration* d = &wd;
-  EXPECT_TRUE(wd.IsWorkgroup());
+  EXPECT_TRUE(d->Is<WorkgroupDecoration>());
   EXPECT_FALSE(d->Is<StageDecoration>());
 }
 
diff --git a/src/reader/wgsl/parser_impl_function_decl_test.cc b/src/reader/wgsl/parser_impl_function_decl_test.cc
index d25e44d..ca155f2 100644
--- a/src/reader/wgsl/parser_impl_function_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_function_decl_test.cc
@@ -74,12 +74,12 @@
 
   auto& decorations = f->decorations();
   ASSERT_EQ(decorations.size(), 1u);
-  ASSERT_TRUE(decorations[0]->IsWorkgroup());
+  ASSERT_TRUE(decorations[0]->Is<ast::WorkgroupDecoration>());
 
   uint32_t x = 0;
   uint32_t y = 0;
   uint32_t z = 0;
-  std::tie(x, y, z) = decorations[0]->AsWorkgroup()->values();
+  std::tie(x, y, z) = decorations[0]->As<ast::WorkgroupDecoration>()->values();
   EXPECT_EQ(x, 2u);
   EXPECT_EQ(y, 3u);
   EXPECT_EQ(z, 4u);
@@ -116,14 +116,14 @@
   uint32_t x = 0;
   uint32_t y = 0;
   uint32_t z = 0;
-  ASSERT_TRUE(decorations[0]->IsWorkgroup());
-  std::tie(x, y, z) = decorations[0]->AsWorkgroup()->values();
+  ASSERT_TRUE(decorations[0]->Is<ast::WorkgroupDecoration>());
+  std::tie(x, y, z) = decorations[0]->As<ast::WorkgroupDecoration>()->values();
   EXPECT_EQ(x, 2u);
   EXPECT_EQ(y, 3u);
   EXPECT_EQ(z, 4u);
 
-  ASSERT_TRUE(decorations[1]->IsWorkgroup());
-  std::tie(x, y, z) = decorations[1]->AsWorkgroup()->values();
+  ASSERT_TRUE(decorations[1]->Is<ast::WorkgroupDecoration>());
+  std::tie(x, y, z) = decorations[1]->As<ast::WorkgroupDecoration>()->values();
   EXPECT_EQ(x, 5u);
   EXPECT_EQ(y, 6u);
   EXPECT_EQ(z, 7u);
@@ -161,14 +161,14 @@
   uint32_t x = 0;
   uint32_t y = 0;
   uint32_t z = 0;
-  ASSERT_TRUE(decos[0]->IsWorkgroup());
-  std::tie(x, y, z) = decos[0]->AsWorkgroup()->values();
+  ASSERT_TRUE(decos[0]->Is<ast::WorkgroupDecoration>());
+  std::tie(x, y, z) = decos[0]->As<ast::WorkgroupDecoration>()->values();
   EXPECT_EQ(x, 2u);
   EXPECT_EQ(y, 3u);
   EXPECT_EQ(z, 4u);
 
-  ASSERT_TRUE(decos[1]->IsWorkgroup());
-  std::tie(x, y, z) = decos[1]->AsWorkgroup()->values();
+  ASSERT_TRUE(decos[1]->Is<ast::WorkgroupDecoration>());
+  std::tie(x, y, z) = decos[1]->As<ast::WorkgroupDecoration>()->values();
   EXPECT_EQ(x, 5u);
   EXPECT_EQ(y, 6u);
   EXPECT_EQ(z, 7u);
diff --git a/src/reader/wgsl/parser_impl_function_decoration_list_test.cc b/src/reader/wgsl/parser_impl_function_decoration_list_test.cc
index c77e783..9fd25c5 100644
--- a/src/reader/wgsl/parser_impl_function_decoration_list_test.cc
+++ b/src/reader/wgsl/parser_impl_function_decoration_list_test.cc
@@ -38,12 +38,12 @@
   uint32_t x = 0;
   uint32_t y = 0;
   uint32_t z = 0;
-  ASSERT_TRUE(deco_0->IsWorkgroup());
-  std::tie(x, y, z) = deco_0->AsWorkgroup()->values();
+  ASSERT_TRUE(deco_0->Is<ast::WorkgroupDecoration>());
+  std::tie(x, y, z) = deco_0->As<ast::WorkgroupDecoration>()->values();
   EXPECT_EQ(x, 2u);
 
-  ASSERT_TRUE(deco_1->IsWorkgroup());
-  std::tie(x, y, z) = deco_1->AsWorkgroup()->values();
+  ASSERT_TRUE(deco_1->Is<ast::WorkgroupDecoration>());
+  std::tie(x, y, z) = deco_1->As<ast::WorkgroupDecoration>()->values();
   EXPECT_EQ(x, 3u);
   EXPECT_EQ(y, 4u);
   EXPECT_EQ(z, 5u);
diff --git a/src/reader/wgsl/parser_impl_function_decoration_test.cc b/src/reader/wgsl/parser_impl_function_decoration_test.cc
index 0e39a34..13b9d45 100644
--- a/src/reader/wgsl/parser_impl_function_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_function_decoration_test.cc
@@ -32,12 +32,12 @@
   ASSERT_FALSE(p->has_error());
   auto* func_deco = deco.value->As<ast::FunctionDecoration>();
   ASSERT_NE(func_deco, nullptr);
-  ASSERT_TRUE(func_deco->IsWorkgroup());
+  ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
 
   uint32_t x = 0;
   uint32_t y = 0;
   uint32_t z = 0;
-  std::tie(x, y, z) = func_deco->AsWorkgroup()->values();
+  std::tie(x, y, z) = func_deco->As<ast::WorkgroupDecoration>()->values();
   EXPECT_EQ(x, 4u);
   EXPECT_EQ(y, 1u);
   EXPECT_EQ(z, 1u);
@@ -52,12 +52,12 @@
   ASSERT_FALSE(p->has_error());
   auto* func_deco = deco.value->As<ast::FunctionDecoration>();
   ASSERT_NE(func_deco, nullptr) << p->error();
-  ASSERT_TRUE(func_deco->IsWorkgroup());
+  ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
 
   uint32_t x = 0;
   uint32_t y = 0;
   uint32_t z = 0;
-  std::tie(x, y, z) = func_deco->AsWorkgroup()->values();
+  std::tie(x, y, z) = func_deco->As<ast::WorkgroupDecoration>()->values();
   EXPECT_EQ(x, 4u);
   EXPECT_EQ(y, 5u);
   EXPECT_EQ(z, 1u);
@@ -72,12 +72,12 @@
   ASSERT_FALSE(p->has_error());
   auto* func_deco = deco.value->As<ast::FunctionDecoration>();
   ASSERT_NE(func_deco, nullptr);
-  ASSERT_TRUE(func_deco->IsWorkgroup());
+  ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
 
   uint32_t x = 0;
   uint32_t y = 0;
   uint32_t z = 0;
-  std::tie(x, y, z) = func_deco->AsWorkgroup()->values();
+  std::tie(x, y, z) = func_deco->As<ast::WorkgroupDecoration>()->values();
   EXPECT_EQ(x, 4u);
   EXPECT_EQ(y, 5u);
   EXPECT_EQ(z, 6u);
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index ad77a7c..a417837 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -346,11 +346,11 @@
   for (auto* deco : func->decorations()) {
     make_indent();
     out_ << "[[";
-    if (deco->IsWorkgroup()) {
+    if (auto* workgroup = deco->As<ast::WorkgroupDecoration>()) {
       uint32_t x = 0;
       uint32_t y = 0;
       uint32_t z = 0;
-      std::tie(x, y, z) = deco->AsWorkgroup()->values();
+      std::tie(x, y, z) = workgroup->values();
       out_ << "workgroup_size(" << std::to_string(x) << ", "
            << std::to_string(y) << ", " << std::to_string(z) << ")";
     }