ast: Add 'Expression' suffix to literals (2/2)

Literals are now expressions, so in keeping with all the other
expression types, suffix the class name with Expression.

I'm not overly keen on requiring everything to have an Expression
suffix, but consistency is better than personal preference.

Note: this should have been part of 30848b6, but I managed to drop
this change instead of squashing it. Opps.

Bug: tint:888
Change-Id: Idfaf96abe165a6bf5028e60a160e7408aa2bf9db
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/68943
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/ast/array.cc b/src/ast/array.cc
index 779a950..e8339f8 100644
--- a/src/ast/array.cc
+++ b/src/ast/array.cc
@@ -30,7 +30,7 @@
   if (auto* ident = size->As<IdentifierExpression>()) {
     return symbols.NameFor(ident->symbol);
   }
-  if (auto* literal = size->As<IntLiteral>()) {
+  if (auto* literal = size->As<IntLiteralExpression>()) {
     return std::to_string(literal->ValueAsU32());
   }
   // This will never be exposed to the user as the Resolver will reject this
diff --git a/src/ast/bool_literal_expression.cc b/src/ast/bool_literal_expression.cc
index c61afd8..8bb4e2b 100644
--- a/src/ast/bool_literal_expression.cc
+++ b/src/ast/bool_literal_expression.cc
@@ -16,20 +16,23 @@
 
 #include "src/program_builder.h"
 
-TINT_INSTANTIATE_TYPEINFO(tint::ast::BoolLiteral);
+TINT_INSTANTIATE_TYPEINFO(tint::ast::BoolLiteralExpression);
 
 namespace tint {
 namespace ast {
 
-BoolLiteral::BoolLiteral(ProgramID pid, const Source& src, bool val)
+BoolLiteralExpression::BoolLiteralExpression(ProgramID pid,
+                                             const Source& src,
+                                             bool val)
     : Base(pid, src), value(val) {}
 
-BoolLiteral::~BoolLiteral() = default;
+BoolLiteralExpression::~BoolLiteralExpression() = default;
 
-const BoolLiteral* BoolLiteral::Clone(CloneContext* ctx) const {
+const BoolLiteralExpression* BoolLiteralExpression::Clone(
+    CloneContext* ctx) const {
   // Clone arguments outside of create() call to have deterministic ordering
   auto src = ctx->Clone(source);
-  return ctx->dst->create<BoolLiteral>(src, value);
+  return ctx->dst->create<BoolLiteralExpression>(src, value);
 }
 
 }  // namespace ast
diff --git a/src/ast/bool_literal_expression.h b/src/ast/bool_literal_expression.h
index 9a571d2..a41d3cb 100644
--- a/src/ast/bool_literal_expression.h
+++ b/src/ast/bool_literal_expression.h
@@ -23,20 +23,21 @@
 namespace ast {
 
 /// A boolean literal
-class BoolLiteral : public Castable<BoolLiteral, Literal> {
+class BoolLiteralExpression
+    : public Castable<BoolLiteralExpression, LiteralExpression> {
  public:
   /// Constructor
   /// @param pid the identifier of the program that owns this node
   /// @param src the source of this node
   /// @param value the bool literals value
-  BoolLiteral(ProgramID pid, const Source& src, bool value);
-  ~BoolLiteral() override;
+  BoolLiteralExpression(ProgramID pid, const Source& src, bool value);
+  ~BoolLiteralExpression() override;
 
   /// Clones this node and all transitive child nodes using the `CloneContext`
   /// `ctx`.
   /// @param ctx the clone context
   /// @return the newly cloned node
-  const BoolLiteral* Clone(CloneContext* ctx) const override;
+  const BoolLiteralExpression* Clone(CloneContext* ctx) const override;
 
   /// The boolean literal value
   const bool value;
diff --git a/src/ast/bool_literal_expression_test.cc b/src/ast/bool_literal_expression_test.cc
index 67d306e..d8093db 100644
--- a/src/ast/bool_literal_expression_test.cc
+++ b/src/ast/bool_literal_expression_test.cc
@@ -18,17 +18,17 @@
 namespace ast {
 namespace {
 
-using BoolLiteralTest = TestHelper;
+using BoolLiteralExpressionTest = TestHelper;
 
-TEST_F(BoolLiteralTest, True) {
-  auto* b = create<BoolLiteral>(true);
-  ASSERT_TRUE(b->Is<BoolLiteral>());
+TEST_F(BoolLiteralExpressionTest, True) {
+  auto* b = create<BoolLiteralExpression>(true);
+  ASSERT_TRUE(b->Is<BoolLiteralExpression>());
   ASSERT_TRUE(b->value);
 }
 
-TEST_F(BoolLiteralTest, False) {
-  auto* b = create<BoolLiteral>(false);
-  ASSERT_TRUE(b->Is<BoolLiteral>());
+TEST_F(BoolLiteralExpressionTest, False) {
+  auto* b = create<BoolLiteralExpression>(false);
+  ASSERT_TRUE(b->Is<BoolLiteralExpression>());
   ASSERT_FALSE(b->value);
 }
 
diff --git a/src/ast/case_statement.h b/src/ast/case_statement.h
index 71c80db..c1e5688 100644
--- a/src/ast/case_statement.h
+++ b/src/ast/case_statement.h
@@ -24,7 +24,7 @@
 namespace ast {
 
 /// A list of case literals
-using CaseSelectorList = std::vector<const IntLiteral*>;
+using CaseSelectorList = std::vector<const IntLiteralExpression*>;
 
 /// A case statement
 class CaseStatement : public Castable<CaseStatement, Statement> {
diff --git a/src/ast/case_statement_test.cc b/src/ast/case_statement_test.cc
index 7fc92ec..a46161b 100644
--- a/src/ast/case_statement_test.cc
+++ b/src/ast/case_statement_test.cc
@@ -27,7 +27,7 @@
 
 TEST_F(CaseStatementTest, Creation_i32) {
   CaseSelectorList b;
-  auto* selector = create<SintLiteral>(2);
+  auto* selector = create<SintLiteralExpression>(2);
   b.push_back(selector);
 
   auto* discard = create<DiscardStatement>();
@@ -42,7 +42,7 @@
 
 TEST_F(CaseStatementTest, Creation_u32) {
   CaseSelectorList b;
-  auto* selector = create<UintLiteral>(2u);
+  auto* selector = create<UintLiteralExpression>(2u);
   b.push_back(selector);
 
   auto* discard = create<DiscardStatement>();
@@ -57,7 +57,7 @@
 
 TEST_F(CaseStatementTest, Creation_WithSource) {
   CaseSelectorList b;
-  b.push_back(create<SintLiteral>(2));
+  b.push_back(create<SintLiteralExpression>(2));
 
   auto* body = create<BlockStatement>(StatementList{
       create<DiscardStatement>(),
@@ -78,7 +78,7 @@
 
 TEST_F(CaseStatementTest, IsDefault_WithSelectors) {
   CaseSelectorList b;
-  b.push_back(create<SintLiteral>(2));
+  b.push_back(create<SintLiteralExpression>(2));
 
   auto* c = create<CaseStatement>(b, create<BlockStatement>(StatementList{}));
   EXPECT_FALSE(c->IsDefault());
@@ -125,8 +125,9 @@
       {
         ProgramBuilder b1;
         ProgramBuilder b2;
-        b1.create<CaseStatement>(CaseSelectorList{b2.create<SintLiteral>(2)},
-                                 b1.create<BlockStatement>(StatementList{}));
+        b1.create<CaseStatement>(
+            CaseSelectorList{b2.create<SintLiteralExpression>(2)},
+            b1.create<BlockStatement>(StatementList{}));
       },
       "internal compiler error");
 }
diff --git a/src/ast/float_literal_expression.cc b/src/ast/float_literal_expression.cc
index a76cc8d..4a1f45b 100644
--- a/src/ast/float_literal_expression.cc
+++ b/src/ast/float_literal_expression.cc
@@ -18,20 +18,23 @@
 
 #include "src/program_builder.h"
 
-TINT_INSTANTIATE_TYPEINFO(tint::ast::FloatLiteral);
+TINT_INSTANTIATE_TYPEINFO(tint::ast::FloatLiteralExpression);
 
 namespace tint {
 namespace ast {
 
-FloatLiteral::FloatLiteral(ProgramID pid, const Source& src, float val)
+FloatLiteralExpression::FloatLiteralExpression(ProgramID pid,
+                                               const Source& src,
+                                               float val)
     : Base(pid, src), value(val) {}
 
-FloatLiteral::~FloatLiteral() = default;
+FloatLiteralExpression::~FloatLiteralExpression() = default;
 
-const FloatLiteral* FloatLiteral::Clone(CloneContext* ctx) const {
+const FloatLiteralExpression* FloatLiteralExpression::Clone(
+    CloneContext* ctx) const {
   // Clone arguments outside of create() call to have deterministic ordering
   auto src = ctx->Clone(source);
-  return ctx->dst->create<FloatLiteral>(src, value);
+  return ctx->dst->create<FloatLiteralExpression>(src, value);
 }
 
 }  // namespace ast
diff --git a/src/ast/float_literal_expression.h b/src/ast/float_literal_expression.h
index 0e1b243..1765d53 100644
--- a/src/ast/float_literal_expression.h
+++ b/src/ast/float_literal_expression.h
@@ -23,20 +23,21 @@
 namespace ast {
 
 /// A float literal
-class FloatLiteral : public Castable<FloatLiteral, Literal> {
+class FloatLiteralExpression
+    : public Castable<FloatLiteralExpression, LiteralExpression> {
  public:
   /// Constructor
   /// @param pid the identifier of the program that owns this node
   /// @param src the source of this node
   /// @param value the float literals value
-  FloatLiteral(ProgramID pid, const Source& src, float value);
-  ~FloatLiteral() override;
+  FloatLiteralExpression(ProgramID pid, const Source& src, float value);
+  ~FloatLiteralExpression() override;
 
   /// Clones this node and all transitive child nodes using the `CloneContext`
   /// `ctx`.
   /// @param ctx the clone context
   /// @return the newly cloned node
-  const FloatLiteral* Clone(CloneContext* ctx) const override;
+  const FloatLiteralExpression* Clone(CloneContext* ctx) const override;
 
   /// The float literal value
   const float value;
diff --git a/src/ast/float_literal_expression_test.cc b/src/ast/float_literal_expression_test.cc
index a89f2ee..cd1e445 100644
--- a/src/ast/float_literal_expression_test.cc
+++ b/src/ast/float_literal_expression_test.cc
@@ -18,11 +18,11 @@
 namespace ast {
 namespace {
 
-using FloatLiteralTest = TestHelper;
+using FloatLiteralExpressionTest = TestHelper;
 
-TEST_F(FloatLiteralTest, Value) {
-  auto* f = create<FloatLiteral>(47.2f);
-  ASSERT_TRUE(f->Is<FloatLiteral>());
+TEST_F(FloatLiteralExpressionTest, Value) {
+  auto* f = create<FloatLiteralExpression>(47.2f);
+  ASSERT_TRUE(f->Is<FloatLiteralExpression>());
   EXPECT_EQ(f->value, 47.2f);
 }
 
diff --git a/src/ast/int_literal_expression.cc b/src/ast/int_literal_expression.cc
index c620d29..b610de9 100644
--- a/src/ast/int_literal_expression.cc
+++ b/src/ast/int_literal_expression.cc
@@ -14,14 +14,15 @@
 
 #include "src/ast/int_literal_expression.h"
 
-TINT_INSTANTIATE_TYPEINFO(tint::ast::IntLiteral);
+TINT_INSTANTIATE_TYPEINFO(tint::ast::IntLiteralExpression);
 
 namespace tint {
 namespace ast {
 
-IntLiteral::IntLiteral(ProgramID pid, const Source& src) : Base(pid, src) {}
+IntLiteralExpression::IntLiteralExpression(ProgramID pid, const Source& src)
+    : Base(pid, src) {}
 
-IntLiteral::~IntLiteral() = default;
+IntLiteralExpression::~IntLiteralExpression() = default;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/int_literal_expression.h b/src/ast/int_literal_expression.h
index aa79aaf..88aa1de 100644
--- a/src/ast/int_literal_expression.h
+++ b/src/ast/int_literal_expression.h
@@ -21,9 +21,10 @@
 namespace ast {
 
 /// An integer literal. This could be either signed or unsigned.
-class IntLiteral : public Castable<IntLiteral, Literal> {
+class IntLiteralExpression
+    : public Castable<IntLiteralExpression, LiteralExpression> {
  public:
-  ~IntLiteral() override;
+  ~IntLiteralExpression() override;
 
   /// @returns the literal value as a u32
   virtual uint32_t ValueAsU32() const = 0;
@@ -35,7 +36,7 @@
   /// Constructor
   /// @param pid the identifier of the program that owns this node
   /// @param src the source of this node
-  IntLiteral(ProgramID pid, const Source& src);
+  IntLiteralExpression(ProgramID pid, const Source& src);
 };  // namespace ast
 
 }  // namespace ast
diff --git a/src/ast/int_literal_expression_test.cc b/src/ast/int_literal_expression_test.cc
index 8f95e0f..d6d9f1c 100644
--- a/src/ast/int_literal_expression_test.cc
+++ b/src/ast/int_literal_expression_test.cc
@@ -18,16 +18,16 @@
 namespace ast {
 namespace {
 
-using IntLiteralTest = TestHelper;
+using IntLiteralExpressionTest = TestHelper;
 
-TEST_F(IntLiteralTest, Sint_IsInt) {
-  auto* i = create<SintLiteral>(47);
-  ASSERT_TRUE(i->Is<IntLiteral>());
+TEST_F(IntLiteralExpressionTest, Sint_IsInt) {
+  auto* i = create<SintLiteralExpression>(47);
+  ASSERT_TRUE(i->Is<IntLiteralExpression>());
 }
 
-TEST_F(IntLiteralTest, Uint_IsInt) {
-  auto* i = create<UintLiteral>(42);
-  EXPECT_TRUE(i->Is<IntLiteral>());
+TEST_F(IntLiteralExpressionTest, Uint_IsInt) {
+  auto* i = create<UintLiteralExpression>(42);
+  EXPECT_TRUE(i->Is<IntLiteralExpression>());
 }
 
 }  // namespace
diff --git a/src/ast/literal_expression.cc b/src/ast/literal_expression.cc
index 523cd51..e9ab969 100644
--- a/src/ast/literal_expression.cc
+++ b/src/ast/literal_expression.cc
@@ -14,14 +14,15 @@
 
 #include "src/ast/literal_expression.h"
 
-TINT_INSTANTIATE_TYPEINFO(tint::ast::Literal);
+TINT_INSTANTIATE_TYPEINFO(tint::ast::LiteralExpression);
 
 namespace tint {
 namespace ast {
 
-Literal::Literal(ProgramID pid, const Source& src) : Base(pid, src) {}
+LiteralExpression::LiteralExpression(ProgramID pid, const Source& src)
+    : Base(pid, src) {}
 
-Literal::~Literal() = default;
+LiteralExpression::~LiteralExpression() = default;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/literal_expression.h b/src/ast/literal_expression.h
index c76deb6..40114e1 100644
--- a/src/ast/literal_expression.h
+++ b/src/ast/literal_expression.h
@@ -23,15 +23,15 @@
 namespace ast {
 
 /// Base class for a literal value expressions
-class Literal : public Castable<Literal, Expression> {
+class LiteralExpression : public Castable<LiteralExpression, Expression> {
  public:
-  ~Literal() override;
+  ~LiteralExpression() override;
 
  protected:
   /// Constructor
   /// @param pid the identifier of the program that owns this node
   /// @param src the input source
-  Literal(ProgramID pid, const Source& src);
+  LiteralExpression(ProgramID pid, const Source& src);
 };
 
 }  // namespace ast
diff --git a/src/ast/sint_literal_expression.cc b/src/ast/sint_literal_expression.cc
index 78da9fc..7288250 100644
--- a/src/ast/sint_literal_expression.cc
+++ b/src/ast/sint_literal_expression.cc
@@ -16,24 +16,27 @@
 
 #include "src/program_builder.h"
 
-TINT_INSTANTIATE_TYPEINFO(tint::ast::SintLiteral);
+TINT_INSTANTIATE_TYPEINFO(tint::ast::SintLiteralExpression);
 
 namespace tint {
 namespace ast {
 
-SintLiteral::SintLiteral(ProgramID pid, const Source& src, int32_t val)
+SintLiteralExpression::SintLiteralExpression(ProgramID pid,
+                                             const Source& src,
+                                             int32_t val)
     : Base(pid, src), value(val) {}
 
-SintLiteral::~SintLiteral() = default;
+SintLiteralExpression::~SintLiteralExpression() = default;
 
-uint32_t SintLiteral::ValueAsU32() const {
+uint32_t SintLiteralExpression::ValueAsU32() const {
   return static_cast<uint32_t>(value);
 }
 
-const SintLiteral* SintLiteral::Clone(CloneContext* ctx) const {
+const SintLiteralExpression* SintLiteralExpression::Clone(
+    CloneContext* ctx) const {
   // Clone arguments outside of create() call to have deterministic ordering
   auto src = ctx->Clone(source);
-  return ctx->dst->create<SintLiteral>(src, value);
+  return ctx->dst->create<SintLiteralExpression>(src, value);
 }
 
 }  // namespace ast
diff --git a/src/ast/sint_literal_expression.h b/src/ast/sint_literal_expression.h
index 584f360..dac1b3f 100644
--- a/src/ast/sint_literal_expression.h
+++ b/src/ast/sint_literal_expression.h
@@ -23,14 +23,15 @@
 namespace ast {
 
 /// A signed int literal
-class SintLiteral : public Castable<SintLiteral, IntLiteral> {
+class SintLiteralExpression
+    : public Castable<SintLiteralExpression, IntLiteralExpression> {
  public:
   /// Constructor
   /// @param pid the identifier of the program that owns this node
   /// @param src the source of this node
   /// @param value the signed int literals value
-  SintLiteral(ProgramID pid, const Source& src, int32_t value);
-  ~SintLiteral() override;
+  SintLiteralExpression(ProgramID pid, const Source& src, int32_t value);
+  ~SintLiteralExpression() override;
 
   /// @returns the literal value as a u32
   uint32_t ValueAsU32() const override;
@@ -39,7 +40,7 @@
   /// `ctx`.
   /// @param ctx the clone context
   /// @return the newly cloned node
-  const SintLiteral* Clone(CloneContext* ctx) const override;
+  const SintLiteralExpression* Clone(CloneContext* ctx) const override;
 
   /// The int literal value
   const int32_t value;
diff --git a/src/ast/sint_literal_expression_test.cc b/src/ast/sint_literal_expression_test.cc
index 7503e62..5f3652e 100644
--- a/src/ast/sint_literal_expression_test.cc
+++ b/src/ast/sint_literal_expression_test.cc
@@ -18,11 +18,11 @@
 namespace ast {
 namespace {
 
-using SintLiteralTest = TestHelper;
+using SintLiteralExpressionTest = TestHelper;
 
-TEST_F(SintLiteralTest, Value) {
-  auto* i = create<SintLiteral>(47);
-  ASSERT_TRUE(i->Is<SintLiteral>());
+TEST_F(SintLiteralExpressionTest, Value) {
+  auto* i = create<SintLiteralExpression>(47);
+  ASSERT_TRUE(i->Is<SintLiteralExpression>());
   EXPECT_EQ(i->value, 47);
 }
 
diff --git a/src/ast/switch_statement_test.cc b/src/ast/switch_statement_test.cc
index 355f70f..ed2f840 100644
--- a/src/ast/switch_statement_test.cc
+++ b/src/ast/switch_statement_test.cc
@@ -25,7 +25,7 @@
 
 TEST_F(SwitchStatementTest, Creation) {
   CaseSelectorList lit;
-  lit.push_back(create<SintLiteral>(1));
+  lit.push_back(create<SintLiteralExpression>(1));
 
   auto* ident = Expr("ident");
   CaseStatementList body;
@@ -50,7 +50,7 @@
 
 TEST_F(SwitchStatementTest, IsSwitch) {
   CaseSelectorList lit;
-  lit.push_back(create<SintLiteral>(2));
+  lit.push_back(create<SintLiteralExpression>(2));
 
   auto* ident = Expr("ident");
   CaseStatementList body;
diff --git a/src/ast/traverse_expressions.h b/src/ast/traverse_expressions.h
index ebcd684..0281906 100644
--- a/src/ast/traverse_expressions.h
+++ b/src/ast/traverse_expressions.h
@@ -122,7 +122,7 @@
       to_visit.push_back(member->structure);
     } else if (auto* unary = expr->As<UnaryOpExpression>()) {
       to_visit.push_back(unary->expr);
-    } else if (expr->IsAnyOf<Literal, IdentifierExpression,
+    } else if (expr->IsAnyOf<LiteralExpression, IdentifierExpression,
                              PhonyExpression>()) {
       // Leaf expression
     } else {
diff --git a/src/ast/uint_literal_expression.cc b/src/ast/uint_literal_expression.cc
index 9efc365..0fc837c 100644
--- a/src/ast/uint_literal_expression.cc
+++ b/src/ast/uint_literal_expression.cc
@@ -16,24 +16,27 @@
 
 #include "src/program_builder.h"
 
-TINT_INSTANTIATE_TYPEINFO(tint::ast::UintLiteral);
+TINT_INSTANTIATE_TYPEINFO(tint::ast::UintLiteralExpression);
 
 namespace tint {
 namespace ast {
 
-UintLiteral::UintLiteral(ProgramID pid, const Source& src, uint32_t val)
+UintLiteralExpression::UintLiteralExpression(ProgramID pid,
+                                             const Source& src,
+                                             uint32_t val)
     : Base(pid, src), value(val) {}
 
-UintLiteral::~UintLiteral() = default;
+UintLiteralExpression::~UintLiteralExpression() = default;
 
-uint32_t UintLiteral::ValueAsU32() const {
+uint32_t UintLiteralExpression::ValueAsU32() const {
   return value;
 }
 
-const UintLiteral* UintLiteral::Clone(CloneContext* ctx) const {
+const UintLiteralExpression* UintLiteralExpression::Clone(
+    CloneContext* ctx) const {
   // Clone arguments outside of create() call to have deterministic ordering
   auto src = ctx->Clone(source);
-  return ctx->dst->create<UintLiteral>(src, value);
+  return ctx->dst->create<UintLiteralExpression>(src, value);
 }
 
 }  // namespace ast
diff --git a/src/ast/uint_literal_expression.h b/src/ast/uint_literal_expression.h
index 9a89046..61ed4f0 100644
--- a/src/ast/uint_literal_expression.h
+++ b/src/ast/uint_literal_expression.h
@@ -23,14 +23,15 @@
 namespace ast {
 
 /// A uint literal
-class UintLiteral : public Castable<UintLiteral, IntLiteral> {
+class UintLiteralExpression
+    : public Castable<UintLiteralExpression, IntLiteralExpression> {
  public:
   /// Constructor
   /// @param pid the identifier of the program that owns this node
   /// @param src the source of this node
   /// @param value the uint literals value
-  UintLiteral(ProgramID pid, const Source& src, uint32_t value);
-  ~UintLiteral() override;
+  UintLiteralExpression(ProgramID pid, const Source& src, uint32_t value);
+  ~UintLiteralExpression() override;
 
   /// @returns the literal value as a u32
   uint32_t ValueAsU32() const override;
@@ -39,7 +40,7 @@
   /// `ctx`.
   /// @param ctx the clone context
   /// @return the newly cloned node
-  const UintLiteral* Clone(CloneContext* ctx) const override;
+  const UintLiteralExpression* Clone(CloneContext* ctx) const override;
 
   /// The int literal value
   const uint32_t value;
diff --git a/src/ast/uint_literal_expression_test.cc b/src/ast/uint_literal_expression_test.cc
index a65750a..15d6243 100644
--- a/src/ast/uint_literal_expression_test.cc
+++ b/src/ast/uint_literal_expression_test.cc
@@ -18,11 +18,11 @@
 namespace ast {
 namespace {
 
-using UintLiteralTest = TestHelper;
+using UintLiteralExpressionTest = TestHelper;
 
-TEST_F(UintLiteralTest, Value) {
-  auto* u = create<UintLiteral>(47);
-  ASSERT_TRUE(u->Is<UintLiteral>());
+TEST_F(UintLiteralExpressionTest, Value) {
+  auto* u = create<UintLiteralExpression>(47);
+  ASSERT_TRUE(u->Is<UintLiteralExpression>());
   EXPECT_EQ(u->value, 47u);
 }
 
diff --git a/src/ast/workgroup_decoration_test.cc b/src/ast/workgroup_decoration_test.cc
index 68b5b22..c8b3bf3 100644
--- a/src/ast/workgroup_decoration_test.cc
+++ b/src/ast/workgroup_decoration_test.cc
@@ -27,8 +27,8 @@
   auto* d = WorkgroupSize(2);
   auto values = d->Values();
 
-  ASSERT_TRUE(values[0]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[0]->As<ast::IntLiteral>()->ValueAsU32(), 2u);
+  ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
 
   EXPECT_EQ(values[1], nullptr);
   EXPECT_EQ(values[2], nullptr);
@@ -37,11 +37,11 @@
   auto* d = WorkgroupSize(2, 4);
   auto values = d->Values();
 
-  ASSERT_TRUE(values[0]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[0]->As<ast::IntLiteral>()->ValueAsU32(), 2u);
+  ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
 
-  ASSERT_TRUE(values[1]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[1]->As<ast::IntLiteral>()->ValueAsU32(), 4u);
+  ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
 
   EXPECT_EQ(values[2], nullptr);
 }
@@ -50,25 +50,25 @@
   auto* d = WorkgroupSize(2, 4, 6);
   auto values = d->Values();
 
-  ASSERT_TRUE(values[0]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[0]->As<ast::IntLiteral>()->ValueAsU32(), 2u);
+  ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
 
-  ASSERT_TRUE(values[1]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[1]->As<ast::IntLiteral>()->ValueAsU32(), 4u);
+  ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
 
-  ASSERT_TRUE(values[2]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[2]->As<ast::IntLiteral>()->ValueAsU32(), 6u);
+  ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
 }
 
 TEST_F(WorkgroupDecorationTest, Creation_WithIdentifier) {
   auto* d = WorkgroupSize(2, 4, "depth");
   auto values = d->Values();
 
-  ASSERT_TRUE(values[0]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[0]->As<ast::IntLiteral>()->ValueAsU32(), 2u);
+  ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
 
-  ASSERT_TRUE(values[1]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[1]->As<ast::IntLiteral>()->ValueAsU32(), 4u);
+  ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
 
   auto* z_ident = As<ast::IdentifierExpression>(values[2]);
   ASSERT_TRUE(z_ident);
diff --git a/src/clone_context.h b/src/clone_context.h
index 9d765a0..e399deb 100644
--- a/src/clone_context.h
+++ b/src/clone_context.h
@@ -251,10 +251,10 @@
   /// Example:
   ///
   /// ```
-  ///   // Replace all ast::UintLiterals with the number 42
+  ///   // Replace all ast::UintLiteralExpressions with the number 42
   ///   CloneCtx ctx(&out, in);
-  ///   ctx.ReplaceAll([&] (ast::UintLiteral* l) {
-  ///       return ctx->dst->create<ast::UintLiteral>(
+  ///   ctx.ReplaceAll([&] (ast::UintLiteralExpression* l) {
+  ///       return ctx->dst->create<ast::UintLiteralExpression>(
   ///           ctx->Clone(l->source),
   ///           ctx->Clone(l->type),
   ///           42);
diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc
index baf9b45..171dbc8 100644
--- a/src/inspector/inspector.cc
+++ b/src/inspector/inspector.cc
@@ -263,29 +263,29 @@
       continue;
     }
 
-    auto* literal = var->constructor->As<ast::Literal>();
+    auto* literal = var->constructor->As<ast::LiteralExpression>();
     if (!literal) {
       // This is invalid WGSL, but handling gracefully.
       result[constant_id] = Scalar();
       continue;
     }
 
-    if (auto* l = literal->As<ast::BoolLiteral>()) {
+    if (auto* l = literal->As<ast::BoolLiteralExpression>()) {
       result[constant_id] = Scalar(l->value);
       continue;
     }
 
-    if (auto* l = literal->As<ast::UintLiteral>()) {
+    if (auto* l = literal->As<ast::UintLiteralExpression>()) {
       result[constant_id] = Scalar(l->value);
       continue;
     }
 
-    if (auto* l = literal->As<ast::SintLiteral>()) {
+    if (auto* l = literal->As<ast::SintLiteralExpression>()) {
       result[constant_id] = Scalar(l->value);
       continue;
     }
 
-    if (auto* l = literal->As<ast::FloatLiteral>()) {
+    if (auto* l = literal->As<ast::FloatLiteralExpression>()) {
       result[constant_id] = Scalar(l->value);
       continue;
     }
diff --git a/src/program_builder.h b/src/program_builder.h
index 2b3406d..fd8b194 100644
--- a/src/program_builder.h
+++ b/src/program_builder.h
@@ -1037,53 +1037,53 @@
   /// @param source the source information
   /// @param value the boolean value
   /// @return a Scalar constructor for the given value
-  const ast::Literal* Expr(const Source& source, bool value) {
-    return create<ast::BoolLiteral>(source, value);
+  const ast::LiteralExpression* Expr(const Source& source, bool value) {
+    return create<ast::BoolLiteralExpression>(source, value);
   }
 
   /// @param value the boolean value
   /// @return a Scalar constructor for the given value
-  const ast::BoolLiteral* Expr(bool value) {
-    return create<ast::BoolLiteral>(value);
+  const ast::BoolLiteralExpression* Expr(bool value) {
+    return create<ast::BoolLiteralExpression>(value);
   }
 
   /// @param source the source information
   /// @param value the float value
   /// @return a Scalar constructor for the given value
-  const ast::FloatLiteral* Expr(const Source& source, f32 value) {
-    return create<ast::FloatLiteral>(source, value);
+  const ast::FloatLiteralExpression* Expr(const Source& source, f32 value) {
+    return create<ast::FloatLiteralExpression>(source, value);
   }
 
   /// @param value the float value
   /// @return a Scalar constructor for the given value
-  const ast::FloatLiteral* Expr(f32 value) {
-    return create<ast::FloatLiteral>(value);
+  const ast::FloatLiteralExpression* Expr(f32 value) {
+    return create<ast::FloatLiteralExpression>(value);
   }
 
   /// @param source the source information
   /// @param value the integer value
   /// @return a Scalar constructor for the given value
-  const ast::Literal* Expr(const Source& source, i32 value) {
-    return create<ast::SintLiteral>(source, value);
+  const ast::LiteralExpression* Expr(const Source& source, i32 value) {
+    return create<ast::SintLiteralExpression>(source, value);
   }
 
   /// @param value the integer value
   /// @return a Scalar constructor for the given value
-  const ast::SintLiteral* Expr(i32 value) {
-    return create<ast::SintLiteral>(value);
+  const ast::SintLiteralExpression* Expr(i32 value) {
+    return create<ast::SintLiteralExpression>(value);
   }
 
   /// @param source the source information
   /// @param value the unsigned int value
   /// @return a Scalar constructor for the given value
-  const ast::UintLiteral* Expr(const Source& source, u32 value) {
-    return create<ast::UintLiteral>(source, value);
+  const ast::UintLiteralExpression* Expr(const Source& source, u32 value) {
+    return create<ast::UintLiteralExpression>(source, value);
   }
 
   /// @param value the unsigned int value
   /// @return a Scalar constructor for the given value
-  const ast::UintLiteral* Expr(u32 value) {
-    return create<ast::UintLiteral>(value);
+  const ast::UintLiteralExpression* Expr(u32 value) {
+    return create<ast::UintLiteralExpression>(value);
   }
 
   /// Converts `arg` to an `ast::Expression` using `Expr()`, then appends it to
@@ -1127,53 +1127,53 @@
   /// @param source the source location for the literal
   /// @param val the boolan value
   /// @return a boolean literal with the given value
-  const ast::BoolLiteral* Literal(const Source& source, bool val) {
-    return create<ast::BoolLiteral>(source, val);
+  const ast::BoolLiteralExpression* Literal(const Source& source, bool val) {
+    return create<ast::BoolLiteralExpression>(source, val);
   }
 
   /// @param val the boolan value
   /// @return a boolean literal with the given value
-  const ast::BoolLiteral* Literal(bool val) {
-    return create<ast::BoolLiteral>(val);
+  const ast::BoolLiteralExpression* Literal(bool val) {
+    return create<ast::BoolLiteralExpression>(val);
   }
 
   /// @param source the source location for the literal
   /// @param val the float value
   /// @return a float literal with the given value
-  const ast::FloatLiteral* Literal(const Source& source, f32 val) {
-    return create<ast::FloatLiteral>(source, val);
+  const ast::FloatLiteralExpression* Literal(const Source& source, f32 val) {
+    return create<ast::FloatLiteralExpression>(source, val);
   }
 
   /// @param val the float value
   /// @return a float literal with the given value
-  const ast::FloatLiteral* Literal(f32 val) {
-    return create<ast::FloatLiteral>(val);
+  const ast::FloatLiteralExpression* Literal(f32 val) {
+    return create<ast::FloatLiteralExpression>(val);
   }
 
   /// @param source the source location for the literal
   /// @param val the unsigned int value
   /// @return a ast::UintLiteral with the given value
-  const ast::UintLiteral* Literal(const Source& source, u32 val) {
-    return create<ast::UintLiteral>(source, val);
+  const ast::UintLiteralExpression* Literal(const Source& source, u32 val) {
+    return create<ast::UintLiteralExpression>(source, val);
   }
 
   /// @param val the unsigned int value
   /// @return a ast::UintLiteral with the given value
-  const ast::UintLiteral* Literal(u32 val) {
-    return create<ast::UintLiteral>(val);
+  const ast::UintLiteralExpression* Literal(u32 val) {
+    return create<ast::UintLiteralExpression>(val);
   }
 
   /// @param source the source location for the literal
   /// @param val the integer value
   /// @return the ast::SintLiteral with the given value
-  const ast::SintLiteral* Literal(const Source& source, i32 val) {
-    return create<ast::SintLiteral>(source, val);
+  const ast::SintLiteralExpression* Literal(const Source& source, i32 val) {
+    return create<ast::SintLiteralExpression>(source, val);
   }
 
   /// @param val the integer value
   /// @return the ast::SintLiteral with the given value
-  const ast::SintLiteral* Literal(i32 val) {
-    return create<ast::SintLiteral>(val);
+  const ast::SintLiteralExpression* Literal(i32 val) {
+    return create<ast::SintLiteralExpression>(val);
   }
 
   /// @param args the arguments for the type constructor
@@ -2237,7 +2237,7 @@
   /// @param selector a single case selector
   /// @param body the case body
   /// @returns the case statement pointer
-  const ast::CaseStatement* Case(const ast::IntLiteral* selector,
+  const ast::CaseStatement* Case(const ast::IntLiteralExpression* selector,
                                  const ast::BlockStatement* body = nullptr) {
     return Case(ast::CaseSelectorList{selector}, body);
   }
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 8c31667..08db5f4 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -2548,7 +2548,7 @@
       return source_expr;
     }
     case SkipReason::kPointSizeBuiltinValue: {
-      return {ty_.F32(), create<ast::FloatLiteral>(Source{}, 1.0f)};
+      return {ty_.F32(), create<ast::FloatLiteralExpression>(Source{}, 1.0f)};
     }
     case SkipReason::kPointSizeBuiltinPointer:
       Fail() << "unhandled use of a pointer to the PointSize builtin, with ID: "
@@ -3063,9 +3063,11 @@
         // The Tint AST handles 32-bit values.
         const uint32_t value32 = uint32_t(value & 0xFFFFFFFF);
         if (selector.type->IsUnsignedScalarOrVector()) {
-          selectors.emplace_back(create<ast::UintLiteral>(Source{}, value32));
+          selectors.emplace_back(
+              create<ast::UintLiteralExpression>(Source{}, value32));
         } else {
-          selectors.emplace_back(create<ast::SintLiteral>(Source{}, value32));
+          selectors.emplace_back(
+              create<ast::SintLiteralExpression>(Source{}, value32));
         }
       }
     }
@@ -4475,7 +4477,7 @@
   auto current_type_id = composite_type_id;
 
   auto make_index = [this](uint32_t literal) {
-    return create<ast::UintLiteral>(Source{}, literal);
+    return create<ast::UintLiteralExpression>(Source{}, literal);
   };
 
   // Build up a nested expression for the decomposition by walking down the type
@@ -4591,11 +4593,11 @@
 }
 
 const ast::Expression* FunctionEmitter::MakeTrue(const Source& source) const {
-  return create<ast::BoolLiteral>(source, true);
+  return create<ast::BoolLiteralExpression>(source, true);
 }
 
 const ast::Expression* FunctionEmitter::MakeFalse(const Source& source) const {
-  return create<ast::BoolLiteral>(source, false);
+  return create<ast::BoolLiteralExpression>(source, false);
 }
 
 TypedExpression FunctionEmitter::MakeVectorShuffle(
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index 15fed61..252a2ff 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -603,7 +603,7 @@
   if (where == inst_source_.end()) {
     return {};
   }
-  return Source{where->second };
+  return Source{where->second};
 }
 
 bool ParserImpl::ParseInternalModuleExceptFunctions() {
@@ -1353,13 +1353,13 @@
   for (auto& inst : module_->types_values()) {
     // These will be populated for a valid scalar spec constant.
     const Type* ast_type = nullptr;
-    ast::Literal* ast_expr = nullptr;
+    ast::LiteralExpression* ast_expr = nullptr;
 
     switch (inst.opcode()) {
       case SpvOpSpecConstantTrue:
       case SpvOpSpecConstantFalse: {
         ast_type = ConvertType(inst.type_id());
-        ast_expr = create<ast::BoolLiteral>(
+        ast_expr = create<ast::BoolLiteralExpression>(
             Source{}, inst.opcode() == SpvOpSpecConstantTrue);
         break;
       }
@@ -1367,16 +1367,16 @@
         ast_type = ConvertType(inst.type_id());
         const uint32_t literal_value = inst.GetSingleWordInOperand(0);
         if (ast_type->Is<I32>()) {
-          ast_expr = create<ast::SintLiteral>(
+          ast_expr = create<ast::SintLiteralExpression>(
               Source{}, static_cast<int32_t>(literal_value));
         } else if (ast_type->Is<U32>()) {
-          ast_expr = create<ast::UintLiteral>(
+          ast_expr = create<ast::UintLiteralExpression>(
               Source{}, static_cast<uint32_t>(literal_value));
         } else if (ast_type->Is<F32>()) {
           float float_value;
           // Copy the bits so we can read them as a float.
           std::memcpy(&float_value, &literal_value, sizeof(float_value));
-          ast_expr = create<ast::FloatLiteral>(Source{}, float_value);
+          ast_expr = create<ast::FloatLiteralExpression>(Source{}, float_value);
         } else {
           return Fail() << " invalid result type for OpSpecConstant "
                         << inst.PrettyPrint();
@@ -1955,20 +1955,22 @@
   // Currently "null<type>" is missing from the WGSL parser.
   // See https://bugs.chromium.org/p/tint/issues/detail?id=34
   if (ast_type->Is<U32>()) {
-    return {ty_.U32(), create<ast::UintLiteral>(source, spirv_const->GetU32())};
+    return {ty_.U32(),
+            create<ast::UintLiteralExpression>(source, spirv_const->GetU32())};
   }
   if (ast_type->Is<I32>()) {
-    return {ty_.I32(), create<ast::SintLiteral>(source, spirv_const->GetS32())};
+    return {ty_.I32(),
+            create<ast::SintLiteralExpression>(source, spirv_const->GetS32())};
   }
   if (ast_type->Is<F32>()) {
-    return {ty_.F32(),
-            create<ast::FloatLiteral>(source, spirv_const->GetFloat())};
+    return {ty_.F32(), create<ast::FloatLiteralExpression>(
+                           source, spirv_const->GetFloat())};
   }
   if (ast_type->Is<Bool>()) {
     const bool value = spirv_const->AsNullConstant()
                            ? false
                            : spirv_const->AsBoolConstant()->value();
-    return {ty_.Bool(), create<ast::BoolLiteral>(source, value)};
+    return {ty_.Bool(), create<ast::BoolLiteralExpression>(source, value)};
   }
   Fail() << "expected scalar constant";
   return {};
@@ -1989,16 +1991,16 @@
   type = type->UnwrapAlias();
 
   if (type->Is<Bool>()) {
-    return create<ast::BoolLiteral>(Source{}, false);
+    return create<ast::BoolLiteralExpression>(Source{}, false);
   }
   if (type->Is<U32>()) {
-    return create<ast::UintLiteral>(Source{}, 0u);
+    return create<ast::UintLiteralExpression>(Source{}, 0u);
   }
   if (type->Is<I32>()) {
-    return create<ast::SintLiteral>(Source{}, 0);
+    return create<ast::SintLiteralExpression>(Source{}, 0);
   }
   if (type->Is<F32>()) {
-    return create<ast::FloatLiteral>(Source{}, 0.0f);
+    return create<ast::FloatLiteralExpression>(Source{}, 0.0f);
   }
   if (type->Is<Alias>()) {
     // TODO(amaiorano): No type constructor for TypeName (yet?)
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index 1ae05ed..77df7ed 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -1947,12 +1947,12 @@
       return Failure::kErrored;
     } else if (!cond.matched) {
       break;
-    } else if (!cond->Is<ast::IntLiteral>()) {
+    } else if (!cond->Is<ast::IntLiteralExpression>()) {
       return add_error(cond.value->source,
                        "invalid case selector must be an integer value");
     }
 
-    selectors.push_back(cond.value->As<ast::IntLiteral>());
+    selectors.push_back(cond.value->As<ast::IntLiteralExpression>());
 
     if (!match(Token::Type::kComma)) {
       break;
@@ -2841,22 +2841,22 @@
 //   | FLOAT_LITERAL
 //   | TRUE
 //   | FALSE
-Maybe<const ast::Literal*> ParserImpl::const_literal() {
+Maybe<const ast::LiteralExpression*> ParserImpl::const_literal() {
   auto t = peek();
   if (t.IsError()) {
     return add_error(t.source(), t.to_str());
   }
   if (match(Token::Type::kTrue)) {
-    return create<ast::BoolLiteral>(t.source(), true);
+    return create<ast::BoolLiteralExpression>(t.source(), true);
   }
   if (match(Token::Type::kFalse)) {
-    return create<ast::BoolLiteral>(t.source(), false);
+    return create<ast::BoolLiteralExpression>(t.source(), false);
   }
   if (match(Token::Type::kSintLiteral)) {
-    return create<ast::SintLiteral>(t.source(), t.to_i32());
+    return create<ast::SintLiteralExpression>(t.source(), t.to_i32());
   }
   if (match(Token::Type::kUintLiteral)) {
-    return create<ast::UintLiteral>(t.source(), t.to_u32());
+    return create<ast::UintLiteralExpression>(t.source(), t.to_u32());
   }
   if (match(Token::Type::kFloatLiteral)) {
     auto p = peek();
@@ -2865,7 +2865,7 @@
       return add_error(p.source(),
                        "float literals must not be suffixed with 'f'");
     }
-    return create<ast::FloatLiteral>(t.source(), t.to_f32());
+    return create<ast::FloatLiteralExpression>(t.source(), t.to_f32());
   }
   return Failure::kNoMatch;
 }
diff --git a/src/reader/wgsl/parser_impl.h b/src/reader/wgsl/parser_impl.h
index 2da91e2..26601c4 100644
--- a/src/reader/wgsl/parser_impl.h
+++ b/src/reader/wgsl/parser_impl.h
@@ -568,7 +568,7 @@
   Maybe<const ast::BlockStatement*> continuing_stmt();
   /// Parses a `const_literal` grammar element
   /// @returns the const literal parsed or nullptr if none found
-  Maybe<const ast::Literal*> const_literal();
+  Maybe<const ast::LiteralExpression*> const_literal();
   /// Parses a `const_expr` grammar element, erroring on parse failure.
   /// @returns the parsed constructor expression or nullptr on error
   Expect<const ast::Expression*> expect_const_expr();
diff --git a/src/reader/wgsl/parser_impl_additive_expression_test.cc b/src/reader/wgsl/parser_impl_additive_expression_test.cc
index fb66a73..e4eae74 100644
--- a/src/reader/wgsl/parser_impl_additive_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_additive_expression_test.cc
@@ -35,8 +35,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, AdditiveExpression_Parses_Minus) {
@@ -55,8 +55,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, AdditiveExpression_InvalidLHS) {
diff --git a/src/reader/wgsl/parser_impl_and_expression_test.cc b/src/reader/wgsl/parser_impl_and_expression_test.cc
index 73aa8de..823b5d8 100644
--- a/src/reader/wgsl/parser_impl_and_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_and_expression_test.cc
@@ -35,8 +35,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Register("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, AndExpression_InvalidLHS) {
diff --git a/src/reader/wgsl/parser_impl_argument_expression_list_test.cc b/src/reader/wgsl/parser_impl_argument_expression_list_test.cc
index 575ca43..b16d67b 100644
--- a/src/reader/wgsl/parser_impl_argument_expression_list_test.cc
+++ b/src/reader/wgsl/parser_impl_argument_expression_list_test.cc
@@ -46,7 +46,7 @@
 
   ASSERT_EQ(e.value.size(), 3u);
   ASSERT_TRUE(e.value[0]->Is<ast::IdentifierExpression>());
-  ASSERT_TRUE(e.value[1]->Is<ast::Literal>());
+  ASSERT_TRUE(e.value[1]->Is<ast::LiteralExpression>());
   ASSERT_TRUE(e.value[2]->Is<ast::BinaryExpression>());
 }
 
@@ -58,7 +58,7 @@
 
   ASSERT_EQ(e.value.size(), 2u);
   ASSERT_TRUE(e.value[0]->Is<ast::IdentifierExpression>());
-  ASSERT_TRUE(e.value[1]->Is<ast::Literal>());
+  ASSERT_TRUE(e.value[1]->Is<ast::LiteralExpression>());
 }
 
 TEST_F(ParserImplTest, ArgumentExpressionList_HandlesMissingLeftParen) {
diff --git a/src/reader/wgsl/parser_impl_assignment_stmt_test.cc b/src/reader/wgsl/parser_impl_assignment_stmt_test.cc
index 99ffcb3..8f8f165 100644
--- a/src/reader/wgsl/parser_impl_assignment_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_assignment_stmt_test.cc
@@ -36,8 +36,8 @@
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
   ASSERT_NE(e->rhs, nullptr);
-  ASSERT_TRUE(e->rhs->Is<ast::SintLiteral>());
-  EXPECT_EQ(e->rhs->As<ast::SintLiteral>()->value, 123);
+  ASSERT_TRUE(e->rhs->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(e->rhs->As<ast::SintLiteralExpression>()->value, 123);
 }
 
 TEST_F(ParserImplTest, AssignmentStmt_Parses_ToMember) {
@@ -53,8 +53,8 @@
   ASSERT_NE(e->rhs, nullptr);
 
   ASSERT_NE(e->rhs, nullptr);
-  ASSERT_TRUE(e->rhs->Is<ast::SintLiteral>());
-  EXPECT_EQ(e->rhs->As<ast::SintLiteral>()->value, 123);
+  ASSERT_TRUE(e->rhs->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(e->rhs->As<ast::SintLiteralExpression>()->value, 123);
 
   ASSERT_TRUE(e->lhs->Is<ast::MemberAccessorExpression>());
   auto* mem = e->lhs->As<ast::MemberAccessorExpression>();
@@ -67,8 +67,8 @@
   auto* idx = mem->structure->As<ast::IndexAccessorExpression>();
 
   ASSERT_NE(idx->index, nullptr);
-  ASSERT_TRUE(idx->index->Is<ast::SintLiteral>());
-  EXPECT_EQ(idx->index->As<ast::SintLiteral>()->value, 2);
+  ASSERT_TRUE(idx->index->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(idx->index->As<ast::SintLiteralExpression>()->value, 2);
 
   ASSERT_TRUE(idx->object->Is<ast::MemberAccessorExpression>());
   mem = idx->object->As<ast::MemberAccessorExpression>();
@@ -101,8 +101,8 @@
   ASSERT_NE(e->rhs, nullptr);
 
   ASSERT_NE(e->rhs, nullptr);
-  ASSERT_TRUE(e->rhs->Is<ast::SintLiteral>());
-  EXPECT_EQ(e->rhs->As<ast::SintLiteral>()->value, 123);
+  ASSERT_TRUE(e->rhs->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(e->rhs->As<ast::SintLiteralExpression>()->value, 123);
 
   ASSERT_TRUE(e->lhs->Is<ast::PhonyExpression>());
 }
diff --git a/src/reader/wgsl/parser_impl_call_stmt_test.cc b/src/reader/wgsl/parser_impl_call_stmt_test.cc
index edd8142..ed49d4b 100644
--- a/src/reader/wgsl/parser_impl_call_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_call_stmt_test.cc
@@ -55,7 +55,7 @@
   EXPECT_EQ(c->func->symbol, p->builder().Symbols().Get("a"));
 
   EXPECT_EQ(c->args.size(), 3u);
-  EXPECT_TRUE(c->args[0]->Is<ast::IntLiteral>());
+  EXPECT_TRUE(c->args[0]->Is<ast::IntLiteralExpression>());
   EXPECT_TRUE(c->args[1]->Is<ast::IdentifierExpression>());
   EXPECT_TRUE(c->args[2]->Is<ast::BinaryExpression>());
 }
@@ -74,7 +74,7 @@
   EXPECT_EQ(c->func->symbol, p->builder().Symbols().Get("a"));
 
   EXPECT_EQ(c->args.size(), 2u);
-  EXPECT_TRUE(c->args[0]->Is<ast::IntLiteral>());
+  EXPECT_TRUE(c->args[0]->Is<ast::IntLiteralExpression>());
   EXPECT_TRUE(c->args[1]->Is<ast::IdentifierExpression>());
 }
 
diff --git a/src/reader/wgsl/parser_impl_const_expr_test.cc b/src/reader/wgsl/parser_impl_const_expr_test.cc
index baf5823..f5958d1 100644
--- a/src/reader/wgsl/parser_impl_const_expr_test.cc
+++ b/src/reader/wgsl/parser_impl_const_expr_test.cc
@@ -33,11 +33,11 @@
   ASSERT_EQ(t->values.size(), 2u);
   auto& v = t->values;
 
-  ASSERT_TRUE(v[0]->Is<ast::FloatLiteral>());
-  EXPECT_FLOAT_EQ(v[0]->As<ast::FloatLiteral>()->value, 1.);
+  ASSERT_TRUE(v[0]->Is<ast::FloatLiteralExpression>());
+  EXPECT_FLOAT_EQ(v[0]->As<ast::FloatLiteralExpression>()->value, 1.);
 
-  ASSERT_TRUE(v[1]->Is<ast::FloatLiteral>());
-  EXPECT_FLOAT_EQ(v[1]->As<ast::FloatLiteral>()->value, 2.);
+  ASSERT_TRUE(v[1]->Is<ast::FloatLiteralExpression>());
+  EXPECT_FLOAT_EQ(v[1]->As<ast::FloatLiteralExpression>()->value, 2.);
 }
 
 TEST_F(ParserImplTest, ConstExpr_TypeDecl_Empty) {
@@ -66,8 +66,8 @@
   EXPECT_EQ(t->type->As<ast::Vector>()->width, 2u);
 
   ASSERT_EQ(t->values.size(), 2u);
-  ASSERT_TRUE(t->values[0]->Is<ast::Literal>());
-  ASSERT_TRUE(t->values[1]->Is<ast::Literal>());
+  ASSERT_TRUE(t->values[0]->Is<ast::LiteralExpression>());
+  ASSERT_TRUE(t->values[1]->Is<ast::LiteralExpression>());
 }
 
 TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingRightParen) {
@@ -112,8 +112,8 @@
   ASSERT_FALSE(p->has_error()) << p->error();
   ASSERT_FALSE(e.errored);
   ASSERT_NE(e.value, nullptr);
-  ASSERT_TRUE(e.value->Is<ast::BoolLiteral>());
-  EXPECT_TRUE(e.value->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(e.value->Is<ast::BoolLiteralExpression>());
+  EXPECT_TRUE(e.value->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, ConstExpr_ConstLiteral_Invalid) {
diff --git a/src/reader/wgsl/parser_impl_const_literal_test.cc b/src/reader/wgsl/parser_impl_const_literal_test.cc
index 97d625e..37350b9 100644
--- a/src/reader/wgsl/parser_impl_const_literal_test.cc
+++ b/src/reader/wgsl/parser_impl_const_literal_test.cc
@@ -48,8 +48,8 @@
   EXPECT_FALSE(c.errored);
   EXPECT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(c.value, nullptr);
-  ASSERT_TRUE(c->Is<ast::SintLiteral>());
-  EXPECT_EQ(c->As<ast::SintLiteral>()->value, -234);
+  ASSERT_TRUE(c->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(c->As<ast::SintLiteralExpression>()->value, -234);
   EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
 }
 
@@ -60,8 +60,8 @@
   EXPECT_FALSE(c.errored);
   EXPECT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(c.value, nullptr);
-  ASSERT_TRUE(c->Is<ast::UintLiteral>());
-  EXPECT_EQ(c->As<ast::UintLiteral>()->value, 234u);
+  ASSERT_TRUE(c->Is<ast::UintLiteralExpression>());
+  EXPECT_EQ(c->As<ast::UintLiteralExpression>()->value, 234u);
   EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
 }
 
@@ -72,8 +72,8 @@
   EXPECT_FALSE(c.errored);
   EXPECT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(c.value, nullptr);
-  ASSERT_TRUE(c->Is<ast::FloatLiteral>());
-  EXPECT_FLOAT_EQ(c->As<ast::FloatLiteral>()->value, 234e12f);
+  ASSERT_TRUE(c->Is<ast::FloatLiteralExpression>());
+  EXPECT_FLOAT_EQ(c->As<ast::FloatLiteralExpression>()->value, 234e12f);
   EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 8u}}));
 }
 
@@ -136,8 +136,8 @@
   EXPECT_FALSE(c.errored);
   EXPECT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(c.value, nullptr);
-  ASSERT_TRUE(c->Is<ast::FloatLiteral>());
-  EXPECT_FLOAT_EQ(c->As<ast::FloatLiteral>()->value, params.expected);
+  ASSERT_TRUE(c->Is<ast::FloatLiteralExpression>());
+  EXPECT_FLOAT_EQ(c->As<ast::FloatLiteralExpression>()->value, params.expected);
 }
 
 FloatLiteralTestCase float_literal_test_cases[] = {
@@ -394,8 +394,8 @@
   EXPECT_FALSE(c.errored);
   EXPECT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(c.value, nullptr);
-  ASSERT_TRUE(c->Is<ast::FloatLiteral>());
-  EXPECT_FLOAT_EQ(c->As<ast::FloatLiteral>()->value,
+  ASSERT_TRUE(c->Is<ast::FloatLiteralExpression>());
+  EXPECT_FLOAT_EQ(c->As<ast::FloatLiteralExpression>()->value,
                   std::numeric_limits<float>::max());
   EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 42u}}));
 }
@@ -417,8 +417,8 @@
   EXPECT_FALSE(c.errored);
   EXPECT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(c.value, nullptr);
-  ASSERT_TRUE(c->Is<ast::FloatLiteral>());
-  EXPECT_FLOAT_EQ(c->As<ast::FloatLiteral>()->value,
+  ASSERT_TRUE(c->Is<ast::FloatLiteralExpression>());
+  EXPECT_FLOAT_EQ(c->As<ast::FloatLiteralExpression>()->value,
                   std::numeric_limits<float>::lowest());
   EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 43u}}));
 }
@@ -430,8 +430,8 @@
   EXPECT_FALSE(c.errored);
   EXPECT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(c.value, nullptr);
-  ASSERT_TRUE(c->Is<ast::BoolLiteral>());
-  EXPECT_TRUE(c->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(c->Is<ast::BoolLiteralExpression>());
+  EXPECT_TRUE(c->As<ast::BoolLiteralExpression>()->value);
   EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
 }
 
@@ -442,8 +442,8 @@
   EXPECT_FALSE(c.errored);
   EXPECT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(c.value, nullptr);
-  ASSERT_TRUE(c->Is<ast::BoolLiteral>());
-  EXPECT_FALSE(c->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(c->Is<ast::BoolLiteralExpression>());
+  EXPECT_FALSE(c->As<ast::BoolLiteralExpression>()->value);
   EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 6u}}));
 }
 
diff --git a/src/reader/wgsl/parser_impl_equality_expression_test.cc b/src/reader/wgsl/parser_impl_equality_expression_test.cc
index 72db3a6..2d6c2f0 100644
--- a/src/reader/wgsl/parser_impl_equality_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_equality_expression_test.cc
@@ -35,8 +35,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, EqualityExpression_Parses_NotEqual) {
@@ -55,8 +55,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, EqualityExpression_InvalidLHS) {
diff --git a/src/reader/wgsl/parser_impl_exclusive_or_expression_test.cc b/src/reader/wgsl/parser_impl_exclusive_or_expression_test.cc
index 6fbf186..ad58ce6 100644
--- a/src/reader/wgsl/parser_impl_exclusive_or_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_exclusive_or_expression_test.cc
@@ -35,8 +35,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, ExclusiveOrExpression_InvalidLHS) {
diff --git a/src/reader/wgsl/parser_impl_function_decl_test.cc b/src/reader/wgsl/parser_impl_function_decl_test.cc
index 67131b8..d593c22 100644
--- a/src/reader/wgsl/parser_impl_function_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_function_decl_test.cc
@@ -71,14 +71,14 @@
 
   auto values = decorations[0]->As<ast::WorkgroupDecoration>()->Values();
 
-  ASSERT_TRUE(values[0]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[0]->As<ast::IntLiteral>()->ValueAsU32(), 2u);
+  ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
 
-  ASSERT_TRUE(values[1]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[1]->As<ast::IntLiteral>()->ValueAsU32(), 3u);
+  ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 3u);
 
-  ASSERT_TRUE(values[2]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[2]->As<ast::IntLiteral>()->ValueAsU32(), 4u);
+  ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
 
   auto* body = f->body;
   ASSERT_EQ(body->statements.size(), 1u);
@@ -110,14 +110,14 @@
   ASSERT_TRUE(decorations[0]->Is<ast::WorkgroupDecoration>());
   auto values = decorations[0]->As<ast::WorkgroupDecoration>()->Values();
 
-  ASSERT_TRUE(values[0]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[0]->As<ast::IntLiteral>()->ValueAsU32(), 2u);
+  ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
 
-  ASSERT_TRUE(values[1]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[1]->As<ast::IntLiteral>()->ValueAsU32(), 3u);
+  ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 3u);
 
-  ASSERT_TRUE(values[2]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[2]->As<ast::IntLiteral>()->ValueAsU32(), 4u);
+  ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
 
   ASSERT_TRUE(decorations[1]->Is<ast::StageDecoration>());
   EXPECT_EQ(decorations[1]->As<ast::StageDecoration>()->stage,
@@ -154,14 +154,14 @@
   ASSERT_TRUE(decos[0]->Is<ast::WorkgroupDecoration>());
   auto values = decos[0]->As<ast::WorkgroupDecoration>()->Values();
 
-  ASSERT_TRUE(values[0]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[0]->As<ast::IntLiteral>()->ValueAsU32(), 2u);
+  ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
 
-  ASSERT_TRUE(values[1]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[1]->As<ast::IntLiteral>()->ValueAsU32(), 3u);
+  ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 3u);
 
-  ASSERT_TRUE(values[2]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[2]->As<ast::IntLiteral>()->ValueAsU32(), 4u);
+  ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
 
   ASSERT_TRUE(decos[1]->Is<ast::StageDecoration>());
   EXPECT_EQ(decos[1]->As<ast::StageDecoration>()->stage,
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 0b681c0..9f5b0b6 100644
--- a/src/reader/wgsl/parser_impl_function_decoration_list_test.cc
+++ b/src/reader/wgsl/parser_impl_function_decoration_list_test.cc
@@ -36,10 +36,10 @@
   ASSERT_TRUE(deco_0->Is<ast::WorkgroupDecoration>());
   const ast::Expression* x = deco_0->As<ast::WorkgroupDecoration>()->x;
   ASSERT_NE(x, nullptr);
-  auto* x_literal = x->As<ast::Literal>();
+  auto* x_literal = x->As<ast::LiteralExpression>();
   ASSERT_NE(x_literal, nullptr);
-  ASSERT_TRUE(x_literal->Is<ast::IntLiteral>());
-  EXPECT_EQ(x_literal->As<ast::IntLiteral>()->ValueAsU32(), 2u);
+  ASSERT_TRUE(x_literal->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(x_literal->As<ast::IntLiteralExpression>()->ValueAsU32(), 2u);
 
   ASSERT_TRUE(deco_1->Is<ast::StageDecoration>());
   EXPECT_EQ(deco_1->As<ast::StageDecoration>()->stage,
diff --git a/src/reader/wgsl/parser_impl_function_decoration_test.cc b/src/reader/wgsl/parser_impl_function_decoration_test.cc
index d63d272..f254f35 100644
--- a/src/reader/wgsl/parser_impl_function_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_function_decoration_test.cc
@@ -34,8 +34,8 @@
 
   auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
 
-  ASSERT_TRUE(values[0]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[0]->As<ast::IntLiteral>()->ValueAsU32(), 4u);
+  ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
 
   EXPECT_EQ(values[1], nullptr);
   EXPECT_EQ(values[2], nullptr);
@@ -54,11 +54,11 @@
 
   auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
 
-  ASSERT_TRUE(values[0]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[0]->As<ast::IntLiteral>()->ValueAsU32(), 4u);
+  ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
 
-  ASSERT_TRUE(values[1]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[1]->As<ast::IntLiteral>()->ValueAsU32(), 5u);
+  ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
 
   EXPECT_EQ(values[2], nullptr);
 }
@@ -76,14 +76,14 @@
 
   auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
 
-  ASSERT_TRUE(values[0]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[0]->As<ast::IntLiteral>()->ValueAsU32(), 4u);
+  ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
 
-  ASSERT_TRUE(values[1]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[1]->As<ast::IntLiteral>()->ValueAsU32(), 5u);
+  ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
 
-  ASSERT_TRUE(values[2]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[2]->As<ast::IntLiteral>()->ValueAsU32(), 6u);
+  ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
 }
 
 TEST_F(ParserImplTest, Decoration_Workgroup_WithIdent) {
@@ -99,8 +99,8 @@
 
   auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
 
-  ASSERT_TRUE(values[0]->Is<ast::IntLiteral>());
-  EXPECT_EQ(values[0]->As<ast::IntLiteral>()->ValueAsU32(), 4u);
+  ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
+  EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
 
   ASSERT_NE(values[1], nullptr);
   auto* y_ident = values[1]->As<ast::IdentifierExpression>();
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 29fe795..f77aa31 100644
--- a/src/reader/wgsl/parser_impl_global_constant_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_global_constant_decl_test.cc
@@ -42,7 +42,7 @@
   EXPECT_EQ(e->source.range.end.column, 6u);
 
   ASSERT_NE(e->constructor, nullptr);
-  EXPECT_TRUE(e->constructor->Is<ast::Literal>());
+  EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
 
   EXPECT_FALSE(
       ast::HasDecoration<ast::OverrideDecoration>(e.value->decorations));
@@ -69,7 +69,7 @@
   EXPECT_EQ(e->source.range.end.column, 6u);
 
   ASSERT_NE(e->constructor, nullptr);
-  EXPECT_TRUE(e->constructor->Is<ast::Literal>());
+  EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
 
   EXPECT_FALSE(
       ast::HasDecoration<ast::OverrideDecoration>(e.value->decorations));
@@ -137,7 +137,7 @@
   EXPECT_EQ(e->source.range.end.column, 22u);
 
   ASSERT_NE(e->constructor, nullptr);
-  EXPECT_TRUE(e->constructor->Is<ast::Literal>());
+  EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
 
   auto* override_deco =
       ast::GetDecoration<ast::OverrideDecoration>(e.value->decorations);
@@ -169,7 +169,7 @@
   EXPECT_EQ(e->source.range.end.column, 19u);
 
   ASSERT_NE(e->constructor, nullptr);
-  EXPECT_TRUE(e->constructor->Is<ast::Literal>());
+  EXPECT_TRUE(e->constructor->Is<ast::LiteralExpression>());
 
   auto* override_deco =
       ast::GetDecoration<ast::OverrideDecoration>(e.value->decorations);
diff --git a/src/reader/wgsl/parser_impl_global_variable_decl_test.cc b/src/reader/wgsl/parser_impl_global_variable_decl_test.cc
index 9823c3f..d79a8ae 100644
--- a/src/reader/wgsl/parser_impl_global_variable_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_global_variable_decl_test.cc
@@ -63,7 +63,7 @@
   EXPECT_EQ(e->source.range.end.column, 15u);
 
   ASSERT_NE(e->constructor, nullptr);
-  ASSERT_TRUE(e->constructor->Is<ast::FloatLiteral>());
+  ASSERT_TRUE(e->constructor->Is<ast::FloatLiteralExpression>());
 }
 
 TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
diff --git a/src/reader/wgsl/parser_impl_inclusive_or_expression_test.cc b/src/reader/wgsl/parser_impl_inclusive_or_expression_test.cc
index 5f6d5da..bc633ad 100644
--- a/src/reader/wgsl/parser_impl_inclusive_or_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_inclusive_or_expression_test.cc
@@ -35,8 +35,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, InclusiveOrExpression_InvalidLHS) {
diff --git a/src/reader/wgsl/parser_impl_logical_and_expression_test.cc b/src/reader/wgsl/parser_impl_logical_and_expression_test.cc
index b394558..1322308 100644
--- a/src/reader/wgsl/parser_impl_logical_and_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_logical_and_expression_test.cc
@@ -35,8 +35,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, LogicalAndExpression_InvalidLHS) {
diff --git a/src/reader/wgsl/parser_impl_logical_or_expression_test.cc b/src/reader/wgsl/parser_impl_logical_or_expression_test.cc
index 5b1d884..fe60f8b 100644
--- a/src/reader/wgsl/parser_impl_logical_or_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_logical_or_expression_test.cc
@@ -35,8 +35,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, LogicalOrExpression_InvalidLHS) {
diff --git a/src/reader/wgsl/parser_impl_multiplicative_expression_test.cc b/src/reader/wgsl/parser_impl_multiplicative_expression_test.cc
index c2ab2f1..08a1ccf 100644
--- a/src/reader/wgsl/parser_impl_multiplicative_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_multiplicative_expression_test.cc
@@ -35,8 +35,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, MultiplicativeExpression_Parses_Divide) {
@@ -55,8 +55,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, MultiplicativeExpression_Parses_Modulo) {
@@ -75,8 +75,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, MultiplicativeExpression_InvalidLHS) {
diff --git a/src/reader/wgsl/parser_impl_primary_expression_test.cc b/src/reader/wgsl/parser_impl_primary_expression_test.cc
index e364e5a..66312fd 100644
--- a/src/reader/wgsl/parser_impl_primary_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_primary_expression_test.cc
@@ -44,17 +44,17 @@
 
   ASSERT_EQ(ty->values.size(), 4u);
   const auto& val = ty->values;
-  ASSERT_TRUE(val[0]->Is<ast::SintLiteral>());
-  EXPECT_EQ(val[0]->As<ast::SintLiteral>()->value, 1);
+  ASSERT_TRUE(val[0]->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(val[0]->As<ast::SintLiteralExpression>()->value, 1);
 
-  ASSERT_TRUE(val[1]->Is<ast::SintLiteral>());
-  EXPECT_EQ(val[1]->As<ast::SintLiteral>()->value, 2);
+  ASSERT_TRUE(val[1]->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(val[1]->As<ast::SintLiteralExpression>()->value, 2);
 
-  ASSERT_TRUE(val[2]->Is<ast::SintLiteral>());
-  EXPECT_EQ(val[2]->As<ast::SintLiteral>()->value, 3);
+  ASSERT_TRUE(val[2]->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(val[2]->As<ast::SintLiteralExpression>()->value, 3);
 
-  ASSERT_TRUE(val[3]->Is<ast::SintLiteral>());
-  EXPECT_EQ(val[3]->As<ast::SintLiteral>()->value, 4);
+  ASSERT_TRUE(val[3]->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(val[3]->As<ast::SintLiteralExpression>()->value, 4);
 }
 
 TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_ZeroConstructor) {
@@ -159,11 +159,11 @@
   auto values = constructor->values;
   ASSERT_EQ(values.size(), 2u);
 
-  ASSERT_TRUE(values[0]->Is<ast::UintLiteral>());
-  EXPECT_EQ(values[0]->As<ast::UintLiteral>()->value, 1u);
+  ASSERT_TRUE(values[0]->Is<ast::UintLiteralExpression>());
+  EXPECT_EQ(values[0]->As<ast::UintLiteralExpression>()->value, 1u);
 
-  ASSERT_TRUE(values[1]->Is<ast::FloatLiteral>());
-  EXPECT_EQ(values[1]->As<ast::FloatLiteral>()->value, 2.f);
+  ASSERT_TRUE(values[1]->Is<ast::FloatLiteralExpression>());
+  EXPECT_EQ(values[1]->As<ast::FloatLiteralExpression>()->value, 2.f);
 }
 
 TEST_F(ParserImplTest, PrimaryExpression_ConstLiteral_True) {
@@ -173,8 +173,8 @@
   EXPECT_FALSE(e.errored);
   EXPECT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(e.value, nullptr);
-  ASSERT_TRUE(e->Is<ast::BoolLiteral>());
-  EXPECT_TRUE(e->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(e->Is<ast::BoolLiteralExpression>());
+  EXPECT_TRUE(e->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, PrimaryExpression_ParenExpr) {
@@ -231,7 +231,7 @@
   ASSERT_TRUE(c->type->Is<ast::F32>());
   ASSERT_EQ(c->values.size(), 1u);
 
-  ASSERT_TRUE(c->values[0]->Is<ast::IntLiteral>());
+  ASSERT_TRUE(c->values[0]->Is<ast::IntLiteralExpression>());
 }
 
 TEST_F(ParserImplTest, PrimaryExpression_Bitcast) {
@@ -246,7 +246,7 @@
 
   auto* c = e->As<ast::BitcastExpression>();
   ASSERT_TRUE(c->type->Is<ast::F32>());
-  ASSERT_TRUE(c->expr->Is<ast::IntLiteral>());
+  ASSERT_TRUE(c->expr->Is<ast::IntLiteralExpression>());
 }
 
 TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingGreaterThan) {
diff --git a/src/reader/wgsl/parser_impl_relational_expression_test.cc b/src/reader/wgsl/parser_impl_relational_expression_test.cc
index 290fec3..1418b83 100644
--- a/src/reader/wgsl/parser_impl_relational_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_relational_expression_test.cc
@@ -35,8 +35,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Register("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, RelationalExpression_Parses_GreaterThan) {
@@ -55,8 +55,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Register("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, RelationalExpression_Parses_LessThanEqual) {
@@ -75,8 +75,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Register("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, RelationalExpression_Parses_GreaterThanEqual) {
@@ -95,8 +95,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Register("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, RelationalExpression_InvalidLHS) {
diff --git a/src/reader/wgsl/parser_impl_shift_expression_test.cc b/src/reader/wgsl/parser_impl_shift_expression_test.cc
index 1b6e73b..98694c5 100644
--- a/src/reader/wgsl/parser_impl_shift_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_shift_expression_test.cc
@@ -35,8 +35,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, ShiftExpression_Parses_ShiftRight) {
@@ -55,8 +55,8 @@
   auto* ident = rel->lhs->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteral>());
-  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteral>()->value);
+  ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
+  ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
 TEST_F(ParserImplTest, ShiftExpression_InvalidSpaceLeft) {
diff --git a/src/reader/wgsl/parser_impl_singular_expression_test.cc b/src/reader/wgsl/parser_impl_singular_expression_test.cc
index d229ce4..b0d1f45 100644
--- a/src/reader/wgsl/parser_impl_singular_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_singular_expression_test.cc
@@ -34,8 +34,8 @@
   auto* ident = idx->object->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(idx->index->Is<ast::SintLiteral>());
-  EXPECT_EQ(idx->index->As<ast::SintLiteral>()->value, 1);
+  ASSERT_TRUE(idx->index->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(idx->index->As<ast::SintLiteralExpression>()->value, 1);
 }
 
 TEST_F(ParserImplTest, SingularExpression_Array_ExpressionIndex) {
@@ -116,7 +116,7 @@
   EXPECT_EQ(c->func->symbol, p->builder().Symbols().Get("test"));
 
   EXPECT_EQ(c->args.size(), 3u);
-  EXPECT_TRUE(c->args[0]->Is<ast::IntLiteral>());
+  EXPECT_TRUE(c->args[0]->Is<ast::IntLiteralExpression>());
   EXPECT_TRUE(c->args[1]->Is<ast::IdentifierExpression>());
   EXPECT_TRUE(c->args[2]->Is<ast::BinaryExpression>());
 }
diff --git a/src/reader/wgsl/parser_impl_type_decl_test.cc b/src/reader/wgsl/parser_impl_type_decl_test.cc
index 957ab07..17c3b20 100644
--- a/src/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_type_decl_test.cc
@@ -455,7 +455,7 @@
   EXPECT_EQ(a->decorations.size(), 0u);
   EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 14u}}));
 
-  auto* size = a->count->As<ast::SintLiteral>();
+  auto* size = a->count->As<ast::SintLiteralExpression>();
   ASSERT_NE(size, nullptr);
   EXPECT_EQ(size->ValueAsI32(), 5);
 }
@@ -475,7 +475,7 @@
   EXPECT_EQ(a->decorations.size(), 0u);
   EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 15u}}));
 
-  auto* size = a->count->As<ast::UintLiteral>();
+  auto* size = a->count->As<ast::UintLiteralExpression>();
   ASSERT_NE(size, nullptr);
   EXPECT_EQ(size->ValueAsU32(), 5u);
 }
@@ -513,7 +513,7 @@
   ASSERT_FALSE(a->IsRuntimeArray());
   ASSERT_TRUE(a->type->Is<ast::F32>());
 
-  auto* size = a->count->As<ast::SintLiteral>();
+  auto* size = a->count->As<ast::SintLiteralExpression>();
   ASSERT_NE(size, nullptr);
   EXPECT_EQ(size->ValueAsI32(), 5);
 
diff --git a/src/reader/wgsl/parser_impl_unary_expression_test.cc b/src/reader/wgsl/parser_impl_unary_expression_test.cc
index b746035..8a3dd24 100644
--- a/src/reader/wgsl/parser_impl_unary_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_unary_expression_test.cc
@@ -34,8 +34,8 @@
   auto* ident = idx->object->As<ast::IdentifierExpression>();
   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
 
-  ASSERT_TRUE(idx->index->Is<ast::SintLiteral>());
-  ASSERT_EQ(idx->index->As<ast::SintLiteral>()->value, 2);
+  ASSERT_TRUE(idx->index->Is<ast::SintLiteralExpression>());
+  ASSERT_EQ(idx->index->As<ast::SintLiteralExpression>()->value, 2);
 }
 
 TEST_F(ParserImplTest, UnaryExpression_Minus) {
@@ -50,8 +50,8 @@
   auto* u = e->As<ast::UnaryOpExpression>();
   ASSERT_EQ(u->op, ast::UnaryOp::kNegation);
 
-  ASSERT_TRUE(u->expr->Is<ast::SintLiteral>());
-  EXPECT_EQ(u->expr->As<ast::SintLiteral>()->value, 1);
+  ASSERT_TRUE(u->expr->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(u->expr->As<ast::SintLiteralExpression>()->value, 1);
 }
 
 TEST_F(ParserImplTest, UnaryExpression_AddressOf) {
@@ -132,8 +132,8 @@
   auto* u = e->As<ast::UnaryOpExpression>();
   ASSERT_EQ(u->op, ast::UnaryOp::kNot);
 
-  ASSERT_TRUE(u->expr->Is<ast::SintLiteral>());
-  EXPECT_EQ(u->expr->As<ast::SintLiteral>()->value, 1);
+  ASSERT_TRUE(u->expr->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(u->expr->As<ast::SintLiteralExpression>()->value, 1);
 }
 
 TEST_F(ParserImplTest, UnaryExpression_Bang_InvalidRHS) {
@@ -158,8 +158,8 @@
   auto* u = e->As<ast::UnaryOpExpression>();
   ASSERT_EQ(u->op, ast::UnaryOp::kComplement);
 
-  ASSERT_TRUE(u->expr->Is<ast::SintLiteral>());
-  EXPECT_EQ(u->expr->As<ast::SintLiteral>()->value, 1);
+  ASSERT_TRUE(u->expr->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(u->expr->As<ast::SintLiteralExpression>()->value, 1);
 }
 
 TEST_F(ParserImplTest, UnaryExpression_PrefixPlusPlus) {
diff --git a/src/reader/wgsl/parser_impl_variable_stmt_test.cc b/src/reader/wgsl/parser_impl_variable_stmt_test.cc
index 5a6653d..c248e7a 100644
--- a/src/reader/wgsl/parser_impl_variable_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_variable_stmt_test.cc
@@ -55,7 +55,7 @@
   ASSERT_EQ(e->source.range.end.column, 6u);
 
   ASSERT_NE(e->variable->constructor, nullptr);
-  EXPECT_TRUE(e->variable->constructor->Is<ast::Literal>());
+  EXPECT_TRUE(e->variable->constructor->Is<ast::LiteralExpression>());
 }
 
 TEST_F(ParserImplTest, VariableStmt_VariableDecl_Invalid) {
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index 28ed7ba..1f3bcea 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -2015,7 +2015,7 @@
         ws[i].value = 0;
         continue;
       }
-    } else if (!expr->Is<ast::Literal>()) {
+    } else if (!expr->Is<ast::LiteralExpression>()) {
       AddError(
           "workgroup_size argument must be either a literal or a "
           "module-scope constant",
@@ -2367,7 +2367,7 @@
       sem_expr = TypeConstructor(ctor);
     } else if (auto* ident = expr->As<ast::IdentifierExpression>()) {
       sem_expr = Identifier(ident);
-    } else if (auto* literal = expr->As<ast::Literal>()) {
+    } else if (auto* literal = expr->As<ast::LiteralExpression>()) {
       sem_expr = Literal(literal);
     } else if (auto* member = expr->As<ast::MemberAccessorExpression>()) {
       sem_expr = MemberAccessor(member);
@@ -2424,7 +2424,7 @@
     if (!parent_raw_ty->Is<sem::Reference>()) {
       // TODO(bclayton): expand this to allow any const_expr expression
       // https://github.com/gpuweb/gpuweb/issues/1272
-      if (!idx->As<ast::IntLiteral>()) {
+      if (!idx->As<ast::IntLiteralExpression>()) {
         AddError("index must be signed or unsigned integer literal",
                  idx->source);
         return nullptr;
@@ -2617,7 +2617,8 @@
       bool is_const_expr = true;
       ast::TraverseExpressions(
           arg->Declaration(), diagnostics_, [&](const ast::Expression* e) {
-            if (e->IsAnyOf<ast::Literal, ast::TypeConstructorExpression>()) {
+            if (e->IsAnyOf<ast::LiteralExpression,
+                           ast::TypeConstructorExpression>()) {
               return ast::TraverseAction::Descend;
             }
             is_const_expr = false;
@@ -2764,7 +2765,7 @@
   return builder_->create<sem::Expression>(expr, ty, current_statement_, val);
 }
 
-sem::Expression* Resolver::Literal(const ast::Literal* literal) {
+sem::Expression* Resolver::Literal(const ast::LiteralExpression* literal) {
   auto* ty = TypeOf(literal);
   if (!ty) {
     return nullptr;
@@ -3574,17 +3575,17 @@
   return ty->FriendlyName(builder_->Symbols());
 }
 
-sem::Type* Resolver::TypeOf(const ast::Literal* lit) {
-  if (lit->Is<ast::SintLiteral>()) {
+sem::Type* Resolver::TypeOf(const ast::LiteralExpression* lit) {
+  if (lit->Is<ast::SintLiteralExpression>()) {
     return builder_->create<sem::I32>();
   }
-  if (lit->Is<ast::UintLiteral>()) {
+  if (lit->Is<ast::UintLiteralExpression>()) {
     return builder_->create<sem::U32>();
   }
-  if (lit->Is<ast::FloatLiteral>()) {
+  if (lit->Is<ast::FloatLiteralExpression>()) {
     return builder_->create<sem::F32>();
   }
-  if (lit->Is<ast::BoolLiteral>()) {
+  if (lit->Is<ast::BoolLiteralExpression>()) {
     return builder_->create<sem::Bool>();
   }
   TINT_UNREACHABLE(Resolver, diagnostics_)
@@ -3780,7 +3781,7 @@
       }
 
       count_expr = var->Declaration()->constructor;
-    } else if (!count_expr->Is<ast::Literal>()) {
+    } else if (!count_expr->Is<ast::LiteralExpression>()) {
       AddError(
           "array size expression must be either a literal or a module-scope "
           "constant",
@@ -4259,7 +4260,7 @@
       auto v = selector->ValueAsU32();
       auto it = selectors.find(v);
       if (it != selectors.end()) {
-        auto val = selector->Is<ast::IntLiteral>()
+        auto val = selector->Is<ast::IntLiteralExpression>()
                        ? std::to_string(selector->ValueAsI32())
                        : std::to_string(selector->ValueAsU32());
         AddError("duplicate switch case '" + val + "'", selector->source);
diff --git a/src/resolver/resolver.h b/src/resolver/resolver.h
index b6c5118..6578ce1 100644
--- a/src/resolver/resolver.h
+++ b/src/resolver/resolver.h
@@ -176,7 +176,7 @@
   sem::Call* FunctionCall(const ast::CallExpression*);
   sem::Expression* Identifier(const ast::IdentifierExpression*);
   sem::Call* IntrinsicCall(const ast::CallExpression*, sem::IntrinsicType);
-  sem::Expression* Literal(const ast::Literal*);
+  sem::Expression* Literal(const ast::LiteralExpression*);
   sem::Expression* MemberAccessor(const ast::MemberAccessorExpression*);
   sem::Expression* TypeConstructor(const ast::TypeConstructorExpression*);
   sem::Expression* UnaryOp(const ast::UnaryOpExpression*);
@@ -329,7 +329,7 @@
 
   /// @returns the semantic type of the AST literal `lit`
   /// @param lit the literal
-  sem::Type* TypeOf(const ast::Literal* lit);
+  sem::Type* TypeOf(const ast::LiteralExpression* lit);
 
   /// Assigns `stmt` to #current_statement_, #current_compound_statement_, and
   /// possibly #current_block_, pushes the variable scope, then calls
@@ -376,7 +376,7 @@
 
   sem::Constant EvaluateConstantValue(const ast::Expression* expr,
                                       const sem::Type* type);
-  sem::Constant EvaluateConstantValue(const ast::Literal* literal,
+  sem::Constant EvaluateConstantValue(const ast::LiteralExpression* literal,
                                       const sem::Type* type);
   sem::Constant EvaluateConstantValue(
       const ast::TypeConstructorExpression* type_ctor,
diff --git a/src/resolver/resolver_constants.cc b/src/resolver/resolver_constants.cc
index 5541d64..4252e1b 100644
--- a/src/resolver/resolver_constants.cc
+++ b/src/resolver/resolver_constants.cc
@@ -29,7 +29,7 @@
 
 sem::Constant Resolver::EvaluateConstantValue(const ast::Expression* expr,
                                               const sem::Type* type) {
-  if (auto* e = expr->As<ast::Literal>()) {
+  if (auto* e = expr->As<ast::LiteralExpression>()) {
     return EvaluateConstantValue(e, type);
   }
   if (auto* e = expr->As<ast::TypeConstructorExpression>()) {
@@ -38,18 +38,19 @@
   return {};
 }
 
-sem::Constant Resolver::EvaluateConstantValue(const ast::Literal* literal,
-                                              const sem::Type* type) {
-  if (auto* lit = literal->As<ast::SintLiteral>()) {
+sem::Constant Resolver::EvaluateConstantValue(
+    const ast::LiteralExpression* literal,
+    const sem::Type* type) {
+  if (auto* lit = literal->As<ast::SintLiteralExpression>()) {
     return {type, {lit->ValueAsI32()}};
   }
-  if (auto* lit = literal->As<ast::UintLiteral>()) {
+  if (auto* lit = literal->As<ast::UintLiteralExpression>()) {
     return {type, {lit->ValueAsU32()}};
   }
-  if (auto* lit = literal->As<ast::FloatLiteral>()) {
+  if (auto* lit = literal->As<ast::FloatLiteralExpression>()) {
     return {type, {lit->value}};
   }
-  if (auto* lit = literal->As<ast::BoolLiteral>()) {
+  if (auto* lit = literal->As<ast::BoolLiteralExpression>()) {
     return {type, {lit->value}};
   }
   TINT_UNREACHABLE(Resolver, builder_->Diagnostics());
diff --git a/src/resolver/resolver_test.cc b/src/resolver/resolver_test.cc
index 45afc80..a92c19c 100644
--- a/src/resolver/resolver_test.cc
+++ b/src/resolver/resolver_test.cc
@@ -114,7 +114,7 @@
   auto* assign = Assign(lhs, rhs);
   auto* block = Block(assign);
   ast::CaseSelectorList lit;
-  lit.push_back(create<ast::SintLiteral>(3));
+  lit.push_back(create<ast::SintLiteralExpression>(3));
   auto* cse = create<ast::CaseStatement>(lit, block);
   auto* cond_var = Var("c", ty.i32());
   auto* sw = Switch(cond_var, cse, DefaultCase());
diff --git a/src/transform/decompose_memory_access.cc b/src/transform/decompose_memory_access.cc
index ff9d8ad..a06f8e0 100644
--- a/src/transform/decompose_memory_access.cc
+++ b/src/transform/decompose_memory_access.cc
@@ -330,9 +330,9 @@
   /// @param expr the expression to convert to an Offset
   /// @returns an Offset for the given ast::Expression
   const Offset* ToOffset(const ast::Expression* expr) {
-    if (auto* u32 = expr->As<ast::UintLiteral>()) {
+    if (auto* u32 = expr->As<ast::UintLiteralExpression>()) {
       return offsets_.Create<OffsetLiteral>(u32->value);
-    } else if (auto* i32 = expr->As<ast::SintLiteral>()) {
+    } else if (auto* i32 = expr->As<ast::SintLiteralExpression>()) {
       if (i32->value > 0) {
         return offsets_.Create<OffsetLiteral>(i32->value);
       }
diff --git a/src/transform/fold_constants.cc b/src/transform/fold_constants.cc
index 773136f..994bc1e 100644
--- a/src/transform/fold_constants.cc
+++ b/src/transform/fold_constants.cc
@@ -81,8 +81,10 @@
     }
 
     if (ty->is_scalar()) {
-      return value.WithScalarAt(
-          0, [&](auto&& s) -> const ast::Literal* { return ctx.dst->Expr(s); });
+      return value.WithScalarAt(0,
+                                [&](auto&& s) -> const ast::LiteralExpression* {
+                                  return ctx.dst->Expr(s);
+                                });
     }
 
     return nullptr;
diff --git a/src/transform/fold_trivial_single_use_lets.cc b/src/transform/fold_trivial_single_use_lets.cc
index c83008c..aa83b8f 100644
--- a/src/transform/fold_trivial_single_use_lets.cc
+++ b/src/transform/fold_trivial_single_use_lets.cc
@@ -37,7 +37,7 @@
     return nullptr;
   }
   auto* ctor = var->constructor;
-  if (!IsAnyOf<ast::IdentifierExpression, ast::Literal>(ctor)) {
+  if (!IsAnyOf<ast::IdentifierExpression, ast::LiteralExpression>(ctor)) {
     return nullptr;
   }
   return var_decl;
diff --git a/src/transform/inline_pointer_lets.cc b/src/transform/inline_pointer_lets.cc
index 0c59887..5bdf0fc 100644
--- a/src/transform/inline_pointer_lets.cc
+++ b/src/transform/inline_pointer_lets.cc
@@ -46,7 +46,7 @@
   if (auto* a = expr->As<ast::IndexAccessorExpression>()) {
     CollectSavedArrayIndices(program, a->object, cb);
 
-    if (!a->index->Is<ast::Literal>()) {
+    if (!a->index->Is<ast::LiteralExpression>()) {
       cb(a->index);
     }
     return;
diff --git a/src/transform/transform_test.cc b/src/transform/transform_test.cc
index 981f7d2..e8b8736 100644
--- a/src/transform/transform_test.cc
+++ b/src/transform/transform_test.cc
@@ -84,7 +84,7 @@
   ASSERT_TRUE(arr->As<ast::Array>()->type->Is<ast::F32>());
   ASSERT_EQ(arr->As<ast::Array>()->decorations.size(), 0u);
 
-  auto* size = arr->As<ast::Array>()->count->As<ast::IntLiteral>();
+  auto* size = arr->As<ast::Array>()->count->As<ast::IntLiteralExpression>();
   ASSERT_NE(size, nullptr);
   EXPECT_EQ(size->ValueAsI32(), 2);
 }
@@ -104,7 +104,7 @@
                 ->stride,
             64u);
 
-  auto* size = arr->As<ast::Array>()->count->As<ast::IntLiteral>();
+  auto* size = arr->As<ast::Array>()->count->As<ast::IntLiteralExpression>();
   ASSERT_NE(size, nullptr);
   EXPECT_EQ(size->ValueAsI32(), 2);
 }
diff --git a/src/writer/append_vector.cc b/src/writer/append_vector.cc
index 9520cc9..5059690 100644
--- a/src/writer/append_vector.cc
+++ b/src/writer/append_vector.cc
@@ -85,7 +85,7 @@
     const auto num_supplied = vc->values.size();
     if (num_supplied == 0) {
       // Zero-value vector constructor. Populate with zeros
-      auto buildZero = [&]() -> const ast::Literal* {
+      auto buildZero = [&]() -> const ast::LiteralExpression* {
         if (packed_el_sem_ty->Is<sem::I32>()) {
           return b->Expr(0);
         } else if (packed_el_sem_ty->Is<sem::U32>()) {
diff --git a/src/writer/append_vector_test.cc b/src/writer/append_vector_test.cc
index 26de490..67030e8 100644
--- a/src/writer/append_vector_test.cc
+++ b/src/writer/append_vector_test.cc
@@ -249,7 +249,7 @@
   ASSERT_NE(vec_0004, nullptr);
   ASSERT_EQ(vec_0004->values.size(), 4u);
   for (size_t i = 0; i < 3; i++) {
-    auto* literal = As<ast::SintLiteral>(vec_0004->values[i]);
+    auto* literal = As<ast::SintLiteralExpression>(vec_0004->values[i]);
     ASSERT_NE(literal, nullptr);
     EXPECT_EQ(literal->value, 0);
   }
diff --git a/src/writer/glsl/generator_impl.cc b/src/writer/glsl/generator_impl.cc
index 81aac7f..7825126 100644
--- a/src/writer/glsl/generator_impl.cc
+++ b/src/writer/glsl/generator_impl.cc
@@ -1472,7 +1472,7 @@
   if (auto* i = expr->As<ast::IdentifierExpression>()) {
     return EmitIdentifier(out, i);
   }
-  if (auto* l = expr->As<ast::Literal>()) {
+  if (auto* l = expr->As<ast::LiteralExpression>()) {
     return EmitLiteral(out, l);
   }
   if (auto* m = expr->As<ast::MemberAccessorExpression>()) {
@@ -2008,10 +2008,11 @@
   return true;
 }
 
-bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::Literal* lit) {
-  if (auto* l = lit->As<ast::BoolLiteral>()) {
+bool GeneratorImpl::EmitLiteral(std::ostream& out,
+                                const ast::LiteralExpression* lit) {
+  if (auto* l = lit->As<ast::BoolLiteralExpression>()) {
     out << (l->value ? "true" : "false");
-  } else if (auto* fl = lit->As<ast::FloatLiteral>()) {
+  } else if (auto* fl = lit->As<ast::FloatLiteralExpression>()) {
     if (std::isinf(fl->value)) {
       out << (fl->value >= 0 ? "asfloat(0x7f800000u)" : "asfloat(0xff800000u)");
     } else if (std::isnan(fl->value)) {
@@ -2019,9 +2020,9 @@
     } else {
       out << FloatToString(fl->value) << "f";
     }
-  } else if (auto* sl = lit->As<ast::SintLiteral>()) {
+  } else if (auto* sl = lit->As<ast::SintLiteralExpression>()) {
     out << sl->value;
-  } else if (auto* ul = lit->As<ast::UintLiteral>()) {
+  } else if (auto* ul = lit->As<ast::UintLiteralExpression>()) {
     out << ul->value << "u";
   } else {
     diagnostics_.add_error(diag::System::Writer, "unknown literal type");
diff --git a/src/writer/glsl/generator_impl.h b/src/writer/glsl/generator_impl.h
index 42ff92f..6155f0b 100644
--- a/src/writer/glsl/generator_impl.h
+++ b/src/writer/glsl/generator_impl.h
@@ -254,7 +254,7 @@
   /// @param out the output stream
   /// @param lit the literal to emit
   /// @returns true if the literal was successfully emitted
-  bool EmitLiteral(std::ostream& out, const ast::Literal* lit);
+  bool EmitLiteral(std::ostream& out, const ast::LiteralExpression* lit);
   /// Handles a loop statement
   /// @param stmt the statement to emit
   /// @returns true if the statement was emitted
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index 23433ce..0bc975f 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -2204,7 +2204,7 @@
   if (auto* i = expr->As<ast::IdentifierExpression>()) {
     return EmitIdentifier(out, i);
   }
-  if (auto* l = expr->As<ast::Literal>()) {
+  if (auto* l = expr->As<ast::LiteralExpression>()) {
     return EmitLiteral(out, l);
   }
   if (auto* m = expr->As<ast::MemberAccessorExpression>()) {
@@ -2683,10 +2683,11 @@
   return true;
 }
 
-bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::Literal* lit) {
-  if (auto* l = lit->As<ast::BoolLiteral>()) {
+bool GeneratorImpl::EmitLiteral(std::ostream& out,
+                                const ast::LiteralExpression* lit) {
+  if (auto* l = lit->As<ast::BoolLiteralExpression>()) {
     out << (l->value ? "true" : "false");
-  } else if (auto* fl = lit->As<ast::FloatLiteral>()) {
+  } else if (auto* fl = lit->As<ast::FloatLiteralExpression>()) {
     if (std::isinf(fl->value)) {
       out << (fl->value >= 0 ? "asfloat(0x7f800000u)" : "asfloat(0xff800000u)");
     } else if (std::isnan(fl->value)) {
@@ -2694,9 +2695,9 @@
     } else {
       out << FloatToString(fl->value) << "f";
     }
-  } else if (auto* sl = lit->As<ast::SintLiteral>()) {
+  } else if (auto* sl = lit->As<ast::SintLiteralExpression>()) {
     out << sl->value;
-  } else if (auto* ul = lit->As<ast::UintLiteral>()) {
+  } else if (auto* ul = lit->As<ast::UintLiteralExpression>()) {
     out << ul->value << "u";
   } else {
     diagnostics_.add_error(diag::System::Writer, "unknown literal type");
diff --git a/src/writer/hlsl/generator_impl.h b/src/writer/hlsl/generator_impl.h
index 62b822b..e63524f 100644
--- a/src/writer/hlsl/generator_impl.h
+++ b/src/writer/hlsl/generator_impl.h
@@ -287,7 +287,7 @@
   /// @param out the output stream
   /// @param lit the literal to emit
   /// @returns true if the literal was successfully emitted
-  bool EmitLiteral(std::ostream& out, const ast::Literal* lit);
+  bool EmitLiteral(std::ostream& out, const ast::LiteralExpression* lit);
   /// Handles a loop statement
   /// @param stmt the statement to emit
   /// @returns true if the statement was emitted
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 7593e2a..77c87bd 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -1379,10 +1379,11 @@
   return true;
 }
 
-bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::Literal* lit) {
-  if (auto* l = lit->As<ast::BoolLiteral>()) {
+bool GeneratorImpl::EmitLiteral(std::ostream& out,
+                                const ast::LiteralExpression* lit) {
+  if (auto* l = lit->As<ast::BoolLiteralExpression>()) {
     out << (l->value ? "true" : "false");
-  } else if (auto* fl = lit->As<ast::FloatLiteral>()) {
+  } else if (auto* fl = lit->As<ast::FloatLiteralExpression>()) {
     if (std::isinf(fl->value)) {
       out << (fl->value >= 0 ? "INFINITY" : "-INFINITY");
     } else if (std::isnan(fl->value)) {
@@ -1390,7 +1391,7 @@
     } else {
       out << FloatToString(fl->value) << "f";
     }
-  } else if (auto* sl = lit->As<ast::SintLiteral>()) {
+  } else if (auto* sl = lit->As<ast::SintLiteralExpression>()) {
     // MSL (and C++) parse `-2147483648` as a `long` because it parses unary
     // minus and `2147483648` as separate tokens, and the latter doesn't
     // fit into an (32-bit) `int`. WGSL, OTOH, parses this as an `i32`. To avoid
@@ -1402,7 +1403,7 @@
     } else {
       out << sl->value;
     }
-  } else if (auto* ul = lit->As<ast::UintLiteral>()) {
+  } else if (auto* ul = lit->As<ast::UintLiteralExpression>()) {
     out << ul->value << "u";
   } else {
     diagnostics_.add_error(diag::System::Writer, "unknown literal type");
@@ -1431,7 +1432,7 @@
   if (auto* i = expr->As<ast::IdentifierExpression>()) {
     return EmitIdentifier(out, i);
   }
-  if (auto* l = expr->As<ast::Literal>()) {
+  if (auto* l = expr->As<ast::LiteralExpression>()) {
     return EmitLiteral(out, l);
   }
   if (auto* m = expr->As<ast::MemberAccessorExpression>()) {
diff --git a/src/writer/msl/generator_impl.h b/src/writer/msl/generator_impl.h
index e72cf77..40b16cc 100644
--- a/src/writer/msl/generator_impl.h
+++ b/src/writer/msl/generator_impl.h
@@ -216,7 +216,7 @@
   /// @param out the output of the expression stream
   /// @param lit the literal to emit
   /// @returns true if the literal was successfully emitted
-  bool EmitLiteral(std::ostream& out, const ast::Literal* lit);
+  bool EmitLiteral(std::ostream& out, const ast::LiteralExpression* lit);
   /// Handles a loop statement
   /// @param stmt the statement to emit
   /// @returns true if the statement was emitted
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 27e87e0..e6a1365 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -583,7 +583,7 @@
   if (auto* i = expr->As<ast::IdentifierExpression>()) {
     return GenerateIdentifierExpression(i);
   }
-  if (auto* l = expr->As<ast::Literal>()) {
+  if (auto* l = expr->As<ast::LiteralExpression>()) {
     return GenerateLiteralIfNeeded(nullptr, l);
   }
   if (auto* m = expr->As<ast::MemberAccessorExpression>()) {
@@ -777,16 +777,16 @@
 
       // SPIR-V requires specialization constants to have initializers.
       if (type->Is<sem::F32>()) {
-        ast::FloatLiteral l(ProgramID(), Source{}, 0.0f);
+        ast::FloatLiteralExpression l(ProgramID(), Source{}, 0.0f);
         init_id = GenerateLiteralIfNeeded(var, &l);
       } else if (type->Is<sem::U32>()) {
-        ast::UintLiteral l(ProgramID(), Source{}, 0);
+        ast::UintLiteralExpression l(ProgramID(), Source{}, 0);
         init_id = GenerateLiteralIfNeeded(var, &l);
       } else if (type->Is<sem::I32>()) {
-        ast::SintLiteral l(ProgramID(), Source{}, 0);
+        ast::SintLiteralExpression l(ProgramID(), Source{}, 0);
         init_id = GenerateLiteralIfNeeded(var, &l);
       } else if (type->Is<sem::Bool>()) {
-        ast::BoolLiteral l(ProgramID(), Source{}, false);
+        ast::BoolLiteralExpression l(ProgramID(), Source{}, false);
         init_id = GenerateLiteralIfNeeded(var, &l);
       } else {
         error_ = "invalid type for pipeline constant ID, must be scalar";
@@ -928,7 +928,7 @@
   auto extract_id = extract.to_i();
 
   // If the index is a literal, we use OpCompositeExtract.
-  if (auto* literal = expr->index->As<ast::IntLiteral>()) {
+  if (auto* literal = expr->index->As<ast::IntLiteralExpression>()) {
     if (!push_function_inst(spv::Op::OpCompositeExtract,
                             {Operand::Int(result_type_id), extract,
                              Operand::Int(info->source_id),
@@ -1256,7 +1256,7 @@
 
 uint32_t Builder::GenerateConstructorExpression(const ast::Variable* var,
                                                 const ast::Expression* expr) {
-  if (auto* literal = expr->As<ast::Literal>()) {
+  if (auto* literal = expr->As<ast::LiteralExpression>()) {
     return GenerateLiteralIfNeeded(var, literal);
   }
   if (auto* type = expr->As<ast::TypeConstructorExpression>()) {
@@ -1269,7 +1269,7 @@
 
 bool Builder::is_constructor_const(const ast::Expression* expr,
                                    bool is_global_init) {
-  if (expr->Is<ast::Literal>()) {
+  if (expr->Is<ast::LiteralExpression>()) {
     return true;
   }
 
@@ -1281,7 +1281,7 @@
   for (size_t i = 0; i < tc->values.size(); ++i) {
     auto* e = tc->values[i];
 
-    if (!e->IsAnyOf<ast::TypeConstructorExpression, ast::Literal>()) {
+    if (!e->IsAnyOf<ast::TypeConstructorExpression, ast::LiteralExpression>()) {
       if (is_global_init) {
         error_ = "constructor must be a constant expression";
         return false;
@@ -1295,7 +1295,7 @@
       return false;
     }
 
-    auto* lit = e->As<ast::Literal>();
+    auto* lit = e->As<ast::LiteralExpression>();
     if (result_type->Is<sem::Vector>() && lit == nullptr) {
       return false;
     }
@@ -1610,18 +1610,18 @@
     uint32_t one_id;
     uint32_t zero_id;
     if (to_elem_type->Is<sem::F32>()) {
-      ast::FloatLiteral one(ProgramID(), Source{}, 1.0f);
-      ast::FloatLiteral zero(ProgramID(), Source{}, 0.0f);
+      ast::FloatLiteralExpression one(ProgramID(), Source{}, 1.0f);
+      ast::FloatLiteralExpression zero(ProgramID(), Source{}, 0.0f);
       one_id = GenerateLiteralIfNeeded(nullptr, &one);
       zero_id = GenerateLiteralIfNeeded(nullptr, &zero);
     } else if (to_elem_type->Is<sem::U32>()) {
-      ast::UintLiteral one(ProgramID(), Source{}, 1);
-      ast::UintLiteral zero(ProgramID(), Source{}, 0);
+      ast::UintLiteralExpression one(ProgramID(), Source{}, 1);
+      ast::UintLiteralExpression zero(ProgramID(), Source{}, 0);
       one_id = GenerateLiteralIfNeeded(nullptr, &one);
       zero_id = GenerateLiteralIfNeeded(nullptr, &zero);
     } else if (to_elem_type->Is<sem::I32>()) {
-      ast::SintLiteral one(ProgramID(), Source{}, 1);
-      ast::SintLiteral zero(ProgramID(), Source{}, 0);
+      ast::SintLiteralExpression one(ProgramID(), Source{}, 1);
+      ast::SintLiteralExpression zero(ProgramID(), Source{}, 0);
       one_id = GenerateLiteralIfNeeded(nullptr, &one);
       zero_id = GenerateLiteralIfNeeded(nullptr, &zero);
     } else {
@@ -1665,7 +1665,7 @@
 }
 
 uint32_t Builder::GenerateLiteralIfNeeded(const ast::Variable* var,
-                                          const ast::Literal* lit) {
+                                          const ast::LiteralExpression* lit) {
   ScalarConstant constant;
 
   auto* global = builder_.Sem().Get<sem::GlobalVariable>(var);
@@ -1674,16 +1674,16 @@
     constant.constant_id = global->ConstantId();
   }
 
-  if (auto* l = lit->As<ast::BoolLiteral>()) {
+  if (auto* l = lit->As<ast::BoolLiteralExpression>()) {
     constant.kind = ScalarConstant::Kind::kBool;
     constant.value.b = l->value;
-  } else if (auto* sl = lit->As<ast::SintLiteral>()) {
+  } else if (auto* sl = lit->As<ast::SintLiteralExpression>()) {
     constant.kind = ScalarConstant::Kind::kI32;
     constant.value.i32 = sl->value;
-  } else if (auto* ul = lit->As<ast::UintLiteral>()) {
+  } else if (auto* ul = lit->As<ast::UintLiteralExpression>()) {
     constant.kind = ScalarConstant::Kind::kU32;
     constant.value.u32 = ul->value;
-  } else if (auto* fl = lit->As<ast::FloatLiteral>()) {
+  } else if (auto* fl = lit->As<ast::FloatLiteralExpression>()) {
     constant.kind = ScalarConstant::Kind::kF32;
     constant.value.f32 = fl->value;
   } else {
@@ -2920,7 +2920,7 @@
         op = spv::Op::OpImageQuerySizeLod;
         spirv_params.emplace_back(gen(level));
       } else {
-        ast::SintLiteral i32_0(ProgramID(), Source{}, 0);
+        ast::SintLiteralExpression i32_0(ProgramID(), Source{}, 0);
         op = spv::Op::OpImageQuerySizeLod;
         spirv_params.emplace_back(
             Operand::Int(GenerateLiteralIfNeeded(nullptr, &i32_0)));
@@ -2952,7 +2952,7 @@
           texture_type->Is<sem::StorageTexture>()) {
         op = spv::Op::OpImageQuerySize;
       } else {
-        ast::SintLiteral i32_0(ProgramID(), Source{}, 0);
+        ast::SintLiteralExpression i32_0(ProgramID(), Source{}, 0);
         op = spv::Op::OpImageQuerySizeLod;
         spirv_params.emplace_back(
             Operand::Int(GenerateLiteralIfNeeded(nullptr, &i32_0)));
@@ -3074,7 +3074,7 @@
       }
       spirv_params.emplace_back(gen_arg(Usage::kDepthRef));
 
-      ast::FloatLiteral float_0(ProgramID(), Source{}, 0.0);
+      ast::FloatLiteralExpression float_0(ProgramID(), Source{}, 0.0);
       image_operands.emplace_back(ImageOperand{
           SpvImageOperandsLodMask,
           Operand::Int(GenerateLiteralIfNeeded(nullptr, &float_0))});
@@ -3625,7 +3625,7 @@
 
     case_ids.push_back(block_id);
     for (auto* selector : item->selectors) {
-      auto* int_literal = selector->As<ast::IntLiteral>();
+      auto* int_literal = selector->As<ast::IntLiteralExpression>();
       if (!int_literal) {
         error_ = "expected integer literal for switch case label";
         return false;
diff --git a/src/writer/spirv/builder.h b/src/writer/spirv/builder.h
index c07ca5f..66e4f4a 100644
--- a/src/writer/spirv/builder.h
+++ b/src/writer/spirv/builder.h
@@ -353,7 +353,7 @@
   /// @param lit the literal to generate
   /// @returns the ID on success or 0 on failure
   uint32_t GenerateLiteralIfNeeded(const ast::Variable* var,
-                                   const ast::Literal* lit);
+                                   const ast::LiteralExpression* lit);
   /// Generates a binary expression
   /// @param expr the expression to generate
   /// @returns the expression ID on success or 0 otherwise
diff --git a/src/writer/spirv/builder_literal_test.cc b/src/writer/spirv/builder_literal_test.cc
index d93e34a..ee72713 100644
--- a/src/writer/spirv/builder_literal_test.cc
+++ b/src/writer/spirv/builder_literal_test.cc
@@ -22,7 +22,7 @@
 using BuilderTest = TestHelper;
 
 TEST_F(BuilderTest, Literal_Bool_True) {
-  auto* b_true = create<ast::BoolLiteral>(true);
+  auto* b_true = create<ast::BoolLiteralExpression>(true);
   WrapInFunction(b_true);
 
   spirv::Builder& b = Build();
@@ -37,7 +37,7 @@
 }
 
 TEST_F(BuilderTest, Literal_Bool_False) {
-  auto* b_false = create<ast::BoolLiteral>(false);
+  auto* b_false = create<ast::BoolLiteralExpression>(false);
   WrapInFunction(b_false);
 
   spirv::Builder& b = Build();
@@ -52,8 +52,8 @@
 }
 
 TEST_F(BuilderTest, Literal_Bool_Dedup) {
-  auto* b_true = create<ast::BoolLiteral>(true);
-  auto* b_false = create<ast::BoolLiteral>(false);
+  auto* b_true = create<ast::BoolLiteralExpression>(true);
+  auto* b_false = create<ast::BoolLiteralExpression>(false);
   WrapInFunction(b_true, b_false);
 
   spirv::Builder& b = Build();
@@ -72,7 +72,7 @@
 }
 
 TEST_F(BuilderTest, Literal_I32) {
-  auto* i = create<ast::SintLiteral>(-23);
+  auto* i = create<ast::SintLiteralExpression>(-23);
   WrapInFunction(i);
   spirv::Builder& b = Build();
 
@@ -86,8 +86,8 @@
 }
 
 TEST_F(BuilderTest, Literal_I32_Dedup) {
-  auto* i1 = create<ast::SintLiteral>(-23);
-  auto* i2 = create<ast::SintLiteral>(-23);
+  auto* i1 = create<ast::SintLiteralExpression>(-23);
+  auto* i2 = create<ast::SintLiteralExpression>(-23);
   WrapInFunction(i1, i2);
 
   spirv::Builder& b = Build();
@@ -102,7 +102,7 @@
 }
 
 TEST_F(BuilderTest, Literal_U32) {
-  auto* i = create<ast::UintLiteral>(23);
+  auto* i = create<ast::UintLiteralExpression>(23);
   WrapInFunction(i);
 
   spirv::Builder& b = Build();
@@ -117,8 +117,8 @@
 }
 
 TEST_F(BuilderTest, Literal_U32_Dedup) {
-  auto* i1 = create<ast::UintLiteral>(23);
-  auto* i2 = create<ast::UintLiteral>(23);
+  auto* i1 = create<ast::UintLiteralExpression>(23);
+  auto* i2 = create<ast::UintLiteralExpression>(23);
   WrapInFunction(i1, i2);
 
   spirv::Builder& b = Build();
@@ -133,7 +133,7 @@
 }
 
 TEST_F(BuilderTest, Literal_F32) {
-  auto* i = create<ast::FloatLiteral>(23.245f);
+  auto* i = create<ast::FloatLiteralExpression>(23.245f);
   WrapInFunction(i);
 
   spirv::Builder& b = Build();
@@ -148,8 +148,8 @@
 }
 
 TEST_F(BuilderTest, Literal_F32_Dedup) {
-  auto* i1 = create<ast::FloatLiteral>(23.245f);
-  auto* i2 = create<ast::FloatLiteral>(23.245f);
+  auto* i1 = create<ast::FloatLiteralExpression>(23.245f);
+  auto* i2 = create<ast::FloatLiteralExpression>(23.245f);
   WrapInFunction(i1, i2);
 
   spirv::Builder& b = Build();
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index 4a316c9..b1fe63b 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -131,7 +131,7 @@
   if (auto* i = expr->As<ast::IdentifierExpression>()) {
     return EmitIdentifier(out, i);
   }
-  if (auto* l = expr->As<ast::Literal>()) {
+  if (auto* l = expr->As<ast::LiteralExpression>()) {
     return EmitLiteral(out, l);
   }
   if (auto* c = expr->As<ast::TypeConstructorExpression>()) {
@@ -268,14 +268,15 @@
   return true;
 }
 
-bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::Literal* lit) {
-  if (auto* bl = lit->As<ast::BoolLiteral>()) {
+bool GeneratorImpl::EmitLiteral(std::ostream& out,
+                                const ast::LiteralExpression* lit) {
+  if (auto* bl = lit->As<ast::BoolLiteralExpression>()) {
     out << (bl->value ? "true" : "false");
-  } else if (auto* fl = lit->As<ast::FloatLiteral>()) {
+  } else if (auto* fl = lit->As<ast::FloatLiteralExpression>()) {
     out << FloatToBitPreservingString(fl->value);
-  } else if (auto* sl = lit->As<ast::SintLiteral>()) {
+  } else if (auto* sl = lit->As<ast::SintLiteralExpression>()) {
     out << sl->value;
-  } else if (auto* ul = lit->As<ast::UintLiteral>()) {
+  } else if (auto* ul = lit->As<ast::UintLiteralExpression>()) {
     out << ul->value << "u";
   } else {
     diagnostics_.add_error(diag::System::Writer, "unknown literal type");
diff --git a/src/writer/wgsl/generator_impl.h b/src/writer/wgsl/generator_impl.h
index e1a060c..7f4a68c 100644
--- a/src/writer/wgsl/generator_impl.h
+++ b/src/writer/wgsl/generator_impl.h
@@ -99,7 +99,7 @@
   /// @param out the output of the expression stream
   /// @param expr the literal expression expression
   /// @returns true if the literal expression is emitted
-  bool EmitLiteral(std::ostream& out, const ast::Literal* expr);
+  bool EmitLiteral(std::ostream& out, const ast::LiteralExpression* expr);
   /// Handles a continue statement
   /// @param stmt the statement to emit
   /// @returns true if the statement was emitted successfully