Make IntLiteral store and return a u32 value

With this change, the base IntLiteral class now stores a u32, and
derived UintLiteral and SintLiteral are implemented in terms of it. This
will allow us to improve the current pattern of casting down to each
derived type to retrieve the value.

Change-Id: I0c1e56c5e04333a0d3d5f30a3fb28e784f785843
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/42900
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/ast/int_literal.cc b/src/ast/int_literal.cc
index e48801e..ba0b978 100644
--- a/src/ast/int_literal.cc
+++ b/src/ast/int_literal.cc
@@ -19,8 +19,8 @@
 namespace tint {
 namespace ast {
 
-IntLiteral::IntLiteral(const Source& source, type::Type* type)
-    : Base(source, type) {}
+IntLiteral::IntLiteral(const Source& source, type::Type* type, uint32_t value)
+    : Base(source, type), value_(value) {}
 
 IntLiteral::~IntLiteral() = default;
 
diff --git a/src/ast/int_literal.h b/src/ast/int_literal.h
index f522c1e..c8f0d7d 100644
--- a/src/ast/int_literal.h
+++ b/src/ast/int_literal.h
@@ -25,12 +25,19 @@
  public:
   ~IntLiteral() override;
 
+  /// @returns the literal value as a u32
+  uint32_t value_as_u32() const { return value_; }
+
  protected:
   /// Constructor
   /// @param source the input source
   /// @param type the type of the literal
-  IntLiteral(const Source& source, type::Type* type);
-};
+  /// @param value value of the literal
+  IntLiteral(const Source& source, type::Type* type, uint32_t value);
+
+ private:
+  uint32_t const value_;
+};  // namespace ast
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/sint_literal.cc b/src/ast/sint_literal.cc
index be82a94..7a7eaef 100644
--- a/src/ast/sint_literal.cc
+++ b/src/ast/sint_literal.cc
@@ -23,23 +23,23 @@
 namespace ast {
 
 SintLiteral::SintLiteral(const Source& source, type::Type* type, int32_t value)
-    : Base(source, type), value_(value) {}
+    : Base(source, type, static_cast<uint32_t>(value)) {}
 
 SintLiteral::~SintLiteral() = default;
 
 std::string SintLiteral::to_str(const semantic::Info&) const {
-  return std::to_string(value_);
+  return std::to_string(value());
 }
 
 std::string SintLiteral::name() const {
-  return "__sint" + type()->type_name() + "_" + std::to_string(value_);
+  return "__sint" + type()->type_name() + "_" + std::to_string(value());
 }
 
 SintLiteral* SintLiteral::Clone(CloneContext* ctx) const {
   // Clone arguments outside of create() call to have deterministic ordering
   auto src = ctx->Clone(source());
   auto* ty = ctx->Clone(type());
-  return ctx->dst->create<SintLiteral>(src, ty, value_);
+  return ctx->dst->create<SintLiteral>(src, ty, value());
 }
 
 }  // namespace ast
diff --git a/src/ast/sint_literal.h b/src/ast/sint_literal.h
index 366c08f..08b87de 100644
--- a/src/ast/sint_literal.h
+++ b/src/ast/sint_literal.h
@@ -33,7 +33,7 @@
   ~SintLiteral() override;
 
   /// @returns the int literal value
-  int32_t value() const { return value_; }
+  int32_t value() const { return static_cast<int32_t>(value_as_u32()); }
 
   /// @returns the name for this literal. This name is unique to this value.
   std::string name() const override;
@@ -47,9 +47,6 @@
   /// @param ctx the clone context
   /// @return the newly cloned node
   SintLiteral* Clone(CloneContext* ctx) const override;
-
- private:
-  int32_t const value_;
 };
 
 }  // namespace ast
diff --git a/src/ast/uint_literal.cc b/src/ast/uint_literal.cc
index d46602b..aaaf341 100644
--- a/src/ast/uint_literal.cc
+++ b/src/ast/uint_literal.cc
@@ -23,23 +23,23 @@
 namespace ast {
 
 UintLiteral::UintLiteral(const Source& source, type::Type* type, uint32_t value)
-    : Base(source, type), value_(value) {}
+    : Base(source, type, value) {}
 
 UintLiteral::~UintLiteral() = default;
 
 std::string UintLiteral::to_str(const semantic::Info&) const {
-  return std::to_string(value_);
+  return std::to_string(value());
 }
 
 std::string UintLiteral::name() const {
-  return "__uint" + std::to_string(value_);
+  return "__uint" + std::to_string(value());
 }
 
 UintLiteral* UintLiteral::Clone(CloneContext* ctx) const {
   // Clone arguments outside of create() call to have deterministic ordering
   auto src = ctx->Clone(source());
   auto* ty = ctx->Clone(type());
-  return ctx->dst->create<UintLiteral>(src, ty, value_);
+  return ctx->dst->create<UintLiteral>(src, ty, value());
 }
 
 }  // namespace ast
diff --git a/src/ast/uint_literal.h b/src/ast/uint_literal.h
index bb69f86..5862b13 100644
--- a/src/ast/uint_literal.h
+++ b/src/ast/uint_literal.h
@@ -33,7 +33,7 @@
   ~UintLiteral() override;
 
   /// @returns the uint literal value
-  uint32_t value() const { return value_; }
+  uint32_t value() const { return value_as_u32(); }
 
   /// @returns the name for this literal. This name is unique to this value.
   std::string name() const override;
@@ -47,9 +47,6 @@
   /// @param ctx the clone context
   /// @return the newly cloned node
   UintLiteral* Clone(CloneContext* ctx) const override;
-
- private:
-  uint32_t const value_;
 };
 
 }  // namespace ast