Revert "[ast] Remove unused constructors and setters."

This reverts commit 4d28b2793512069dc23f88b2804f3594dbd80d45.

Reason for revert: Seeing weird build breakage ...

Original change's description:
> [ast] Remove unused constructors and setters.
>
> This CL removes unused default constructors and various set methods
> from the AST classes where they are not longer required.
>
> Change-Id: Ic437911c62d8c9e4354a1fa6bdc8483ce7511daf
> Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/34641
> Auto-Submit: dan sinclair <dsinclair@chromium.org>
> Reviewed-by: Ben Clayton <bclayton@google.com>
> Commit-Queue: dan sinclair <dsinclair@chromium.org>

TBR=dsinclair@chromium.org,bclayton@google.com

Change-Id: I9d5bf6fd6d47131650c964cad4e17a1cbe86b040
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/34682
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/array_accessor_expression.cc b/src/ast/array_accessor_expression.cc
index 79d5075..75f3bf5 100644
--- a/src/ast/array_accessor_expression.cc
+++ b/src/ast/array_accessor_expression.cc
@@ -20,6 +20,8 @@
 namespace tint {
 namespace ast {
 
+ArrayAccessorExpression::ArrayAccessorExpression() : Base() {}
+
 ArrayAccessorExpression::ArrayAccessorExpression(Expression* array,
                                                  Expression* idx_expr)
     : Base(), array_(array), idx_expr_(idx_expr) {}
diff --git a/src/ast/array_accessor_expression.h b/src/ast/array_accessor_expression.h
index 73cbdac..9cc98f7 100644
--- a/src/ast/array_accessor_expression.h
+++ b/src/ast/array_accessor_expression.h
@@ -29,6 +29,8 @@
     : public Castable<ArrayAccessorExpression, Expression> {
  public:
   /// Constructor
+  ArrayAccessorExpression();
+  /// Constructor
   /// @param array the array
   /// @param idx_expr the index expression
   ArrayAccessorExpression(Expression* array, Expression* idx_expr);
@@ -43,6 +45,9 @@
   ArrayAccessorExpression(ArrayAccessorExpression&&);
   ~ArrayAccessorExpression() override;
 
+  /// Sets the array
+  /// @param array the array
+  void set_array(Expression* array) { array_ = array; }
   /// @returns the array
   Expression* array() const { return array_; }
 
diff --git a/src/ast/array_accessor_expression_test.cc b/src/ast/array_accessor_expression_test.cc
index 9526284..f657815 100644
--- a/src/ast/array_accessor_expression_test.cc
+++ b/src/ast/array_accessor_expression_test.cc
@@ -43,10 +43,7 @@
 }
 
 TEST_F(ArrayAccessorExpressionTest, IsArrayAccessor) {
-  auto* ary = create<IdentifierExpression>("ary");
-  auto* idx = create<IdentifierExpression>("idx");
-
-  ArrayAccessorExpression exp(ary, idx);
+  ArrayAccessorExpression exp;
   EXPECT_TRUE(exp.Is<ArrayAccessorExpression>());
 }
 
@@ -61,14 +58,16 @@
 TEST_F(ArrayAccessorExpressionTest, IsValid_MissingArray) {
   auto* idx = create<IdentifierExpression>("idx");
 
-  ArrayAccessorExpression exp(nullptr, idx);
+  ArrayAccessorExpression exp;
+  exp.set_idx_expr(idx);
   EXPECT_FALSE(exp.IsValid());
 }
 
 TEST_F(ArrayAccessorExpressionTest, IsValid_MissingIndex) {
   auto* ary = create<IdentifierExpression>("ary");
 
-  ArrayAccessorExpression exp(ary, nullptr);
+  ArrayAccessorExpression exp;
+  exp.set_array(ary);
   EXPECT_FALSE(exp.IsValid());
 }
 
diff --git a/src/ast/assignment_statement.cc b/src/ast/assignment_statement.cc
index 69f82f5..fe72839 100644
--- a/src/ast/assignment_statement.cc
+++ b/src/ast/assignment_statement.cc
@@ -20,6 +20,8 @@
 namespace tint {
 namespace ast {
 
+AssignmentStatement::AssignmentStatement() : Base() {}
+
 AssignmentStatement::AssignmentStatement(Expression* lhs, Expression* rhs)
     : Base(), lhs_(lhs), rhs_(rhs) {}
 
diff --git a/src/ast/assignment_statement.h b/src/ast/assignment_statement.h
index 558ae42..2b61bd8 100644
--- a/src/ast/assignment_statement.h
+++ b/src/ast/assignment_statement.h
@@ -29,6 +29,8 @@
 class AssignmentStatement : public Castable<AssignmentStatement, Statement> {
  public:
   /// Constructor
+  AssignmentStatement();
+  /// Constructor
   /// @param lhs the left side of the expression
   /// @param rhs the right side of the expression
   AssignmentStatement(Expression* lhs, Expression* rhs);
@@ -41,8 +43,15 @@
   AssignmentStatement(AssignmentStatement&&);
   ~AssignmentStatement() override;
 
+  /// Sets the left side of the statement
+  /// @param lhs the left side to set
+  void set_lhs(Expression* lhs) { lhs_ = lhs; }
   /// @returns the left side expression
   Expression* lhs() const { return lhs_; }
+
+  /// Sets the right side of the statement
+  /// @param rhs the right side to set
+  void set_rhs(Expression* rhs) { rhs_ = rhs; }
   /// @returns the right side expression
   Expression* rhs() const { return rhs_; }
 
diff --git a/src/ast/assignment_statement_test.cc b/src/ast/assignment_statement_test.cc
index 8fa68a4..b804363 100644
--- a/src/ast/assignment_statement_test.cc
+++ b/src/ast/assignment_statement_test.cc
@@ -61,14 +61,16 @@
 TEST_F(AssignmentStatementTest, IsValid_MissingLHS) {
   auto* rhs = create<IdentifierExpression>("rhs");
 
-  AssignmentStatement stmt(nullptr, rhs);
+  AssignmentStatement stmt;
+  stmt.set_rhs(rhs);
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(AssignmentStatementTest, IsValid_MissingRHS) {
   auto* lhs = create<IdentifierExpression>("lhs");
 
-  AssignmentStatement stmt(lhs, nullptr);
+  AssignmentStatement stmt;
+  stmt.set_lhs(lhs);
   EXPECT_FALSE(stmt.IsValid());
 }
 
diff --git a/src/ast/binary_expression.cc b/src/ast/binary_expression.cc
index f7ce959..e6f3555 100644
--- a/src/ast/binary_expression.cc
+++ b/src/ast/binary_expression.cc
@@ -20,6 +20,8 @@
 namespace tint {
 namespace ast {
 
+BinaryExpression::BinaryExpression() : Base() {}
+
 BinaryExpression::BinaryExpression(BinaryOp op,
                                    Expression* lhs,
                                    Expression* rhs)
diff --git a/src/ast/binary_expression.h b/src/ast/binary_expression.h
index d042e6d..783954f 100644
--- a/src/ast/binary_expression.h
+++ b/src/ast/binary_expression.h
@@ -51,6 +51,8 @@
 class BinaryExpression : public Castable<BinaryExpression, Expression> {
  public:
   /// Constructor
+  BinaryExpression();
+  /// Constructor
   /// @param op the operation type
   /// @param lhs the left side of the expression
   /// @param rhs the right side of the expression
@@ -68,6 +70,9 @@
   BinaryExpression(BinaryExpression&&);
   ~BinaryExpression() override;
 
+  /// Sets the binary op type
+  /// @param op the binary op type
+  void set_op(BinaryOp op) { op_ = op; }
   /// @returns the binary op type
   BinaryOp op() const { return op_; }
 
@@ -108,8 +113,15 @@
   /// @returns true if the op is modulo
   bool IsModulo() const { return op_ == BinaryOp::kModulo; }
 
+  /// Sets the left side of the expression
+  /// @param lhs the left side to set
+  void set_lhs(Expression* lhs) { lhs_ = lhs; }
   /// @returns the left side expression
   Expression* lhs() const { return lhs_; }
+
+  /// Sets the right side of the expression
+  /// @param rhs the right side to set
+  void set_rhs(Expression* rhs) { rhs_ = rhs; }
   /// @returns the right side expression
   Expression* rhs() const { return rhs_; }
 
diff --git a/src/ast/binary_expression_test.cc b/src/ast/binary_expression_test.cc
index 6494a78..2242b24 100644
--- a/src/ast/binary_expression_test.cc
+++ b/src/ast/binary_expression_test.cc
@@ -46,11 +46,8 @@
   EXPECT_EQ(src.range.begin.column, 2u);
 }
 
-TEST_F(BinaryExpressionTest, IsBinary) {
-  auto* lhs = create<IdentifierExpression>("lhs");
-  auto* rhs = create<IdentifierExpression>("rhs");
-
-  BinaryExpression r(BinaryOp::kEqual, lhs, rhs);
+TEST_F(BinaryExpressionTest, IsBinaryal) {
+  BinaryExpression r;
   EXPECT_TRUE(r.Is<BinaryExpression>());
 }
 
@@ -65,7 +62,9 @@
 TEST_F(BinaryExpressionTest, IsValid_Null_LHS) {
   auto* rhs = create<IdentifierExpression>("rhs");
 
-  BinaryExpression r(BinaryOp::kEqual, nullptr, rhs);
+  BinaryExpression r;
+  r.set_op(BinaryOp::kEqual);
+  r.set_rhs(rhs);
   EXPECT_FALSE(r.IsValid());
 }
 
@@ -80,7 +79,9 @@
 TEST_F(BinaryExpressionTest, IsValid_Null_RHS) {
   auto* lhs = create<IdentifierExpression>("lhs");
 
-  BinaryExpression r(BinaryOp::kEqual, lhs, nullptr);
+  BinaryExpression r;
+  r.set_op(BinaryOp::kEqual);
+  r.set_lhs(lhs);
   EXPECT_FALSE(r.IsValid());
 }
 
diff --git a/src/ast/bitcast_expression.cc b/src/ast/bitcast_expression.cc
index 8b7fb21..8d30b6a 100644
--- a/src/ast/bitcast_expression.cc
+++ b/src/ast/bitcast_expression.cc
@@ -20,6 +20,8 @@
 namespace tint {
 namespace ast {
 
+BitcastExpression::BitcastExpression() : Base() {}
+
 BitcastExpression::BitcastExpression(type::Type* type, Expression* expr)
     : Base(), type_(type), expr_(expr) {}
 
diff --git a/src/ast/bitcast_expression.h b/src/ast/bitcast_expression.h
index b846b73..f736071 100644
--- a/src/ast/bitcast_expression.h
+++ b/src/ast/bitcast_expression.h
@@ -29,6 +29,8 @@
 class BitcastExpression : public Castable<BitcastExpression, Expression> {
  public:
   /// Constructor
+  BitcastExpression();
+  /// Constructor
   /// @param type the type
   /// @param expr the expr
   BitcastExpression(type::Type* type, Expression* expr);
@@ -41,8 +43,15 @@
   BitcastExpression(BitcastExpression&&);
   ~BitcastExpression() override;
 
+  /// Sets the type
+  /// @param type the type
+  void set_type(type::Type* type) { type_ = type; }
   /// @returns the left side expression
   type::Type* type() const { return type_; }
+
+  /// Sets the expr
+  /// @param expr the expression
+  void set_expr(Expression* expr) { expr_ = expr; }
   /// @returns the expression
   Expression* expr() const { return expr_; }
 
diff --git a/src/ast/bitcast_expression_test.cc b/src/ast/bitcast_expression_test.cc
index 1c8afc1..51d48c9 100644
--- a/src/ast/bitcast_expression_test.cc
+++ b/src/ast/bitcast_expression_test.cc
@@ -44,10 +44,7 @@
 }
 
 TEST_F(BitcastExpressionTest, IsBitcast) {
-  type::F32 f32;
-  auto* expr = create<IdentifierExpression>("expr");
-
-  BitcastExpression exp(&f32, expr);
+  BitcastExpression exp;
   EXPECT_TRUE(exp.Is<BitcastExpression>());
 }
 
@@ -62,14 +59,16 @@
 TEST_F(BitcastExpressionTest, IsValid_MissingType) {
   auto* expr = create<IdentifierExpression>("expr");
 
-  BitcastExpression exp(nullptr, expr);
+  BitcastExpression exp;
+  exp.set_expr(expr);
   EXPECT_FALSE(exp.IsValid());
 }
 
 TEST_F(BitcastExpressionTest, IsValid_MissingExpr) {
   type::F32 f32;
 
-  BitcastExpression exp(&f32, nullptr);
+  BitcastExpression exp;
+  exp.set_type(&f32);
   EXPECT_FALSE(exp.IsValid());
 }
 
diff --git a/src/ast/call_expression.cc b/src/ast/call_expression.cc
index 6839f6c..fdee36e 100644
--- a/src/ast/call_expression.cc
+++ b/src/ast/call_expression.cc
@@ -20,6 +20,8 @@
 namespace tint {
 namespace ast {
 
+CallExpression::CallExpression() : Base() {}
+
 CallExpression::CallExpression(Expression* func, ExpressionList params)
     : Base(), func_(func), params_(params) {}
 
diff --git a/src/ast/call_expression.h b/src/ast/call_expression.h
index faa8dcb..3c12822 100644
--- a/src/ast/call_expression.h
+++ b/src/ast/call_expression.h
@@ -28,6 +28,8 @@
 class CallExpression : public Castable<CallExpression, Expression> {
  public:
   /// Constructor
+  CallExpression();
+  /// Constructor
   /// @param func the function
   /// @param params the parameters
   CallExpression(Expression* func, ExpressionList params);
@@ -40,8 +42,15 @@
   CallExpression(CallExpression&&);
   ~CallExpression() override;
 
+  /// Sets the func
+  /// @param func the func
+  void set_func(Expression* func) { func_ = func; }
   /// @returns the func
   Expression* func() const { return func_; }
+
+  /// Sets the parameters
+  /// @param params the parameters
+  void set_params(ExpressionList params) { params_ = params; }
   /// @returns the parameters
   const ExpressionList& params() const { return params_; }
 
diff --git a/src/ast/call_expression_test.cc b/src/ast/call_expression_test.cc
index be84072..0d30953 100644
--- a/src/ast/call_expression_test.cc
+++ b/src/ast/call_expression_test.cc
@@ -59,7 +59,7 @@
 }
 
 TEST_F(CallExpressionTest, IsValid_MissingFunction) {
-  CallExpression stmt(nullptr, {});
+  CallExpression stmt;
   EXPECT_FALSE(stmt.IsValid());
 }
 
diff --git a/src/ast/call_statement.cc b/src/ast/call_statement.cc
index b02d521..9158fbb 100644
--- a/src/ast/call_statement.cc
+++ b/src/ast/call_statement.cc
@@ -21,6 +21,8 @@
 namespace tint {
 namespace ast {
 
+CallStatement::CallStatement() : Base() {}
+
 CallStatement::CallStatement(CallExpression* call) : Base(), call_(call) {}
 
 CallStatement::CallStatement(CallStatement&&) = default;
diff --git a/src/ast/call_statement.h b/src/ast/call_statement.h
index 2af7582..026e61f 100644
--- a/src/ast/call_statement.h
+++ b/src/ast/call_statement.h
@@ -28,12 +28,17 @@
 class CallStatement : public Castable<CallStatement, Statement> {
  public:
   /// Constructor
+  CallStatement();
+  /// Constructor
   /// @param call the function
   explicit CallStatement(CallExpression* call);
   /// Move constructor
   CallStatement(CallStatement&&);
   ~CallStatement() override;
 
+  /// Sets the call expression
+  /// @param call the call
+  void set_expr(CallExpression* call) { call_ = call; }
   /// @returns the call expression
   CallExpression* expr() const { return call_; }
 
diff --git a/src/ast/call_statement_test.cc b/src/ast/call_statement_test.cc
index 8a0e7b5..4a6a5fe 100644
--- a/src/ast/call_statement_test.cc
+++ b/src/ast/call_statement_test.cc
@@ -33,7 +33,7 @@
 }
 
 TEST_F(CallStatementTest, IsCall) {
-  CallStatement c(nullptr);
+  CallStatement c;
   EXPECT_TRUE(c.Is<CallStatement>());
 }
 
@@ -44,13 +44,12 @@
 }
 
 TEST_F(CallStatementTest, IsValid_MissingExpr) {
-  CallStatement c(nullptr);
+  CallStatement c;
   EXPECT_FALSE(c.IsValid());
 }
 
 TEST_F(CallStatementTest, IsValid_InvalidExpr) {
-  CallExpression stmt(nullptr, {});
-  CallStatement c(&stmt);
+  CallStatement c(create<CallExpression>());
   EXPECT_FALSE(c.IsValid());
 }
 
diff --git a/src/ast/case_statement.h b/src/ast/case_statement.h
index cea4327..9ed2deb 100644
--- a/src/ast/case_statement.h
+++ b/src/ast/case_statement.h
@@ -52,6 +52,11 @@
   CaseStatement(CaseStatement&&);
   ~CaseStatement() override;
 
+  /// Sets the selectors for the case statement
+  /// @param selectors the selectors to set
+  void set_selectors(CaseSelectorList selectors) {
+    selectors_ = std::move(selectors);
+  }
   /// @returns the case selectors, empty if none set
   const CaseSelectorList& selectors() const { return selectors_; }
   /// @returns true if this is a default statement
diff --git a/src/ast/case_statement_test.cc b/src/ast/case_statement_test.cc
index ba62191..5600173 100644
--- a/src/ast/case_statement_test.cc
+++ b/src/ast/case_statement_test.cc
@@ -82,7 +82,8 @@
   auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
-  CaseStatement c(body);
+  CaseStatement c(create<BlockStatement>());
+  c.set_body(body);
   EXPECT_TRUE(c.IsDefault());
 }
 
@@ -91,7 +92,8 @@
   CaseSelectorList b;
   b.push_back(create<SintLiteral>(&i32, 2));
 
-  CaseStatement c(b, create<BlockStatement>());
+  CaseStatement c(create<BlockStatement>());
+  c.set_selectors(b);
   EXPECT_FALSE(c.IsDefault());
 }
 
diff --git a/src/ast/decorated_variable.h b/src/ast/decorated_variable.h
index 8a0b12c..b78abbc 100644
--- a/src/ast/decorated_variable.h
+++ b/src/ast/decorated_variable.h
@@ -28,7 +28,6 @@
 class DecoratedVariable : public Castable<DecoratedVariable, Variable> {
  public:
   /// Create a new empty decorated variable statement
-  /// Note, used by the `Clone` method.
   DecoratedVariable();
   /// Create a decorated variable from an existing variable
   /// @param var the variable to initialize from
diff --git a/src/ast/decorated_variable_test.cc b/src/ast/decorated_variable_test.cc
index d31a7cf..63a4340 100644
--- a/src/ast/decorated_variable_test.cc
+++ b/src/ast/decorated_variable_test.cc
@@ -107,8 +107,7 @@
 }
 
 TEST_F(DecoratedVariableTest, IsDecorated) {
-  type::I32 t;
-  DecoratedVariable dv(create<Variable>("my_var", StorageClass::kNone, &t));
+  DecoratedVariable dv;
   EXPECT_TRUE(dv.Is<DecoratedVariable>());
 }
 
diff --git a/src/ast/else_statement.h b/src/ast/else_statement.h
index f39a1f0..01be9a8 100644
--- a/src/ast/else_statement.h
+++ b/src/ast/else_statement.h
@@ -51,11 +51,17 @@
   ElseStatement(ElseStatement&&);
   ~ElseStatement() override;
 
+  /// Sets the condition for the else statement
+  /// @param condition the condition to set
+  void set_condition(Expression* condition) { condition_ = condition; }
   /// @returns the else condition or nullptr if none set
   Expression* condition() const { return condition_; }
   /// @returns true if the else has a condition
   bool HasCondition() const { return condition_ != nullptr; }
 
+  /// Sets the else body
+  /// @param body the else body
+  void set_body(BlockStatement* body) { body_ = body; }
   /// @returns the else body
   const BlockStatement* body() const { return body_; }
   /// @returns the else body
diff --git a/src/ast/else_statement_test.cc b/src/ast/else_statement_test.cc
index 166d805..40ac0e0 100644
--- a/src/ast/else_statement_test.cc
+++ b/src/ast/else_statement_test.cc
@@ -90,7 +90,7 @@
 }
 
 TEST_F(ElseStatementTest, IsValid_InvalidCondition) {
-  auto* cond = create<ScalarConstructorExpression>(nullptr);
+  auto* cond = create<ScalarConstructorExpression>();
   ElseStatement e(cond, create<BlockStatement>());
   EXPECT_FALSE(e.IsValid());
 }
diff --git a/src/ast/function.cc b/src/ast/function.cc
index ea0bb62..5f53799 100644
--- a/src/ast/function.cc
+++ b/src/ast/function.cc
@@ -28,6 +28,8 @@
 namespace tint {
 namespace ast {
 
+Function::Function() = default;
+
 Function::Function(const std::string& name,
                    VariableList params,
                    type::Type* return_type,
diff --git a/src/ast/function.h b/src/ast/function.h
index 26f2125..a7afe1e 100644
--- a/src/ast/function.h
+++ b/src/ast/function.h
@@ -50,7 +50,8 @@
     SetDecoration* set = nullptr;
   };
 
-  /// Create a function
+  /// Create a new empty function statement
+  Function();  /// Create a function
   /// @param name the function name
   /// @param params the function parameters
   /// @param return_type the return type
@@ -75,8 +76,15 @@
 
   ~Function() override;
 
+  /// Sets the function name
+  /// @param name the name to set
+  void set_name(const std::string& name) { name_ = name; }
   /// @returns the function name
   const std::string& name() { return name_; }
+
+  /// Sets the function parameters
+  /// @param params the function parameters
+  void set_params(VariableList params) { params_ = std::move(params); }
   /// @returns the function params
   const VariableList& params() const { return params_; }
 
diff --git a/src/ast/if_statement_test.cc b/src/ast/if_statement_test.cc
index a87930a..45e99ba 100644
--- a/src/ast/if_statement_test.cc
+++ b/src/ast/if_statement_test.cc
@@ -67,8 +67,8 @@
   body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
-  else_stmts.push_back(create<ElseStatement>(
-      create<IdentifierExpression>("Ident"), create<BlockStatement>()));
+  else_stmts.push_back(create<ElseStatement>(create<BlockStatement>()));
+  else_stmts[0]->set_condition(create<IdentifierExpression>("Ident"));
   else_stmts.push_back(create<ElseStatement>(create<BlockStatement>()));
 
   IfStatement stmt(cond, body);
@@ -119,8 +119,8 @@
   body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
-  else_stmts.push_back(create<ElseStatement>(
-      create<IdentifierExpression>("Ident"), create<BlockStatement>()));
+  else_stmts.push_back(create<ElseStatement>(create<BlockStatement>()));
+  else_stmts[0]->set_condition(create<IdentifierExpression>("Ident"));
   else_stmts.push_back(create<ElseStatement>(create<BlockStatement>()));
   else_stmts.push_back(nullptr);
 
@@ -135,8 +135,8 @@
   body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
-  else_stmts.push_back(create<ElseStatement>(create<IdentifierExpression>(""),
-                                             create<BlockStatement>()));
+  else_stmts.push_back(create<ElseStatement>(create<BlockStatement>()));
+  else_stmts[0]->set_condition(create<IdentifierExpression>(""));
 
   IfStatement stmt(cond, body);
   stmt.set_else_statements(else_stmts);
@@ -164,8 +164,8 @@
 
   ElseStatementList else_stmts;
   else_stmts.push_back(create<ElseStatement>(create<BlockStatement>()));
-  else_stmts.push_back(create<ElseStatement>(
-      create<IdentifierExpression>("ident"), create<BlockStatement>()));
+  else_stmts.push_back(create<ElseStatement>(create<BlockStatement>()));
+  else_stmts[1]->set_condition(create<IdentifierExpression>("ident"));
 
   IfStatement stmt(cond, body);
   stmt.set_else_statements(else_stmts);
@@ -205,9 +205,11 @@
   else_body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
-  else_stmts.push_back(create<ElseStatement>(
-      create<IdentifierExpression>("ident"), else_if_body));
-  else_stmts.push_back(create<ElseStatement>(else_body));
+  else_stmts.push_back(create<ElseStatement>(create<BlockStatement>()));
+  else_stmts[0]->set_condition(create<IdentifierExpression>("ident"));
+  else_stmts[0]->set_body(else_if_body);
+  else_stmts.push_back(create<ElseStatement>(create<BlockStatement>()));
+  else_stmts[1]->set_body(else_body);
 
   IfStatement stmt(cond, body);
   stmt.set_else_statements(else_stmts);
diff --git a/src/ast/location_decoration.h b/src/ast/location_decoration.h
index dc641e4..560c3d6 100644
--- a/src/ast/location_decoration.h
+++ b/src/ast/location_decoration.h
@@ -29,7 +29,7 @@
   /// constructor
   /// @param value the location value
   /// @param source the source of this decoration
-  LocationDecoration(uint32_t value, const Source& source);
+  explicit LocationDecoration(uint32_t value, const Source& source);
   ~LocationDecoration() override;
 
   /// @returns the location value
diff --git a/src/ast/member_accessor_expression.cc b/src/ast/member_accessor_expression.cc
index 0345d35..8f81846 100644
--- a/src/ast/member_accessor_expression.cc
+++ b/src/ast/member_accessor_expression.cc
@@ -20,6 +20,8 @@
 namespace tint {
 namespace ast {
 
+MemberAccessorExpression::MemberAccessorExpression() = default;
+
 MemberAccessorExpression::MemberAccessorExpression(Expression* structure,
                                                    IdentifierExpression* member)
     : Base(), struct_(structure), member_(member) {}
diff --git a/src/ast/member_accessor_expression.h b/src/ast/member_accessor_expression.h
index 3b9b09a..4b4f859 100644
--- a/src/ast/member_accessor_expression.h
+++ b/src/ast/member_accessor_expression.h
@@ -31,6 +31,8 @@
     : public Castable<MemberAccessorExpression, Expression> {
  public:
   /// Constructor
+  MemberAccessorExpression();
+  /// Constructor
   /// @param structure the structure
   /// @param member the member
   MemberAccessorExpression(Expression* structure, IdentifierExpression* member);
@@ -45,8 +47,15 @@
   MemberAccessorExpression(MemberAccessorExpression&&);
   ~MemberAccessorExpression() override;
 
+  /// Sets the structure
+  /// @param structure the structure
+  void set_structure(Expression* structure) { struct_ = structure; }
   /// @returns the structure
   Expression* structure() const { return struct_; }
+
+  /// Sets the member
+  /// @param member the member
+  void set_member(IdentifierExpression* member) { member_ = member; }
   /// @returns the member expression
   IdentifierExpression* member() const { return member_; }
 
diff --git a/src/ast/member_accessor_expression_test.cc b/src/ast/member_accessor_expression_test.cc
index d307b80..331157f 100644
--- a/src/ast/member_accessor_expression_test.cc
+++ b/src/ast/member_accessor_expression_test.cc
@@ -45,10 +45,7 @@
 }
 
 TEST_F(MemberAccessorExpressionTest, IsMemberAccessor) {
-  auto* str = create<IdentifierExpression>("structure");
-  auto* mem = create<IdentifierExpression>("member");
-
-  MemberAccessorExpression stmt(str, mem);
+  MemberAccessorExpression stmt;
   EXPECT_TRUE(stmt.Is<MemberAccessorExpression>());
 }
 
@@ -63,7 +60,8 @@
 TEST_F(MemberAccessorExpressionTest, IsValid_NullStruct) {
   auto* mem = create<IdentifierExpression>("member");
 
-  MemberAccessorExpression stmt(nullptr, mem);
+  MemberAccessorExpression stmt;
+  stmt.set_member(mem);
   EXPECT_FALSE(stmt.IsValid());
 }
 
@@ -78,7 +76,8 @@
 TEST_F(MemberAccessorExpressionTest, IsValid_NullMember) {
   auto* str = create<IdentifierExpression>("structure");
 
-  MemberAccessorExpression stmt(str, nullptr);
+  MemberAccessorExpression stmt;
+  stmt.set_structure(str);
   EXPECT_FALSE(stmt.IsValid());
 }
 
diff --git a/src/ast/module_test.cc b/src/ast/module_test.cc
index a26b62b..0bdbf49 100644
--- a/src/ast/module_test.cc
+++ b/src/ast/module_test.cc
@@ -139,8 +139,7 @@
 }
 
 TEST_F(ModuleTest, IsValid_Invalid_Function) {
-  VariableList p;
-  auto* func = create<Function>("", p, nullptr, nullptr);
+  auto* func = create<Function>();
 
   Module m;
   m.AddFunction(func);
diff --git a/src/ast/scalar_constructor_expression.cc b/src/ast/scalar_constructor_expression.cc
index 90b83f7..7a68042 100644
--- a/src/ast/scalar_constructor_expression.cc
+++ b/src/ast/scalar_constructor_expression.cc
@@ -20,6 +20,8 @@
 namespace tint {
 namespace ast {
 
+ScalarConstructorExpression::ScalarConstructorExpression() : Base() {}
+
 ScalarConstructorExpression::ScalarConstructorExpression(Literal* literal)
     : literal_(literal) {}
 
diff --git a/src/ast/scalar_constructor_expression.h b/src/ast/scalar_constructor_expression.h
index 5a3fd65..05ce216 100644
--- a/src/ast/scalar_constructor_expression.h
+++ b/src/ast/scalar_constructor_expression.h
@@ -29,6 +29,8 @@
     : public Castable<ScalarConstructorExpression, ConstructorExpression> {
  public:
   /// Constructor
+  ScalarConstructorExpression();
+  /// Constructor
   /// @param literal the const literal
   explicit ScalarConstructorExpression(Literal* literal);
   /// Constructor
@@ -39,6 +41,9 @@
   ScalarConstructorExpression(ScalarConstructorExpression&&);
   ~ScalarConstructorExpression() override;
 
+  /// Set the literal value
+  /// @param literal the literal
+  void set_literal(Literal* literal) { literal_ = literal; }
   /// @returns the literal value
   Literal* literal() const { return literal_; }
 
diff --git a/src/ast/scalar_constructor_expression_test.cc b/src/ast/scalar_constructor_expression_test.cc
index 0168356..60e4185 100644
--- a/src/ast/scalar_constructor_expression_test.cc
+++ b/src/ast/scalar_constructor_expression_test.cc
@@ -48,7 +48,7 @@
 }
 
 TEST_F(ScalarConstructorExpressionTest, IsValid_MissingLiteral) {
-  ScalarConstructorExpression c(nullptr);
+  ScalarConstructorExpression c;
   EXPECT_FALSE(c.IsValid());
 }
 
diff --git a/src/ast/struct.cc b/src/ast/struct.cc
index 2db5e45..bb07647 100644
--- a/src/ast/struct.cc
+++ b/src/ast/struct.cc
@@ -21,6 +21,8 @@
 namespace tint {
 namespace ast {
 
+Struct::Struct() : Base() {}
+
 Struct::Struct(StructMemberList members)
     : Base(), members_(std::move(members)) {}
 
diff --git a/src/ast/struct.h b/src/ast/struct.h
index ab49a0f..0b37d28 100644
--- a/src/ast/struct.h
+++ b/src/ast/struct.h
@@ -29,6 +29,8 @@
 /// A struct statement.
 class Struct : public Castable<Struct, Node> {
  public:
+  /// Create a new empty struct statement
+  Struct();
   /// Create a new struct statement
   /// @param members The struct members
   explicit Struct(StructMemberList members);
diff --git a/src/ast/struct_member.cc b/src/ast/struct_member.cc
index 9cdb902..cefbede 100644
--- a/src/ast/struct_member.cc
+++ b/src/ast/struct_member.cc
@@ -21,6 +21,8 @@
 namespace tint {
 namespace ast {
 
+StructMember::StructMember() = default;
+
 StructMember::StructMember(const std::string& name,
                            type::Type* type,
                            StructMemberDecorationList decorations)
diff --git a/src/ast/struct_member.h b/src/ast/struct_member.h
index 4064767..a659e87 100644
--- a/src/ast/struct_member.h
+++ b/src/ast/struct_member.h
@@ -31,6 +31,8 @@
 /// A struct member statement.
 class StructMember : public Castable<StructMember, Node> {
  public:
+  /// Create a new empty struct member statement
+  StructMember();
   /// Create a new struct member statement
   /// @param name The struct member name
   /// @param type The struct member type
@@ -52,8 +54,14 @@
 
   ~StructMember() override;
 
+  /// Sets the name
+  /// @param name the name to set
+  void set_name(const std::string& name) { name_ = name; }
   /// @returns the name
   const std::string& name() const { return name_; }
+  /// Sets the type
+  /// @param type the type to set
+  void set_type(type::Type* type) { type_ = type; }
   /// @returns the type
   type::Type* type() const { return type_; }
   /// Sets the decorations
diff --git a/src/ast/struct_test.cc b/src/ast/struct_test.cc
index b615bc8..11e9bb8 100644
--- a/src/ast/struct_test.cc
+++ b/src/ast/struct_test.cc
@@ -87,7 +87,7 @@
 }
 
 TEST_F(StructTest, IsValid) {
-  Struct s({});
+  Struct s;
   EXPECT_TRUE(s.IsValid());
 }
 
diff --git a/src/ast/switch_statement.cc b/src/ast/switch_statement.cc
index 7ee3abc3..18140b6 100644
--- a/src/ast/switch_statement.cc
+++ b/src/ast/switch_statement.cc
@@ -21,6 +21,8 @@
 namespace tint {
 namespace ast {
 
+SwitchStatement::SwitchStatement() : Base() {}
+
 SwitchStatement::SwitchStatement(Expression* condition, CaseStatementList body)
     : condition_(condition), body_(body) {}
 
diff --git a/src/ast/switch_statement.h b/src/ast/switch_statement.h
index d44a45f..53c80ca 100644
--- a/src/ast/switch_statement.h
+++ b/src/ast/switch_statement.h
@@ -30,6 +30,8 @@
 class SwitchStatement : public Castable<SwitchStatement, Statement> {
  public:
   /// Constructor
+  SwitchStatement();
+  /// Constructor
   /// @param condition the switch condition
   /// @param body the switch body
   SwitchStatement(Expression* condition, CaseStatementList body);
@@ -44,6 +46,9 @@
   SwitchStatement(SwitchStatement&&);
   ~SwitchStatement() override;
 
+  /// Sets the condition for the switch statement
+  /// @param condition the condition to set
+  void set_condition(Expression* condition) { condition_ = condition; }
   /// @returns the switch condition or nullptr if none set
   Expression* condition() const { return condition_; }
   /// @returns true if this is a default statement
diff --git a/src/ast/switch_statement_test.cc b/src/ast/switch_statement_test.cc
index df82f3d..14d90e6 100644
--- a/src/ast/switch_statement_test.cc
+++ b/src/ast/switch_statement_test.cc
@@ -56,16 +56,7 @@
 }
 
 TEST_F(SwitchStatementTest, IsSwitch) {
-  type::I32 i32;
-
-  CaseSelectorList lit;
-  lit.push_back(create<SintLiteral>(&i32, 2));
-
-  auto* ident = create<IdentifierExpression>("ident");
-  CaseStatementList body;
-  body.push_back(create<CaseStatement>(lit, create<BlockStatement>()));
-
-  SwitchStatement stmt(ident, body);
+  SwitchStatement stmt;
   EXPECT_TRUE(stmt.Is<SwitchStatement>());
 }
 
@@ -92,7 +83,8 @@
   CaseStatementList body;
   body.push_back(create<CaseStatement>(lit, create<BlockStatement>()));
 
-  SwitchStatement stmt(nullptr, body);
+  SwitchStatement stmt;
+  stmt.set_body(body);
   EXPECT_FALSE(stmt.IsValid());
 }
 
diff --git a/src/ast/type/struct_type_test.cc b/src/ast/type/struct_type_test.cc
index 3dd11f1..1a915a2 100644
--- a/src/ast/type/struct_type_test.cc
+++ b/src/ast/type/struct_type_test.cc
@@ -40,16 +40,14 @@
 using StructTest = TestHelper;
 
 TEST_F(StructTest, Creation) {
-  StructMemberList members;
-  auto* impl = create<ast::Struct>(members);
+  auto* impl = create<ast::Struct>();
   auto* ptr = impl;
   Struct s{"S", impl};
   EXPECT_EQ(s.impl(), ptr);
 }
 
 TEST_F(StructTest, Is) {
-  StructMemberList members;
-  auto* impl = create<ast::Struct>(members);
+  auto* impl = create<ast::Struct>();
   Struct s{"S", impl};
   Type* ty = &s;
   EXPECT_FALSE(ty->Is<AccessControl>());
@@ -68,8 +66,7 @@
 }
 
 TEST_F(StructTest, TypeName) {
-  StructMemberList members;
-  auto* impl = create<ast::Struct>(members);
+  auto* impl = create<ast::Struct>();
   Struct s{"my_struct", impl};
   EXPECT_EQ(s.type_name(), "__struct_my_struct");
 }
diff --git a/src/ast/type_constructor_expression.cc b/src/ast/type_constructor_expression.cc
index 455912a..8717833 100644
--- a/src/ast/type_constructor_expression.cc
+++ b/src/ast/type_constructor_expression.cc
@@ -20,6 +20,8 @@
 namespace tint {
 namespace ast {
 
+TypeConstructorExpression::TypeConstructorExpression() : Base() {}
+
 TypeConstructorExpression::TypeConstructorExpression(type::Type* type,
                                                      ExpressionList values)
     : Base(), type_(type), values_(std::move(values)) {}
diff --git a/src/ast/type_constructor_expression.h b/src/ast/type_constructor_expression.h
index 7f239dc..12b0e97 100644
--- a/src/ast/type_constructor_expression.h
+++ b/src/ast/type_constructor_expression.h
@@ -28,10 +28,11 @@
 class TypeConstructorExpression
     : public Castable<TypeConstructorExpression, ConstructorExpression> {
  public:
+  TypeConstructorExpression();
   /// Constructor
   /// @param type the type
   /// @param values the values
-  TypeConstructorExpression(type::Type* type, ExpressionList values);
+  explicit TypeConstructorExpression(type::Type* type, ExpressionList values);
   /// Constructor
   /// @param source the constructor source
   /// @param type the type
@@ -43,8 +44,15 @@
   TypeConstructorExpression(TypeConstructorExpression&&);
   ~TypeConstructorExpression() override;
 
+  /// Set the type
+  /// @param type the type
+  void set_type(type::Type* type) { type_ = type; }
   /// @returns the type
   type::Type* type() const { return type_; }
+
+  /// Set the values
+  /// @param values the values
+  void set_values(ExpressionList values) { values_ = std::move(values); }
   /// @returns the values
   const ExpressionList& values() const { return values_; }
 
diff --git a/src/ast/type_constructor_expression_test.cc b/src/ast/type_constructor_expression_test.cc
index d7efed7..477faf5 100644
--- a/src/ast/type_constructor_expression_test.cc
+++ b/src/ast/type_constructor_expression_test.cc
@@ -52,11 +52,7 @@
 }
 
 TEST_F(TypeConstructorExpressionTest, IsTypeConstructor) {
-  type::F32 f32;
-  ExpressionList expr;
-  expr.push_back(create<IdentifierExpression>("expr"));
-
-  TypeConstructorExpression t(&f32, expr);
+  TypeConstructorExpression t;
   EXPECT_TRUE(t.Is<TypeConstructorExpression>());
 }
 
@@ -81,7 +77,8 @@
   ExpressionList expr;
   expr.push_back(create<IdentifierExpression>("expr"));
 
-  TypeConstructorExpression t(nullptr, expr);
+  TypeConstructorExpression t;
+  t.set_values(expr);
   EXPECT_FALSE(t.IsValid());
 }
 
diff --git a/src/ast/unary_op_expression.cc b/src/ast/unary_op_expression.cc
index b33d034..c5bc38c 100644
--- a/src/ast/unary_op_expression.cc
+++ b/src/ast/unary_op_expression.cc
@@ -20,6 +20,8 @@
 namespace tint {
 namespace ast {
 
+UnaryOpExpression::UnaryOpExpression() : Base() {}
+
 UnaryOpExpression::UnaryOpExpression(UnaryOp op, Expression* expr)
     : Base(), op_(op), expr_(expr) {}
 
diff --git a/src/ast/unary_op_expression.h b/src/ast/unary_op_expression.h
index 4fbefd5..d2c5e42 100644
--- a/src/ast/unary_op_expression.h
+++ b/src/ast/unary_op_expression.h
@@ -29,6 +29,8 @@
 class UnaryOpExpression : public Castable<UnaryOpExpression, Expression> {
  public:
   /// Constructor
+  UnaryOpExpression();
+  /// Constructor
   /// @param op the op
   /// @param expr the expr
   UnaryOpExpression(UnaryOp op, Expression* expr);
@@ -41,8 +43,15 @@
   UnaryOpExpression(UnaryOpExpression&&);
   ~UnaryOpExpression() override;
 
+  /// Sets the op
+  /// @param op the op
+  void set_op(UnaryOp op) { op_ = op; }
   /// @returns the op
   UnaryOp op() const { return op_; }
+
+  /// Sets the expr
+  /// @param expr the expression
+  void set_expr(Expression* expr) { expr_ = expr; }
   /// @returns the expression
   Expression* expr() const { return expr_; }
 
diff --git a/src/ast/unary_op_expression_test.cc b/src/ast/unary_op_expression_test.cc
index 5e3ec1f..ea6e516 100644
--- a/src/ast/unary_op_expression_test.cc
+++ b/src/ast/unary_op_expression_test.cc
@@ -42,8 +42,7 @@
 }
 
 TEST_F(UnaryOpExpressionTest, IsUnaryOp) {
-  auto* ident = create<IdentifierExpression>("ident");
-  UnaryOpExpression u(UnaryOp::kNot, ident);
+  UnaryOpExpression u;
   EXPECT_TRUE(u.Is<UnaryOpExpression>());
 }
 
@@ -54,7 +53,8 @@
 }
 
 TEST_F(UnaryOpExpressionTest, IsValid_NullExpression) {
-  UnaryOpExpression u(UnaryOp::kNot, nullptr);
+  UnaryOpExpression u;
+  u.set_op(UnaryOp::kNot);
   EXPECT_FALSE(u.IsValid());
 }
 
diff --git a/src/ast/variable.cc b/src/ast/variable.cc
index 8e48867..01ae068 100644
--- a/src/ast/variable.cc
+++ b/src/ast/variable.cc
@@ -39,9 +39,11 @@
 Variable::~Variable() = default;
 
 Variable* Variable::Clone(CloneContext* ctx) const {
-  auto* cloned =
-      ctx->mod->create<Variable>(name(), storage_class(), ctx->Clone(type()));
+  auto* cloned = ctx->mod->create<Variable>();
   cloned->set_source(ctx->Clone(source()));
+  cloned->set_name(name());
+  cloned->set_storage_class(storage_class());
+  cloned->set_type(ctx->Clone(type()));
   cloned->set_constructor(ctx->Clone(constructor()));
   cloned->set_is_const(is_const());
   return cloned;
diff --git a/src/ast/variable.h b/src/ast/variable.h
index 72de0f1..43fe16c 100644
--- a/src/ast/variable.h
+++ b/src/ast/variable.h
@@ -78,6 +78,8 @@
 /// The storage class for a formal parameter is always StorageClass::kNone.
 class Variable : public Castable<Variable, Node> {
  public:
+  /// Create a new empty variable statement
+  Variable();
   /// Create a variable
   /// @param name the variables name
   /// @param sc the variable storage class
@@ -147,10 +149,6 @@
   void to_str(std::ostream& out, size_t indent) const override;
 
  protected:
-  /// Constructor
-  /// Used by the DecoratedVariable constructor.
-  Variable();
-
   /// Output information for this variable.
   /// @param out the stream to write to
   /// @param indent number of spaces to indent the node when writing
diff --git a/src/ast/variable_decl_statement.cc b/src/ast/variable_decl_statement.cc
index 0b3feea..f1ec4d3 100644
--- a/src/ast/variable_decl_statement.cc
+++ b/src/ast/variable_decl_statement.cc
@@ -20,6 +20,8 @@
 namespace tint {
 namespace ast {
 
+VariableDeclStatement::VariableDeclStatement() : Base() {}
+
 VariableDeclStatement::VariableDeclStatement(Variable* variable)
     : Base(), variable_(variable) {}
 
diff --git a/src/ast/variable_decl_statement.h b/src/ast/variable_decl_statement.h
index 6ec3748..bdf5ed2 100644
--- a/src/ast/variable_decl_statement.h
+++ b/src/ast/variable_decl_statement.h
@@ -30,6 +30,8 @@
     : public Castable<VariableDeclStatement, Statement> {
  public:
   /// Constructor
+  VariableDeclStatement();
+  /// Constructor
   /// @param variable the variable
   explicit VariableDeclStatement(Variable* variable);
   /// Constructor
@@ -40,6 +42,9 @@
   VariableDeclStatement(VariableDeclStatement&&);
   ~VariableDeclStatement() override;
 
+  /// Sets the variable
+  /// @param variable the variable to set
+  void set_variable(Variable* variable) { variable_ = variable; }
   /// @returns the variable
   Variable* variable() const { return variable_; }
 
diff --git a/src/ast/variable_decl_statement_test.cc b/src/ast/variable_decl_statement_test.cc
index daa7c2a..afd1538 100644
--- a/src/ast/variable_decl_statement_test.cc
+++ b/src/ast/variable_decl_statement_test.cc
@@ -43,10 +43,7 @@
 }
 
 TEST_F(VariableDeclStatementTest, IsVariableDecl) {
-  type::F32 f32;
-  auto* var = create<Variable>("a", StorageClass::kNone, &f32);
-
-  VariableDeclStatement s(var);
+  VariableDeclStatement s;
   EXPECT_TRUE(s.Is<VariableDeclStatement>());
 }
 
@@ -65,7 +62,7 @@
 }
 
 TEST_F(VariableDeclStatementTest, IsValid_NullVariable) {
-  VariableDeclStatement stmt(nullptr);
+  VariableDeclStatement stmt;
   EXPECT_FALSE(stmt.IsValid());
 }
 
diff --git a/src/ast/variable_test.cc b/src/ast/variable_test.cc
index 9f22a94..0b8bf9b 100644
--- a/src/ast/variable_test.cc
+++ b/src/ast/variable_test.cc
@@ -53,9 +53,14 @@
 }
 
 TEST_F(VariableTest, CreationEmpty) {
-  type::I32 t;
   Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}};
-  Variable v(s, "a_var", StorageClass::kWorkgroup, &t);
+  Variable v;
+  v.set_source(s);
+  v.set_storage_class(StorageClass::kWorkgroup);
+  v.set_name("a_var");
+
+  type::I32 t;
+  v.set_type(&t);
 
   EXPECT_EQ(v.name(), "a_var");
   EXPECT_EQ(v.storage_class(), StorageClass::kWorkgroup);
@@ -91,7 +96,7 @@
 }
 
 TEST_F(VariableTest, IsValid_MissingBoth) {
-  Variable v("", StorageClass::kNone, nullptr);
+  Variable v;
   EXPECT_FALSE(v.IsValid());
 }