[glsl] Emit boolean types

Add emitting of the boolean type and constants.

Bug: 42251044
Change-Id: I8ec901c8a3b8ad33bb3215326ddb35608398e113
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/200241
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/glsl/writer/constant_test.cc b/src/tint/lang/glsl/writer/constant_test.cc
index f5e4367..9686bf1 100644
--- a/src/tint/lang/glsl/writer/constant_test.cc
+++ b/src/tint/lang/glsl/writer/constant_test.cc
@@ -33,8 +33,34 @@
 namespace tint::glsl::writer {
 namespace {
 
-TEST_F(GlslWriterTest, DISABLED_Constant_Bool_True) {
-    FAIL();
+TEST_F(GlslWriterTest, ConstantBoolFalse) {
+    auto* f = b.Function("a", ty.bool_());
+    f->Block()->Append(b.Return(f, false));
+
+    ASSERT_TRUE(Generate()) << err_ << output_.glsl;
+    EXPECT_EQ(output_.glsl, GlslHeader() + R"(
+bool a() {
+  return false;
+}
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+}
+)");
+}
+
+TEST_F(GlslWriterTest, ConstantBoolTrue) {
+    auto* f = b.Function("a", ty.bool_());
+    f->Block()->Append(b.Return(f, true));
+
+    ASSERT_TRUE(Generate()) << err_ << output_.glsl;
+    EXPECT_EQ(output_.glsl, GlslHeader() + R"(
+bool a() {
+  return true;
+}
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+}
+)");
 }
 
 }  // namespace
diff --git a/src/tint/lang/glsl/writer/printer/printer.cc b/src/tint/lang/glsl/writer/printer/printer.cc
index d8f4c25b..3d65b00 100644
--- a/src/tint/lang/glsl/writer/printer/printer.cc
+++ b/src/tint/lang/glsl/writer/printer/printer.cc
@@ -35,6 +35,8 @@
 #include "src/tint/lang/core/ir/return.h"
 #include "src/tint/lang/core/ir/unreachable.h"
 #include "src/tint/lang/core/ir/validator.h"
+#include "src/tint/lang/core/type/bool.h"
+#include "src/tint/lang/core/type/void.h"
 #include "src/tint/lang/glsl/writer/common/version.h"
 #include "src/tint/utils/generator/text_generator.h"
 #include "src/tint/utils/macros/scoped_assignment.h"
@@ -141,7 +143,7 @@
         TINT_SCOPED_ASSIGNMENT(current_block_, block);
 
         for (auto* inst : *block) {
-            Switch(
+            tint::Switch(
                 inst,                                                      //
                 [&](const core::ir::Return* r) { EmitReturn(r); },         //
                 [&](const core::ir::Unreachable*) { EmitUnreachable(); },  //
@@ -152,7 +154,15 @@
     /// Emit a type
     /// @param out the stream to emit too
     /// @param ty the type to emit
-    void EmitType(StringStream& out, [[maybe_unused]] const core::type::Type* ty) { out << "void"; }
+    void EmitType(StringStream& out, const core::type::Type* ty) {
+        tint::Switch(
+            ty,                                               //
+            [&](const core::type::Bool*) { out << "bool"; },  //
+            [&](const core::type::Void*) { out << "void"; },  //
+
+            // TODO(dsinclair): Handle remaining types
+            TINT_ICE_ON_NO_MATCH);
+    }
 
     /// Emit a return instruction
     /// @param r the return instruction
@@ -165,13 +175,35 @@
 
         auto out = Line();
         out << "return";
-        // TODO(dsinclair): Handle return args
-        // if (!r->Args().IsEmpty()) {
-        //     out << " " << Expr(r->Args().Front());
-        // }
+        if (!r->Args().IsEmpty()) {
+            out << " ";
+            EmitValue(out, r->Args().Front());
+        }
         out << ";";
     }
 
+    void EmitValue(StringStream& out, const core::ir::Value* v) {
+        tint::Switch(
+            v,                                                           //
+            [&](const core::ir::Constant* c) { EmitConstant(out, c); },  //
+
+            // TODO(dsinclair): Handle remaining value types
+            TINT_ICE_ON_NO_MATCH);
+    }
+
+    void EmitConstant(StringStream& out, const core::ir::Constant* c) {
+        EmitConstant(out, c->Value());
+    }
+
+    void EmitConstant(StringStream& out, const core::constant::Value* c) {
+        tint::Switch(
+            c->Type(),  //
+            [&](const core::type::Bool*) { out << (c->ValueAs<AInt>() ? "true" : "false"); },
+
+            // TODO(dsinclair): Emit remaining constant types
+            TINT_ICE_ON_NO_MATCH);
+    }
+
     /// Emit an unreachable instruction
     void EmitUnreachable() { Line() << "/* unreachable */"; }
 };