Replace use of std::unique_ptr<T> with T* for AST nodes

This is a minimal effort to fix up the code. There's substantial code
cleanup which can now be done, which is done in the next change.

Bug: tint:322
Change-Id: Iafcf5e814837d9534889e8c21333de4931a19cfa
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32864
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/array_accessor_expression.cc b/src/ast/array_accessor_expression.cc
index 9fa112f..e8eea8a 100644
--- a/src/ast/array_accessor_expression.cc
+++ b/src/ast/array_accessor_expression.cc
@@ -19,18 +19,14 @@
 
 ArrayAccessorExpression::ArrayAccessorExpression() : Expression() {}
 
-ArrayAccessorExpression::ArrayAccessorExpression(
-    std::unique_ptr<Expression> array,
-    std::unique_ptr<Expression> idx_expr)
-    : Expression(), array_(std::move(array)), idx_expr_(std::move(idx_expr)) {}
+ArrayAccessorExpression::ArrayAccessorExpression(Expression* array,
+                                                 Expression* idx_expr)
+    : Expression(), array_(array), idx_expr_(idx_expr) {}
 
-ArrayAccessorExpression::ArrayAccessorExpression(
-    const Source& source,
-    std::unique_ptr<Expression> array,
-    std::unique_ptr<Expression> idx_expr)
-    : Expression(source),
-      array_(std::move(array)),
-      idx_expr_(std::move(idx_expr)) {}
+ArrayAccessorExpression::ArrayAccessorExpression(const Source& source,
+                                                 Expression* array,
+                                                 Expression* idx_expr)
+    : Expression(source), array_(array), idx_expr_(idx_expr) {}
 
 ArrayAccessorExpression::ArrayAccessorExpression(ArrayAccessorExpression&&) =
     default;
diff --git a/src/ast/array_accessor_expression.h b/src/ast/array_accessor_expression.h
index 0359161..bb716ec 100644
--- a/src/ast/array_accessor_expression.h
+++ b/src/ast/array_accessor_expression.h
@@ -32,37 +32,29 @@
   /// Constructor
   /// @param array the array
   /// @param idx_expr the index expression
-  ArrayAccessorExpression(std::unique_ptr<Expression> array,
-                          std::unique_ptr<Expression> idx_expr);
+  ArrayAccessorExpression(Expression* array, Expression* idx_expr);
   /// Constructor
   /// @param source the array accessor source
   /// @param array the array
   /// @param idx_expr the index expression
   ArrayAccessorExpression(const Source& source,
-                          std::unique_ptr<Expression> array,
-                          std::unique_ptr<Expression> idx_expr);
+                          Expression* array,
+                          Expression* idx_expr);
   /// Move constructor
   ArrayAccessorExpression(ArrayAccessorExpression&&);
   ~ArrayAccessorExpression() override;
 
   /// Sets the array
   /// @param array the array
-  void set_array(std::unique_ptr<Expression> array) {
-    array_ = std::move(array);
-  }
+  void set_array(Expression* array) { array_ = array; }
   /// @returns the array
-  Expression* array() const { return array_.get(); }
+  Expression* array() const { return array_; }
 
   /// Sets the index expression
   /// @param idx_expr the index expression
-  void set_idx_expr(std::unique_ptr<Expression> idx_expr) {
-    idx_expr_ = std::move(idx_expr);
-  }
+  void set_idx_expr(Expression* idx_expr) { idx_expr_ = idx_expr; }
   /// @returns the index expression
-  Expression* idx_expr() const { return idx_expr_.get(); }
-  /// Removes the index expression from the array accessor
-  /// @returns the unique pointer to the index expression
-  std::unique_ptr<Expression> take_idx_expr() { return std::move(idx_expr_); }
+  Expression* idx_expr() const { return idx_expr_; }
 
   /// @returns true if this is an array accessor expression
   bool IsArrayAccessor() const override;
@@ -78,8 +70,8 @@
  private:
   ArrayAccessorExpression(const ArrayAccessorExpression&) = delete;
 
-  std::unique_ptr<Expression> array_;
-  std::unique_ptr<Expression> idx_expr_;
+  Expression* array_ = nullptr;
+  Expression* idx_expr_ = nullptr;
 };
 
 }  // namespace ast
diff --git a/src/ast/array_accessor_expression_test.cc b/src/ast/array_accessor_expression_test.cc
index b9b95fa..d24bb4d 100644
--- a/src/ast/array_accessor_expression_test.cc
+++ b/src/ast/array_accessor_expression_test.cc
@@ -24,19 +24,19 @@
 using ArrayAccessorExpressionTest = TestHelper;
 
 TEST_F(ArrayAccessorExpressionTest, Create) {
-  auto ary = create<IdentifierExpression>("ary");
-  auto idx = create<IdentifierExpression>("idx");
+  auto* ary = create<IdentifierExpression>("ary");
+  auto* idx = create<IdentifierExpression>("idx");
 
-  auto* ary_ptr = ary.get();
-  auto* idx_ptr = idx.get();
+  auto* ary_ptr = ary;
+  auto* idx_ptr = idx;
 
   ArrayAccessorExpression exp(std::move(ary), std::move(idx));
   ASSERT_EQ(exp.array(), ary_ptr);
   ASSERT_EQ(exp.idx_expr(), idx_ptr);
 }
 TEST_F(ArrayAccessorExpressionTest, CreateWithSource) {
-  auto ary = create<IdentifierExpression>("ary");
-  auto idx = create<IdentifierExpression>("idx");
+  auto* ary = create<IdentifierExpression>("ary");
+  auto* idx = create<IdentifierExpression>("idx");
 
   ArrayAccessorExpression exp(Source{Source::Location{20, 2}}, std::move(ary),
                               std::move(idx));
@@ -51,15 +51,15 @@
 }
 
 TEST_F(ArrayAccessorExpressionTest, IsValid) {
-  auto ary = create<IdentifierExpression>("ary");
-  auto idx = create<IdentifierExpression>("idx");
+  auto* ary = create<IdentifierExpression>("ary");
+  auto* idx = create<IdentifierExpression>("idx");
 
   ArrayAccessorExpression exp(std::move(ary), std::move(idx));
   EXPECT_TRUE(exp.IsValid());
 }
 
 TEST_F(ArrayAccessorExpressionTest, IsValid_MissingArray) {
-  auto idx = create<IdentifierExpression>("idx");
+  auto* idx = create<IdentifierExpression>("idx");
 
   ArrayAccessorExpression exp;
   exp.set_idx_expr(std::move(idx));
@@ -67,7 +67,7 @@
 }
 
 TEST_F(ArrayAccessorExpressionTest, IsValid_MissingIndex) {
-  auto ary = create<IdentifierExpression>("ary");
+  auto* ary = create<IdentifierExpression>("ary");
 
   ArrayAccessorExpression exp;
   exp.set_array(std::move(ary));
@@ -75,22 +75,22 @@
 }
 
 TEST_F(ArrayAccessorExpressionTest, IsValid_InvalidArray) {
-  auto ary = create<IdentifierExpression>("");
-  auto idx = create<IdentifierExpression>("idx");
+  auto* ary = create<IdentifierExpression>("");
+  auto* idx = create<IdentifierExpression>("idx");
   ArrayAccessorExpression exp(std::move(ary), std::move(idx));
   EXPECT_FALSE(exp.IsValid());
 }
 
 TEST_F(ArrayAccessorExpressionTest, IsValid_InvalidIndex) {
-  auto ary = create<IdentifierExpression>("ary");
-  auto idx = create<IdentifierExpression>("");
+  auto* ary = create<IdentifierExpression>("ary");
+  auto* idx = create<IdentifierExpression>("");
   ArrayAccessorExpression exp(std::move(ary), std::move(idx));
   EXPECT_FALSE(exp.IsValid());
 }
 
 TEST_F(ArrayAccessorExpressionTest, ToStr) {
-  auto ary = create<IdentifierExpression>("ary");
-  auto idx = create<IdentifierExpression>("idx");
+  auto* ary = create<IdentifierExpression>("ary");
+  auto* idx = create<IdentifierExpression>("idx");
 
   ArrayAccessorExpression exp(std::move(ary), std::move(idx));
   std::ostringstream out;
diff --git a/src/ast/array_decoration.h b/src/ast/array_decoration.h
index 1594e01..473dc5b 100644
--- a/src/ast/array_decoration.h
+++ b/src/ast/array_decoration.h
@@ -46,8 +46,8 @@
   explicit ArrayDecoration(const Source& source);
 };
 
-/// A list of unique array decorations
-using ArrayDecorationList = std::vector<std::unique_ptr<ArrayDecoration>>;
+/// A list of array decorations
+using ArrayDecorationList = std::vector<ArrayDecoration*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/assignment_statement.cc b/src/ast/assignment_statement.cc
index d9bc04f..0430624 100644
--- a/src/ast/assignment_statement.cc
+++ b/src/ast/assignment_statement.cc
@@ -19,14 +19,13 @@
 
 AssignmentStatement::AssignmentStatement() : Statement() {}
 
-AssignmentStatement::AssignmentStatement(std::unique_ptr<Expression> lhs,
-                                         std::unique_ptr<Expression> rhs)
-    : Statement(), lhs_(std::move(lhs)), rhs_(std::move(rhs)) {}
+AssignmentStatement::AssignmentStatement(Expression* lhs, Expression* rhs)
+    : Statement(), lhs_(lhs), rhs_(rhs) {}
 
 AssignmentStatement::AssignmentStatement(const Source& source,
-                                         std::unique_ptr<Expression> lhs,
-                                         std::unique_ptr<Expression> rhs)
-    : Statement(source), lhs_(std::move(lhs)), rhs_(std::move(rhs)) {}
+                                         Expression* lhs,
+                                         Expression* rhs)
+    : Statement(source), lhs_(lhs), rhs_(rhs) {}
 
 AssignmentStatement::AssignmentStatement(AssignmentStatement&&) = default;
 
diff --git a/src/ast/assignment_statement.h b/src/ast/assignment_statement.h
index cf105cd..0a2c379 100644
--- a/src/ast/assignment_statement.h
+++ b/src/ast/assignment_statement.h
@@ -33,30 +33,27 @@
   /// Constructor
   /// @param lhs the left side of the expression
   /// @param rhs the right side of the expression
-  AssignmentStatement(std::unique_ptr<Expression> lhs,
-                      std::unique_ptr<Expression> rhs);
+  AssignmentStatement(Expression* lhs, Expression* rhs);
   /// Constructor
   /// @param source the assignment statement source
   /// @param lhs the left side of the expression
   /// @param rhs the right side of the expression
-  AssignmentStatement(const Source& source,
-                      std::unique_ptr<Expression> lhs,
-                      std::unique_ptr<Expression> rhs);
+  AssignmentStatement(const Source& source, Expression* lhs, Expression* rhs);
   /// Move constructor
   AssignmentStatement(AssignmentStatement&&);
   ~AssignmentStatement() override;
 
   /// Sets the left side of the statement
   /// @param lhs the left side to set
-  void set_lhs(std::unique_ptr<Expression> lhs) { lhs_ = std::move(lhs); }
+  void set_lhs(Expression* lhs) { lhs_ = lhs; }
   /// @returns the left side expression
-  Expression* lhs() const { return lhs_.get(); }
+  Expression* lhs() const { return lhs_; }
 
   /// Sets the right side of the statement
   /// @param rhs the right side to set
-  void set_rhs(std::unique_ptr<Expression> rhs) { rhs_ = std::move(rhs); }
+  void set_rhs(Expression* rhs) { rhs_ = rhs; }
   /// @returns the right side expression
-  Expression* rhs() const { return rhs_.get(); }
+  Expression* rhs() const { return rhs_; }
 
   /// @returns true if this is an assignment statement
   bool IsAssign() const override;
@@ -72,8 +69,8 @@
  private:
   AssignmentStatement(const AssignmentStatement&) = delete;
 
-  std::unique_ptr<Expression> lhs_;
-  std::unique_ptr<Expression> rhs_;
+  Expression* lhs_ = nullptr;
+  Expression* rhs_ = nullptr;
 };
 
 }  // namespace ast
diff --git a/src/ast/assignment_statement_test.cc b/src/ast/assignment_statement_test.cc
index fffe29a..6be673e 100644
--- a/src/ast/assignment_statement_test.cc
+++ b/src/ast/assignment_statement_test.cc
@@ -24,11 +24,11 @@
 using AssignmentStatementTest = TestHelper;
 
 TEST_F(AssignmentStatementTest, Creation) {
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
 
-  auto* lhs_ptr = lhs.get();
-  auto* rhs_ptr = rhs.get();
+  auto* lhs_ptr = lhs;
+  auto* rhs_ptr = rhs;
 
   AssignmentStatement stmt(std::move(lhs), std::move(rhs));
   EXPECT_EQ(stmt.lhs(), lhs_ptr);
@@ -36,8 +36,8 @@
 }
 
 TEST_F(AssignmentStatementTest, CreationWithSource) {
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
 
   AssignmentStatement stmt(Source{Source::Location{20, 2}}, std::move(lhs),
                            std::move(rhs));
@@ -47,23 +47,23 @@
 }
 
 TEST_F(AssignmentStatementTest, IsAssign) {
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
 
   AssignmentStatement stmt(std::move(lhs), std::move(rhs));
   EXPECT_TRUE(stmt.IsAssign());
 }
 
 TEST_F(AssignmentStatementTest, IsValid) {
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
 
   AssignmentStatement stmt(std::move(lhs), std::move(rhs));
   EXPECT_TRUE(stmt.IsValid());
 }
 
 TEST_F(AssignmentStatementTest, IsValid_MissingLHS) {
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
 
   AssignmentStatement stmt;
   stmt.set_rhs(std::move(rhs));
@@ -71,7 +71,7 @@
 }
 
 TEST_F(AssignmentStatementTest, IsValid_MissingRHS) {
-  auto lhs = create<ast::IdentifierExpression>("lhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
 
   AssignmentStatement stmt;
   stmt.set_lhs(std::move(lhs));
@@ -79,22 +79,22 @@
 }
 
 TEST_F(AssignmentStatementTest, IsValid_InvalidLHS) {
-  auto lhs = create<ast::IdentifierExpression>("");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
   AssignmentStatement stmt(std::move(lhs), std::move(rhs));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(AssignmentStatementTest, IsValid_InvalidRHS) {
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("");
   AssignmentStatement stmt(std::move(lhs), std::move(rhs));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(AssignmentStatementTest, ToStr) {
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
 
   AssignmentStatement stmt(std::move(lhs), std::move(rhs));
   std::ostringstream out;
diff --git a/src/ast/binary_expression.cc b/src/ast/binary_expression.cc
index 0b9e5a3..25d7fb7 100644
--- a/src/ast/binary_expression.cc
+++ b/src/ast/binary_expression.cc
@@ -20,15 +20,15 @@
 BinaryExpression::BinaryExpression() : Expression() {}
 
 BinaryExpression::BinaryExpression(BinaryOp op,
-                                   std::unique_ptr<Expression> lhs,
-                                   std::unique_ptr<Expression> rhs)
-    : Expression(), op_(op), lhs_(std::move(lhs)), rhs_(std::move(rhs)) {}
+                                   Expression* lhs,
+                                   Expression* rhs)
+    : Expression(), op_(op), lhs_(lhs), rhs_(rhs) {}
 
 BinaryExpression::BinaryExpression(const Source& source,
                                    BinaryOp op,
-                                   std::unique_ptr<Expression> lhs,
-                                   std::unique_ptr<Expression> rhs)
-    : Expression(source), op_(op), lhs_(std::move(lhs)), rhs_(std::move(rhs)) {}
+                                   Expression* lhs,
+                                   Expression* rhs)
+    : Expression(source), op_(op), lhs_(lhs), rhs_(rhs) {}
 
 BinaryExpression::BinaryExpression(BinaryExpression&&) = default;
 
diff --git a/src/ast/binary_expression.h b/src/ast/binary_expression.h
index 9724ad2..4ef24d8 100644
--- a/src/ast/binary_expression.h
+++ b/src/ast/binary_expression.h
@@ -56,9 +56,7 @@
   /// @param op the operation type
   /// @param lhs the left side of the expression
   /// @param rhs the right side of the expression
-  BinaryExpression(BinaryOp op,
-                   std::unique_ptr<Expression> lhs,
-                   std::unique_ptr<Expression> rhs);
+  BinaryExpression(BinaryOp op, Expression* lhs, Expression* rhs);
   /// Constructor
   /// @param source the binary expression source
   /// @param op the operation type
@@ -66,8 +64,8 @@
   /// @param rhs the right side of the expression
   BinaryExpression(const Source& source,
                    BinaryOp op,
-                   std::unique_ptr<Expression> lhs,
-                   std::unique_ptr<Expression> rhs);
+                   Expression* lhs,
+                   Expression* rhs);
   /// Move constructor
   BinaryExpression(BinaryExpression&&);
   ~BinaryExpression() override;
@@ -117,15 +115,15 @@
 
   /// Sets the left side of the expression
   /// @param lhs the left side to set
-  void set_lhs(std::unique_ptr<Expression> lhs) { lhs_ = std::move(lhs); }
+  void set_lhs(Expression* lhs) { lhs_ = lhs; }
   /// @returns the left side expression
-  Expression* lhs() const { return lhs_.get(); }
+  Expression* lhs() const { return lhs_; }
 
   /// Sets the right side of the expression
   /// @param rhs the right side to set
-  void set_rhs(std::unique_ptr<Expression> rhs) { rhs_ = std::move(rhs); }
+  void set_rhs(Expression* rhs) { rhs_ = rhs; }
   /// @returns the right side expression
-  Expression* rhs() const { return rhs_.get(); }
+  Expression* rhs() const { return rhs_; }
 
   /// @returns true if this is a op expression
   bool IsBinary() const override;
@@ -142,8 +140,8 @@
   BinaryExpression(const BinaryExpression&) = delete;
 
   BinaryOp op_ = BinaryOp::kNone;
-  std::unique_ptr<Expression> lhs_;
-  std::unique_ptr<Expression> rhs_;
+  Expression* lhs_ = nullptr;
+  Expression* rhs_ = nullptr;
 };
 
 inline std::ostream& operator<<(std::ostream& out, BinaryOp op) {
diff --git a/src/ast/binary_expression_test.cc b/src/ast/binary_expression_test.cc
index c6e0d04..5648bb2 100644
--- a/src/ast/binary_expression_test.cc
+++ b/src/ast/binary_expression_test.cc
@@ -26,11 +26,11 @@
 using BinaryExpressionTest = TestHelper;
 
 TEST_F(BinaryExpressionTest, Creation) {
-  auto lhs = create<IdentifierExpression>("lhs");
-  auto rhs = create<IdentifierExpression>("rhs");
+  auto* lhs = create<IdentifierExpression>("lhs");
+  auto* rhs = create<IdentifierExpression>("rhs");
 
-  auto* lhs_ptr = lhs.get();
-  auto* rhs_ptr = rhs.get();
+  auto* lhs_ptr = lhs;
+  auto* rhs_ptr = rhs;
 
   BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
   EXPECT_EQ(r.lhs(), lhs_ptr);
@@ -39,8 +39,8 @@
 }
 
 TEST_F(BinaryExpressionTest, Creation_WithSource) {
-  auto lhs = create<IdentifierExpression>("lhs");
-  auto rhs = create<IdentifierExpression>("rhs");
+  auto* lhs = create<IdentifierExpression>("lhs");
+  auto* rhs = create<IdentifierExpression>("rhs");
 
   BinaryExpression r(Source{Source::Location{20, 2}}, BinaryOp::kEqual,
                      std::move(lhs), std::move(rhs));
@@ -55,15 +55,15 @@
 }
 
 TEST_F(BinaryExpressionTest, IsValid) {
-  auto lhs = create<IdentifierExpression>("lhs");
-  auto rhs = create<IdentifierExpression>("rhs");
+  auto* lhs = create<IdentifierExpression>("lhs");
+  auto* rhs = create<IdentifierExpression>("rhs");
 
   BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
   EXPECT_TRUE(r.IsValid());
 }
 
 TEST_F(BinaryExpressionTest, IsValid_Null_LHS) {
-  auto rhs = create<IdentifierExpression>("rhs");
+  auto* rhs = create<IdentifierExpression>("rhs");
 
   BinaryExpression r;
   r.set_op(BinaryOp::kEqual);
@@ -72,15 +72,15 @@
 }
 
 TEST_F(BinaryExpressionTest, IsValid_Invalid_LHS) {
-  auto lhs = create<IdentifierExpression>("");
-  auto rhs = create<IdentifierExpression>("rhs");
+  auto* lhs = create<IdentifierExpression>("");
+  auto* rhs = create<IdentifierExpression>("rhs");
 
   BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
   EXPECT_FALSE(r.IsValid());
 }
 
 TEST_F(BinaryExpressionTest, IsValid_Null_RHS) {
-  auto lhs = create<IdentifierExpression>("lhs");
+  auto* lhs = create<IdentifierExpression>("lhs");
 
   BinaryExpression r;
   r.set_op(BinaryOp::kEqual);
@@ -89,24 +89,24 @@
 }
 
 TEST_F(BinaryExpressionTest, IsValid_Invalid_RHS) {
-  auto lhs = create<IdentifierExpression>("lhs");
-  auto rhs = create<IdentifierExpression>("");
+  auto* lhs = create<IdentifierExpression>("lhs");
+  auto* rhs = create<IdentifierExpression>("");
 
   BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
   EXPECT_FALSE(r.IsValid());
 }
 
 TEST_F(BinaryExpressionTest, IsValid_Binary_None) {
-  auto lhs = create<IdentifierExpression>("lhs");
-  auto rhs = create<IdentifierExpression>("rhs");
+  auto* lhs = create<IdentifierExpression>("lhs");
+  auto* rhs = create<IdentifierExpression>("rhs");
 
   BinaryExpression r(BinaryOp::kNone, std::move(lhs), std::move(rhs));
   EXPECT_FALSE(r.IsValid());
 }
 
 TEST_F(BinaryExpressionTest, ToStr) {
-  auto lhs = create<IdentifierExpression>("lhs");
-  auto rhs = create<IdentifierExpression>("rhs");
+  auto* lhs = create<IdentifierExpression>("lhs");
+  auto* rhs = create<IdentifierExpression>("rhs");
 
   BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
   std::ostringstream out;
diff --git a/src/ast/bitcast_expression.cc b/src/ast/bitcast_expression.cc
index 6bd378e..693c4ba 100644
--- a/src/ast/bitcast_expression.cc
+++ b/src/ast/bitcast_expression.cc
@@ -19,14 +19,13 @@
 
 BitcastExpression::BitcastExpression() : Expression() {}
 
-BitcastExpression::BitcastExpression(type::Type* type,
-                                     std::unique_ptr<Expression> expr)
-    : Expression(), type_(type), expr_(std::move(expr)) {}
+BitcastExpression::BitcastExpression(type::Type* type, Expression* expr)
+    : Expression(), type_(type), expr_(expr) {}
 
 BitcastExpression::BitcastExpression(const Source& source,
                                      type::Type* type,
-                                     std::unique_ptr<Expression> expr)
-    : Expression(source), type_(type), expr_(std::move(expr)) {}
+                                     Expression* expr)
+    : Expression(source), type_(type), expr_(expr) {}
 
 BitcastExpression::BitcastExpression(BitcastExpression&&) = default;
 BitcastExpression::~BitcastExpression() = default;
diff --git a/src/ast/bitcast_expression.h b/src/ast/bitcast_expression.h
index c74fc7b..014787f 100644
--- a/src/ast/bitcast_expression.h
+++ b/src/ast/bitcast_expression.h
@@ -33,29 +33,27 @@
   /// Constructor
   /// @param type the type
   /// @param expr the expr
-  BitcastExpression(type::Type* type, std::unique_ptr<Expression> expr);
+  BitcastExpression(type::Type* type, Expression* expr);
   /// Constructor
   /// @param source the bitcast expression source
   /// @param type the type
   /// @param expr the expr
-  BitcastExpression(const Source& source,
-                    type::Type* type,
-                    std::unique_ptr<Expression> expr);
+  BitcastExpression(const Source& source, type::Type* type, Expression* expr);
   /// Move constructor
   BitcastExpression(BitcastExpression&&);
   ~BitcastExpression() override;
 
   /// Sets the type
   /// @param type the type
-  void set_type(type::Type* type) { type_ = std::move(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(std::unique_ptr<Expression> expr) { expr_ = std::move(expr); }
+  void set_expr(Expression* expr) { expr_ = expr; }
   /// @returns the expression
-  Expression* expr() const { return expr_.get(); }
+  Expression* expr() const { return expr_; }
 
   /// @returns true if this is a bitcast expression
   bool IsBitcast() const override;
@@ -72,7 +70,7 @@
   BitcastExpression(const BitcastExpression&) = delete;
 
   type::Type* type_ = nullptr;
-  std::unique_ptr<Expression> expr_;
+  Expression* expr_ = nullptr;
 };
 
 }  // namespace ast
diff --git a/src/ast/bitcast_expression_test.cc b/src/ast/bitcast_expression_test.cc
index baee3d2..64565d4 100644
--- a/src/ast/bitcast_expression_test.cc
+++ b/src/ast/bitcast_expression_test.cc
@@ -26,9 +26,9 @@
 
 TEST_F(BitcastExpressionTest, Create) {
   type::F32Type f32;
-  auto expr = create<IdentifierExpression>("expr");
+  auto* expr = create<IdentifierExpression>("expr");
 
-  auto* expr_ptr = expr.get();
+  auto* expr_ptr = expr;
 
   BitcastExpression exp(&f32, std::move(expr));
   ASSERT_EQ(exp.type(), &f32);
@@ -37,7 +37,7 @@
 
 TEST_F(BitcastExpressionTest, CreateWithSource) {
   type::F32Type f32;
-  auto expr = create<IdentifierExpression>("expr");
+  auto* expr = create<IdentifierExpression>("expr");
 
   BitcastExpression exp(Source{Source::Location{20, 2}}, &f32, std::move(expr));
   auto src = exp.source();
@@ -52,14 +52,14 @@
 
 TEST_F(BitcastExpressionTest, IsValid) {
   type::F32Type f32;
-  auto expr = create<IdentifierExpression>("expr");
+  auto* expr = create<IdentifierExpression>("expr");
 
   BitcastExpression exp(&f32, std::move(expr));
   EXPECT_TRUE(exp.IsValid());
 }
 
 TEST_F(BitcastExpressionTest, IsValid_MissingType) {
-  auto expr = create<IdentifierExpression>("expr");
+  auto* expr = create<IdentifierExpression>("expr");
 
   BitcastExpression exp;
   exp.set_expr(std::move(expr));
@@ -76,14 +76,14 @@
 
 TEST_F(BitcastExpressionTest, IsValid_InvalidExpr) {
   type::F32Type f32;
-  auto expr = create<IdentifierExpression>("");
+  auto* expr = create<IdentifierExpression>("");
   BitcastExpression e(&f32, std::move(expr));
   EXPECT_FALSE(e.IsValid());
 }
 
 TEST_F(BitcastExpressionTest, ToStr) {
   type::F32Type f32;
-  auto expr = create<IdentifierExpression>("expr");
+  auto* expr = create<IdentifierExpression>("expr");
 
   BitcastExpression exp(&f32, std::move(expr));
   std::ostringstream out;
diff --git a/src/ast/block_statement.cc b/src/ast/block_statement.cc
index 33ee8c3..7934d02 100644
--- a/src/ast/block_statement.cc
+++ b/src/ast/block_statement.cc
@@ -30,7 +30,7 @@
 }
 
 bool BlockStatement::IsValid() const {
-  for (const auto& stmt : *this) {
+  for (auto* stmt : *this) {
     if (stmt == nullptr || !stmt->IsValid()) {
       return false;
     }
@@ -42,7 +42,7 @@
   make_indent(out, indent);
   out << "Block{" << std::endl;
 
-  for (const auto& stmt : *this) {
+  for (auto* stmt : *this) {
     stmt->to_str(out, indent + 2);
   }
 
diff --git a/src/ast/block_statement.h b/src/ast/block_statement.h
index 8fc2ce7..eee8f7c 100644
--- a/src/ast/block_statement.h
+++ b/src/ast/block_statement.h
@@ -38,16 +38,14 @@
 
   /// Appends a statement to the block
   /// @param stmt the statement to append
-  void append(std::unique_ptr<ast::Statement> stmt) {
-    statements_.push_back(std::move(stmt));
-  }
+  void append(ast::Statement* stmt) { statements_.push_back(stmt); }
 
   /// Insert a statement to the block
   /// @param index the index to insert at
   /// @param stmt the statement to insert
-  void insert(size_t index, std::unique_ptr<ast::Statement> stmt) {
+  void insert(size_t index, ast::Statement* stmt) {
     auto offset = static_cast<decltype(statements_)::difference_type>(index);
-    statements_.insert(statements_.begin() + offset, std::move(stmt));
+    statements_.insert(statements_.begin() + offset, stmt);
   }
 
   /// @returns true if the block is empty
@@ -57,35 +55,35 @@
 
   /// @returns the last statement in the block or nullptr if block empty
   const ast::Statement* last() const {
-    return statements_.empty() ? nullptr : statements_.back().get();
+    return statements_.empty() ? nullptr : statements_.back();
   }
   /// @returns the last statement in the block or nullptr if block empty
   ast::Statement* last() {
-    return statements_.empty() ? nullptr : statements_.back().get();
+    return statements_.empty() ? nullptr : statements_.back();
   }
 
   /// Retrieves the statement at |idx|
   /// @param idx the index. The index is not bounds checked.
   /// @returns the statement at |idx|
-  const ast::Statement* get(size_t idx) const { return statements_[idx].get(); }
+  const ast::Statement* get(size_t idx) const { return statements_[idx]; }
 
   /// Retrieves the statement at |idx|
   /// @param idx the index. The index is not bounds checked.
   /// @returns the statement at |idx|
-  ast::Statement* operator[](size_t idx) { return statements_[idx].get(); }
+  ast::Statement* operator[](size_t idx) { return statements_[idx]; }
   /// Retrieves the statement at |idx|
   /// @param idx the index. The index is not bounds checked.
   /// @returns the statement at |idx|
   const ast::Statement* operator[](size_t idx) const {
-    return statements_[idx].get();
+    return statements_[idx];
   }
 
   /// @returns the beginning iterator
-  std::vector<std::unique_ptr<ast::Statement>>::const_iterator begin() const {
+  std::vector<ast::Statement*>::const_iterator begin() const {
     return statements_.begin();
   }
   /// @returns the ending iterator
-  std::vector<std::unique_ptr<ast::Statement>>::const_iterator end() const {
+  std::vector<ast::Statement*>::const_iterator end() const {
     return statements_.end();
   }
 
@@ -103,7 +101,7 @@
  private:
   BlockStatement(const BlockStatement&) = delete;
 
-  std::vector<std::unique_ptr<ast::Statement>> statements_;
+  std::vector<ast::Statement*> statements_;
 };
 
 }  // namespace ast
diff --git a/src/ast/block_statement_test.cc b/src/ast/block_statement_test.cc
index 542ece5..010b7d4 100644
--- a/src/ast/block_statement_test.cc
+++ b/src/ast/block_statement_test.cc
@@ -28,8 +28,8 @@
 using BlockStatementTest = TestHelper;
 
 TEST_F(BlockStatementTest, Creation) {
-  auto d = create<DiscardStatement>();
-  auto* ptr = d.get();
+  auto* d = create<DiscardStatement>();
+  auto* ptr = d;
 
   BlockStatement b;
   b.append(std::move(d));
@@ -39,12 +39,12 @@
 }
 
 TEST_F(BlockStatementTest, Creation_WithInsert) {
-  auto s1 = create<DiscardStatement>();
-  auto s2 = create<DiscardStatement>();
-  auto s3 = create<DiscardStatement>();
-  auto* p1 = s1.get();
-  auto* p2 = s2.get();
-  auto* p3 = s3.get();
+  auto* s1 = create<DiscardStatement>();
+  auto* s2 = create<DiscardStatement>();
+  auto* s3 = create<DiscardStatement>();
+  auto* p1 = s1;
+  auto* p2 = s2;
+  auto* p3 = s3;
 
   BlockStatement b;
   b.insert(0, std::move(s1));
diff --git a/src/ast/builder.cc b/src/ast/builder.cc
index fce7b91..c30672a 100644
--- a/src/ast/builder.cc
+++ b/src/ast/builder.cc
@@ -19,15 +19,14 @@
 
 Builder::Builder() = default;
 
-Builder::Builder(Context* ctx) : ctx_(ctx) {}
+Builder::Builder(tint::Context* ctx) : ctx_(ctx) {}
 
 Builder::~Builder() = default;
 
-std::unique_ptr<ast::Variable> Builder::make_var(const std::string& name,
-                                                 ast::StorageClass storage,
-                                                 ast::type::Type* type) {
-  auto var = create<ast::Variable>(name, storage, type);
-  return var;
+ast::Variable* Builder::make_var(const std::string& name,
+                                 ast::StorageClass storage,
+                                 ast::type::Type* type) {
+  return create<ast::Variable>(name, storage, type);
 }
 
 }  // namespace ast
diff --git a/src/ast/builder.h b/src/ast/builder.h
index 77c9e2d..389d6c6 100644
--- a/src/ast/builder.h
+++ b/src/ast/builder.h
@@ -51,12 +51,12 @@
   Builder();
   /// Constructor
   /// @param ctx the context to use in the builder
-  explicit Builder(Context* ctx);
+  explicit Builder(tint::Context* ctx);
   virtual ~Builder();
 
   /// Sets the given context into the builder
   /// @param ctx the context to set
-  void set_context(Context* ctx) { ctx_ = ctx; }
+  void set_context(tint::Context* ctx) { ctx_ = ctx; }
 
   /// Creates a new type
   /// @param args the arguments to pass to the type constructor
@@ -106,63 +106,59 @@
 
   /// @param expr the expression
   /// @return expr
-  std::unique_ptr<ast::Expression> make_expr(
-      std::unique_ptr<ast::Expression> expr) {
-    return expr;
-  }
+  ast::Expression* make_expr(ast::Expression* expr) { return expr; }
 
   /// @param name the identifier name
   /// @return an IdentifierExpression with the given name
-  std::unique_ptr<ast::IdentifierExpression> make_expr(
-      const std::string& name) {
+  ast::IdentifierExpression* make_expr(const std::string& name) {
     return create<ast::IdentifierExpression>(name);
   }
 
   /// @param name the identifier name
   /// @return an IdentifierExpression with the given name
-  std::unique_ptr<ast::IdentifierExpression> make_expr(const char* name) {
+  ast::IdentifierExpression* make_expr(const char* name) {
     return create<ast::IdentifierExpression>(name);
   }
 
   /// @param value the float value
   /// @return a Scalar constructor for the given value
-  std::unique_ptr<ast::ScalarConstructorExpression> make_expr(float value) {
+  ast::ScalarConstructorExpression* make_expr(float value) {
     return create<ast::ScalarConstructorExpression>(make_literal(value));
   }
 
   /// @param value the int value
   /// @return a Scalar constructor for the given value
-  std::unique_ptr<ast::ScalarConstructorExpression> make_expr(int32_t value) {
+  ast::ScalarConstructorExpression* make_expr(int32_t value) {
     return create<ast::ScalarConstructorExpression>(make_literal(value));
   }
 
   /// @param value the unsigned int value
   /// @return a Scalar constructor for the given value
-  std::unique_ptr<ast::ScalarConstructorExpression> make_expr(uint32_t value) {
+  ast::ScalarConstructorExpression* make_expr(uint32_t value) {
     return create<ast::ScalarConstructorExpression>(make_literal(value));
   }
 
   /// @param val the boolan value
   /// @return a boolean literal with the given value
-  std::unique_ptr<ast::BoolLiteral> make_literal(bool val) {
+  ast::BoolLiteral* make_literal(bool val) {
     return create<ast::BoolLiteral>(bool_type(), val);
   }
 
   /// @param val the float value
   /// @return a float literal with the given value
-  std::unique_ptr<ast::FloatLiteral> make_literal(float val) {
+  ast::FloatLiteral* make_literal(float val) {
     return create<ast::FloatLiteral>(f32(), val);
   }
 
   /// @param val the unsigned int value
   /// @return a UintLiteral with the given value
-  std::unique_ptr<ast::UintLiteral> make_literal(uint32_t val) {
+  ast::UintLiteral* make_literal(uint32_t val) {
     return create<ast::UintLiteral>(u32(), val);
   }
 
   /// @param val the integer value
   /// @return the SintLiteral with the given value
-  std::unique_ptr<ast::SintLiteral> make_literal(int32_t val) {
+  ast::SintLiteral* make_literal(int32_t val) {
     return create<ast::SintLiteral>(i32(), val);
   }
 
@@ -191,8 +187,8 @@
   /// @return an `ast::TypeConstructorExpression` of type `ty`, with the values
   /// of `args` converted to `ast::Expression`s using `make_expr()`
   template <typename... ARGS>
-  std::unique_ptr<ast::TypeConstructorExpression> construct(ast::type::Type* ty,
-                                                            ARGS&&... args) {
+  ast::TypeConstructorExpression* construct(ast::type::Type* ty,
+                                            ARGS&&... args) {
     ast::ExpressionList vals;
     append_expr(vals, std::forward<ARGS>(args)...);
     return create<ast::TypeConstructorExpression>(ty, std::move(vals));
@@ -202,9 +198,9 @@
   /// @param storage the variable storage class
   /// @param type the variable type
   /// @returns a `ast::Variable` with the given name, storage and type
-  virtual std::unique_ptr<ast::Variable> make_var(const std::string& name,
-                                                  ast::StorageClass storage,
-                                                  ast::type::Type* type);
+  virtual ast::Variable* make_var(const std::string& name,
+                                  ast::StorageClass storage,
+                                  ast::type::Type* type);
 
   /// @param func the function name
   /// @param args the function call arguments
@@ -217,15 +213,17 @@
     return ast::CallExpression{make_expr(func), std::move(params)};
   }
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx_->create<T>(std::forward<ARGS>(args)...);
   }
 
  private:
-  Context* ctx_ = nullptr;
+  tint::Context* ctx_ = nullptr;
 };
 
 }  // namespace ast
diff --git a/src/ast/call_expression.cc b/src/ast/call_expression.cc
index 74ea7f4..c3d7d83 100644
--- a/src/ast/call_expression.cc
+++ b/src/ast/call_expression.cc
@@ -19,14 +19,13 @@
 
 CallExpression::CallExpression() : Expression() {}
 
-CallExpression::CallExpression(std::unique_ptr<Expression> func,
-                               ExpressionList params)
-    : Expression(), func_(std::move(func)), params_(std::move(params)) {}
+CallExpression::CallExpression(Expression* func, ExpressionList params)
+    : Expression(), func_(func), params_(params) {}
 
 CallExpression::CallExpression(const Source& source,
-                               std::unique_ptr<Expression> func,
+                               Expression* func,
                                ExpressionList params)
-    : Expression(source), func_(std::move(func)), params_(std::move(params)) {}
+    : Expression(source), func_(func), params_(params) {}
 
 CallExpression::CallExpression(CallExpression&&) = default;
 
@@ -41,7 +40,7 @@
     return false;
 
   // All params must be valid
-  for (const auto& param : params_) {
+  for (auto* param : params_) {
     if (param == nullptr || !param->IsValid())
       return false;
   }
@@ -55,7 +54,7 @@
 
   make_indent(out, indent + 2);
   out << "(" << std::endl;
-  for (const auto& param : params_)
+  for (auto* param : params_)
     param->to_str(out, indent + 4);
 
   make_indent(out, indent + 2);
diff --git a/src/ast/call_expression.h b/src/ast/call_expression.h
index 4edeb84..cae3f9c 100644
--- a/src/ast/call_expression.h
+++ b/src/ast/call_expression.h
@@ -32,27 +32,25 @@
   /// Constructor
   /// @param func the function
   /// @param params the parameters
-  CallExpression(std::unique_ptr<Expression> func, ExpressionList params);
+  CallExpression(Expression* func, ExpressionList params);
   /// Constructor
   /// @param source the call expression source
   /// @param func the function
   /// @param params the parameters
-  CallExpression(const Source& source,
-                 std::unique_ptr<Expression> func,
-                 ExpressionList params);
+  CallExpression(const Source& source, Expression* func, ExpressionList params);
   /// Move constructor
   CallExpression(CallExpression&&);
   ~CallExpression() override;
 
   /// Sets the func
   /// @param func the func
-  void set_func(std::unique_ptr<Expression> func) { func_ = std::move(func); }
+  void set_func(Expression* func) { func_ = func; }
   /// @returns the func
-  Expression* func() const { return func_.get(); }
+  Expression* func() const { return func_; }
 
   /// Sets the parameters
   /// @param params the parameters
-  void set_params(ExpressionList params) { params_ = std::move(params); }
+  void set_params(ExpressionList params) { params_ = params; }
   /// @returns the parameters
   const ExpressionList& params() const { return params_; }
 
@@ -70,7 +68,7 @@
  private:
   CallExpression(const CallExpression&) = delete;
 
-  std::unique_ptr<Expression> func_;
+  Expression* func_ = nullptr;
   ExpressionList params_;
 };
 
diff --git a/src/ast/call_expression_test.cc b/src/ast/call_expression_test.cc
index e03fd9f..885bc87 100644
--- a/src/ast/call_expression_test.cc
+++ b/src/ast/call_expression_test.cc
@@ -24,26 +24,26 @@
 using CallExpressionTest = TestHelper;
 
 TEST_F(CallExpressionTest, Creation) {
-  auto func = create<IdentifierExpression>("func");
+  auto* func = create<IdentifierExpression>("func");
   ExpressionList params;
   params.push_back(create<IdentifierExpression>("param1"));
   params.push_back(create<IdentifierExpression>("param2"));
 
-  auto* func_ptr = func.get();
-  auto* param1_ptr = params[0].get();
-  auto* param2_ptr = params[1].get();
+  auto* func_ptr = func;
+  auto* param1_ptr = params[0];
+  auto* param2_ptr = params[1];
 
   CallExpression stmt(std::move(func), std::move(params));
   EXPECT_EQ(stmt.func(), func_ptr);
 
   const auto& vec = stmt.params();
   ASSERT_EQ(vec.size(), 2u);
-  EXPECT_EQ(vec[0].get(), param1_ptr);
-  EXPECT_EQ(vec[1].get(), param2_ptr);
+  EXPECT_EQ(vec[0], param1_ptr);
+  EXPECT_EQ(vec[1], param2_ptr);
 }
 
 TEST_F(CallExpressionTest, Creation_WithSource) {
-  auto func = create<IdentifierExpression>("func");
+  auto* func = create<IdentifierExpression>("func");
   CallExpression stmt(Source{Source::Location{20, 2}}, std::move(func), {});
   auto src = stmt.source();
   EXPECT_EQ(src.range.begin.line, 20u);
@@ -51,13 +51,13 @@
 }
 
 TEST_F(CallExpressionTest, IsCall) {
-  auto func = create<IdentifierExpression>("func");
+  auto* func = create<IdentifierExpression>("func");
   CallExpression stmt(std::move(func), {});
   EXPECT_TRUE(stmt.IsCall());
 }
 
 TEST_F(CallExpressionTest, IsValid) {
-  auto func = create<IdentifierExpression>("func");
+  auto* func = create<IdentifierExpression>("func");
   CallExpression stmt(std::move(func), {});
   EXPECT_TRUE(stmt.IsValid());
 }
@@ -68,7 +68,7 @@
 }
 
 TEST_F(CallExpressionTest, IsValid_NullParam) {
-  auto func = create<IdentifierExpression>("func");
+  auto* func = create<IdentifierExpression>("func");
   ExpressionList params;
   params.push_back(create<IdentifierExpression>("param1"));
   params.push_back(nullptr);
@@ -79,7 +79,7 @@
 }
 
 TEST_F(CallExpressionTest, IsValid_InvalidFunction) {
-  auto func = create<IdentifierExpression>("");
+  auto* func = create<IdentifierExpression>("");
   ExpressionList params;
   params.push_back(create<IdentifierExpression>("param1"));
 
@@ -88,7 +88,7 @@
 }
 
 TEST_F(CallExpressionTest, IsValid_InvalidParam) {
-  auto func = create<IdentifierExpression>("func");
+  auto* func = create<IdentifierExpression>("func");
   ExpressionList params;
   params.push_back(create<IdentifierExpression>(""));
 
@@ -97,7 +97,7 @@
 }
 
 TEST_F(CallExpressionTest, ToStr_NoParams) {
-  auto func = create<IdentifierExpression>("func");
+  auto* func = create<IdentifierExpression>("func");
   CallExpression stmt(std::move(func), {});
   std::ostringstream out;
   stmt.to_str(out, 2);
@@ -110,7 +110,7 @@
 }
 
 TEST_F(CallExpressionTest, ToStr_WithParams) {
-  auto func = create<IdentifierExpression>("func");
+  auto* func = create<IdentifierExpression>("func");
   ExpressionList params;
   params.push_back(create<IdentifierExpression>("param1"));
   params.push_back(create<IdentifierExpression>("param2"));
diff --git a/src/ast/call_statement.cc b/src/ast/call_statement.cc
index 9bc4925..7c43049 100644
--- a/src/ast/call_statement.cc
+++ b/src/ast/call_statement.cc
@@ -21,8 +21,7 @@
 
 CallStatement::CallStatement() : Statement() {}
 
-CallStatement::CallStatement(std::unique_ptr<CallExpression> call)
-    : Statement(), call_(std::move(call)) {}
+CallStatement::CallStatement(CallExpression* call) : Statement(), call_(call) {}
 
 CallStatement::CallStatement(CallStatement&&) = default;
 
diff --git a/src/ast/call_statement.h b/src/ast/call_statement.h
index 374136b..c4cee4d 100644
--- a/src/ast/call_statement.h
+++ b/src/ast/call_statement.h
@@ -31,18 +31,16 @@
   CallStatement();
   /// Constructor
   /// @param call the function
-  explicit CallStatement(std::unique_ptr<CallExpression> call);
+  explicit CallStatement(CallExpression* call);
   /// Move constructor
   CallStatement(CallStatement&&);
   ~CallStatement() override;
 
   /// Sets the call expression
   /// @param call the call
-  void set_expr(std::unique_ptr<CallExpression> call) {
-    call_ = std::move(call);
-  }
+  void set_expr(CallExpression* call) { call_ = call; }
   /// @returns the call expression
-  CallExpression* expr() const { return call_.get(); }
+  CallExpression* expr() const { return call_; }
 
   /// @returns true if this is a call statement
   bool IsCall() const override;
@@ -58,7 +56,7 @@
  private:
   CallStatement(const CallStatement&) = delete;
 
-  std::unique_ptr<CallExpression> call_;
+  CallExpression* call_ = nullptr;
 };
 
 }  // namespace ast
diff --git a/src/ast/call_statement_test.cc b/src/ast/call_statement_test.cc
index b186606..4201fce 100644
--- a/src/ast/call_statement_test.cc
+++ b/src/ast/call_statement_test.cc
@@ -25,9 +25,9 @@
 using CallStatementTest = TestHelper;
 
 TEST_F(CallStatementTest, Creation) {
-  auto expr = create<ast::CallExpression>(
+  auto* expr = create<ast::CallExpression>(
       create<ast::IdentifierExpression>("func"), ExpressionList{});
-  auto* expr_ptr = expr.get();
+  auto* expr_ptr = expr;
 
   CallStatement c(std::move(expr));
   EXPECT_EQ(c.expr(), expr_ptr);
diff --git a/src/ast/case_statement.cc b/src/ast/case_statement.cc
index 3b137aa..667390c 100644
--- a/src/ast/case_statement.cc
+++ b/src/ast/case_statement.cc
@@ -17,19 +17,15 @@
 namespace tint {
 namespace ast {
 
-CaseStatement::CaseStatement(std::unique_ptr<BlockStatement> body)
-    : Statement(), body_(std::move(body)) {}
+CaseStatement::CaseStatement(BlockStatement* body) : Statement(), body_(body) {}
 
-CaseStatement::CaseStatement(CaseSelectorList selectors,
-                             std::unique_ptr<BlockStatement> body)
-    : Statement(), selectors_(std::move(selectors)), body_(std::move(body)) {}
+CaseStatement::CaseStatement(CaseSelectorList selectors, BlockStatement* body)
+    : Statement(), selectors_(selectors), body_(body) {}
 
 CaseStatement::CaseStatement(const Source& source,
                              CaseSelectorList selectors,
-                             std::unique_ptr<BlockStatement> body)
-    : Statement(source),
-      selectors_(std::move(selectors)),
-      body_(std::move(body)) {}
+                             BlockStatement* body)
+    : Statement(source), selectors_(selectors), body_(body) {}
 
 CaseStatement::CaseStatement(CaseStatement&&) = default;
 
@@ -51,7 +47,7 @@
   } else {
     out << "Case ";
     bool first = true;
-    for (const auto& selector : selectors_) {
+    for (auto* selector : selectors_) {
       if (!first)
         out << ", ";
 
@@ -62,7 +58,7 @@
   }
 
   if (body_ != nullptr) {
-    for (const auto& stmt : *body_) {
+    for (auto* stmt : *body_) {
       stmt->to_str(out, indent + 2);
     }
   }
diff --git a/src/ast/case_statement.h b/src/ast/case_statement.h
index b15c93b..73844fd 100644
--- a/src/ast/case_statement.h
+++ b/src/ast/case_statement.h
@@ -28,7 +28,7 @@
 namespace ast {
 
 /// A list of case literals
-using CaseSelectorList = std::vector<std::unique_ptr<ast::IntLiteral>>;
+using CaseSelectorList = std::vector<IntLiteral*>;
 
 /// A case statement
 class CaseStatement : public Statement {
@@ -36,19 +36,18 @@
   /// Constructor
   /// Creates a default case statement
   /// @param body the case body
-  explicit CaseStatement(std::unique_ptr<BlockStatement> body);
+  explicit CaseStatement(BlockStatement* body);
   /// Constructor
   /// @param selectors the case selectors
   /// @param body the case body
-  CaseStatement(CaseSelectorList selectors,
-                std::unique_ptr<BlockStatement> body);
+  CaseStatement(CaseSelectorList selectors, BlockStatement* body);
   /// Constructor
   /// @param source the source information
   /// @param selectors the case selectors
   /// @param body the case body
   CaseStatement(const Source& source,
                 CaseSelectorList selectors,
-                std::unique_ptr<BlockStatement> body);
+                BlockStatement* body);
   /// Move constructor
   CaseStatement(CaseStatement&&);
   ~CaseStatement() override;
@@ -65,13 +64,11 @@
 
   /// Sets the case body
   /// @param body the case body
-  void set_body(std::unique_ptr<BlockStatement> body) {
-    body_ = std::move(body);
-  }
+  void set_body(BlockStatement* body) { body_ = body; }
   /// @returns the case body
-  const BlockStatement* body() const { return body_.get(); }
+  const BlockStatement* body() const { return body_; }
   /// @returns the case body
-  BlockStatement* body() { return body_.get(); }
+  BlockStatement* body() { return body_; }
 
   /// @returns true if this is a case statement
   bool IsCase() const override;
@@ -88,11 +85,11 @@
   CaseStatement(const CaseStatement&) = delete;
 
   CaseSelectorList selectors_;
-  std::unique_ptr<BlockStatement> body_;
+  BlockStatement* body_ = nullptr;
 };
 
-/// A list of unique case statements
-using CaseStatementList = std::vector<std::unique_ptr<CaseStatement>>;
+/// A list of case statements
+using CaseStatementList = std::vector<CaseStatement*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/case_statement_test.cc b/src/ast/case_statement_test.cc
index 0e9cb90..bc87b85 100644
--- a/src/ast/case_statement_test.cc
+++ b/src/ast/case_statement_test.cc
@@ -34,15 +34,15 @@
   CaseSelectorList b;
   b.push_back(create<SintLiteral>(&i32, 2));
 
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
-  auto* int_ptr = b.back().get();
+  auto* int_ptr = b.back();
   auto* discard_ptr = body->get(0);
 
   CaseStatement c(std::move(b), std::move(body));
   ASSERT_EQ(c.selectors().size(), 1u);
-  EXPECT_EQ(c.selectors()[0].get(), int_ptr);
+  EXPECT_EQ(c.selectors()[0], int_ptr);
   ASSERT_EQ(c.body()->size(), 1u);
   EXPECT_EQ(c.body()->get(0), discard_ptr);
 }
@@ -53,15 +53,15 @@
   CaseSelectorList b;
   b.push_back(create<UintLiteral>(&u32, 2));
 
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
-  auto* int_ptr = b.back().get();
+  auto* int_ptr = b.back();
   auto* discard_ptr = body->get(0);
 
   CaseStatement c(std::move(b), std::move(body));
   ASSERT_EQ(c.selectors().size(), 1u);
-  EXPECT_EQ(c.selectors()[0].get(), int_ptr);
+  EXPECT_EQ(c.selectors()[0], int_ptr);
   ASSERT_EQ(c.body()->size(), 1u);
   EXPECT_EQ(c.body()->get(0), discard_ptr);
 }
@@ -71,7 +71,7 @@
   CaseSelectorList b;
   b.push_back(create<SintLiteral>(&i32, 2));
 
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   CaseStatement c(Source{Source::Location{20, 2}}, std::move(b),
@@ -82,7 +82,7 @@
 }
 
 TEST_F(CaseStatementTest, IsDefault_WithoutSelectors) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   CaseStatement c(create<ast::BlockStatement>());
@@ -115,7 +115,7 @@
   CaseSelectorList b;
   b.push_back(create<SintLiteral>(&i32, 2));
 
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
   body->append(nullptr);
 
@@ -128,7 +128,7 @@
   CaseSelectorList b;
   b.push_back(create<SintLiteral>(&i32, 2));
 
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<IfStatement>(nullptr, create<ast::BlockStatement>()));
 
   CaseStatement c({std::move(b)}, std::move(body));
@@ -140,7 +140,7 @@
   CaseSelectorList b;
   b.push_back(create<SintLiteral>(&i32, -2));
 
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
   CaseStatement c({std::move(b)}, std::move(body));
 
@@ -157,7 +157,7 @@
   CaseSelectorList b;
   b.push_back(create<UintLiteral>(&u32, 2));
 
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
   CaseStatement c({std::move(b)}, std::move(body));
 
@@ -176,7 +176,7 @@
   b.push_back(create<SintLiteral>(&i32, 1));
   b.push_back(create<SintLiteral>(&i32, 2));
 
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
   CaseStatement c(std::move(b), std::move(body));
 
@@ -189,7 +189,7 @@
 }
 
 TEST_F(CaseStatementTest, ToStr_WithoutSelectors) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
   CaseStatement c(CaseSelectorList{}, std::move(body));
 
diff --git a/src/ast/decorated_variable.cc b/src/ast/decorated_variable.cc
index f0b621a..cd83395 100644
--- a/src/ast/decorated_variable.cc
+++ b/src/ast/decorated_variable.cc
@@ -23,7 +23,7 @@
 
 DecoratedVariable::DecoratedVariable() = default;
 
-DecoratedVariable::DecoratedVariable(std::unique_ptr<Variable> var)
+DecoratedVariable::DecoratedVariable(Variable* var)
     : Variable(var->source(), var->name(), var->storage_class(), var->type()) {}
 
 DecoratedVariable::DecoratedVariable(DecoratedVariable&&) = default;
@@ -31,7 +31,7 @@
 DecoratedVariable::~DecoratedVariable() = default;
 
 bool DecoratedVariable::HasLocationDecoration() const {
-  for (const auto& deco : decorations_) {
+  for (auto* deco : decorations_) {
     if (deco->IsLocation()) {
       return true;
     }
@@ -40,7 +40,7 @@
 }
 
 bool DecoratedVariable::HasBuiltinDecoration() const {
-  for (const auto& deco : decorations_) {
+  for (auto* deco : decorations_) {
     if (deco->IsBuiltin()) {
       return true;
     }
@@ -49,7 +49,7 @@
 }
 
 bool DecoratedVariable::HasConstantIdDecoration() const {
-  for (const auto& deco : decorations_) {
+  for (auto* deco : decorations_) {
     if (deco->IsConstantId()) {
       return true;
     }
@@ -59,7 +59,7 @@
 
 uint32_t DecoratedVariable::constant_id() const {
   assert(HasConstantIdDecoration());
-  for (const auto& deco : decorations_) {
+  for (auto* deco : decorations_) {
     if (deco->IsConstantId()) {
       return deco->AsConstantId()->value();
     }
@@ -85,7 +85,7 @@
 
   make_indent(out, indent + 2);
   out << "Decorations{" << std::endl;
-  for (const auto& deco : decorations_) {
+  for (auto* deco : decorations_) {
     deco->to_str(out, indent + 4);
   }
 
diff --git a/src/ast/decorated_variable.h b/src/ast/decorated_variable.h
index 54f8b07..8c2c34b 100644
--- a/src/ast/decorated_variable.h
+++ b/src/ast/decorated_variable.h
@@ -31,7 +31,7 @@
   DecoratedVariable();
   /// Create a decorated variable from an existing variable
   /// @param var the variable to initialize from
-  explicit DecoratedVariable(std::unique_ptr<Variable> var);
+  explicit DecoratedVariable(Variable* var);
   /// Move constructor
   DecoratedVariable(DecoratedVariable&&);
 
diff --git a/src/ast/decorated_variable_test.cc b/src/ast/decorated_variable_test.cc
index 706a509..70f1ab7 100644
--- a/src/ast/decorated_variable_test.cc
+++ b/src/ast/decorated_variable_test.cc
@@ -34,7 +34,7 @@
 
 TEST_F(DecoratedVariableTest, Creation) {
   type::I32Type t;
-  auto var = create<Variable>("my_var", StorageClass::kFunction, &t);
+  auto* var = create<Variable>("my_var", StorageClass::kFunction, &t);
   DecoratedVariable dv(std::move(var));
 
   EXPECT_EQ(dv.name(), "my_var");
@@ -49,7 +49,7 @@
 TEST_F(DecoratedVariableTest, CreationWithSource) {
   Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}};
   type::F32Type t;
-  auto var = create<Variable>(s, "i", StorageClass::kPrivate, &t);
+  auto* var = create<Variable>(s, "i", StorageClass::kPrivate, &t);
   DecoratedVariable dv(std::move(var));
 
   EXPECT_EQ(dv.name(), "i");
@@ -63,7 +63,7 @@
 
 TEST_F(DecoratedVariableTest, NoDecorations) {
   type::I32Type t;
-  auto var = create<Variable>("my_var", StorageClass::kFunction, &t);
+  auto* var = create<Variable>("my_var", StorageClass::kFunction, &t);
   DecoratedVariable dv(std::move(var));
   EXPECT_FALSE(dv.HasLocationDecoration());
   EXPECT_FALSE(dv.HasBuiltinDecoration());
@@ -72,7 +72,7 @@
 
 TEST_F(DecoratedVariableTest, WithDecorations) {
   type::F32Type t;
-  auto var = create<Variable>("my_var", StorageClass::kFunction, &t);
+  auto* var = create<Variable>("my_var", StorageClass::kFunction, &t);
   DecoratedVariable dv(std::move(var));
 
   VariableDecorationList decos;
@@ -89,7 +89,7 @@
 
 TEST_F(DecoratedVariableTest, ConstantId) {
   type::F32Type t;
-  auto var = create<Variable>("my_var", StorageClass::kFunction, &t);
+  auto* var = create<Variable>("my_var", StorageClass::kFunction, &t);
   DecoratedVariable dv(std::move(var));
 
   VariableDecorationList decos;
@@ -101,7 +101,7 @@
 
 TEST_F(DecoratedVariableTest, IsValid) {
   type::I32Type t;
-  auto var = create<Variable>("my_var", StorageClass::kNone, &t);
+  auto* var = create<Variable>("my_var", StorageClass::kNone, &t);
   DecoratedVariable dv(std::move(var));
   EXPECT_TRUE(dv.IsValid());
 }
@@ -113,7 +113,7 @@
 
 TEST_F(DecoratedVariableTest, to_str) {
   type::F32Type t;
-  auto var = create<Variable>("my_var", StorageClass::kFunction, &t);
+  auto* var = create<Variable>("my_var", StorageClass::kFunction, &t);
   DecoratedVariable dv(std::move(var));
   dv.set_constructor(create<IdentifierExpression>("expr"));
 
diff --git a/src/ast/decoration.h b/src/ast/decoration.h
index ea6d686..9b43a08 100644
--- a/src/ast/decoration.h
+++ b/src/ast/decoration.h
@@ -65,22 +65,20 @@
 };
 
 /// As dynamically casts |deco| to the target type |TO|.
-/// @return the dynamically cast decoration, or nullptr if |deco| is not of the
-/// type |TO|.
+/// @return the cast decoration, or nullptr if |deco| is not of the type |TO|.
 template <typename TO>
-std::unique_ptr<TO> As(std::unique_ptr<Decoration>&& deco) {
+TO* As(Decoration* deco) {
   if (deco == nullptr) {
     return nullptr;
   }
   if (deco->Is<TO>()) {
-    auto ptr = static_cast<TO*>(deco.release());
-    return std::unique_ptr<TO>(ptr);
+    return static_cast<TO*>(deco);
   }
   return nullptr;
 }
 
-/// A list of unique decorations
-using DecorationList = std::vector<std::unique_ptr<Decoration>>;
+/// A list of decorations
+using DecorationList = std::vector<Decoration*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/decoration_test.cc b/src/ast/decoration_test.cc
index 06029e7..104dbb7 100644
--- a/src/ast/decoration_test.cc
+++ b/src/ast/decoration_test.cc
@@ -28,21 +28,21 @@
 using DecorationTest = TestHelper;
 
 TEST_F(DecorationTest, AsCorrectType) {
-  auto* decoration = new ConstantIdDecoration(1, Source{});
-  auto upcast = std::unique_ptr<Decoration>(decoration);
-  auto downcast = As<VariableDecoration>(std::move(upcast));
-  EXPECT_EQ(decoration, downcast.get());
+  auto* decoration = create<ConstantIdDecoration>(1, Source{});
+  auto* upcast = static_cast<Decoration*>(decoration);
+  auto* downcast = As<VariableDecoration>(upcast);
+  EXPECT_EQ(decoration, downcast);
 }
 
 TEST_F(DecorationTest, AsIncorrectType) {
-  auto* decoration = new ConstantIdDecoration(1, Source{});
-  auto upcast = std::unique_ptr<Decoration>(decoration);
-  auto downcast = As<ArrayDecoration>(std::move(upcast));
-  EXPECT_EQ(nullptr, downcast.get());
+  auto* decoration = create<ConstantIdDecoration>(1, Source{});
+  auto* upcast = static_cast<Decoration*>(decoration);
+  auto* downcast = As<ArrayDecoration>(upcast);
+  EXPECT_EQ(nullptr, downcast);
 }
 
 TEST_F(DecorationTest, Is) {
-  auto decoration = create<ConstantIdDecoration>(1, Source{});
+  auto* decoration = create<ConstantIdDecoration>(1, Source{});
   EXPECT_TRUE(decoration->Is<VariableDecoration>());
   EXPECT_FALSE(decoration->Is<ArrayDecoration>());
 }
diff --git a/src/ast/else_statement.cc b/src/ast/else_statement.cc
index f216144..b084f8d 100644
--- a/src/ast/else_statement.cc
+++ b/src/ast/else_statement.cc
@@ -17,23 +17,18 @@
 namespace tint {
 namespace ast {
 
-ElseStatement::ElseStatement(std::unique_ptr<BlockStatement> body)
-    : Statement(), body_(std::move(body)) {}
+ElseStatement::ElseStatement(BlockStatement* body) : Statement(), body_(body) {}
 
-ElseStatement::ElseStatement(std::unique_ptr<Expression> condition,
-                             std::unique_ptr<BlockStatement> body)
-    : Statement(), condition_(std::move(condition)), body_(std::move(body)) {}
+ElseStatement::ElseStatement(Expression* condition, BlockStatement* body)
+    : Statement(), condition_(condition), body_(body) {}
+
+ElseStatement::ElseStatement(const Source& source, BlockStatement* body)
+    : Statement(source), body_(body) {}
 
 ElseStatement::ElseStatement(const Source& source,
-                             std::unique_ptr<BlockStatement> body)
-    : Statement(source), body_(std::move(body)) {}
-
-ElseStatement::ElseStatement(const Source& source,
-                             std::unique_ptr<Expression> condition,
-                             std::unique_ptr<BlockStatement> body)
-    : Statement(source),
-      condition_(std::move(condition)),
-      body_(std::move(body)) {}
+                             Expression* condition,
+                             BlockStatement* body)
+    : Statement(source), condition_(condition), body_(body) {}
 
 ElseStatement::ElseStatement(ElseStatement&&) = default;
 
@@ -67,7 +62,7 @@
   out << "{" << std::endl;
 
   if (body_ != nullptr) {
-    for (const auto& stmt : *body_) {
+    for (auto* stmt : *body_) {
       stmt->to_str(out, indent + 4);
     }
   }
diff --git a/src/ast/else_statement.h b/src/ast/else_statement.h
index 5fb3801..c1feb6e 100644
--- a/src/ast/else_statement.h
+++ b/src/ast/else_statement.h
@@ -31,46 +31,41 @@
  public:
   /// Constructor
   /// @param body the else body
-  explicit ElseStatement(std::unique_ptr<BlockStatement> body);
+  explicit ElseStatement(BlockStatement* body);
   /// Constructor
   /// @param condition the else condition
   /// @param body the else body
-  ElseStatement(std::unique_ptr<Expression> condition,
-                std::unique_ptr<BlockStatement> body);
+  ElseStatement(Expression* condition, BlockStatement* body);
   /// Constructor
   /// @param source the source information
   /// @param body the else body
-  ElseStatement(const Source& source, std::unique_ptr<BlockStatement> body);
+  ElseStatement(const Source& source, BlockStatement* body);
   /// Constructor
   /// @param source the source information
   /// @param condition the else condition
   /// @param body the else body
   ElseStatement(const Source& source,
-                std::unique_ptr<Expression> condition,
-                std::unique_ptr<BlockStatement> body);
+                Expression* condition,
+                BlockStatement* body);
   /// Move constructor
   ElseStatement(ElseStatement&&);
   ~ElseStatement() override;
 
   /// Sets the condition for the else statement
   /// @param condition the condition to set
-  void set_condition(std::unique_ptr<Expression> condition) {
-    condition_ = std::move(condition);
-  }
+  void set_condition(Expression* condition) { condition_ = condition; }
   /// @returns the else condition or nullptr if none set
-  Expression* condition() const { return condition_.get(); }
+  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(std::unique_ptr<BlockStatement> body) {
-    body_ = std::move(body);
-  }
+  void set_body(BlockStatement* body) { body_ = body; }
   /// @returns the else body
-  const BlockStatement* body() const { return body_.get(); }
+  const BlockStatement* body() const { return body_; }
   /// @returns the else body
-  BlockStatement* body() { return body_.get(); }
+  BlockStatement* body() { return body_; }
 
   /// @returns true if this is a else statement
   bool IsElse() const override;
@@ -86,12 +81,12 @@
  private:
   ElseStatement(const ElseStatement&) = delete;
 
-  std::unique_ptr<Expression> condition_;
-  std::unique_ptr<BlockStatement> body_;
+  Expression* condition_ = nullptr;
+  BlockStatement* body_ = nullptr;
 };
 
-/// A list of unique else statements
-using ElseStatementList = std::vector<std::unique_ptr<ElseStatement>>;
+/// A list of else statements
+using ElseStatementList = std::vector<ElseStatement*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/else_statement_test.cc b/src/ast/else_statement_test.cc
index 8c3acdc..b52cbec 100644
--- a/src/ast/else_statement_test.cc
+++ b/src/ast/else_statement_test.cc
@@ -29,12 +29,12 @@
 
 TEST_F(ElseStatementTest, Creation) {
   ast::type::BoolType bool_type;
-  auto cond = create<ScalarConstructorExpression>(
+  auto* cond = create<ScalarConstructorExpression>(
       create<BoolLiteral>(&bool_type, true));
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
-  auto* cond_ptr = cond.get();
+  auto* cond_ptr = cond;
   auto* discard_ptr = body->get(0);
 
   ElseStatement e(std::move(cond), std::move(body));
@@ -57,7 +57,7 @@
 
 TEST_F(ElseStatementTest, HasCondition) {
   ast::type::BoolType bool_type;
-  auto cond = create<ScalarConstructorExpression>(
+  auto* cond = create<ScalarConstructorExpression>(
       create<BoolLiteral>(&bool_type, true));
   ElseStatement e(std::move(cond), create<BlockStatement>());
   EXPECT_TRUE(e.HasCondition());
@@ -74,7 +74,7 @@
 }
 
 TEST_F(ElseStatementTest, IsValid_WithBody) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   ElseStatement e(std::move(body));
@@ -82,7 +82,7 @@
 }
 
 TEST_F(ElseStatementTest, IsValid_WithNullBodyStatement) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
   body->append(nullptr);
 
@@ -91,13 +91,13 @@
 }
 
 TEST_F(ElseStatementTest, IsValid_InvalidCondition) {
-  auto cond = create<ScalarConstructorExpression>();
+  auto* cond = create<ScalarConstructorExpression>();
   ElseStatement e(std::move(cond), create<BlockStatement>());
   EXPECT_FALSE(e.IsValid());
 }
 
 TEST_F(ElseStatementTest, IsValid_InvalidBodyStatement) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<IfStatement>(nullptr, create<ast::BlockStatement>()));
 
   ElseStatement e(std::move(body));
@@ -106,9 +106,9 @@
 
 TEST_F(ElseStatementTest, ToStr) {
   ast::type::BoolType bool_type;
-  auto cond = create<ScalarConstructorExpression>(
+  auto* cond = create<ScalarConstructorExpression>(
       create<BoolLiteral>(&bool_type, true));
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   ElseStatement e(std::move(cond), std::move(body));
@@ -126,7 +126,7 @@
 }
 
 TEST_F(ElseStatementTest, ToStr_NoCondition) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   ElseStatement e(std::move(body));
diff --git a/src/ast/expression.h b/src/ast/expression.h
index 603ae92..e696812 100644
--- a/src/ast/expression.h
+++ b/src/ast/expression.h
@@ -117,8 +117,8 @@
   type::Type* result_type_ = nullptr;
 };
 
-/// A list of unique expressions
-using ExpressionList = std::vector<std::unique_ptr<Expression>>;
+/// A list of expressions
+using ExpressionList = std::vector<Expression*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/function.cc b/src/ast/function.cc
index 7ff3774..da18d53 100644
--- a/src/ast/function.cc
+++ b/src/ast/function.cc
@@ -29,30 +29,30 @@
 Function::Function(const std::string& name,
                    VariableList params,
                    type::Type* return_type,
-                   std::unique_ptr<BlockStatement> body)
+                   BlockStatement* body)
     : Node(),
       name_(name),
       params_(std::move(params)),
       return_type_(return_type),
-      body_(std::move(body)) {}
+      body_(body) {}
 
 Function::Function(const Source& source,
                    const std::string& name,
                    VariableList params,
                    type::Type* return_type,
-                   std::unique_ptr<BlockStatement> body)
+                   BlockStatement* body)
     : Node(source),
       name_(name),
       params_(std::move(params)),
       return_type_(return_type),
-      body_(std::move(body)) {}
+      body_(body) {}
 
 Function::Function(Function&&) = default;
 
 Function::~Function() = default;
 
 std::tuple<uint32_t, uint32_t, uint32_t> Function::workgroup_size() const {
-  for (const auto& deco : decorations_) {
+  for (auto* deco : decorations_) {
     if (deco->IsWorkgroup()) {
       return deco->AsWorkgroup()->values();
     }
@@ -61,7 +61,7 @@
 }
 
 ast::PipelineStage Function::pipeline_stage() const {
-  for (const auto& deco : decorations_) {
+  for (auto* deco : decorations_) {
     if (deco->IsStage()) {
       return deco->AsStage()->value();
     }
@@ -86,9 +86,9 @@
     if (!var->IsDecorated()) {
       continue;
     }
-    for (auto& deco : var->AsDecorated()->decorations()) {
+    for (auto* deco : var->AsDecorated()->decorations()) {
       if (deco->IsLocation()) {
-        ret.push_back({var, deco.get()->AsLocation()});
+        ret.push_back({var, deco->AsLocation()});
         break;
       }
     }
@@ -108,7 +108,7 @@
 
     BindingDecoration* binding = nullptr;
     SetDecoration* set = nullptr;
-    for (const auto& deco : var->AsDecorated()->decorations()) {
+    for (auto* deco : var->AsDecorated()->decorations()) {
       if (deco->IsBinding()) {
         binding = deco->AsBinding();
       } else if (deco->IsSet()) {
@@ -136,7 +136,7 @@
 
     BindingDecoration* binding = nullptr;
     SetDecoration* set = nullptr;
-    for (const auto& deco : var->AsDecorated()->decorations()) {
+    for (auto* deco : var->AsDecorated()->decorations()) {
       if (deco->IsBinding()) {
         binding = deco->AsBinding();
       } else if (deco->IsSet()) {
@@ -160,9 +160,9 @@
     if (!var->IsDecorated()) {
       continue;
     }
-    for (auto& deco : var->AsDecorated()->decorations()) {
+    for (auto* deco : var->AsDecorated()->decorations()) {
       if (deco->IsBuiltin()) {
-        ret.push_back({var, deco.get()->AsBuiltin()});
+        ret.push_back({var, deco->AsBuiltin()});
         break;
       }
     }
@@ -213,7 +213,7 @@
 }
 
 bool Function::IsValid() const {
-  for (const auto& param : params_) {
+  for (auto* param : params_) {
     if (param == nullptr || !param->IsValid())
       return false;
   }
@@ -234,7 +234,7 @@
   out << "Function " << name_ << " -> " << return_type_->type_name()
       << std::endl;
 
-  for (const auto& deco : decorations()) {
+  for (auto* deco : decorations()) {
     deco->to_str(out, indent);
   }
 
@@ -244,7 +244,7 @@
   if (params_.size() > 0) {
     out << std::endl;
 
-    for (const auto& param : params_)
+    for (auto* param : params_)
       param->to_str(out, indent + 2);
 
     make_indent(out, indent);
@@ -255,7 +255,7 @@
   out << "{" << std::endl;
 
   if (body_ != nullptr) {
-    for (const auto& stmt : *body_) {
+    for (auto* stmt : *body_) {
       stmt->to_str(out, indent + 2);
     }
   }
@@ -268,7 +268,7 @@
   std::ostringstream out;
 
   out << "__func" + return_type_->type_name();
-  for (const auto& param : params_) {
+  for (auto* param : params_) {
     out << param->type()->type_name();
   }
 
@@ -288,7 +288,7 @@
 
     BindingDecoration* binding = nullptr;
     SetDecoration* set = nullptr;
-    for (const auto& deco : var->AsDecorated()->decorations()) {
+    for (auto* deco : var->AsDecorated()->decorations()) {
       if (deco->IsBinding()) {
         binding = deco->AsBinding();
       } else if (deco->IsSet()) {
@@ -321,7 +321,7 @@
 
     BindingDecoration* binding = nullptr;
     SetDecoration* set = nullptr;
-    for (const auto& deco : var->AsDecorated()->decorations()) {
+    for (auto* deco : var->AsDecorated()->decorations()) {
       if (deco->IsBinding()) {
         binding = deco->AsBinding();
       } else if (deco->IsSet()) {
diff --git a/src/ast/function.h b/src/ast/function.h
index cbd4d20..679a6d8 100644
--- a/src/ast/function.h
+++ b/src/ast/function.h
@@ -51,8 +51,7 @@
   };
 
   /// Create a new empty function statement
-  Function();
-  /// Create a function
+  Function();  /// Create a function
   /// @param name the function name
   /// @param params the function parameters
   /// @param return_type the return type
@@ -60,7 +59,7 @@
   Function(const std::string& name,
            VariableList params,
            type::Type* return_type,
-           std::unique_ptr<BlockStatement> body);
+           BlockStatement* body);
   /// Create a function
   /// @param source the variable source
   /// @param name the function name
@@ -71,7 +70,7 @@
            const std::string& name,
            VariableList params,
            type::Type* return_type,
-           std::unique_ptr<BlockStatement> body);
+           BlockStatement* body);
   /// Move constructor
   Function(Function&&);
 
@@ -97,8 +96,8 @@
   }
   /// Adds a decoration to the function
   /// @param deco the decoration to set
-  void add_decoration(std::unique_ptr<FunctionDecoration> deco) {
-    decorations_.push_back(std::move(deco));
+  void add_decoration(FunctionDecoration* deco) {
+    decorations_.push_back(deco);
   }
   /// @returns the decorations attached to this function
   const FunctionDecorationList& decorations() const { return decorations_; }
@@ -187,13 +186,11 @@
 
   /// Sets the body of the function
   /// @param body the function body
-  void set_body(std::unique_ptr<BlockStatement> body) {
-    body_ = std::move(body);
-  }
+  void set_body(BlockStatement* body) { body_ = body; }
   /// @returns the function body
-  const BlockStatement* body() const { return body_.get(); }
+  const BlockStatement* body() const { return body_; }
   /// @returns the function body
-  BlockStatement* body() { return body_.get(); }
+  BlockStatement* body() { return body_; }
 
   /// @returns true if the name and type are both present
   bool IsValid() const override;
@@ -216,14 +213,14 @@
   std::string name_;
   VariableList params_;
   type::Type* return_type_ = nullptr;
-  std::unique_ptr<BlockStatement> body_;
+  BlockStatement* body_ = nullptr;
   std::vector<Variable*> referenced_module_vars_;
   std::vector<std::string> ancestor_entry_points_;
   FunctionDecorationList decorations_;
 };
 
-/// A list of unique functions
-using FunctionList = std::vector<std::unique_ptr<Function>>;
+/// A list of functions
+using FunctionList = std::vector<Function*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/function_decoration.h b/src/ast/function_decoration.h
index 603cb49..360991d 100644
--- a/src/ast/function_decoration.h
+++ b/src/ast/function_decoration.h
@@ -51,8 +51,8 @@
   explicit FunctionDecoration(const Source& source);
 };
 
-/// A list of unique function decorations
-using FunctionDecorationList = std::vector<std::unique_ptr<FunctionDecoration>>;
+/// A list of function decorations
+using FunctionDecorationList = std::vector<FunctionDecoration*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/function_test.cc b/src/ast/function_test.cc
index 0eb838d..5ba7e18 100644
--- a/src/ast/function_test.cc
+++ b/src/ast/function_test.cc
@@ -38,14 +38,14 @@
 
   VariableList params;
   params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
-  auto* var_ptr = params[0].get();
+  auto* var_ptr = params[0];
 
   Function f("func", std::move(params), &void_type,
              create<ast::BlockStatement>());
   EXPECT_EQ(f.name(), "func");
   ASSERT_EQ(f.params().size(), 1u);
   EXPECT_EQ(f.return_type(), &void_type);
-  EXPECT_EQ(f.params()[0].get(), var_ptr);
+  EXPECT_EQ(f.params()[0], var_ptr);
 }
 
 TEST_F(FunctionTest, Creation_WithSource) {
@@ -188,7 +188,7 @@
   VariableList params;
   params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<DiscardStatement>());
 
   Function f("func", std::move(params), &void_type,
@@ -249,7 +249,7 @@
   VariableList params;
   params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<DiscardStatement>());
   block->append(nullptr);
 
@@ -266,7 +266,7 @@
   VariableList params;
   params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<DiscardStatement>());
   block->append(nullptr);
 
@@ -280,7 +280,7 @@
   type::VoidType void_type;
   type::I32Type i32;
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<DiscardStatement>());
 
   Function f("func", {}, &void_type, create<ast::BlockStatement>());
@@ -300,7 +300,7 @@
   type::VoidType void_type;
   type::I32Type i32;
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<DiscardStatement>());
 
   Function f("func", {}, &void_type, create<ast::BlockStatement>());
@@ -325,7 +325,7 @@
   VariableList params;
   params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<DiscardStatement>());
 
   Function f("func", std::move(params), &void_type,
@@ -373,9 +373,9 @@
   type::VoidType void_type;
 
   VariableList params;
-  auto body = create<ast::BlockStatement>();
-  auto stmt = create<DiscardStatement>();
-  auto* stmt_ptr = stmt.get();
+  auto* body = create<ast::BlockStatement>();
+  auto* stmt = create<DiscardStatement>();
+  auto* stmt_ptr = stmt;
   body->append(std::move(stmt));
   Function f("func", std::move(params), &void_type,
              create<ast::BlockStatement>());
@@ -388,7 +388,7 @@
   type::VoidType void_type;
 
   VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   Function f("func", std::move(params), &void_type,
              create<ast::BlockStatement>());
   f.set_body(std::move(body));
diff --git a/src/ast/if_statement.cc b/src/ast/if_statement.cc
index 3f869bd..6e4ffbe 100644
--- a/src/ast/if_statement.cc
+++ b/src/ast/if_statement.cc
@@ -19,16 +19,13 @@
 namespace tint {
 namespace ast {
 
-IfStatement::IfStatement(std::unique_ptr<Expression> condition,
-                         std::unique_ptr<BlockStatement> body)
-    : Statement(), condition_(std::move(condition)), body_(std::move(body)) {}
+IfStatement::IfStatement(Expression* condition, BlockStatement* body)
+    : Statement(), condition_(condition), body_(body) {}
 
 IfStatement::IfStatement(const Source& source,
-                         std::unique_ptr<Expression> condition,
-                         std::unique_ptr<BlockStatement> body)
-    : Statement(source),
-      condition_(std::move(condition)),
-      body_(std::move(body)) {}
+                         Expression* condition,
+                         BlockStatement* body)
+    : Statement(source), condition_(condition), body_(body) {}
 
 IfStatement::IfStatement(IfStatement&&) = default;
 
@@ -47,7 +44,7 @@
   }
 
   bool found_else = false;
-  for (const auto& el : else_statements_) {
+  for (auto* el : else_statements_) {
     // Else statement must be last
     if (found_else)
       return false;
@@ -81,7 +78,7 @@
   out << "{" << std::endl;
 
   if (body_ != nullptr) {
-    for (const auto& stmt : *body_) {
+    for (auto* stmt : *body_) {
       stmt->to_str(out, indent + 4);
     }
   }
@@ -94,7 +91,7 @@
   make_indent(out, indent);
   out << "}" << std::endl;
 
-  for (const auto& e : else_statements_) {
+  for (auto* e : else_statements_) {
     e->to_str(out, indent);
   }
 }
diff --git a/src/ast/if_statement.h b/src/ast/if_statement.h
index 5c1c861..62b53eb 100644
--- a/src/ast/if_statement.h
+++ b/src/ast/if_statement.h
@@ -32,36 +32,31 @@
   /// Constructor
   /// @param condition the if condition
   /// @param body the if body
-  IfStatement(std::unique_ptr<Expression> condition,
-              std::unique_ptr<BlockStatement> body);
+  IfStatement(Expression* condition, BlockStatement* body);
   /// Constructor
   /// @param source the source information
   /// @param condition the if condition
   /// @param body the if body
   IfStatement(const Source& source,
-              std::unique_ptr<Expression> condition,
-              std::unique_ptr<BlockStatement> body);
+              Expression* condition,
+              BlockStatement* body);
   /// Move constructor
   IfStatement(IfStatement&&);
   ~IfStatement() override;
 
   /// Sets the condition for the if statement
   /// @param condition the condition to set
-  void set_condition(std::unique_ptr<Expression> condition) {
-    condition_ = std::move(condition);
-  }
+  void set_condition(Expression* condition) { condition_ = condition; }
   /// @returns the if condition or nullptr if none set
-  Expression* condition() const { return condition_.get(); }
+  Expression* condition() const { return condition_; }
 
   /// Sets the if body
   /// @param body the if body
-  void set_body(std::unique_ptr<BlockStatement> body) {
-    body_ = std::move(body);
-  }
+  void set_body(BlockStatement* body) { body_ = body; }
   /// @returns the if body
-  const BlockStatement* body() const { return body_.get(); }
+  const BlockStatement* body() const { return body_; }
   /// @returns the if body
-  BlockStatement* body() { return body_.get(); }
+  BlockStatement* body() { return body_; }
 
   /// Sets the else statements
   /// @param else_statements the else statements to set
@@ -90,8 +85,8 @@
  private:
   IfStatement(const IfStatement&) = delete;
 
-  std::unique_ptr<Expression> condition_;
-  std::unique_ptr<BlockStatement> body_;
+  Expression* condition_ = nullptr;
+  BlockStatement* body_ = nullptr;
   ElseStatementList else_statements_;
 };
 
diff --git a/src/ast/if_statement_test.cc b/src/ast/if_statement_test.cc
index d465f78..a37afe3 100644
--- a/src/ast/if_statement_test.cc
+++ b/src/ast/if_statement_test.cc
@@ -25,11 +25,11 @@
 using IfStatementTest = TestHelper;
 
 TEST_F(IfStatementTest, Creation) {
-  auto cond = create<IdentifierExpression>("cond");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("cond");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
-  auto* cond_ptr = cond.get();
+  auto* cond_ptr = cond;
   auto* stmt_ptr = body->get(0);
 
   IfStatement stmt(std::move(cond), std::move(body));
@@ -39,8 +39,8 @@
 }
 
 TEST_F(IfStatementTest, Creation_WithSource) {
-  auto cond = create<IdentifierExpression>("cond");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("cond");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   IfStatement stmt(Source{Source::Location{20, 2}}, std::move(cond),
@@ -56,8 +56,8 @@
 }
 
 TEST_F(IfStatementTest, IsValid) {
-  auto cond = create<IdentifierExpression>("cond");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("cond");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
@@ -65,8 +65,8 @@
 }
 
 TEST_F(IfStatementTest, IsValid_WithElseStatements) {
-  auto cond = create<IdentifierExpression>("cond");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("cond");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
@@ -80,7 +80,7 @@
 }
 
 TEST_F(IfStatementTest, IsValid_MissingCondition) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   IfStatement stmt(nullptr, std::move(body));
@@ -88,8 +88,8 @@
 }
 
 TEST_F(IfStatementTest, IsValid_InvalidCondition) {
-  auto cond = create<IdentifierExpression>("");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
@@ -97,8 +97,8 @@
 }
 
 TEST_F(IfStatementTest, IsValid_NullBodyStatement) {
-  auto cond = create<IdentifierExpression>("cond");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("cond");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
   body->append(nullptr);
 
@@ -107,8 +107,8 @@
 }
 
 TEST_F(IfStatementTest, IsValid_InvalidBodyStatement) {
-  auto cond = create<IdentifierExpression>("cond");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("cond");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
   body->append(create<IfStatement>(nullptr, create<BlockStatement>()));
 
@@ -117,8 +117,8 @@
 }
 
 TEST_F(IfStatementTest, IsValid_NullElseStatement) {
-  auto cond = create<IdentifierExpression>("cond");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("cond");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
@@ -133,8 +133,8 @@
 }
 
 TEST_F(IfStatementTest, IsValid_InvalidElseStatement) {
-  auto cond = create<IdentifierExpression>("cond");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("cond");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
@@ -147,8 +147,8 @@
 }
 
 TEST_F(IfStatementTest, IsValid_MultipleElseWiththoutCondition) {
-  auto cond = create<IdentifierExpression>("cond");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("cond");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
@@ -161,8 +161,8 @@
 }
 
 TEST_F(IfStatementTest, IsValid_ElseNotLast) {
-  auto cond = create<IdentifierExpression>("cond");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("cond");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
@@ -176,8 +176,8 @@
 }
 
 TEST_F(IfStatementTest, ToStr) {
-  auto cond = create<IdentifierExpression>("cond");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("cond");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
@@ -196,14 +196,14 @@
 }
 
 TEST_F(IfStatementTest, ToStr_WithElseStatements) {
-  auto cond = create<IdentifierExpression>("cond");
-  auto body = create<BlockStatement>();
+  auto* cond = create<IdentifierExpression>("cond");
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
-  auto else_if_body = create<BlockStatement>();
+  auto* else_if_body = create<BlockStatement>();
   else_if_body->append(create<DiscardStatement>());
 
-  auto else_body = create<BlockStatement>();
+  auto* else_body = create<BlockStatement>();
   else_body->append(create<DiscardStatement>());
   else_body->append(create<DiscardStatement>());
 
diff --git a/src/ast/loop_statement.cc b/src/ast/loop_statement.cc
index 24ebe72..d1e865d 100644
--- a/src/ast/loop_statement.cc
+++ b/src/ast/loop_statement.cc
@@ -17,16 +17,13 @@
 namespace tint {
 namespace ast {
 
-LoopStatement::LoopStatement(std::unique_ptr<BlockStatement> body,
-                             std::unique_ptr<BlockStatement> continuing)
-    : Statement(), body_(std::move(body)), continuing_(std::move(continuing)) {}
+LoopStatement::LoopStatement(BlockStatement* body, BlockStatement* continuing)
+    : Statement(), body_(body), continuing_(continuing) {}
 
 LoopStatement::LoopStatement(const Source& source,
-                             std::unique_ptr<BlockStatement> body,
-                             std::unique_ptr<BlockStatement> continuing)
-    : Statement(source),
-      body_(std::move(body)),
-      continuing_(std::move(continuing)) {}
+                             BlockStatement* body,
+                             BlockStatement* continuing)
+    : Statement(source), body_(body), continuing_(continuing) {}
 
 LoopStatement::LoopStatement(LoopStatement&&) = default;
 
@@ -51,7 +48,7 @@
   out << "Loop{" << std::endl;
 
   if (body_ != nullptr) {
-    for (const auto& stmt : *body_) {
+    for (auto* stmt : *body_) {
       stmt->to_str(out, indent + 2);
     }
   }
@@ -60,7 +57,7 @@
     make_indent(out, indent + 2);
     out << "continuing {" << std::endl;
 
-    for (const auto& stmt : *continuing_) {
+    for (auto* stmt : *continuing_) {
       stmt->to_str(out, indent + 4);
     }
 
diff --git a/src/ast/loop_statement.h b/src/ast/loop_statement.h
index 828cd5f..d0d959f 100644
--- a/src/ast/loop_statement.h
+++ b/src/ast/loop_statement.h
@@ -30,38 +30,33 @@
   /// Constructor
   /// @param body the body statements
   /// @param continuing the continuing statements
-  LoopStatement(std::unique_ptr<BlockStatement> body,
-                std::unique_ptr<BlockStatement> continuing);
+  LoopStatement(BlockStatement* body, BlockStatement* continuing);
   /// Constructor
   /// @param source the loop statement source
   /// @param body the body statements
   /// @param continuing the continuing statements
   LoopStatement(const Source& source,
-                std::unique_ptr<BlockStatement> body,
-                std::unique_ptr<BlockStatement> continuing);
+                BlockStatement* body,
+                BlockStatement* continuing);
   /// Move constructor
   LoopStatement(LoopStatement&&);
   ~LoopStatement() override;
 
   /// Sets the body statements
   /// @param body the body statements
-  void set_body(std::unique_ptr<BlockStatement> body) {
-    body_ = std::move(body);
-  }
+  void set_body(BlockStatement* body) { body_ = body; }
   /// @returns the body statements
-  const BlockStatement* body() const { return body_.get(); }
+  const BlockStatement* body() const { return body_; }
   /// @returns the body statements
-  BlockStatement* body() { return body_.get(); }
+  BlockStatement* body() { return body_; }
 
   /// Sets the continuing statements
   /// @param continuing the continuing statements
-  void set_continuing(std::unique_ptr<BlockStatement> continuing) {
-    continuing_ = std::move(continuing);
-  }
+  void set_continuing(BlockStatement* continuing) { continuing_ = continuing; }
   /// @returns the continuing statements
-  const BlockStatement* continuing() const { return continuing_.get(); }
+  const BlockStatement* continuing() const { return continuing_; }
   /// @returns the continuing statements
-  BlockStatement* continuing() { return continuing_.get(); }
+  BlockStatement* continuing() { return continuing_; }
   /// @returns true if there are continuing statements in the loop
   bool has_continuing() const {
     return continuing_ != nullptr && !continuing_->empty();
@@ -81,8 +76,8 @@
  private:
   LoopStatement(const LoopStatement&) = delete;
 
-  std::unique_ptr<BlockStatement> body_;
-  std::unique_ptr<BlockStatement> continuing_;
+  BlockStatement* body_ = nullptr;
+  BlockStatement* continuing_ = nullptr;
 };
 
 }  // namespace ast
diff --git a/src/ast/loop_statement_test.cc b/src/ast/loop_statement_test.cc
index 56e477d..e8ce319 100644
--- a/src/ast/loop_statement_test.cc
+++ b/src/ast/loop_statement_test.cc
@@ -28,11 +28,11 @@
 using LoopStatementTest = TestHelper;
 
 TEST_F(LoopStatementTest, Creation) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
   auto* b_ptr = body->last();
 
-  auto continuing = create<BlockStatement>();
+  auto* continuing = create<BlockStatement>();
   continuing->append(create<DiscardStatement>());
   auto* c_ptr = continuing->last();
 
@@ -44,10 +44,10 @@
 }
 
 TEST_F(LoopStatementTest, Creation_WithSource) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
-  auto continuing = create<BlockStatement>();
+  auto* continuing = create<BlockStatement>();
   continuing->append(create<DiscardStatement>());
 
   LoopStatement l(Source{Source::Location{20, 2}}, std::move(body),
@@ -63,7 +63,7 @@
 }
 
 TEST_F(LoopStatementTest, HasContinuing_WithoutContinuing) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), {});
@@ -71,10 +71,10 @@
 }
 
 TEST_F(LoopStatementTest, HasContinuing_WithContinuing) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
-  auto continuing = create<BlockStatement>();
+  auto* continuing = create<BlockStatement>();
   continuing->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
@@ -82,10 +82,10 @@
 }
 
 TEST_F(LoopStatementTest, IsValid) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
-  auto continuing = create<BlockStatement>();
+  auto* continuing = create<BlockStatement>();
   continuing->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
@@ -93,7 +93,7 @@
 }
 
 TEST_F(LoopStatementTest, IsValid_WithoutContinuing) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), create<BlockStatement>());
@@ -106,11 +106,11 @@
 }
 
 TEST_F(LoopStatementTest, IsValid_NullBodyStatement) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
   body->append(nullptr);
 
-  auto continuing = create<BlockStatement>();
+  auto* continuing = create<BlockStatement>();
   continuing->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
@@ -118,11 +118,11 @@
 }
 
 TEST_F(LoopStatementTest, IsValid_InvalidBodyStatement) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
   body->append(create<IfStatement>(nullptr, create<BlockStatement>()));
 
-  auto continuing = create<BlockStatement>();
+  auto* continuing = create<BlockStatement>();
   continuing->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
@@ -130,10 +130,10 @@
 }
 
 TEST_F(LoopStatementTest, IsValid_NullContinuingStatement) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
-  auto continuing = create<BlockStatement>();
+  auto* continuing = create<BlockStatement>();
   continuing->append(create<DiscardStatement>());
   continuing->append(nullptr);
 
@@ -142,10 +142,10 @@
 }
 
 TEST_F(LoopStatementTest, IsValid_InvalidContinuingStatement) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
-  auto continuing = create<BlockStatement>();
+  auto* continuing = create<BlockStatement>();
   continuing->append(create<DiscardStatement>());
   continuing->append(create<IfStatement>(nullptr, create<BlockStatement>()));
 
@@ -154,7 +154,7 @@
 }
 
 TEST_F(LoopStatementTest, ToStr) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), {});
@@ -167,10 +167,10 @@
 }
 
 TEST_F(LoopStatementTest, ToStr_WithContinuing) {
-  auto body = create<BlockStatement>();
+  auto* body = create<BlockStatement>();
   body->append(create<DiscardStatement>());
 
-  auto continuing = create<BlockStatement>();
+  auto* continuing = create<BlockStatement>();
   continuing->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
diff --git a/src/ast/member_accessor_expression.cc b/src/ast/member_accessor_expression.cc
index d10eb06..18ca50d 100644
--- a/src/ast/member_accessor_expression.cc
+++ b/src/ast/member_accessor_expression.cc
@@ -19,18 +19,14 @@
 
 MemberAccessorExpression::MemberAccessorExpression() = default;
 
-MemberAccessorExpression::MemberAccessorExpression(
-    std::unique_ptr<Expression> structure,
-    std::unique_ptr<IdentifierExpression> member)
-    : Expression(), struct_(std::move(structure)), member_(std::move(member)) {}
+MemberAccessorExpression::MemberAccessorExpression(Expression* structure,
+                                                   IdentifierExpression* member)
+    : Expression(), struct_(structure), member_(member) {}
 
-MemberAccessorExpression::MemberAccessorExpression(
-    const Source& source,
-    std::unique_ptr<Expression> structure,
-    std::unique_ptr<IdentifierExpression> member)
-    : Expression(source),
-      struct_(std::move(structure)),
-      member_(std::move(member)) {}
+MemberAccessorExpression::MemberAccessorExpression(const Source& source,
+                                                   Expression* structure,
+                                                   IdentifierExpression* member)
+    : Expression(source), struct_(structure), member_(member) {}
 
 MemberAccessorExpression::MemberAccessorExpression(MemberAccessorExpression&&) =
     default;
diff --git a/src/ast/member_accessor_expression.h b/src/ast/member_accessor_expression.h
index ee56fc6..f0c9aa9 100644
--- a/src/ast/member_accessor_expression.h
+++ b/src/ast/member_accessor_expression.h
@@ -34,34 +34,29 @@
   /// Constructor
   /// @param structure the structure
   /// @param member the member
-  MemberAccessorExpression(std::unique_ptr<Expression> structure,
-                           std::unique_ptr<IdentifierExpression> member);
+  MemberAccessorExpression(Expression* structure, IdentifierExpression* member);
   /// Constructor
   /// @param source the member accessor expression source
   /// @param structure the structure
   /// @param member the member
   MemberAccessorExpression(const Source& source,
-                           std::unique_ptr<Expression> structure,
-                           std::unique_ptr<IdentifierExpression> member);
+                           Expression* structure,
+                           IdentifierExpression* member);
   /// Move constructor
   MemberAccessorExpression(MemberAccessorExpression&&);
   ~MemberAccessorExpression() override;
 
   /// Sets the structure
   /// @param structure the structure
-  void set_structure(std::unique_ptr<Expression> structure) {
-    struct_ = std::move(structure);
-  }
+  void set_structure(Expression* structure) { struct_ = structure; }
   /// @returns the structure
-  Expression* structure() const { return struct_.get(); }
+  Expression* structure() const { return struct_; }
 
   /// Sets the member
   /// @param member the member
-  void set_member(std::unique_ptr<IdentifierExpression> member) {
-    member_ = std::move(member);
-  }
+  void set_member(IdentifierExpression* member) { member_ = member; }
   /// @returns the member expression
-  IdentifierExpression* member() const { return member_.get(); }
+  IdentifierExpression* member() const { return member_; }
 
   /// @returns true if this is a member accessor expression
   bool IsMemberAccessor() const override;
@@ -77,8 +72,8 @@
  private:
   MemberAccessorExpression(const MemberAccessorExpression&) = delete;
 
-  std::unique_ptr<Expression> struct_;
-  std::unique_ptr<IdentifierExpression> member_;
+  Expression* struct_ = nullptr;
+  IdentifierExpression* member_ = nullptr;
 };
 
 }  // namespace ast
diff --git a/src/ast/member_accessor_expression_test.cc b/src/ast/member_accessor_expression_test.cc
index 42be3d1..78c06ff 100644
--- a/src/ast/member_accessor_expression_test.cc
+++ b/src/ast/member_accessor_expression_test.cc
@@ -26,11 +26,11 @@
 using MemberAccessorExpressionTest = TestHelper;
 
 TEST_F(MemberAccessorExpressionTest, Creation) {
-  auto str = create<IdentifierExpression>("structure");
-  auto mem = create<IdentifierExpression>("member");
+  auto* str = create<IdentifierExpression>("structure");
+  auto* mem = create<IdentifierExpression>("member");
 
-  auto* str_ptr = str.get();
-  auto* mem_ptr = mem.get();
+  auto* str_ptr = str;
+  auto* mem_ptr = mem;
 
   MemberAccessorExpression stmt(std::move(str), std::move(mem));
   EXPECT_EQ(stmt.structure(), str_ptr);
@@ -38,8 +38,8 @@
 }
 
 TEST_F(MemberAccessorExpressionTest, Creation_WithSource) {
-  auto str = create<IdentifierExpression>("structure");
-  auto mem = create<IdentifierExpression>("member");
+  auto* str = create<IdentifierExpression>("structure");
+  auto* mem = create<IdentifierExpression>("member");
 
   MemberAccessorExpression stmt(Source{Source::Location{20, 2}}, std::move(str),
                                 std::move(mem));
@@ -54,15 +54,15 @@
 }
 
 TEST_F(MemberAccessorExpressionTest, IsValid) {
-  auto str = create<IdentifierExpression>("structure");
-  auto mem = create<IdentifierExpression>("member");
+  auto* str = create<IdentifierExpression>("structure");
+  auto* mem = create<IdentifierExpression>("member");
 
   MemberAccessorExpression stmt(std::move(str), std::move(mem));
   EXPECT_TRUE(stmt.IsValid());
 }
 
 TEST_F(MemberAccessorExpressionTest, IsValid_NullStruct) {
-  auto mem = create<IdentifierExpression>("member");
+  auto* mem = create<IdentifierExpression>("member");
 
   MemberAccessorExpression stmt;
   stmt.set_member(std::move(mem));
@@ -70,15 +70,15 @@
 }
 
 TEST_F(MemberAccessorExpressionTest, IsValid_InvalidStruct) {
-  auto str = create<IdentifierExpression>("");
-  auto mem = create<IdentifierExpression>("member");
+  auto* str = create<IdentifierExpression>("");
+  auto* mem = create<IdentifierExpression>("member");
 
   MemberAccessorExpression stmt(std::move(str), std::move(mem));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(MemberAccessorExpressionTest, IsValid_NullMember) {
-  auto str = create<IdentifierExpression>("structure");
+  auto* str = create<IdentifierExpression>("structure");
 
   MemberAccessorExpression stmt;
   stmt.set_structure(std::move(str));
@@ -86,16 +86,16 @@
 }
 
 TEST_F(MemberAccessorExpressionTest, IsValid_InvalidMember) {
-  auto str = create<IdentifierExpression>("structure");
-  auto mem = create<IdentifierExpression>("");
+  auto* str = create<IdentifierExpression>("structure");
+  auto* mem = create<IdentifierExpression>("");
 
   MemberAccessorExpression stmt(std::move(str), std::move(mem));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(MemberAccessorExpressionTest, ToStr) {
-  auto str = create<IdentifierExpression>("structure");
-  auto mem = create<IdentifierExpression>("member");
+  auto* str = create<IdentifierExpression>("structure");
+  auto* mem = create<IdentifierExpression>("member");
 
   MemberAccessorExpression stmt(std::move(str), std::move(mem));
   std::ostringstream out;
diff --git a/src/ast/module.cc b/src/ast/module.cc
index 92381a7..0d0c261 100644
--- a/src/ast/module.cc
+++ b/src/ast/module.cc
@@ -28,9 +28,9 @@
 Module::~Module() = default;
 
 Function* Module::FindFunctionByName(const std::string& name) const {
-  for (const auto& func : functions_) {
+  for (auto* func : functions_) {
     if (func->name() == name) {
-      return func.get();
+      return func;
     }
   }
   return nullptr;
@@ -38,16 +38,16 @@
 
 Function* Module::FindFunctionByNameAndStage(const std::string& name,
                                              ast::PipelineStage stage) const {
-  for (const auto& func : functions_) {
+  for (auto* func : functions_) {
     if (func->name() == name && func->pipeline_stage() == stage) {
-      return func.get();
+      return func;
     }
   }
   return nullptr;
 }
 
 bool Module::IsValid() const {
-  for (const auto& var : global_variables_) {
+  for (auto* var : global_variables_) {
     if (var == nullptr || !var->IsValid()) {
       return false;
     }
@@ -74,7 +74,7 @@
       return false;
     }
   }
-  for (const auto& func : functions_) {
+  for (auto* func : functions_) {
     if (func == nullptr || !func->IsValid()) {
       return false;
     }
@@ -103,10 +103,10 @@
       str->impl()->to_str(out, indent);
     }
   }
-  for (const auto& var : global_variables_) {
+  for (auto* var : global_variables_) {
     var->to_str(out, indent);
   }
-  for (const auto& func : functions_) {
+  for (auto* func : functions_) {
     func->to_str(out, indent);
   }
   out << "}" << std::endl;
diff --git a/src/ast/module.h b/src/ast/module.h
index 3dca65d..c0b1e7b 100644
--- a/src/ast/module.h
+++ b/src/ast/module.h
@@ -37,9 +37,7 @@
 
   /// Add a global variable to the module
   /// @param var the variable to add
-  void AddGlobalVariable(std::unique_ptr<Variable> var) {
-    global_variables_.push_back(std::move(var));
-  }
+  void AddGlobalVariable(Variable* var) { global_variables_.push_back(var); }
   /// @returns the global variables for the module
   const VariableList& global_variables() const { return global_variables_; }
 
@@ -59,9 +57,7 @@
 
   /// Adds a function to the module
   /// @param func the function
-  void AddFunction(std::unique_ptr<Function> func) {
-    functions_.push_back(std::move(func));
-  }
+  void AddFunction(Function* func) { functions_.push_back(func); }
   /// @returns the modules functions
   const FunctionList& functions() const { return functions_; }
   /// Returns the function with the given name
diff --git a/src/ast/module_test.cc b/src/ast/module_test.cc
index 9b6af13..5a55874 100644
--- a/src/ast/module_test.cc
+++ b/src/ast/module_test.cc
@@ -48,9 +48,9 @@
   type::F32Type f32;
   Module m;
 
-  auto func = create<Function>("main", VariableList{}, &f32,
+  auto* func = create<Function>("main", VariableList{}, &f32,
                                create<ast::BlockStatement>());
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
   m.AddFunction(std::move(func));
   EXPECT_EQ(func_ptr, m.FindFunctionByName("main"));
 }
@@ -67,7 +67,7 @@
 
 TEST_F(ModuleTest, IsValid_GlobalVariable) {
   type::F32Type f32;
-  auto var = create<Variable>("var", StorageClass::kInput, &f32);
+  auto* var = create<Variable>("var", StorageClass::kInput, &f32);
 
   Module m;
   m.AddGlobalVariable(std::move(var));
@@ -81,7 +81,7 @@
 }
 
 TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) {
-  auto var = create<Variable>("var", StorageClass::kInput, nullptr);
+  auto* var = create<Variable>("var", StorageClass::kInput, nullptr);
 
   Module m;
   m.AddGlobalVariable(std::move(var));
@@ -125,7 +125,7 @@
 
 TEST_F(ModuleTest, IsValid_Function) {
   type::F32Type f32;
-  auto func = create<Function>("main", VariableList(), &f32,
+  auto* func = create<Function>("main", VariableList(), &f32,
                                create<ast::BlockStatement>());
 
   Module m;
@@ -140,7 +140,7 @@
 }
 
 TEST_F(ModuleTest, IsValid_Invalid_Function) {
-  auto func = create<Function>();
+  auto* func = create<Function>();
 
   Module m;
   m.AddFunction(std::move(func));
diff --git a/src/ast/return_statement.cc b/src/ast/return_statement.cc
index 9071d62..8f78861 100644
--- a/src/ast/return_statement.cc
+++ b/src/ast/return_statement.cc
@@ -21,12 +21,11 @@
 
 ReturnStatement::ReturnStatement(const Source& source) : Statement(source) {}
 
-ReturnStatement::ReturnStatement(std::unique_ptr<Expression> value)
-    : Statement(), value_(std::move(value)) {}
+ReturnStatement::ReturnStatement(Expression* value)
+    : Statement(), value_(value) {}
 
-ReturnStatement::ReturnStatement(const Source& source,
-                                 std::unique_ptr<Expression> value)
-    : Statement(source), value_(std::move(value)) {}
+ReturnStatement::ReturnStatement(const Source& source, Expression* value)
+    : Statement(source), value_(value) {}
 
 ReturnStatement::ReturnStatement(ReturnStatement&&) = default;
 
diff --git a/src/ast/return_statement.h b/src/ast/return_statement.h
index 164a602..4605fd7 100644
--- a/src/ast/return_statement.h
+++ b/src/ast/return_statement.h
@@ -34,22 +34,20 @@
   explicit ReturnStatement(const Source& source);
   /// Constructor
   /// @param value the return value
-  explicit ReturnStatement(std::unique_ptr<Expression> value);
+  explicit ReturnStatement(Expression* value);
   /// Constructor
   /// @param source the return statement source
   /// @param value the return value
-  ReturnStatement(const Source& source, std::unique_ptr<Expression> value);
+  ReturnStatement(const Source& source, Expression* value);
   /// Move constructor
   ReturnStatement(ReturnStatement&&);
   ~ReturnStatement() override;
 
   /// Sets the value
   /// @param value the value
-  void set_value(std::unique_ptr<Expression> value) {
-    value_ = std::move(value);
-  }
+  void set_value(Expression* value) { value_ = value; }
   /// @returns the value
-  Expression* value() const { return value_.get(); }
+  Expression* value() const { return value_; }
   /// @returns true if the return has a value
   bool has_value() const { return value_ != nullptr; }
 
@@ -67,7 +65,7 @@
  private:
   ReturnStatement(const ReturnStatement&) = delete;
 
-  std::unique_ptr<Expression> value_;
+  Expression* value_ = nullptr;
 };
 
 }  // namespace ast
diff --git a/src/ast/return_statement_test.cc b/src/ast/return_statement_test.cc
index 59c01e5..e883177 100644
--- a/src/ast/return_statement_test.cc
+++ b/src/ast/return_statement_test.cc
@@ -26,8 +26,8 @@
 using ReturnStatementTest = TestHelper;
 
 TEST_F(ReturnStatementTest, Creation) {
-  auto expr = create<IdentifierExpression>("expr");
-  auto* expr_ptr = expr.get();
+  auto* expr = create<IdentifierExpression>("expr");
+  auto* expr_ptr = expr;
 
   ReturnStatement r(std::move(expr));
   EXPECT_EQ(r.value(), expr_ptr);
@@ -51,7 +51,7 @@
 }
 
 TEST_F(ReturnStatementTest, HasValue_WithValue) {
-  auto expr = create<IdentifierExpression>("expr");
+  auto* expr = create<IdentifierExpression>("expr");
   ReturnStatement r(std::move(expr));
   EXPECT_TRUE(r.has_value());
 }
@@ -62,19 +62,19 @@
 }
 
 TEST_F(ReturnStatementTest, IsValid_WithValue) {
-  auto expr = create<IdentifierExpression>("expr");
+  auto* expr = create<IdentifierExpression>("expr");
   ReturnStatement r(std::move(expr));
   EXPECT_TRUE(r.IsValid());
 }
 
 TEST_F(ReturnStatementTest, IsValid_InvalidValue) {
-  auto expr = create<IdentifierExpression>("");
+  auto* expr = create<IdentifierExpression>("");
   ReturnStatement r(std::move(expr));
   EXPECT_FALSE(r.IsValid());
 }
 
 TEST_F(ReturnStatementTest, ToStr_WithValue) {
-  auto expr = create<IdentifierExpression>("expr");
+  auto* expr = create<IdentifierExpression>("expr");
   ReturnStatement r(std::move(expr));
   std::ostringstream out;
   r.to_str(out, 2);
diff --git a/src/ast/scalar_constructor_expression.cc b/src/ast/scalar_constructor_expression.cc
index 52b3ed2..f82983d 100644
--- a/src/ast/scalar_constructor_expression.cc
+++ b/src/ast/scalar_constructor_expression.cc
@@ -20,14 +20,12 @@
 ScalarConstructorExpression::ScalarConstructorExpression()
     : ConstructorExpression() {}
 
-ScalarConstructorExpression::ScalarConstructorExpression(
-    std::unique_ptr<Literal> literal)
-    : ConstructorExpression(), literal_(std::move(literal)) {}
+ScalarConstructorExpression::ScalarConstructorExpression(Literal* literal)
+    : literal_(literal) {}
 
-ScalarConstructorExpression::ScalarConstructorExpression(
-    const Source& source,
-    std::unique_ptr<Literal> litearl)
-    : ConstructorExpression(source), literal_(std::move(litearl)) {}
+ScalarConstructorExpression::ScalarConstructorExpression(const Source& source,
+                                                         Literal* litearl)
+    : ConstructorExpression(source), literal_(litearl) {}
 
 ScalarConstructorExpression::ScalarConstructorExpression(
     ScalarConstructorExpression&&) = default;
diff --git a/src/ast/scalar_constructor_expression.h b/src/ast/scalar_constructor_expression.h
index 0061bf7..360a2e8 100644
--- a/src/ast/scalar_constructor_expression.h
+++ b/src/ast/scalar_constructor_expression.h
@@ -31,12 +31,11 @@
   ScalarConstructorExpression();
   /// Constructor
   /// @param literal the const literal
-  explicit ScalarConstructorExpression(std::unique_ptr<Literal> literal);
+  explicit ScalarConstructorExpression(Literal* literal);
   /// Constructor
   /// @param source the constructor source
   /// @param literal the const literal
-  ScalarConstructorExpression(const Source& source,
-                              std::unique_ptr<Literal> literal);
+  ScalarConstructorExpression(const Source& source, Literal* literal);
   /// Move constructor
   ScalarConstructorExpression(ScalarConstructorExpression&&);
   ~ScalarConstructorExpression() override;
@@ -46,11 +45,9 @@
 
   /// Set the literal value
   /// @param literal the literal
-  void set_literal(std::unique_ptr<Literal> literal) {
-    literal_ = std::move(literal);
-  }
+  void set_literal(Literal* literal) { literal_ = literal; }
   /// @returns the literal value
-  Literal* literal() const { return literal_.get(); }
+  Literal* literal() const { return literal_; }
 
   /// @returns true if the node is valid
   bool IsValid() const override;
@@ -63,7 +60,7 @@
  private:
   ScalarConstructorExpression(const ScalarConstructorExpression&) = delete;
 
-  std::unique_ptr<Literal> literal_;
+  Literal* literal_ = nullptr;
 };
 
 }  // namespace ast
diff --git a/src/ast/scalar_constructor_expression_test.cc b/src/ast/scalar_constructor_expression_test.cc
index e465113..b1525c0 100644
--- a/src/ast/scalar_constructor_expression_test.cc
+++ b/src/ast/scalar_constructor_expression_test.cc
@@ -26,15 +26,15 @@
 
 TEST_F(ScalarConstructorExpressionTest, Creation) {
   ast::type::BoolType bool_type;
-  auto b = create<BoolLiteral>(&bool_type, true);
-  auto* b_ptr = b.get();
+  auto* b = create<BoolLiteral>(&bool_type, true);
+  auto* b_ptr = b;
   ScalarConstructorExpression c(std::move(b));
   EXPECT_EQ(c.literal(), b_ptr);
 }
 
 TEST_F(ScalarConstructorExpressionTest, Creation_WithSource) {
   ast::type::BoolType bool_type;
-  auto b = create<BoolLiteral>(&bool_type, true);
+  auto* b = create<BoolLiteral>(&bool_type, true);
   ScalarConstructorExpression c(Source{Source::Location{20, 2}}, std::move(b));
   auto src = c.source();
   EXPECT_EQ(src.range.begin.line, 20u);
@@ -43,7 +43,7 @@
 
 TEST_F(ScalarConstructorExpressionTest, IsValid) {
   ast::type::BoolType bool_type;
-  auto b = create<BoolLiteral>(&bool_type, true);
+  auto* b = create<BoolLiteral>(&bool_type, true);
   ScalarConstructorExpression c(std::move(b));
   EXPECT_TRUE(c.IsValid());
 }
@@ -55,7 +55,7 @@
 
 TEST_F(ScalarConstructorExpressionTest, ToStr) {
   ast::type::BoolType bool_type;
-  auto b = create<BoolLiteral>(&bool_type, true);
+  auto* b = create<BoolLiteral>(&bool_type, true);
   ScalarConstructorExpression c(std::move(b));
   std::ostringstream out;
   c.to_str(out, 2);
diff --git a/src/ast/struct.cc b/src/ast/struct.cc
index c15c0d1..73dc11f 100644
--- a/src/ast/struct.cc
+++ b/src/ast/struct.cc
@@ -42,16 +42,16 @@
 Struct::~Struct() = default;
 
 StructMember* Struct::get_member(const std::string& name) const {
-  for (auto& mem : members_) {
+  for (auto* mem : members_) {
     if (mem->name() == name) {
-      return mem.get();
+      return mem;
     }
   }
   return nullptr;
 }
 
 bool Struct::IsBlockDecorated() const {
-  for (auto& deco : decorations_) {
+  for (auto* deco : decorations_) {
     if (deco->IsBlock()) {
       return true;
     }
@@ -60,7 +60,7 @@
 }
 
 bool Struct::IsValid() const {
-  for (const auto& mem : members_) {
+  for (auto* mem : members_) {
     if (mem == nullptr || !mem->IsValid()) {
       return false;
     }
@@ -70,13 +70,13 @@
 
 void Struct::to_str(std::ostream& out, size_t indent) const {
   out << "Struct{" << std::endl;
-  for (auto& deco : decorations_) {
+  for (auto* deco : decorations_) {
     make_indent(out, indent + 2);
     out << "[[";
     deco->to_str(out, 0);
     out << "]]" << std::endl;
   }
-  for (const auto& member : members_) {
+  for (auto* member : members_) {
     member->to_str(out, indent + 2);
   }
   make_indent(out, indent);
diff --git a/src/ast/struct_block_decoration.h b/src/ast/struct_block_decoration.h
index f9ae0ab..34b031c 100644
--- a/src/ast/struct_block_decoration.h
+++ b/src/ast/struct_block_decoration.h
@@ -42,7 +42,7 @@
 };
 
 /// List of struct decorations
-using StructDecorationList = std::vector<std::unique_ptr<StructDecoration>>;
+using StructDecorationList = std::vector<StructDecoration*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/struct_decoration.h b/src/ast/struct_decoration.h
index 978d37e..0b889c2 100644
--- a/src/ast/struct_decoration.h
+++ b/src/ast/struct_decoration.h
@@ -42,7 +42,7 @@
 };
 
 /// List of struct decorations
-using StructDecorationList = std::vector<std::unique_ptr<StructDecoration>>;
+using StructDecorationList = std::vector<StructDecoration*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/struct_member.cc b/src/ast/struct_member.cc
index 1f735e0..8d54ad5 100644
--- a/src/ast/struct_member.cc
+++ b/src/ast/struct_member.cc
@@ -40,7 +40,7 @@
 StructMember::~StructMember() = default;
 
 bool StructMember::has_offset_decoration() const {
-  for (const auto& deco : decorations_) {
+  for (auto* deco : decorations_) {
     if (deco->IsOffset()) {
       return true;
     }
@@ -49,7 +49,7 @@
 }
 
 uint32_t StructMember::offset() const {
-  for (const auto& deco : decorations_) {
+  for (auto* deco : decorations_) {
     if (deco->IsOffset()) {
       return deco->AsOffset()->offset();
     }
@@ -61,7 +61,7 @@
   if (name_.empty() || type_ == nullptr) {
     return false;
   }
-  for (const auto& deco : decorations_) {
+  for (auto* deco : decorations_) {
     if (deco == nullptr) {
       return false;
     }
@@ -74,7 +74,7 @@
   out << "StructMember{";
   if (decorations_.size() > 0) {
     out << "[[ ";
-    for (const auto& deco : decorations_)
+    for (auto* deco : decorations_)
       out << deco->str() << " ";
     out << "]] ";
   }
diff --git a/src/ast/struct_member.h b/src/ast/struct_member.h
index 91a0621..00dd870 100644
--- a/src/ast/struct_member.h
+++ b/src/ast/struct_member.h
@@ -93,8 +93,8 @@
   StructMemberDecorationList decorations_;
 };
 
-/// A list of unique struct members
-using StructMemberList = std::vector<std::unique_ptr<StructMember>>;
+/// A list of struct members
+using StructMemberList = std::vector<StructMember*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/struct_member_decoration.h b/src/ast/struct_member_decoration.h
index 1e11aca..f31e6d6 100644
--- a/src/ast/struct_member_decoration.h
+++ b/src/ast/struct_member_decoration.h
@@ -46,9 +46,8 @@
   explicit StructMemberDecoration(const Source& source);
 };
 
-/// A list of unique struct member decorations
-using StructMemberDecorationList =
-    std::vector<std::unique_ptr<StructMemberDecoration>>;
+/// A list of struct member decorations
+using StructMemberDecorationList = std::vector<StructMemberDecoration*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/struct_test.cc b/src/ast/struct_test.cc
index e61a7de..016166e 100644
--- a/src/ast/struct_test.cc
+++ b/src/ast/struct_test.cc
@@ -35,7 +35,7 @@
   members.push_back(
       create<StructMember>("a", &i32, StructMemberDecorationList()));
 
-  Struct s{std::move(members)};
+  Struct s{members};
   EXPECT_EQ(s.members().size(), 1u);
   EXPECT_TRUE(s.decorations().empty());
   EXPECT_EQ(s.source().range.begin.line, 0u);
@@ -54,7 +54,7 @@
   StructDecorationList decos;
   decos.push_back(create<StructBlockDecoration>(Source{}));
 
-  Struct s{std::move(decos), std::move(members)};
+  Struct s{decos, members};
   EXPECT_EQ(s.members().size(), 1u);
   ASSERT_EQ(s.decorations().size(), 1u);
   EXPECT_TRUE(s.decorations()[0]->IsBlock());
@@ -76,7 +76,7 @@
 
   Struct s{
       Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}},
-      std::move(decos), std::move(members)};
+      decos, members};
   EXPECT_EQ(s.members().size(), 1u);
   ASSERT_EQ(s.decorations().size(), 1u);
   EXPECT_TRUE(s.decorations()[0]->IsBlock());
@@ -99,7 +99,7 @@
       create<StructMember>("a", &i32, StructMemberDecorationList()));
   members.push_back(nullptr);
 
-  Struct s{std::move(members)};
+  Struct s{members};
   EXPECT_FALSE(s.IsValid());
 }
 
@@ -110,7 +110,7 @@
   members.push_back(
       create<StructMember>("", &i32, StructMemberDecorationList()));
 
-  Struct s{std::move(members)};
+  Struct s{members};
   EXPECT_FALSE(s.IsValid());
 }
 
@@ -124,7 +124,7 @@
   StructDecorationList decos;
   decos.push_back(create<StructBlockDecoration>(Source{}));
 
-  Struct s{std::move(decos), std::move(members)};
+  Struct s{decos, members};
 
   std::ostringstream out;
   s.to_str(out, 2);
diff --git a/src/ast/switch_statement.cc b/src/ast/switch_statement.cc
index 4a38869..2d86fcb 100644
--- a/src/ast/switch_statement.cc
+++ b/src/ast/switch_statement.cc
@@ -21,16 +21,13 @@
 
 SwitchStatement::SwitchStatement() : Statement() {}
 
-SwitchStatement::SwitchStatement(std::unique_ptr<Expression> condition,
-                                 CaseStatementList body)
-    : Statement(), condition_(std::move(condition)), body_(std::move(body)) {}
+SwitchStatement::SwitchStatement(Expression* condition, CaseStatementList body)
+    : condition_(condition), body_(body) {}
 
 SwitchStatement::SwitchStatement(const Source& source,
-                                 std::unique_ptr<Expression> condition,
+                                 Expression* condition,
                                  CaseStatementList body)
-    : Statement(source),
-      condition_(std::move(condition)),
-      body_(std::move(body)) {}
+    : Statement(source), condition_(condition), body_(body) {}
 
 bool SwitchStatement::IsSwitch() const {
   return true;
@@ -44,7 +41,7 @@
   if (condition_ == nullptr || !condition_->IsValid()) {
     return false;
   }
-  for (const auto& stmt : body_) {
+  for (auto* stmt : body_) {
     if (stmt == nullptr || !stmt->IsValid()) {
       return false;
     }
@@ -60,7 +57,7 @@
   make_indent(out, indent + 2);
   out << "{" << std::endl;
 
-  for (const auto& stmt : body_) {
+  for (auto* stmt : body_) {
     stmt->to_str(out, indent + 4);
   }
 
diff --git a/src/ast/switch_statement.h b/src/ast/switch_statement.h
index ba3f268..e5346da 100644
--- a/src/ast/switch_statement.h
+++ b/src/ast/switch_statement.h
@@ -34,14 +34,13 @@
   /// Constructor
   /// @param condition the switch condition
   /// @param body the switch body
-  SwitchStatement(std::unique_ptr<Expression> condition,
-                  CaseStatementList body);
+  SwitchStatement(Expression* condition, CaseStatementList body);
   /// Constructor
   /// @param source the source information
   /// @param condition the switch condition
   /// @param body the switch body
   SwitchStatement(const Source& source,
-                  std::unique_ptr<Expression> condition,
+                  Expression* condition,
                   CaseStatementList body);
   /// Move constructor
   SwitchStatement(SwitchStatement&&);
@@ -49,11 +48,9 @@
 
   /// Sets the condition for the switch statement
   /// @param condition the condition to set
-  void set_condition(std::unique_ptr<Expression> condition) {
-    condition_ = std::move(condition);
-  }
+  void set_condition(Expression* condition) { condition_ = condition; }
   /// @returns the switch condition or nullptr if none set
-  Expression* condition() const { return condition_.get(); }
+  Expression* condition() const { return condition_; }
   /// @returns true if this is a default statement
   bool IsDefault() const { return condition_ == nullptr; }
 
@@ -77,7 +74,7 @@
  private:
   SwitchStatement(const SwitchStatement&) = delete;
 
-  std::unique_ptr<Expression> condition_;
+  Expression* condition_ = nullptr;
   CaseStatementList body_;
 };
 
diff --git a/src/ast/switch_statement_test.cc b/src/ast/switch_statement_test.cc
index 9e27d4a..66dcd20 100644
--- a/src/ast/switch_statement_test.cc
+++ b/src/ast/switch_statement_test.cc
@@ -34,22 +34,22 @@
   CaseSelectorList lit;
   lit.push_back(create<SintLiteral>(&i32, 1));
 
-  auto ident = create<IdentifierExpression>("ident");
+  auto* ident = create<IdentifierExpression>("ident");
   CaseStatementList body;
   body.push_back(
       create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
 
-  auto* ident_ptr = ident.get();
-  auto* case_ptr = body[0].get();
+  auto* ident_ptr = ident;
+  auto* case_ptr = body[0];
 
   SwitchStatement stmt(std::move(ident), std::move(body));
   EXPECT_EQ(stmt.condition(), ident_ptr);
   ASSERT_EQ(stmt.body().size(), 1u);
-  EXPECT_EQ(stmt.body()[0].get(), case_ptr);
+  EXPECT_EQ(stmt.body()[0], case_ptr);
 }
 
 TEST_F(SwitchStatementTest, Creation_WithSource) {
-  auto ident = create<IdentifierExpression>("ident");
+  auto* ident = create<IdentifierExpression>("ident");
 
   SwitchStatement stmt(Source{Source::Location{20, 2}}, std::move(ident),
                        CaseStatementList());
@@ -69,7 +69,7 @@
   CaseSelectorList lit;
   lit.push_back(create<SintLiteral>(&i32, 2));
 
-  auto ident = create<IdentifierExpression>("ident");
+  auto* ident = create<IdentifierExpression>("ident");
   CaseStatementList body;
   body.push_back(
       create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
@@ -99,7 +99,7 @@
   CaseSelectorList lit;
   lit.push_back(create<SintLiteral>(&i32, 2));
 
-  auto ident = create<IdentifierExpression>("");
+  auto* ident = create<IdentifierExpression>("");
   CaseStatementList body;
   body.push_back(
       create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
@@ -114,7 +114,7 @@
   CaseSelectorList lit;
   lit.push_back(create<SintLiteral>(&i32, 2));
 
-  auto ident = create<IdentifierExpression>("ident");
+  auto* ident = create<IdentifierExpression>("ident");
   CaseStatementList body;
   body.push_back(
       create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
@@ -125,9 +125,9 @@
 }
 
 TEST_F(SwitchStatementTest, IsValid_Invalid_BodyStatement) {
-  auto ident = create<IdentifierExpression>("ident");
+  auto* ident = create<IdentifierExpression>("ident");
 
-  auto case_body = create<ast::BlockStatement>();
+  auto* case_body = create<ast::BlockStatement>();
   case_body->append(nullptr);
 
   CaseStatementList body;
@@ -139,7 +139,7 @@
 }
 
 TEST_F(SwitchStatementTest, ToStr_Empty) {
-  auto ident = create<IdentifierExpression>("ident");
+  auto* ident = create<IdentifierExpression>("ident");
 
   SwitchStatement stmt(std::move(ident), {});
   std::ostringstream out;
@@ -158,7 +158,7 @@
   CaseSelectorList lit;
   lit.push_back(create<SintLiteral>(&i32, 2));
 
-  auto ident = create<IdentifierExpression>("ident");
+  auto* ident = create<IdentifierExpression>("ident");
   CaseStatementList body;
   body.push_back(
       create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
diff --git a/src/ast/test_helper.h b/src/ast/test_helper.h
index 596d0ce..c97284c 100644
--- a/src/ast/test_helper.h
+++ b/src/ast/test_helper.h
@@ -19,6 +19,7 @@
 #include <utility>
 
 #include "gtest/gtest.h"
+#include "src/context.h"
 
 namespace tint {
 namespace ast {
@@ -30,12 +31,17 @@
   TestHelperBase() {}
   ~TestHelperBase() = default;
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx.create<T>(std::forward<ARGS>(args)...);
   }
+
+  /// The context
+  Context ctx;
 };
 using TestHelper = TestHelperBase<testing::Test>;
 
diff --git a/src/ast/type/access_control_type_test.cc b/src/ast/type/access_control_type_test.cc
index 11a2ae9..748114b 100644
--- a/src/ast/type/access_control_type_test.cc
+++ b/src/ast/type/access_control_type_test.cc
@@ -132,7 +132,7 @@
 
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   AccessControlType at{AccessControl::kReadOnly, &struct_type};
   EXPECT_EQ(16u, at.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@@ -181,7 +181,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   AccessControlType at{AccessControl::kReadOnly, &struct_type};
   EXPECT_EQ(16u, at.BaseAlignment(MemoryLayout::kUniformBuffer));
diff --git a/src/ast/type/alias_type_test.cc b/src/ast/type/alias_type_test.cc
index e0ff50b..ae62a0f 100644
--- a/src/ast/type/alias_type_test.cc
+++ b/src/ast/type/alias_type_test.cc
@@ -197,7 +197,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   AliasType alias{"alias", &struct_type};
   EXPECT_EQ(16u, alias.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@@ -246,7 +246,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   AliasType alias{"alias", &struct_type};
   EXPECT_EQ(16u, alias.BaseAlignment(MemoryLayout::kUniformBuffer));
diff --git a/src/ast/type/array_type.cc b/src/ast/type/array_type.cc
index 9a5960a..4a7b64d 100644
--- a/src/ast/type/array_type.cc
+++ b/src/ast/type/array_type.cc
@@ -68,7 +68,7 @@
 }
 
 uint32_t ArrayType::array_stride() const {
-  for (const auto& deco : decos_) {
+  for (auto* deco : decos_) {
     if (deco->IsStride()) {
       return deco->AsStride()->stride();
     }
@@ -77,7 +77,7 @@
 }
 
 bool ArrayType::has_array_stride() const {
-  for (const auto& deco : decos_) {
+  for (auto* deco : decos_) {
     if (deco->IsStride()) {
       return true;
     }
diff --git a/src/ast/type/struct_type.cc b/src/ast/type/struct_type.cc
index 98b426c..c6db7a0 100644
--- a/src/ast/type/struct_type.cc
+++ b/src/ast/type/struct_type.cc
@@ -26,8 +26,8 @@
 namespace ast {
 namespace type {
 
-StructType::StructType(const std::string& name, std::unique_ptr<Struct> impl)
-    : name_(name), struct_(std::move(impl)) {}
+StructType::StructType(const std::string& name, Struct* impl)
+    : name_(name), struct_(impl) {}
 
 StructType::StructType(StructType&&) = default;
 
@@ -46,7 +46,7 @@
     return 0;
   }
 
-  const auto& last_member = struct_->members().back();
+  auto* last_member = struct_->members().back();
 
   // If there is no offset, then this is not a host-shareable struct, returning
   // 0 indicates this to the caller.
@@ -67,7 +67,7 @@
 
 uint64_t StructType::BaseAlignment(MemoryLayout mem_layout) const {
   uint64_t max = 0;
-  for (const auto& member : struct_->members()) {
+  for (auto* member : struct_->members()) {
     if (member->type()->BaseAlignment(mem_layout) > max) {
       max = member->type()->BaseAlignment(mem_layout);
     }
diff --git a/src/ast/type/struct_type.h b/src/ast/type/struct_type.h
index 50c1565..99ee491 100644
--- a/src/ast/type/struct_type.h
+++ b/src/ast/type/struct_type.h
@@ -31,7 +31,7 @@
   /// Constructor
   /// @param name the name of the struct
   /// @param impl the struct data
-  StructType(const std::string& name, std::unique_ptr<Struct> impl);
+  StructType(const std::string& name, Struct* impl);
   /// Move constructor
   StructType(StructType&&);
   ~StructType() override;
@@ -46,7 +46,7 @@
   bool IsStruct() const override;
 
   /// @returns the struct name
-  Struct* impl() const { return struct_.get(); }
+  Struct* impl() const { return struct_; }
 
   /// @returns the name for the type
   std::string type_name() const override;
@@ -63,7 +63,7 @@
 
  private:
   std::string name_;
-  std::unique_ptr<Struct> struct_;
+  Struct* struct_ = nullptr;
 
   uint64_t LargestMemberBaseAlignment(MemoryLayout mem_layout) const;
 };
diff --git a/src/ast/type/struct_type_test.cc b/src/ast/type/struct_type_test.cc
index adbc30c..44d0ccc 100644
--- a/src/ast/type/struct_type_test.cc
+++ b/src/ast/type/struct_type_test.cc
@@ -34,14 +34,14 @@
 using StructTypeTest = TestHelper;
 
 TEST_F(StructTypeTest, Creation) {
-  auto impl = create<Struct>();
-  auto* ptr = impl.get();
+  auto* impl = create<Struct>();
+  auto* ptr = impl;
   StructType s{"S", std::move(impl)};
   EXPECT_EQ(s.impl(), ptr);
 }
 
 TEST_F(StructTypeTest, Is) {
-  auto impl = create<Struct>();
+  auto* impl = create<Struct>();
   StructType s{"S", std::move(impl)};
   EXPECT_FALSE(s.IsAccessControl());
   EXPECT_FALSE(s.IsAlias());
@@ -59,7 +59,7 @@
 }
 
 TEST_F(StructTypeTest, TypeName) {
-  auto impl = create<Struct>();
+  auto* impl = create<Struct>();
   StructType s{"my_struct", std::move(impl)};
   EXPECT_EQ(s.type_name(), "__struct_my_struct");
 }
@@ -80,7 +80,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   EXPECT_EQ(16u,
             struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@@ -114,7 +114,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   EXPECT_EQ(32u,
             struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@@ -149,7 +149,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   EXPECT_EQ(12u,
             struct_type.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
@@ -167,7 +167,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   EXPECT_EQ(16u,
             struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@@ -186,7 +186,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   EXPECT_EQ(16u,
             struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@@ -206,7 +206,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   EXPECT_EQ(16u,
             struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@@ -230,7 +230,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
   EXPECT_EQ(4u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
@@ -263,7 +263,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
   EXPECT_EQ(4u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
@@ -296,7 +296,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   EXPECT_EQ(4u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
 }
@@ -313,7 +313,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
   EXPECT_EQ(8u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
@@ -331,7 +331,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
   EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
@@ -349,7 +349,7 @@
   }
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   StructType struct_type("struct_type", std::move(str));
   EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
   EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
diff --git a/src/ast/type_constructor_expression.cc b/src/ast/type_constructor_expression.cc
index e68ddba..3168df0 100644
--- a/src/ast/type_constructor_expression.cc
+++ b/src/ast/type_constructor_expression.cc
@@ -45,7 +45,7 @@
   if (type_ == nullptr) {
     return false;
   }
-  for (const auto& val : values_) {
+  for (auto* val : values_) {
     if (val == nullptr || !val->IsValid()) {
       return false;
     }
@@ -59,7 +59,7 @@
   make_indent(out, indent + 2);
   out << type_->type_name() << std::endl;
 
-  for (const auto& val : values_) {
+  for (auto* val : values_) {
     val->to_str(out, indent + 2);
   }
   make_indent(out, indent);
diff --git a/src/ast/type_constructor_expression_test.cc b/src/ast/type_constructor_expression_test.cc
index ba2a88f..18914f0 100644
--- a/src/ast/type_constructor_expression_test.cc
+++ b/src/ast/type_constructor_expression_test.cc
@@ -33,12 +33,12 @@
   type::F32Type f32;
   ExpressionList expr;
   expr.push_back(create<IdentifierExpression>("expr"));
-  auto* expr_ptr = expr[0].get();
+  auto* expr_ptr = expr[0];
 
   TypeConstructorExpression t(&f32, std::move(expr));
   EXPECT_EQ(t.type(), &f32);
   ASSERT_EQ(t.values().size(), 1u);
-  EXPECT_EQ(t.values()[0].get(), expr_ptr);
+  EXPECT_EQ(t.values()[0], expr_ptr);
 }
 
 TEST_F(TypeConstructorExpressionTest, Creation_WithSource) {
diff --git a/src/ast/unary_op_expression.cc b/src/ast/unary_op_expression.cc
index 10d73b4..d519451 100644
--- a/src/ast/unary_op_expression.cc
+++ b/src/ast/unary_op_expression.cc
@@ -19,14 +19,13 @@
 
 UnaryOpExpression::UnaryOpExpression() : Expression() {}
 
-UnaryOpExpression::UnaryOpExpression(UnaryOp op,
-                                     std::unique_ptr<Expression> expr)
-    : Expression(), op_(op), expr_(std::move(expr)) {}
+UnaryOpExpression::UnaryOpExpression(UnaryOp op, Expression* expr)
+    : Expression(), op_(op), expr_(expr) {}
 
 UnaryOpExpression::UnaryOpExpression(const Source& source,
                                      UnaryOp op,
-                                     std::unique_ptr<Expression> expr)
-    : Expression(source), op_(op), expr_(std::move(expr)) {}
+                                     Expression* expr)
+    : Expression(source), op_(op), expr_(expr) {}
 
 UnaryOpExpression::UnaryOpExpression(UnaryOpExpression&&) = default;
 
diff --git a/src/ast/unary_op_expression.h b/src/ast/unary_op_expression.h
index fb38ba7..918d779 100644
--- a/src/ast/unary_op_expression.h
+++ b/src/ast/unary_op_expression.h
@@ -33,14 +33,12 @@
   /// Constructor
   /// @param op the op
   /// @param expr the expr
-  UnaryOpExpression(UnaryOp op, std::unique_ptr<Expression> expr);
+  UnaryOpExpression(UnaryOp op, Expression* expr);
   /// Constructor
   /// @param source the unary op expression source
   /// @param op the op
   /// @param expr the expr
-  UnaryOpExpression(const Source& source,
-                    UnaryOp op,
-                    std::unique_ptr<Expression> expr);
+  UnaryOpExpression(const Source& source, UnaryOp op, Expression* expr);
   /// Move constructor
   UnaryOpExpression(UnaryOpExpression&&);
   ~UnaryOpExpression() override;
@@ -53,9 +51,9 @@
 
   /// Sets the expr
   /// @param expr the expression
-  void set_expr(std::unique_ptr<Expression> expr) { expr_ = std::move(expr); }
+  void set_expr(Expression* expr) { expr_ = expr; }
   /// @returns the expression
-  Expression* expr() const { return expr_.get(); }
+  Expression* expr() const { return expr_; }
 
   /// @returns true if this is an as expression
   bool IsUnaryOp() const override;
@@ -72,7 +70,7 @@
   UnaryOpExpression(const UnaryOpExpression&) = delete;
 
   UnaryOp op_ = UnaryOp::kNegation;
-  std::unique_ptr<Expression> expr_;
+  Expression* expr_ = nullptr;
 };
 
 }  // namespace ast
diff --git a/src/ast/unary_op_expression_test.cc b/src/ast/unary_op_expression_test.cc
index 271f8b9..9192139 100644
--- a/src/ast/unary_op_expression_test.cc
+++ b/src/ast/unary_op_expression_test.cc
@@ -26,8 +26,8 @@
 using UnaryOpExpressionTest = TestHelper;
 
 TEST_F(UnaryOpExpressionTest, Creation) {
-  auto ident = create<IdentifierExpression>("ident");
-  auto* ident_ptr = ident.get();
+  auto* ident = create<IdentifierExpression>("ident");
+  auto* ident_ptr = ident;
 
   UnaryOpExpression u(UnaryOp::kNot, std::move(ident));
   EXPECT_EQ(u.op(), UnaryOp::kNot);
@@ -35,7 +35,7 @@
 }
 
 TEST_F(UnaryOpExpressionTest, Creation_WithSource) {
-  auto ident = create<IdentifierExpression>("ident");
+  auto* ident = create<IdentifierExpression>("ident");
   UnaryOpExpression u(Source{Source::Location{20, 2}}, UnaryOp::kNot,
                       std::move(ident));
   auto src = u.source();
@@ -49,7 +49,7 @@
 }
 
 TEST_F(UnaryOpExpressionTest, IsValid) {
-  auto ident = create<IdentifierExpression>("ident");
+  auto* ident = create<IdentifierExpression>("ident");
   UnaryOpExpression u(UnaryOp::kNot, std::move(ident));
   EXPECT_TRUE(u.IsValid());
 }
@@ -61,13 +61,13 @@
 }
 
 TEST_F(UnaryOpExpressionTest, IsValid_InvalidExpression) {
-  auto ident = create<IdentifierExpression>("");
+  auto* ident = create<IdentifierExpression>("");
   UnaryOpExpression u(UnaryOp::kNot, std::move(ident));
   EXPECT_FALSE(u.IsValid());
 }
 
 TEST_F(UnaryOpExpressionTest, ToStr) {
-  auto ident = create<IdentifierExpression>("ident");
+  auto* ident = create<IdentifierExpression>("ident");
   UnaryOpExpression u(UnaryOp::kNot, std::move(ident));
   std::ostringstream out;
   u.to_str(out, 2);
diff --git a/src/ast/variable.h b/src/ast/variable.h
index f2df345..711d6b7 100644
--- a/src/ast/variable.h
+++ b/src/ast/variable.h
@@ -122,11 +122,9 @@
 
   /// Sets the constructor
   /// @param expr the constructor expression
-  void set_constructor(std::unique_ptr<Expression> expr) {
-    constructor_ = std::move(expr);
-  }
+  void set_constructor(Expression* expr) { constructor_ = expr; }
   /// @returns the constructor expression or nullptr if none set
-  Expression* constructor() const { return constructor_.get(); }
+  Expression* constructor() const { return constructor_; }
   /// @returns true if the variable has an constructor
   bool has_constructor() const { return constructor_ != nullptr; }
 
@@ -170,11 +168,11 @@
   StorageClass storage_class_ = StorageClass::kNone;
   // The value type if a const or formal paramter, and the store type if a var
   type::Type* type_ = nullptr;
-  std::unique_ptr<Expression> constructor_;
+  Expression* constructor_ = nullptr;
 };
 
-/// A list of unique variables
-using VariableList = std::vector<std::unique_ptr<Variable>>;
+/// A list of variables
+using VariableList = std::vector<Variable*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/variable_decl_statement.cc b/src/ast/variable_decl_statement.cc
index b19d750..2a509be 100644
--- a/src/ast/variable_decl_statement.cc
+++ b/src/ast/variable_decl_statement.cc
@@ -19,12 +19,12 @@
 
 VariableDeclStatement::VariableDeclStatement() : Statement() {}
 
-VariableDeclStatement::VariableDeclStatement(std::unique_ptr<Variable> variable)
-    : Statement(), variable_(std::move(variable)) {}
+VariableDeclStatement::VariableDeclStatement(Variable* variable)
+    : Statement(), variable_(variable) {}
 
 VariableDeclStatement::VariableDeclStatement(const Source& source,
-                                             std::unique_ptr<Variable> variable)
-    : Statement(source), variable_(std::move(variable)) {}
+                                             Variable* variable)
+    : Statement(source), variable_(variable) {}
 
 VariableDeclStatement::VariableDeclStatement(VariableDeclStatement&&) = default;
 
diff --git a/src/ast/variable_decl_statement.h b/src/ast/variable_decl_statement.h
index 4873de0..a628991 100644
--- a/src/ast/variable_decl_statement.h
+++ b/src/ast/variable_decl_statement.h
@@ -32,23 +32,20 @@
   VariableDeclStatement();
   /// Constructor
   /// @param variable the variable
-  explicit VariableDeclStatement(std::unique_ptr<Variable> variable);
+  explicit VariableDeclStatement(Variable* variable);
   /// Constructor
   /// @param source the variable statement source
   /// @param variable the variable
-  VariableDeclStatement(const Source& source,
-                        std::unique_ptr<Variable> variable);
+  VariableDeclStatement(const Source& source, Variable* variable);
   /// Move constructor
   VariableDeclStatement(VariableDeclStatement&&);
   ~VariableDeclStatement() override;
 
   /// Sets the variable
   /// @param variable the variable to set
-  void set_variable(std::unique_ptr<Variable> variable) {
-    variable_ = std::move(variable);
-  }
+  void set_variable(Variable* variable) { variable_ = variable; }
   /// @returns the variable
-  Variable* variable() const { return variable_.get(); }
+  Variable* variable() const { return variable_; }
 
   /// @returns true if this is an variable statement
   bool IsVariableDecl() const override;
@@ -64,7 +61,7 @@
  private:
   VariableDeclStatement(const VariableDeclStatement&) = delete;
 
-  std::unique_ptr<Variable> variable_;
+  Variable* variable_ = nullptr;
 };
 
 }  // namespace ast
diff --git a/src/ast/variable_decl_statement_test.cc b/src/ast/variable_decl_statement_test.cc
index b32e2c1..9ab2c3b 100644
--- a/src/ast/variable_decl_statement_test.cc
+++ b/src/ast/variable_decl_statement_test.cc
@@ -26,8 +26,8 @@
 
 TEST_F(VariableDeclStatementTest, Creation) {
   type::F32Type f32;
-  auto var = create<Variable>("a", StorageClass::kNone, &f32);
-  auto* var_ptr = var.get();
+  auto* var = create<Variable>("a", StorageClass::kNone, &f32);
+  auto* var_ptr = var;
 
   VariableDeclStatement stmt(std::move(var));
   EXPECT_EQ(stmt.variable(), var_ptr);
@@ -35,7 +35,7 @@
 
 TEST_F(VariableDeclStatementTest, Creation_WithSource) {
   type::F32Type f32;
-  auto var = create<Variable>("a", StorageClass::kNone, &f32);
+  auto* var = create<Variable>("a", StorageClass::kNone, &f32);
 
   VariableDeclStatement stmt(Source{Source::Location{20, 2}}, std::move(var));
   auto src = stmt.source();
@@ -50,14 +50,14 @@
 
 TEST_F(VariableDeclStatementTest, IsValid) {
   type::F32Type f32;
-  auto var = create<Variable>("a", StorageClass::kNone, &f32);
+  auto* var = create<Variable>("a", StorageClass::kNone, &f32);
   VariableDeclStatement stmt(std::move(var));
   EXPECT_TRUE(stmt.IsValid());
 }
 
 TEST_F(VariableDeclStatementTest, IsValid_InvalidVariable) {
   type::F32Type f32;
-  auto var = create<Variable>("", StorageClass::kNone, &f32);
+  auto* var = create<Variable>("", StorageClass::kNone, &f32);
   VariableDeclStatement stmt(std::move(var));
   EXPECT_FALSE(stmt.IsValid());
 }
@@ -69,7 +69,7 @@
 
 TEST_F(VariableDeclStatementTest, ToStr) {
   type::F32Type f32;
-  auto var = create<Variable>("a", StorageClass::kNone, &f32);
+  auto* var = create<Variable>("a", StorageClass::kNone, &f32);
 
   VariableDeclStatement stmt(Source{Source::Location{20, 2}}, std::move(var));
   std::ostringstream out;
diff --git a/src/ast/variable_decoration.h b/src/ast/variable_decoration.h
index 16c0744..b1c1fa0 100644
--- a/src/ast/variable_decoration.h
+++ b/src/ast/variable_decoration.h
@@ -67,8 +67,8 @@
   explicit VariableDecoration(const Source& source);
 };
 
-/// A list of unique variable decorations
-using VariableDecorationList = std::vector<std::unique_ptr<VariableDecoration>>;
+/// A list of variable decorations
+using VariableDecorationList = std::vector<VariableDecoration*>;
 
 }  // namespace ast
 }  // namespace tint
diff --git a/src/context.cc b/src/context.cc
index 97cb16c..e72ee82 100644
--- a/src/context.cc
+++ b/src/context.cc
@@ -16,6 +16,7 @@
 
 #include <utility>
 
+#include "src/ast/node.h"
 #include "src/namer.h"
 #include "src/type_manager.h"
 
diff --git a/src/context.h b/src/context.h
index 40c7a14..edec3e7 100644
--- a/src/context.h
+++ b/src/context.h
@@ -15,13 +15,22 @@
 #ifndef SRC_CONTEXT_H_
 #define SRC_CONTEXT_H_
 
+#include <assert.h>
+
 #include <memory>
+#include <type_traits>
+#include <utility>
+#include <vector>
 
 #include "src/namer.h"
 #include "src/type_manager.h"
 
 namespace tint {
 
+namespace ast {
+class Node;
+}
+
 /// Context object for Tint. Holds various global resources used through
 /// the system.
 class Context {
@@ -42,9 +51,24 @@
   /// @returns the namer object
   Namer* namer() const { return namer_.get(); }
 
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
+  template <typename T, typename... ARGS>
+  T* create(ARGS&&... args) {
+    static_assert(std::is_base_of<ast::Node, T>::value,
+                  "T does not derive from ast::Node");
+    auto uptr = std::make_unique<T>(std::forward<ARGS>(args)...);
+    auto ptr = uptr.get();
+    ast_nodes_.emplace_back(std::move(uptr));
+    return ptr;
+  }
+
  private:
   TypeManager type_mgr_;
   std::unique_ptr<Namer> namer_;
+  std::vector<std::unique_ptr<ast::Node>> ast_nodes_;
 };
 
 }  // namespace tint
diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc
index cb9b703..dd78493 100644
--- a/src/inspector/inspector.cc
+++ b/src/inspector/inspector.cc
@@ -56,7 +56,7 @@
 std::vector<EntryPoint> Inspector::GetEntryPoints() {
   std::vector<EntryPoint> result;
 
-  for (const auto& func : module_.functions()) {
+  for (auto* func : module_.functions()) {
     if (!func->IsEntryPoint()) {
       continue;
     }
@@ -96,7 +96,7 @@
 
 std::map<uint32_t, Scalar> Inspector::GetConstantIDs() {
   std::map<uint32_t, Scalar> result;
-  for (auto& var : module_.global_variables()) {
+  for (auto* var : module_.global_variables()) {
     if (!var->IsDecorated()) {
       continue;
     }
diff --git a/src/inspector/inspector_test.cc b/src/inspector/inspector_test.cc
index 03104bd..50a9380 100644
--- a/src/inspector/inspector_test.cc
+++ b/src/inspector/inspector_test.cc
@@ -78,8 +78,8 @@
   /// Generates an empty function
   /// @param name name of the function created
   /// @returns a function object
-  std::unique_ptr<ast::Function> MakeEmptyBodyFunction(std::string name) {
-    auto body = create<ast::BlockStatement>();
+  ast::Function* MakeEmptyBodyFunction(std::string name) {
+    auto* body = create<ast::BlockStatement>();
     body->append(create<ast::ReturnStatement>());
     return create<ast::Function>(name, ast::VariableList(), void_type(),
                                  std::move(body));
@@ -89,12 +89,12 @@
   /// @param caller name of the function created
   /// @param callee name of the function to be called
   /// @returns a function object
-  std::unique_ptr<ast::Function> MakeCallerBodyFunction(std::string caller,
-                                                        std::string callee) {
-    auto body = create<ast::BlockStatement>();
-    auto ident_expr = create<ast::IdentifierExpression>(callee);
-    auto call_expr = create<ast::CallExpression>(std::move(ident_expr),
-                                                 ast::ExpressionList());
+  ast::Function* MakeCallerBodyFunction(std::string caller,
+                                        std::string callee) {
+    auto* body = create<ast::BlockStatement>();
+    auto* ident_expr = create<ast::IdentifierExpression>(callee);
+    auto* call_expr = create<ast::CallExpression>(std::move(ident_expr),
+                                                  ast::ExpressionList());
     body->append(create<ast::CallStatement>(std::move(call_expr)));
     body->append(create<ast::ReturnStatement>());
     return create<ast::Function>(caller, ast::VariableList(), void_type(),
@@ -109,9 +109,9 @@
     for (auto inout : inout_vars) {
       std::string in, out;
       std::tie(in, out) = inout;
-      auto in_var =
+      auto* in_var =
           create<ast::Variable>(in, ast::StorageClass::kInput, u32_type());
-      auto out_var =
+      auto* out_var =
           create<ast::Variable>(out, ast::StorageClass::kOutput, u32_type());
       mod()->AddGlobalVariable(std::move(in_var));
       mod()->AddGlobalVariable(std::move(out_var));
@@ -123,10 +123,10 @@
   /// @param inout_vars tuples of {in, out} that will be converted into out = in
   ///                   calls in the function body
   /// @returns a function object
-  std::unique_ptr<ast::Function> MakeInOutVariableBodyFunction(
+  ast::Function* MakeInOutVariableBodyFunction(
       std::string name,
       std::vector<std::tuple<std::string, std::string>> inout_vars) {
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
     for (auto inout : inout_vars) {
       std::string in, out;
       std::tie(in, out) = inout;
@@ -146,11 +146,11 @@
   /// @param inout_vars tuples of {in, out} that will be converted into out = in
   ///                   calls in the function body
   /// @returns a function object
-  std::unique_ptr<ast::Function> MakeInOutVariableCallerBodyFunction(
+  ast::Function* MakeInOutVariableCallerBodyFunction(
       std::string caller,
       std::string callee,
       std::vector<std::tuple<std::string, std::string>> inout_vars) {
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
     for (auto inout : inout_vars) {
       std::string in, out;
       std::tie(in, out) = inout;
@@ -158,9 +158,9 @@
           create<ast::IdentifierExpression>(out),
           create<ast::IdentifierExpression>(in)));
     }
-    auto ident_expr = create<ast::IdentifierExpression>(callee);
-    auto call_expr = create<ast::CallExpression>(std::move(ident_expr),
-                                                 ast::ExpressionList());
+    auto* ident_expr = create<ast::IdentifierExpression>(callee);
+    auto* call_expr = create<ast::CallExpression>(std::move(ident_expr),
+                                                  ast::ExpressionList());
     body->append(create<ast::CallStatement>(std::move(call_expr)));
     body->append(create<ast::ReturnStatement>());
     return create<ast::Function>(caller, ast::VariableList(), void_type(),
@@ -178,7 +178,7 @@
                      uint32_t id,
                      ast::type::Type* type,
                      T* val) {
-    auto dvar = create<ast::DecoratedVariable>(
+    auto* dvar = create<ast::DecoratedVariable>(
         create<ast::Variable>(name, ast::StorageClass::kNone, type));
     dvar->set_is_const(true);
     ast::VariableDecorationList decos;
@@ -194,30 +194,28 @@
   /// @param type AST type of the literal, must resolve to BoolLiteral
   /// @param val scalar value for the literal to contain
   /// @returns a Literal of the expected type and value
-  std::unique_ptr<ast::Literal> MakeLiteral(ast::type::Type* type, bool* val) {
+  ast::Literal* MakeLiteral(ast::type::Type* type, bool* val) {
     return create<ast::BoolLiteral>(type, *val);
   }
 
   /// @param type AST type of the literal, must resolve to UIntLiteral
   /// @param val scalar value for the literal to contain
   /// @returns a Literal of the expected type and value
-  std::unique_ptr<ast::Literal> MakeLiteral(ast::type::Type* type,
-                                            uint32_t* val) {
+  ast::Literal* MakeLiteral(ast::type::Type* type, uint32_t* val) {
     return create<ast::UintLiteral>(type, *val);
   }
 
   /// @param type AST type of the literal, must resolve to IntLiteral
   /// @param val scalar value for the literal to contain
   /// @returns a Literal of the expected type and value
-  std::unique_ptr<ast::Literal> MakeLiteral(ast::type::Type* type,
-                                            int32_t* val) {
+  ast::Literal* MakeLiteral(ast::type::Type* type, int32_t* val) {
     return create<ast::SintLiteral>(type, *val);
   }
 
   /// @param type AST type of the literal, must resolve to FloattLiteral
   /// @param val scalar value for the literal to contain
   /// @returns a Literal of the expected type and value
-  std::unique_ptr<ast::Literal> MakeLiteral(ast::type::Type* type, float* val) {
+  ast::Literal* MakeLiteral(ast::type::Type* type, float* val) {
     return create<ast::FloatLiteral>(type, *val);
   }
 
@@ -271,7 +269,7 @@
       decos.push_back(create<ast::StructBlockDecoration>(Source{}));
     }
 
-    auto str = create<ast::Struct>(std::move(decos), std::move(members));
+    auto* str = create<ast::Struct>(std::move(decos), std::move(members));
 
     return std::make_unique<ast::type::StructType>(name, std::move(str));
   }
@@ -341,7 +339,7 @@
                   ast::StorageClass storage_class,
                   uint32_t set,
                   uint32_t binding) {
-    auto var = create<ast::DecoratedVariable>(
+    auto* var = create<ast::DecoratedVariable>(
         create<ast::Variable>(name, storage_class, type));
     ast::VariableDecorationList decorations;
 
@@ -381,11 +379,11 @@
   /// @param struct_name name of the struct variabler to be accessed
   /// @param members list of members to access, by index and type
   /// @returns a function that references all of the members specified
-  std::unique_ptr<ast::Function> MakeStructVariableReferenceBodyFunction(
+  ast::Function* MakeStructVariableReferenceBodyFunction(
       std::string func_name,
       std::string struct_name,
       std::vector<std::tuple<size_t, ast::type::Type*>> members) {
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
 
     for (auto member : members) {
       size_t member_idx;
@@ -504,7 +502,7 @@
   /// @param sampler_name name of the sampler to use
   /// @param coords_name name of the coords variable to use
   /// @returns a function that references all of the values specified
-  std::unique_ptr<ast::Function> MakeSamplerReferenceBodyFunction(
+  ast::Function* MakeSamplerReferenceBodyFunction(
       const std::string& func_name,
       const std::string& texture_name,
       const std::string& sampler_name,
@@ -512,9 +510,9 @@
       ast::type::Type* base_type) {
     std::string result_name = "sampler_result";
 
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
 
-    auto call_result = create<ast::Variable>(
+    auto* call_result = create<ast::Variable>(
         "sampler_result", ast::StorageClass::kFunction, vec_type(base_type, 4));
     body->append(create<ast::VariableDeclStatement>(std::move(call_result)));
 
@@ -522,7 +520,7 @@
     call_params.push_back(create<ast::IdentifierExpression>(texture_name));
     call_params.push_back(create<ast::IdentifierExpression>(sampler_name));
     call_params.push_back(create<ast::IdentifierExpression>(coords_name));
-    auto call_expr = create<ast::CallExpression>(
+    auto* call_expr = create<ast::CallExpression>(
         create<ast::IdentifierExpression>("textureSample"),
         std::move(call_params));
 
@@ -543,7 +541,7 @@
   /// @param coords_name name of the coords variable to use
   /// @param depth_name name of the depth reference to use
   /// @returns a function that references all of the values specified
-  std::unique_ptr<ast::Function> MakeComparisonSamplerReferenceBodyFunction(
+  ast::Function* MakeComparisonSamplerReferenceBodyFunction(
       const std::string& func_name,
       const std::string& texture_name,
       const std::string& sampler_name,
@@ -552,9 +550,9 @@
       ast::type::Type* base_type) {
     std::string result_name = "sampler_result";
 
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
 
-    auto call_result = create<ast::Variable>(
+    auto* call_result = create<ast::Variable>(
         "sampler_result", ast::StorageClass::kFunction, base_type);
     body->append(create<ast::VariableDeclStatement>(std::move(call_result)));
 
@@ -563,7 +561,7 @@
     call_params.push_back(create<ast::IdentifierExpression>(sampler_name));
     call_params.push_back(create<ast::IdentifierExpression>(coords_name));
     call_params.push_back(create<ast::IdentifierExpression>(depth_name));
-    auto call_expr = create<ast::CallExpression>(
+    auto* call_expr = create<ast::CallExpression>(
         create<ast::IdentifierExpression>("textureSampleCompare"),
         std::move(call_params));
 
@@ -643,11 +641,13 @@
     return &comparison_sampler_type_;
   }
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx_.create<T>(std::forward<ARGS>(args)...);
   }
 
  private:
@@ -723,7 +723,7 @@
 }
 
 TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
-  auto foo = MakeEmptyBodyFunction("foo");
+  auto* foo = MakeEmptyBodyFunction("foo");
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
@@ -738,12 +738,12 @@
 }
 
 TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
-  auto foo = MakeEmptyBodyFunction("foo");
+  auto* foo = MakeEmptyBodyFunction("foo");
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
-  auto bar = MakeEmptyBodyFunction("bar");
+  auto* bar = MakeEmptyBodyFunction("bar");
   bar->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
   mod()->AddFunction(std::move(bar));
@@ -761,15 +761,15 @@
 }
 
 TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
-  auto func = MakeEmptyBodyFunction("func");
+  auto* func = MakeEmptyBodyFunction("func");
   mod()->AddFunction(std::move(func));
 
-  auto foo = MakeCallerBodyFunction("foo", "func");
+  auto* foo = MakeCallerBodyFunction("foo", "func");
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
-  auto bar = MakeCallerBodyFunction("bar", "func");
+  auto* bar = MakeCallerBodyFunction("bar", "func");
   bar->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
   mod()->AddFunction(std::move(bar));
@@ -787,7 +787,7 @@
 }
 
 TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
-  auto foo = MakeCallerBodyFunction("foo", "func");
+  auto* foo = MakeCallerBodyFunction("foo", "func");
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
@@ -804,7 +804,7 @@
 }
 
 TEST_F(InspectorGetEntryPointTest, NonDefaultWorkgroupSize) {
-  auto foo = MakeEmptyBodyFunction("foo");
+  auto* foo = MakeEmptyBodyFunction("foo");
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
   foo->add_decoration(create<ast::WorkgroupDecoration>(8u, 2u, 1u, Source{}));
@@ -822,10 +822,10 @@
 }
 
 TEST_F(InspectorGetEntryPointTest, NoInOutVariables) {
-  auto func = MakeEmptyBodyFunction("func");
+  auto* func = MakeEmptyBodyFunction("func");
   mod()->AddFunction(std::move(func));
 
-  auto foo = MakeCallerBodyFunction("foo", "func");
+  auto* foo = MakeCallerBodyFunction("foo", "func");
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
@@ -841,7 +841,7 @@
 TEST_F(InspectorGetEntryPointTest, EntryPointInOutVariables) {
   AddInOutVariables({{"in_var", "out_var"}});
 
-  auto foo = MakeInOutVariableBodyFunction("foo", {{"in_var", "out_var"}});
+  auto* foo = MakeInOutVariableBodyFunction("foo", {{"in_var", "out_var"}});
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
@@ -862,10 +862,10 @@
 TEST_F(InspectorGetEntryPointTest, FunctionInOutVariables) {
   AddInOutVariables({{"in_var", "out_var"}});
 
-  auto func = MakeInOutVariableBodyFunction("func", {{"in_var", "out_var"}});
+  auto* func = MakeInOutVariableBodyFunction("func", {{"in_var", "out_var"}});
   mod()->AddFunction(std::move(func));
 
-  auto foo = MakeCallerBodyFunction("foo", "func");
+  auto* foo = MakeCallerBodyFunction("foo", "func");
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
@@ -886,11 +886,11 @@
 TEST_F(InspectorGetEntryPointTest, RepeatedInOutVariables) {
   AddInOutVariables({{"in_var", "out_var"}});
 
-  auto func = MakeInOutVariableBodyFunction("func", {{"in_var", "out_var"}});
+  auto* func = MakeInOutVariableBodyFunction("func", {{"in_var", "out_var"}});
   mod()->AddFunction(std::move(func));
 
-  auto foo = MakeInOutVariableCallerBodyFunction("foo", "func",
-                                                 {{"in_var", "out_var"}});
+  auto* foo = MakeInOutVariableCallerBodyFunction("foo", "func",
+                                                  {{"in_var", "out_var"}});
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
@@ -911,7 +911,7 @@
 TEST_F(InspectorGetEntryPointTest, EntryPointMultipleInOutVariables) {
   AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
 
-  auto foo = MakeInOutVariableBodyFunction(
+  auto* foo = MakeInOutVariableBodyFunction(
       "foo", {{"in_var", "out_var"}, {"in2_var", "out2_var"}});
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@@ -935,11 +935,11 @@
 TEST_F(InspectorGetEntryPointTest, FunctionMultipleInOutVariables) {
   AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
 
-  auto func = MakeInOutVariableBodyFunction(
+  auto* func = MakeInOutVariableBodyFunction(
       "func", {{"in_var", "out_var"}, {"in2_var", "out2_var"}});
   mod()->AddFunction(std::move(func));
 
-  auto foo = MakeCallerBodyFunction("foo", "func");
+  auto* foo = MakeCallerBodyFunction("foo", "func");
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
@@ -962,12 +962,12 @@
 TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutVariables) {
   AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
 
-  auto foo = MakeInOutVariableBodyFunction("foo", {{"in_var", "out2_var"}});
+  auto* foo = MakeInOutVariableBodyFunction("foo", {{"in_var", "out2_var"}});
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
-  auto bar = MakeInOutVariableBodyFunction("bar", {{"in2_var", "out_var"}});
+  auto* bar = MakeInOutVariableBodyFunction("bar", {{"in2_var", "out_var"}});
   bar->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
   mod()->AddFunction(std::move(bar));
@@ -997,16 +997,16 @@
 TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsSharedInOutVariables) {
   AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
 
-  auto func = MakeInOutVariableBodyFunction("func", {{"in2_var", "out2_var"}});
+  auto* func = MakeInOutVariableBodyFunction("func", {{"in2_var", "out2_var"}});
   mod()->AddFunction(std::move(func));
 
-  auto foo = MakeInOutVariableCallerBodyFunction("foo", "func",
-                                                 {{"in_var", "out_var"}});
+  auto* foo = MakeInOutVariableCallerBodyFunction("foo", "func",
+                                                  {{"in_var", "out_var"}});
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
-  auto bar = MakeCallerBodyFunction("bar", "func");
+  auto* bar = MakeCallerBodyFunction("bar", "func");
   bar->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
   mod()->AddFunction(std::move(bar));
@@ -1058,7 +1058,7 @@
 // TODO(rharrison): Reenable once GetRemappedNameForEntryPoint isn't a pass
 // through
 TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_OneEntryPoint) {
-  auto foo = MakeEmptyBodyFunction("foo");
+  auto* foo = MakeEmptyBodyFunction("foo");
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
@@ -1073,12 +1073,12 @@
 // through
 TEST_F(InspectorGetRemappedNameForEntryPointTest,
        DISABLED_MultipleEntryPoints) {
-  auto foo = MakeEmptyBodyFunction("foo");
+  auto* foo = MakeEmptyBodyFunction("foo");
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
-  auto bar = MakeEmptyBodyFunction("bar");
+  auto* bar = MakeEmptyBodyFunction("bar");
   bar->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
   mod()->AddFunction(std::move(bar));
@@ -1197,11 +1197,11 @@
       MakeUniformBufferTypes("foo_type", {{i32_type(), 0}});
   AddUniformBuffer("foo_ub", foo_control_type.get(), 0, 0);
 
-  auto ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
-                                                         {{0, i32_type()}});
+  auto* ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
+                                                          {{0, i32_type()}});
   mod()->AddFunction(std::move(ub_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1224,17 +1224,17 @@
 
   ast::StructDecorationList decos;
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
   auto foo_type =
       std::make_unique<ast::type::StructType>("foo_type", std::move(str));
 
   AddUniformBuffer("foo_ub", foo_type.get(), 0, 0);
 
-  auto ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
-                                                         {{0, i32_type()}});
+  auto* ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
+                                                          {{0, i32_type()}});
   mod()->AddFunction(std::move(ub_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1253,11 +1253,11 @@
       MakeUniformBufferTypes("foo_type", {{i32_type(), 0}});
   AddUniformBuffer("foo_ub", foo_control_type.get(), 0, 0);
 
-  auto ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
-                                                         {{0, i32_type()}});
+  auto* ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
+                                                          {{0, i32_type()}});
   mod()->AddFunction(std::move(ub_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1280,11 +1280,11 @@
       "foo_type", {{i32_type(), 0}, {u32_type(), 4}, {f32_type(), 8}});
   AddUniformBuffer("foo_ub", foo_control_type.get(), 0, 0);
 
-  auto ub_func = MakeStructVariableReferenceBodyFunction(
+  auto* ub_func = MakeStructVariableReferenceBodyFunction(
       "ub_func", "foo_ub", {{0, i32_type()}, {1, u32_type()}, {2, f32_type()}});
   mod()->AddFunction(std::move(ub_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1311,7 +1311,7 @@
 
   auto AddReferenceFunc = [this](const std::string& func_name,
                                  const std::string& var_name) {
-    auto ub_func = MakeStructVariableReferenceBodyFunction(
+    auto* ub_func = MakeStructVariableReferenceBodyFunction(
         func_name, var_name,
         {{0, i32_type()}, {1, u32_type()}, {2, f32_type()}});
     mod()->AddFunction(std::move(ub_func));
@@ -1321,20 +1321,20 @@
   AddReferenceFunc("ub_baz_func", "ub_baz");
 
   auto AddFuncCall = [&](ast::BlockStatement* body, const std::string& callee) {
-    auto ident_expr = create<ast::IdentifierExpression>(callee);
-    auto call_expr = create<ast::CallExpression>(std::move(ident_expr),
-                                                 ast::ExpressionList());
+    auto* ident_expr = create<ast::IdentifierExpression>(callee);
+    auto* call_expr = create<ast::CallExpression>(std::move(ident_expr),
+                                                  ast::ExpressionList());
     body->append(create<ast::CallStatement>(std::move(call_expr)));
   };
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
 
-  AddFuncCall(body.get(), "ub_foo_func");
-  AddFuncCall(body.get(), "ub_bar_func");
-  AddFuncCall(body.get(), "ub_baz_func");
+  AddFuncCall(body, "ub_foo_func");
+  AddFuncCall(body, "ub_bar_func");
+  AddFuncCall(body, "ub_baz_func");
 
   body->append(create<ast::ReturnStatement>());
-  std::unique_ptr<ast::Function> func = create<ast::Function>(
-      "ep_func", ast::VariableList(), void_type(), std::move(body));
+  ast::Function* func = create<ast::Function>("ep_func", ast::VariableList(),
+                                              void_type(), std::move(body));
 
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@@ -1366,11 +1366,11 @@
       "foo_type", {{i32_type(), 0}, {u32_array_type(4), 4}});
   AddUniformBuffer("foo_ub", foo_control_type.get(), 0, 0);
 
-  auto ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
-                                                         {{0, i32_type()}});
+  auto* ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
+                                                          {{0, i32_type()}});
   mod()->AddFunction(std::move(ub_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1393,11 +1393,11 @@
       MakeStorageBufferTypes("foo_type", {{i32_type(), 0}});
   AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
 
-  auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
-                                                         {{0, i32_type()}});
+  auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+                                                          {{0, i32_type()}});
   mod()->AddFunction(std::move(sb_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1420,11 +1420,11 @@
       "foo_type", {{i32_type(), 0}, {u32_type(), 4}, {f32_type(), 8}});
   AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
 
-  auto sb_func = MakeStructVariableReferenceBodyFunction(
+  auto* sb_func = MakeStructVariableReferenceBodyFunction(
       "sb_func", "foo_sb", {{0, i32_type()}, {1, u32_type()}, {2, f32_type()}});
   mod()->AddFunction(std::move(sb_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1451,7 +1451,7 @@
 
   auto AddReferenceFunc = [this](const std::string& func_name,
                                  const std::string& var_name) {
-    auto sb_func = MakeStructVariableReferenceBodyFunction(
+    auto* sb_func = MakeStructVariableReferenceBodyFunction(
         func_name, var_name,
         {{0, i32_type()}, {1, u32_type()}, {2, f32_type()}});
     mod()->AddFunction(std::move(sb_func));
@@ -1461,20 +1461,20 @@
   AddReferenceFunc("sb_baz_func", "sb_baz");
 
   auto AddFuncCall = [&](ast::BlockStatement* body, const std::string& callee) {
-    auto ident_expr = create<ast::IdentifierExpression>(callee);
-    auto call_expr = create<ast::CallExpression>(std::move(ident_expr),
-                                                 ast::ExpressionList());
+    auto* ident_expr = create<ast::IdentifierExpression>(callee);
+    auto* call_expr = create<ast::CallExpression>(std::move(ident_expr),
+                                                  ast::ExpressionList());
     body->append(create<ast::CallStatement>(std::move(call_expr)));
   };
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
 
-  AddFuncCall(body.get(), "sb_foo_func");
-  AddFuncCall(body.get(), "sb_bar_func");
-  AddFuncCall(body.get(), "sb_baz_func");
+  AddFuncCall(body, "sb_foo_func");
+  AddFuncCall(body, "sb_bar_func");
+  AddFuncCall(body, "sb_baz_func");
 
   body->append(create<ast::ReturnStatement>());
-  std::unique_ptr<ast::Function> func = create<ast::Function>(
-      "ep_func", ast::VariableList(), void_type(), std::move(body));
+  ast::Function* func = create<ast::Function>("ep_func", ast::VariableList(),
+                                              void_type(), std::move(body));
 
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@@ -1506,11 +1506,11 @@
       "foo_type", {{i32_type(), 0}, {u32_array_type(4), 4}});
   AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
 
-  auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
-                                                         {{0, i32_type()}});
+  auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+                                                          {{0, i32_type()}});
   mod()->AddFunction(std::move(sb_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1533,11 +1533,11 @@
       "foo_type", {{i32_type(), 0}, {u32_array_type(0), 4}});
   AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
 
-  auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
-                                                         {{0, i32_type()}});
+  auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+                                                          {{0, i32_type()}});
   mod()->AddFunction(std::move(sb_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1560,11 +1560,11 @@
       MakeReadOnlyStorageBufferTypes("foo_type", {{i32_type(), 0}});
   AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
 
-  auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
-                                                         {{0, i32_type()}});
+  auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+                                                          {{0, i32_type()}});
   mod()->AddFunction(std::move(sb_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1583,11 +1583,11 @@
       MakeReadOnlyStorageBufferTypes("foo_type", {{i32_type(), 0}});
   AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
 
-  auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
-                                                         {{0, i32_type()}});
+  auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+                                                          {{0, i32_type()}});
   mod()->AddFunction(std::move(sb_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1616,7 +1616,7 @@
 
   auto AddReferenceFunc = [this](const std::string& func_name,
                                  const std::string& var_name) {
-    auto sb_func = MakeStructVariableReferenceBodyFunction(
+    auto* sb_func = MakeStructVariableReferenceBodyFunction(
         func_name, var_name,
         {{0, i32_type()}, {1, u32_type()}, {2, f32_type()}});
     mod()->AddFunction(std::move(sb_func));
@@ -1626,20 +1626,20 @@
   AddReferenceFunc("sb_baz_func", "sb_baz");
 
   auto AddFuncCall = [&](ast::BlockStatement* body, const std::string& callee) {
-    auto ident_expr = create<ast::IdentifierExpression>(callee);
-    auto call_expr = create<ast::CallExpression>(std::move(ident_expr),
-                                                 ast::ExpressionList());
+    auto* ident_expr = create<ast::IdentifierExpression>(callee);
+    auto* call_expr = create<ast::CallExpression>(std::move(ident_expr),
+                                                  ast::ExpressionList());
     body->append(create<ast::CallStatement>(std::move(call_expr)));
   };
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
 
-  AddFuncCall(body.get(), "sb_foo_func");
-  AddFuncCall(body.get(), "sb_bar_func");
-  AddFuncCall(body.get(), "sb_baz_func");
+  AddFuncCall(body, "sb_foo_func");
+  AddFuncCall(body, "sb_bar_func");
+  AddFuncCall(body, "sb_baz_func");
 
   body->append(create<ast::ReturnStatement>());
-  std::unique_ptr<ast::Function> func = create<ast::Function>(
-      "ep_func", ast::VariableList(), void_type(), std::move(body));
+  ast::Function* func = create<ast::Function>("ep_func", ast::VariableList(),
+                                              void_type(), std::move(body));
 
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@@ -1672,11 +1672,11 @@
       "foo_type", {{i32_type(), 0}, {u32_array_type(4), 4}});
   AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
 
-  auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
-                                                         {{0, i32_type()}});
+  auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+                                                          {{0, i32_type()}});
   mod()->AddFunction(std::move(sb_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1701,11 +1701,11 @@
       "foo_type", {{i32_type(), 0}, {u32_array_type(0), 4}});
   AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
 
-  auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
-                                                         {{0, i32_type()}});
+  auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+                                                          {{0, i32_type()}});
   mod()->AddFunction(std::move(sb_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1729,11 +1729,11 @@
       MakeStorageBufferTypes("foo_type", {{i32_type(), 0}});
   AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
 
-  auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
-                                                         {{0, i32_type()}});
+  auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
+                                                          {{0, i32_type()}});
   mod()->AddFunction(std::move(sb_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1753,7 +1753,7 @@
   AddSampler("foo_sampler", 0, 1);
   AddGlobalVariable("foo_coords", f32_type());
 
-  auto func = MakeSamplerReferenceBodyFunction(
+  auto* func = MakeSamplerReferenceBodyFunction(
       "ep", "foo_texture", "foo_sampler", "foo_coords", f32_type());
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@@ -1770,7 +1770,7 @@
 }
 
 TEST_F(InspectorGetSamplerResourceBindingsTest, NoSampler) {
-  auto func = MakeEmptyBodyFunction("ep_func");
+  auto* func = MakeEmptyBodyFunction("ep_func");
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
@@ -1790,11 +1790,11 @@
   AddSampler("foo_sampler", 0, 1);
   AddGlobalVariable("foo_coords", f32_type());
 
-  auto foo_func = MakeSamplerReferenceBodyFunction(
+  auto* foo_func = MakeSamplerReferenceBodyFunction(
       "foo_func", "foo_texture", "foo_sampler", "foo_coords", f32_type());
   mod()->AddFunction(std::move(foo_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "foo_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "foo_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1816,7 +1816,7 @@
   AddSampler("foo_sampler", 0, 1);
   AddGlobalVariable("foo_coords", f32_type());
 
-  auto func = MakeSamplerReferenceBodyFunction(
+  auto* func = MakeSamplerReferenceBodyFunction(
       "ep", "foo_texture", "foo_sampler", "foo_coords", f32_type());
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@@ -1836,7 +1836,7 @@
   AddGlobalVariable("foo_coords", f32_type());
   AddGlobalVariable("foo_depth", f32_type());
 
-  auto func = MakeComparisonSamplerReferenceBodyFunction(
+  auto* func = MakeComparisonSamplerReferenceBodyFunction(
       "ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth",
       f32_type());
   func->add_decoration(
@@ -1859,7 +1859,7 @@
   AddGlobalVariable("foo_coords", f32_type());
   AddGlobalVariable("foo_depth", f32_type());
 
-  auto func = MakeComparisonSamplerReferenceBodyFunction(
+  auto* func = MakeComparisonSamplerReferenceBodyFunction(
       "ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth",
       f32_type());
   func->add_decoration(
@@ -1877,7 +1877,7 @@
 }
 
 TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) {
-  auto func = MakeEmptyBodyFunction("ep_func");
+  auto* func = MakeEmptyBodyFunction("ep_func");
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
@@ -1898,12 +1898,12 @@
   AddGlobalVariable("foo_coords", f32_type());
   AddGlobalVariable("foo_depth", f32_type());
 
-  auto foo_func = MakeComparisonSamplerReferenceBodyFunction(
+  auto* foo_func = MakeComparisonSamplerReferenceBodyFunction(
       "foo_func", "foo_texture", "foo_sampler", "foo_coords", "foo_depth",
       f32_type());
   mod()->AddFunction(std::move(foo_func));
 
-  auto ep_func = MakeCallerBodyFunction("ep_func", "foo_func");
+  auto* ep_func = MakeCallerBodyFunction("ep_func", "foo_func");
   ep_func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
@@ -1926,7 +1926,7 @@
   AddGlobalVariable("foo_coords", f32_type());
   AddGlobalVariable("foo_depth", f32_type());
 
-  auto func = MakeComparisonSamplerReferenceBodyFunction(
+  auto* func = MakeComparisonSamplerReferenceBodyFunction(
       "ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth",
       f32_type());
   func->add_decoration(
@@ -1946,7 +1946,7 @@
   AddSampler("foo_sampler", 0, 1);
   AddGlobalVariable("foo_coords", f32_type());
 
-  auto func = MakeSamplerReferenceBodyFunction(
+  auto* func = MakeSamplerReferenceBodyFunction(
       "ep", "foo_texture", "foo_sampler", "foo_coords", f32_type());
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@@ -1961,7 +1961,7 @@
 }
 
 TEST_F(InspectorGetSampledTextureResourceBindingsTest, Empty) {
-  auto foo = MakeEmptyBodyFunction("foo");
+  auto* foo = MakeEmptyBodyFunction("foo");
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
@@ -1981,7 +1981,7 @@
       GetCoordsType(GetParam().type_dim, GetParam().sampled_kind);
   AddGlobalVariable("foo_coords", coord_type);
 
-  auto func = MakeSamplerReferenceBodyFunction(
+  auto* func = MakeSamplerReferenceBodyFunction(
       "ep", "foo_texture", "foo_sampler", "foo_coords",
       GetBaseType(GetParam().sampled_kind));
   func->add_decoration(
@@ -2090,7 +2090,7 @@
             inspector::ResourceBinding::SampledKind::kUInt}));
 
 TEST_F(InspectorGetMultisampledTextureResourceBindingsTest, Empty) {
-  auto foo = MakeEmptyBodyFunction("foo");
+  auto* foo = MakeEmptyBodyFunction("foo");
   foo->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
@@ -2111,7 +2111,7 @@
       GetCoordsType(GetParam().type_dim, GetParam().sampled_kind);
   AddGlobalVariable("foo_coords", coord_type);
 
-  auto func = MakeSamplerReferenceBodyFunction(
+  auto* func = MakeSamplerReferenceBodyFunction(
       "ep", "foo_texture", "foo_sampler", "foo_coords",
       GetBaseType(GetParam().sampled_kind));
   func->add_decoration(
diff --git a/src/reader/reader.h b/src/reader/reader.h
index f073767..249c8d2 100644
--- a/src/reader/reader.h
+++ b/src/reader/reader.h
@@ -16,6 +16,7 @@
 #define SRC_READER_READER_H_
 
 #include <string>
+#include <utility>
 
 #include "src/ast/module.h"
 #include "src/context.h"
@@ -58,6 +59,15 @@
   /// @param diags the list of diagnostic messages
   void set_diagnostics(const diag::List& diags) { diags_ = diags; }
 
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
+  template <typename T, typename... ARGS>
+  T* create(ARGS&&... args) const {
+    return ctx_.create<T>(std::forward<ARGS>(args)...);
+  }
+
   /// The Tint context object
   Context& ctx_;
 
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 3cf2389..ebdca70 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -487,8 +487,8 @@
     const Construct* construct,
     uint32_t end_id,
     CompletionAction completion_action,
-    std::unique_ptr<ast::BlockStatement> statements,
-    std::unique_ptr<ast::CaseStatementList> cases)
+    ast::BlockStatement* statements,
+    ast::CaseStatementList* cases)
     : construct_(construct),
       end_id_(end_id),
       completion_action_(completion_action),
@@ -514,8 +514,8 @@
   // if-selection with a then-clause ending at the same block
   // as the statement block at the top of the stack.
   const auto& top = statements_stack_.back();
-  auto cond = create<ast::IdentifierExpression>(guard_name);
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>(guard_name);
+  auto* body = create<ast::BlockStatement>();
   auto* const guard_stmt =
       AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
           ->AsIf();
@@ -528,8 +528,8 @@
 void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
   assert(!statements_stack_.empty());
   const auto& top = statements_stack_.back();
-  auto cond = MakeTrue();
-  auto body = create<ast::BlockStatement>();
+  auto* cond = MakeTrue();
+  auto* body = create<ast::BlockStatement>();
   auto* const guard_stmt =
       AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
           ->AsIf();
@@ -542,13 +542,12 @@
 
 const ast::BlockStatement* FunctionEmitter::ast_body() {
   assert(!statements_stack_.empty());
-  return statements_stack_[0].statements_.get();
+  return statements_stack_[0].statements_;
 }
 
-ast::Statement* FunctionEmitter::AddStatement(
-    std::unique_ptr<ast::Statement> statement) {
+ast::Statement* FunctionEmitter::AddStatement(ast::Statement* statement) {
   assert(!statements_stack_.empty());
-  auto* result = statement.get();
+  auto* result = statement;
   if (result != nullptr) {
     statements_stack_.back().statements_->append(std::move(statement));
   }
@@ -556,7 +555,7 @@
 }
 
 ast::Statement* FunctionEmitter::AddStatementForInstruction(
-    std::unique_ptr<ast::Statement> statement,
+    ast::Statement* statement,
     const spvtools::opt::Instruction& inst) {
   auto* node = AddStatement(std::move(statement));
   ApplySourceForInstruction(node, inst);
@@ -565,7 +564,7 @@
 
 ast::Statement* FunctionEmitter::LastStatement() {
   assert(!statements_stack_.empty());
-  const auto& statement_list = statements_stack_.back().statements_;
+  auto* statement_list = statements_stack_.back().statements_;
   assert(!statement_list->empty());
   return statement_list->last();
 }
@@ -593,7 +592,7 @@
                      "element but has "
                   << statements_stack_.size();
   }
-  auto body = std::move(statements_stack_[0].statements_);
+  auto* body = std::move(statements_stack_[0].statements_);
   parser_impl_.get_module().functions().back()->set_body(std::move(body));
   // Maintain the invariant by repopulating the one and only element.
   statements_stack_.clear();
@@ -632,7 +631,7 @@
       [this, &ast_params](const spvtools::opt::Instruction* param) {
         auto* ast_type = parser_impl_.ConvertType(param->type_id());
         if (ast_type != nullptr) {
-          auto ast_param = parser_impl_.MakeVariable(
+          auto* ast_param = parser_impl_.MakeVariable(
               param->result_id(), ast::StorageClass::kNone, ast_type);
           // Parameters are treated as const declarations.
           ast_param->set_is_const(true);
@@ -648,8 +647,8 @@
     return false;
   }
 
-  auto ast_fn = create<ast::Function>(name, std::move(ast_params), ret_ty,
-                                      create<ast::BlockStatement>());
+  auto* ast_fn = create<ast::Function>(name, std::move(ast_params), ret_ty,
+                                       create<ast::BlockStatement>());
 
   if (ep_info_ != nullptr) {
     ast_fn->add_decoration(
@@ -1695,7 +1694,7 @@
     if (failed()) {
       return false;
     }
-    auto var = parser_impl_.MakeVariable(
+    auto* var = parser_impl_.MakeVariable(
         inst.result_id(), ast::StorageClass::kFunction, var_store_type);
     if (inst.NumInOperands() > 1) {
       // SPIR-V initializers are always constants.
@@ -1705,7 +1704,7 @@
           parser_impl_.MakeConstantExpression(inst.GetSingleWordInOperand(1))
               .expr);
     }
-    auto var_decl_stmt = create<ast::VariableDeclStatement>(std::move(var));
+    auto* var_decl_stmt = create<ast::VariableDeclStatement>(std::move(var));
     AddStatementForInstruction(std::move(var_decl_stmt), inst);
     // Save this as an already-named value.
     identifier_values_.insert(inst.result_id());
@@ -1718,9 +1717,9 @@
     return {};
   }
   if (identifier_values_.count(id) || parser_impl_.IsScalarSpecConstant(id)) {
-    return TypedExpression(
+    return TypedExpression{
         parser_impl_.ConvertType(def_use_mgr_->GetDef(id)->type_id()),
-        create<ast::IdentifierExpression>(namer_.Name(id)));
+        create<ast::IdentifierExpression>(namer_.Name(id))};
   }
   if (singly_used_values_.count(id)) {
     auto expr = std::move(singly_used_values_[id]);
@@ -1739,9 +1738,9 @@
   switch (inst->opcode()) {
     case SpvOpVariable:
       // This occurs for module-scope variables.
-      return TypedExpression(
+      return TypedExpression{
           parser_impl_.ConvertType(inst->type_id()),
-          create<ast::IdentifierExpression>(namer_.Name(inst->result_id())));
+          create<ast::IdentifierExpression>(namer_.Name(inst->result_id()))};
     default:
       break;
   }
@@ -1970,17 +1969,17 @@
   const std::string guard_name = block_info.flow_guard_name;
   if (!guard_name.empty()) {
     // Declare the guard variable just before the "if", initialized to true.
-    auto guard_var = create<ast::Variable>(
+    auto* guard_var = create<ast::Variable>(
         guard_name, ast::StorageClass::kFunction, parser_impl_.BoolType());
     guard_var->set_constructor(MakeTrue());
-    auto guard_decl = create<ast::VariableDeclStatement>(std::move(guard_var));
+    auto* guard_decl = create<ast::VariableDeclStatement>(std::move(guard_var));
     AddStatement(std::move(guard_decl));
   }
 
   const auto condition_id =
       block_info.basic_block->terminator()->GetSingleWordInOperand(0);
-  auto cond = MakeExpression(condition_id).expr;
-  auto body = create<ast::BlockStatement>();
+  auto* cond = MakeExpression(condition_id).expr;
+  auto* body = create<ast::BlockStatement>();
   auto* const if_stmt =
       AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
           ->AsIf();
@@ -2108,7 +2107,7 @@
       construct, construct->end_id, [switch_stmt](StatementBlock* s) {
         switch_stmt->set_body(std::move(*std::move(s->cases_)));
       });
-  statements_stack_.back().cases_ = create<ast::CaseStatementList>();
+  statements_stack_.back().cases_ = std::make_unique<ast::CaseStatementList>();
   // Grab a pointer to the case list.  It will get buried in the statement block
   // stack.
   auto* cases = statements_stack_.back().cases_.get();
@@ -2156,7 +2155,7 @@
     // on the case statement list.
     cases->emplace_back(
         create<ast::CaseStatement>(create<ast::BlockStatement>()));
-    auto* clause = cases->back().get();
+    auto* clause = cases->back();
 
     // Create a list of integer literals for the selector values leading to
     // this case clause.
@@ -2192,9 +2191,9 @@
     if ((default_info == clause_heads[i]) && has_selectors &&
         construct->ContainsPos(default_info->pos)) {
       // Generate a default clause with a just fallthrough.
-      auto stmts = create<ast::BlockStatement>();
+      auto* stmts = create<ast::BlockStatement>();
       stmts->append(create<ast::FallthroughStatement>());
-      auto case_stmt = create<ast::CaseStatement>(std::move(stmts));
+      auto* case_stmt = create<ast::CaseStatement>(std::move(stmts));
       cases->emplace_back(std::move(case_stmt));
     }
 
@@ -2287,7 +2286,7 @@
       const EdgeKind false_kind = block_info.succ_edge.find(false_dest)->second;
       auto* const true_info = GetBlockInfo(true_dest);
       auto* const false_info = GetBlockInfo(false_dest);
-      auto cond = MakeExpression(terminator.GetSingleWordInOperand(0)).expr;
+      auto* cond = MakeExpression(terminator.GetSingleWordInOperand(0)).expr;
 
       // We have two distinct destinations. But we only get here if this
       // is a normal terminator; in particular the source block is *not* the
@@ -2313,9 +2312,9 @@
       // requiring a flow guard, then get that flow guard name too.  It will
       // come from at most one of these two branches.
       std::string flow_guard;
-      auto true_branch =
+      auto* true_branch =
           MakeBranchDetailed(block_info, *true_info, false, &flow_guard);
-      auto false_branch =
+      auto* false_branch =
           MakeBranchDetailed(block_info, *false_info, false, &flow_guard);
 
       AddStatement(MakeSimpleIf(std::move(cond), std::move(true_branch),
@@ -2334,7 +2333,7 @@
   return success();
 }
 
-std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
+ast::Statement* FunctionEmitter::MakeBranchDetailed(
     const BlockInfo& src_info,
     const BlockInfo& dest_info,
     bool forced,
@@ -2405,25 +2404,24 @@
       // Unconditional forward branch is implicit.
       break;
   }
-  return {nullptr};
+  return nullptr;
 }
 
-std::unique_ptr<ast::Statement> FunctionEmitter::MakeSimpleIf(
-    std::unique_ptr<ast::Expression> condition,
-    std::unique_ptr<ast::Statement> then_stmt,
-    std::unique_ptr<ast::Statement> else_stmt) const {
+ast::Statement* FunctionEmitter::MakeSimpleIf(ast::Expression* condition,
+                                              ast::Statement* then_stmt,
+                                              ast::Statement* else_stmt) const {
   if ((then_stmt == nullptr) && (else_stmt == nullptr)) {
     return nullptr;
   }
-  auto if_stmt = create<ast::IfStatement>(std::move(condition),
-                                          create<ast::BlockStatement>());
+  auto* if_stmt = create<ast::IfStatement>(std::move(condition),
+                                           create<ast::BlockStatement>());
   if (then_stmt != nullptr) {
-    auto stmts = create<ast::BlockStatement>();
+    auto* stmts = create<ast::BlockStatement>();
     stmts->append(std::move(then_stmt));
     if_stmt->set_body(std::move(stmts));
   }
   if (else_stmt != nullptr) {
-    auto stmts = create<ast::BlockStatement>();
+    auto* stmts = create<ast::BlockStatement>();
     stmts->append(std::move(else_stmt));
     ast::ElseStatementList else_stmts;
     else_stmts.emplace_back(
@@ -2435,7 +2433,7 @@
 
 bool FunctionEmitter::EmitConditionalCaseFallThrough(
     const BlockInfo& src_info,
-    std::unique_ptr<ast::Expression> cond,
+    ast::Expression* cond,
     EdgeKind other_edge_kind,
     const BlockInfo& other_dest,
     bool fall_through_is_true_branch) {
@@ -2462,7 +2460,7 @@
            << "internal error: normal terminator OpBranchConditional has "
               "both backedge and fallthrough edges.  Violates nesting rule";
   }
-  auto other_branch = MakeForcedBranch(src_info, other_dest);
+  auto* other_branch = MakeForcedBranch(src_info, other_dest);
   if (other_branch == nullptr) {
     return Fail() << "internal error: expected a branch for edge-kind "
                   << int(other_edge_kind);
@@ -2512,7 +2510,7 @@
     assert(def_inst);
     const auto phi_var_name = GetDefInfo(id)->phi_var;
     assert(!phi_var_name.empty());
-    auto var =
+    auto* var =
         create<ast::Variable>(phi_var_name, ast::StorageClass::kFunction,
                               parser_impl_.ConvertType(def_inst->type_id()));
     AddStatement(create<ast::VariableDeclStatement>(std::move(var)));
@@ -2560,7 +2558,7 @@
   if (!ast_expr.expr) {
     return false;
   }
-  auto ast_const = parser_impl_.MakeVariable(
+  auto* ast_const = parser_impl_.MakeVariable(
       inst.result_id(), ast::StorageClass::kNone, ast_expr.type);
   if (!ast_const) {
     return false;
@@ -2672,9 +2670,9 @@
     }
     case SpvOpPhi: {
       // Emit a read from the associated state variable.
-      auto expr =
-          TypedExpression(parser_impl_.ConvertType(inst.type_id()),
-                          create<ast::IdentifierExpression>(def_info->phi_var));
+      TypedExpression expr{
+          parser_impl_.ConvertType(inst.type_id()),
+          create<ast::IdentifierExpression>(def_info->phi_var)};
       return EmitConstDefOrWriteToHoistedVar(inst, std::move(expr));
     }
     case SpvOpFunctionCall:
@@ -2708,9 +2706,9 @@
   if (binary_op != ast::BinaryOp::kNone) {
     auto arg0 = MakeOperand(inst, 0);
     auto arg1 = MakeOperand(inst, 1);
-    auto binary_expr = create<ast::BinaryExpression>(
+    auto* binary_expr = create<ast::BinaryExpression>(
         binary_op, std::move(arg0.expr), std::move(arg1.expr));
-    TypedExpression result(ast_type, std::move(binary_expr));
+    TypedExpression result{ast_type, std::move(binary_expr)};
     return parser_impl_.RectifyForcedResultType(std::move(result), opcode,
                                                 arg0.type);
   }
@@ -2718,9 +2716,9 @@
   auto unary_op = ast::UnaryOp::kNegation;
   if (GetUnaryOp(opcode, &unary_op)) {
     auto arg0 = MakeOperand(inst, 0);
-    auto unary_expr =
+    auto* unary_expr =
         create<ast::UnaryOpExpression>(unary_op, std::move(arg0.expr));
-    TypedExpression result(ast_type, std::move(unary_expr));
+    TypedExpression result{ast_type, std::move(unary_expr)};
     return parser_impl_.RectifyForcedResultType(std::move(result), opcode,
                                                 arg0.type);
   }
@@ -2752,10 +2750,10 @@
   if (negated_op != ast::BinaryOp::kNone) {
     auto arg0 = MakeOperand(inst, 0);
     auto arg1 = MakeOperand(inst, 1);
-    auto binary_expr = create<ast::BinaryExpression>(
+    auto* binary_expr = create<ast::BinaryExpression>(
         negated_op, std::move(arg0.expr), std::move(arg1.expr));
-    auto negated_expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot,
-                                                       std::move(binary_expr));
+    auto* negated_expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot,
+                                                        std::move(binary_expr));
     return {ast_type, std::move(negated_expr)};
   }
 
@@ -2831,14 +2829,15 @@
     return {};
   }
 
-  auto func = create<ast::IdentifierExpression>(name);
+  auto* func = create<ast::IdentifierExpression>(name);
   ast::ExpressionList operands;
   // All parameters to GLSL.std.450 extended instructions are IDs.
   for (uint32_t iarg = 2; iarg < inst.NumInOperands(); ++iarg) {
     operands.emplace_back(MakeOperand(inst, iarg).expr);
   }
   auto* ast_type = parser_impl_.ConvertType(inst.type_id());
-  auto call = create<ast::CallExpression>(std::move(func), std::move(operands));
+  auto* call =
+      create<ast::CallExpression>(std::move(func), std::move(operands));
   return {ast_type, std::move(call)};
 }
 
@@ -2928,7 +2927,7 @@
         constants[index] ? constants[index]->AsIntConstant() : nullptr;
     const int64_t index_const_val =
         index_const ? index_const->GetSignExtendedValue() : 0;
-    std::unique_ptr<ast::Expression> next_expr;
+    ast::Expression* next_expr = nullptr;
 
     const auto* pointee_type_inst = def_use_mgr_->GetDef(pointee_type_id);
     if (!pointee_type_inst) {
@@ -2955,7 +2954,7 @@
                    << " is too big. Max handled index is "
                    << ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
           }
-          auto letter_index =
+          auto* letter_index =
               create<ast::IdentifierExpression>(swizzles[index_const_val]);
           next_expr = create<ast::MemberAccessorExpression>(
               std::move(current_expr.expr), std::move(letter_index));
@@ -3003,7 +3002,7 @@
                  << pointee_type_id << " having " << num_members << " members";
           return {};
         }
-        auto member_access = create<ast::IdentifierExpression>(
+        auto* member_access = create<ast::IdentifierExpression>(
             namer_.GetMemberName(pointee_type_id, uint32_t(index_const_val)));
 
         next_expr = create<ast::MemberAccessorExpression>(
@@ -3022,7 +3021,7 @@
     auto* ast_pointer_type = parser_impl_.ConvertType(pointer_type_id);
     assert(ast_pointer_type);
     assert(ast_pointer_type->IsPointer());
-    current_expr.reset(TypedExpression(ast_pointer_type, std::move(next_expr)));
+    current_expr = TypedExpression{ast_pointer_type, std::move(next_expr)};
   }
   return current_expr;
 }
@@ -3062,7 +3061,7 @@
              << " indices: " << inst.PrettyPrint();
       return {};
     }
-    std::unique_ptr<ast::Expression> next_expr;
+    ast::Expression* next_expr = nullptr;
     switch (current_type_inst->opcode()) {
       case SpvOpTypeVector: {
         // Try generating a MemberAccessor expression. That result in something
@@ -3079,7 +3078,7 @@
                  << " is too big. Max handled index is "
                  << ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
         }
-        auto letter_index =
+        auto* letter_index =
             create<ast::IdentifierExpression>(swizzles[index_val]);
         next_expr = create<ast::MemberAccessorExpression>(
             std::move(current_expr.expr), std::move(letter_index));
@@ -3127,7 +3126,7 @@
                  << current_type_id << " having " << num_members << " members";
           return {};
         }
-        auto member_access = create<ast::IdentifierExpression>(
+        auto* member_access = create<ast::IdentifierExpression>(
             namer_.GetMemberName(current_type_id, uint32_t(index_val)));
 
         next_expr = create<ast::MemberAccessorExpression>(
@@ -3140,18 +3139,18 @@
                << current_type_inst->PrettyPrint();
         return {};
     }
-    current_expr.reset(TypedExpression(
-        parser_impl_.ConvertType(current_type_id), std::move(next_expr)));
+    current_expr = TypedExpression{parser_impl_.ConvertType(current_type_id),
+                                   std::move(next_expr)};
   }
   return current_expr;
 }
 
-std::unique_ptr<ast::Expression> FunctionEmitter::MakeTrue() const {
+ast::Expression* FunctionEmitter::MakeTrue() const {
   return create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(parser_impl_.BoolType(), true));
 }
 
-std::unique_ptr<ast::Expression> FunctionEmitter::MakeFalse() const {
+ast::Expression* FunctionEmitter::MakeFalse() const {
   ast::type::BoolType bool_type;
   return create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(parser_impl_.BoolType(), false));
@@ -3489,8 +3488,8 @@
 
   ast::ExpressionList params;
   params.push_back(std::move(arg_expr.expr));
-  TypedExpression result(expr_type, create<ast::TypeConstructorExpression>(
-                                        expr_type, std::move(params)));
+  TypedExpression result{expr_type, create<ast::TypeConstructorExpression>(
+                                        expr_type, std::move(params))};
 
   if (requested_type == expr_type) {
     return result;
@@ -3501,14 +3500,14 @@
 
 bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) {
   // We ignore function attributes such as Inline, DontInline, Pure, Const.
-  auto function = create<ast::IdentifierExpression>(
+  auto* function = create<ast::IdentifierExpression>(
       namer_.Name(inst.GetSingleWordInOperand(0)));
 
   ast::ExpressionList params;
   for (uint32_t iarg = 1; iarg < inst.NumInOperands(); ++iarg) {
     params.emplace_back(MakeOperand(inst, iarg).expr);
   }
-  auto call_expr =
+  auto* call_expr =
       create<ast::CallExpression>(std::move(function), std::move(params));
   auto* result_type = parser_impl_.ConvertType(inst.type_id());
   if (!result_type) {
@@ -3531,14 +3530,14 @@
   const auto intrinsic = GetIntrinsic(inst.opcode());
   std::ostringstream ss;
   ss << intrinsic;
-  auto ident = create<ast::IdentifierExpression>(ss.str());
+  auto* ident = create<ast::IdentifierExpression>(ss.str());
   ident->set_intrinsic(intrinsic);
 
   ast::ExpressionList params;
   for (uint32_t iarg = 0; iarg < inst.NumInOperands(); ++iarg) {
     params.emplace_back(MakeOperand(inst, iarg).expr);
   }
-  auto call_expr =
+  auto* call_expr =
       create<ast::CallExpression>(std::move(ident), std::move(params));
   auto* result_type = parser_impl_.ConvertType(inst.type_id());
   if (!result_type) {
diff --git a/src/reader/spirv/function.h b/src/reader/spirv/function.h
index 1932388..e9c54ad 100644
--- a/src/reader/spirv/function.h
+++ b/src/reader/spirv/function.h
@@ -496,8 +496,8 @@
   /// @param src_info the source block
   /// @param dest_info the destination block
   /// @returns the new statement, or a null statement
-  std::unique_ptr<ast::Statement> MakeBranch(const BlockInfo& src_info,
-                                             const BlockInfo& dest_info) const {
+  ast::Statement* MakeBranch(const BlockInfo& src_info,
+                             const BlockInfo& dest_info) const {
     return MakeBranchDetailed(src_info, dest_info, false, nullptr);
   }
 
@@ -507,9 +507,8 @@
   /// @param src_info the source block
   /// @param dest_info the destination block
   /// @returns the new statement, or a null statement
-  std::unique_ptr<ast::Statement> MakeForcedBranch(
-      const BlockInfo& src_info,
-      const BlockInfo& dest_info) const {
+  ast::Statement* MakeForcedBranch(const BlockInfo& src_info,
+                                   const BlockInfo& dest_info) const {
     return MakeBranchDetailed(src_info, dest_info, true, nullptr);
   }
 
@@ -527,11 +526,10 @@
   /// @param forced if true, always emit the branch (if it exists in WGSL)
   /// @param flow_guard_name_ptr return parameter for control flow guard name
   /// @returns the new statement, or a null statement
-  std::unique_ptr<ast::Statement> MakeBranchDetailed(
-      const BlockInfo& src_info,
-      const BlockInfo& dest_info,
-      bool forced,
-      std::string* flow_guard_name_ptr) const;
+  ast::Statement* MakeBranchDetailed(const BlockInfo& src_info,
+                                     const BlockInfo& dest_info,
+                                     bool forced,
+                                     std::string* flow_guard_name_ptr) const;
 
   /// Returns a new if statement with the given statements as the then-clause
   /// and the else-clause.  Either or both clauses might be nullptr. If both
@@ -540,10 +538,9 @@
   /// @param then_stmt the statement for the then clause of the if, or nullptr
   /// @param else_stmt the statement for the else clause of the if, or nullptr
   /// @returns the new statement, or nullptr
-  std::unique_ptr<ast::Statement> MakeSimpleIf(
-      std::unique_ptr<ast::Expression> condition,
-      std::unique_ptr<ast::Statement> then_stmt,
-      std::unique_ptr<ast::Statement> else_stmt) const;
+  ast::Statement* MakeSimpleIf(ast::Expression* condition,
+                               ast::Statement* then_stmt,
+                               ast::Statement* else_stmt) const;
 
   /// Emits the statements for an normal-terminator OpBranchConditional
   /// where one branch is a case fall through (the true branch if and only
@@ -558,7 +555,7 @@
   /// branch
   /// @returns the false if emission fails
   bool EmitConditionalCaseFallThrough(const BlockInfo& src_info,
-                                      std::unique_ptr<ast::Expression> cond,
+                                      ast::Expression* cond,
                                       EdgeKind other_edge_kind,
                                       const BlockInfo& other_dest,
                                       bool fall_through_is_true_branch);
@@ -719,7 +716,7 @@
   /// Does nothing if the statement is null.
   /// @param statement the new statement
   /// @returns a pointer to the statement.
-  ast::Statement* AddStatement(std::unique_ptr<ast::Statement> statement);
+  ast::Statement* AddStatement(ast::Statement* statement);
 
   /// Appends a new statement to the top of the statement stack, and attaches
   /// source location information from the given instruction. Does nothing if
@@ -727,7 +724,7 @@
   /// @param statement the new statement
   /// @returns a pointer to the statement.
   ast::Statement* AddStatementForInstruction(
-      std::unique_ptr<ast::Statement> statement,
+      ast::Statement* statement,
       const spvtools::opt::Instruction& inst);
 
   /// Sets the source information for the given instruction to the given
@@ -750,8 +747,8 @@
     StatementBlock(const Construct* construct,
                    uint32_t end_id,
                    CompletionAction completion_action,
-                   std::unique_ptr<ast::BlockStatement> statements,
-                   std::unique_ptr<ast::CaseStatementList> cases);
+                   ast::BlockStatement* statements,
+                   ast::CaseStatementList* cases);
     StatementBlock(StatementBlock&&);
     ~StatementBlock();
 
@@ -767,12 +764,12 @@
     // Only one of |statements| or |cases| is active.
 
     // The list of statements being built, if this construct is not a switch.
-    std::unique_ptr<ast::BlockStatement> statements_;
+    ast::BlockStatement* statements_ = nullptr;
     // The list of switch cases being built, if this construct is a switch.
     // The algorithm will cache a pointer to the vector.  We want that pointer
     // to be stable no matter how |statements_stack_| is resized.  That's
     // why we make this a unique_ptr rather than just a plain vector.
-    std::unique_ptr<ast::CaseStatementList> cases_;
+    std::unique_ptr<ast::CaseStatementList> cases_ = nullptr;
   };
 
   /// Pushes an empty statement block onto the statements stack.
@@ -795,16 +792,19 @@
   void PushTrueGuard(uint32_t end_id);
 
   /// @returns a boolean true expression.
-  std::unique_ptr<ast::Expression> MakeTrue() const;
+  ast::Expression* MakeTrue() const;
 
   /// @returns a boolean false expression.
-  std::unique_ptr<ast::Expression> MakeFalse() const;
+  ast::Expression* MakeFalse() const;
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) const {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) const {
+    auto& ctx = parser_impl_.context();
+    return ctx.create<T>(std::forward<ARGS>(args)...);
   }
 
   ParserImpl& parser_impl_;
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index 63cc7c7..6677bb8 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -187,22 +187,6 @@
 
 }  // namespace
 
-TypedExpression::TypedExpression() : type(nullptr), expr(nullptr) {}
-
-TypedExpression::TypedExpression(ast::type::Type* t,
-                                 std::unique_ptr<ast::Expression> e)
-    : type(t), expr(std::move(e)) {}
-
-TypedExpression::TypedExpression(TypedExpression&& other)
-    : type(other.type), expr(std::move(other.expr)) {}
-
-TypedExpression::~TypedExpression() {}
-
-void TypedExpression::reset(TypedExpression&& other) {
-  type = other.type;
-  expr = std::move(other.expr);
-}
-
 ParserImpl::ParserImpl(Context* ctx, const std::vector<uint32_t>& spv_binary)
     : Reader(ctx),
       spv_binary_(spv_binary),
@@ -375,10 +359,10 @@
   return "SPIR-V type " + std::to_string(type_id);
 }
 
-std::unique_ptr<ast::StructMemberDecoration>
-ParserImpl::ConvertMemberDecoration(uint32_t struct_type_id,
-                                    uint32_t member_index,
-                                    const Decoration& decoration) {
+ast::StructMemberDecoration* ParserImpl::ConvertMemberDecoration(
+    uint32_t struct_type_id,
+    uint32_t member_index,
+    const Decoration& decoration) {
   if (decoration.empty()) {
     Fail() << "malformed SPIR-V decoration: it's empty";
     return nullptr;
@@ -861,7 +845,7 @@
         // the members are non-writable.
         is_non_writable = true;
       } else {
-        auto ast_member_decoration =
+        auto* ast_member_decoration =
             ConvertMemberDecoration(type_id, member_index, decoration);
         if (!success_) {
           return nullptr;
@@ -877,14 +861,14 @@
       ++num_non_writable_members;
     }
     const auto member_name = namer_.GetMemberName(type_id, member_index);
-    auto ast_struct_member = create<ast::StructMember>(
+    auto* ast_struct_member = create<ast::StructMember>(
         member_name, ast_member_ty, std::move(ast_member_decorations));
     ast_members.push_back(std::move(ast_struct_member));
   }
 
   // Now make the struct.
-  auto ast_struct = create<ast::Struct>(std::move(ast_struct_decorations),
-                                        std::move(ast_members));
+  auto* ast_struct = create<ast::Struct>(std::move(ast_struct_decorations),
+                                         std::move(ast_members));
 
   namer_.SuggestSanitizedName(type_id, "S");
   auto ast_struct_type = std::make_unique<ast::type::StructType>(
@@ -963,7 +947,7 @@
   for (auto& inst : module_->types_values()) {
     // These will be populated for a valid scalar spec constant.
     ast::type::Type* ast_type = nullptr;
-    std::unique_ptr<ast::ScalarConstructorExpression> ast_expr;
+    ast::ScalarConstructorExpression* ast_expr = nullptr;
 
     switch (inst.opcode()) {
       case SpvOpSpecConstantTrue:
@@ -1001,12 +985,12 @@
         break;
     }
     if (ast_type && ast_expr) {
-      auto ast_var =
+      auto* ast_var =
           MakeVariable(inst.result_id(), ast::StorageClass::kNone, ast_type);
       ast::VariableDecorationList spec_id_decos;
       for (const auto& deco : GetDecorationsFor(inst.result_id())) {
         if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
-          auto cid = create<ast::ConstantIdDecoration>(deco[1], Source{});
+          auto* cid = create<ast::ConstantIdDecoration>(deco[1], Source{});
           spec_id_decos.push_back(std::move(cid));
           break;
         }
@@ -1017,7 +1001,7 @@
         ast_var->set_constructor(std::move(ast_expr));
         ast_module_.AddGlobalVariable(std::move(ast_var));
       } else {
-        auto ast_deco_var = create<ast::DecoratedVariable>(std::move(ast_var));
+        auto* ast_deco_var = create<ast::DecoratedVariable>(std::move(ast_var));
         ast_deco_var->set_is_const(true);
         ast_deco_var->set_constructor(std::move(ast_expr));
         ast_deco_var->set_decorations(std::move(spec_id_decos));
@@ -1118,7 +1102,7 @@
     }
     auto* ast_store_type = ast_type->AsPointer()->type();
     auto ast_storage_class = ast_type->AsPointer()->storage_class();
-    auto ast_var =
+    auto* ast_var =
         MakeVariable(var.result_id(), ast_storage_class, ast_store_type);
     if (var.NumInOperands() > 1) {
       // SPIR-V initializers are always constants.
@@ -1136,7 +1120,7 @@
     // Make sure the variable has a name.
     namer_.SuggestSanitizedName(builtin_position_.per_vertex_var_id,
                                 "gl_Position");
-    auto var = create<ast::DecoratedVariable>(MakeVariable(
+    auto* var = create<ast::DecoratedVariable>(MakeVariable(
         builtin_position_.per_vertex_var_id,
         enum_converter_.ToStorageClass(builtin_position_.storage_class),
         ConvertType(builtin_position_.member_type_id)));
@@ -1150,9 +1134,9 @@
   return success_;
 }
 
-std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
-                                                        ast::StorageClass sc,
-                                                        ast::type::Type* type) {
+ast::Variable* ParserImpl::MakeVariable(uint32_t id,
+                                        ast::StorageClass sc,
+                                        ast::type::Type* type) {
   if (type == nullptr) {
     Fail() << "internal error: can't make ast::Variable for null type";
     return nullptr;
@@ -1167,7 +1151,7 @@
         std::make_unique<ast::type::AccessControlType>(access, type));
   }
 
-  auto ast_var = create<ast::Variable>(namer_.Name(id), sc, type);
+  auto* ast_var = create<ast::Variable>(namer_.Name(id), sc, type);
 
   ast::VariableDecorationList ast_decorations;
   for (auto& deco : GetDecorationsFor(id)) {
@@ -1218,7 +1202,7 @@
     }
   }
   if (!ast_decorations.empty()) {
-    auto decorated_var = create<ast::DecoratedVariable>(std::move(ast_var));
+    auto* decorated_var = create<ast::DecoratedVariable>(std::move(ast_var));
     decorated_var->set_decorations(std::move(ast_decorations));
     ast_var = std::move(decorated_var);
   }
@@ -1315,8 +1299,7 @@
   return {};
 }
 
-std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue(
-    ast::type::Type* type) {
+ast::Expression* ParserImpl::MakeNullValue(ast::type::Type* type) {
   // TODO(dneto): Use the no-operands constructor syntax when it becomes
   // available in Tint.
   // https://github.com/gpuweb/gpuweb/issues/685
@@ -1380,7 +1363,7 @@
   if (type->IsStruct()) {
     auto* struct_ty = type->AsStruct();
     ast::ExpressionList ast_components;
-    for (auto& member : struct_ty->impl()->members()) {
+    for (auto* member : struct_ty->impl()->members()) {
       ast_components.emplace_back(MakeNullValue(member->type()));
     }
     return create<ast::TypeConstructorExpression>(original_type,
diff --git a/src/reader/spirv/parser_impl.h b/src/reader/spirv/parser_impl.h
index 5eaaf08..f4e1a1e 100644
--- a/src/reader/spirv/parser_impl.h
+++ b/src/reader/spirv/parser_impl.h
@@ -56,24 +56,10 @@
 
 /// An AST expression with its type.
 struct TypedExpression {
-  /// Constructor
-  TypedExpression();
-  /// Constructor
-  /// @param t the type
-  /// @param e the expression
-  TypedExpression(ast::type::Type* t, std::unique_ptr<ast::Expression> e);
-  /// Move constructor
-  /// @param other the other typed expression
-  TypedExpression(TypedExpression&& other);
-  /// Destructor
-  ~TypedExpression();
-  /// Takes values from another typed expression.
-  /// @param other the other typed expression
-  void reset(TypedExpression&& other);
   /// The type
-  ast::type::Type* type;
+  ast::type::Type* type = nullptr;
   /// The expression
-  std::unique_ptr<ast::Expression> expr;
+  ast::Expression* expr = nullptr;
 };
 
 /// Parser implementation for SPIR-V.
@@ -187,7 +173,7 @@
   /// @param member_index the index of the member
   /// @param decoration an encoded SPIR-V Decoration
   /// @returns the corresponding ast::StructuMemberDecoration
-  std::unique_ptr<ast::StructMemberDecoration> ConvertMemberDecoration(
+  ast::StructMemberDecoration* ConvertMemberDecoration(
       uint32_t struct_type_id,
       uint32_t member_index,
       const Decoration& decoration);
@@ -274,9 +260,9 @@
   /// @param sc the storage class, which cannot be ast::StorageClass::kNone
   /// @param type the type
   /// @returns a new Variable node, or null in the error case
-  std::unique_ptr<ast::Variable> MakeVariable(uint32_t id,
-                                              ast::StorageClass sc,
-                                              ast::type::Type* type);
+  ast::Variable* MakeVariable(uint32_t id,
+                              ast::StorageClass sc,
+                              ast::type::Type* type);
 
   /// Creates an AST expression node for a SPIR-V constant.
   /// @param id the SPIR-V ID of the constant
@@ -286,7 +272,7 @@
   /// Creates an AST expression node for the null value for the given type.
   /// @param type the AST type
   /// @returns a new expression
-  std::unique_ptr<ast::Expression> MakeNullValue(ast::type::Type* type);
+  ast::Expression* MakeNullValue(ast::type::Type* type);
 
   /// Converts a given expression to the signedness demanded for an operand
   /// of the given SPIR-V opcode, if required.  If the operation assumes
@@ -432,13 +418,6 @@
   bool ApplyArrayDecorations(const spvtools::opt::analysis::Type* spv_type,
                              ast::type::ArrayType* ast_type);
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
-  template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) const {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
-  }
-
   // The SPIR-V binary we're parsing
   std::vector<uint32_t> spv_binary_;
 
diff --git a/src/reader/spirv/parser_impl_convert_member_decoration_test.cc b/src/reader/spirv/parser_impl_convert_member_decoration_test.cc
index e3e4f14..aa75424 100644
--- a/src/reader/spirv/parser_impl_convert_member_decoration_test.cc
+++ b/src/reader/spirv/parser_impl_convert_member_decoration_test.cc
@@ -34,16 +34,16 @@
 TEST_F(SpvParserTest, ConvertMemberDecoration_Empty) {
   auto* p = parser(std::vector<uint32_t>{});
 
-  auto result = p->ConvertMemberDecoration(1, 1, {});
-  EXPECT_EQ(result.get(), nullptr);
+  auto* result = p->ConvertMemberDecoration(1, 1, {});
+  EXPECT_EQ(result, nullptr);
   EXPECT_THAT(p->error(), Eq("malformed SPIR-V decoration: it's empty"));
 }
 
 TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithoutOperand) {
   auto* p = parser(std::vector<uint32_t>{});
 
-  auto result = p->ConvertMemberDecoration(12, 13, {SpvDecorationOffset});
-  EXPECT_EQ(result.get(), nullptr);
+  auto* result = p->ConvertMemberDecoration(12, 13, {SpvDecorationOffset});
+  EXPECT_EQ(result, nullptr);
   EXPECT_THAT(p->error(), Eq("malformed Offset decoration: expected 1 literal "
                              "operand, has 0: member 13 of SPIR-V type 12"));
 }
@@ -51,8 +51,9 @@
 TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithTooManyOperands) {
   auto* p = parser(std::vector<uint32_t>{});
 
-  auto result = p->ConvertMemberDecoration(12, 13, {SpvDecorationOffset, 3, 4});
-  EXPECT_EQ(result.get(), nullptr);
+  auto* result =
+      p->ConvertMemberDecoration(12, 13, {SpvDecorationOffset, 3, 4});
+  EXPECT_EQ(result, nullptr);
   EXPECT_THAT(p->error(), Eq("malformed Offset decoration: expected 1 literal "
                              "operand, has 2: member 13 of SPIR-V type 12"));
 }
@@ -60,8 +61,8 @@
 TEST_F(SpvParserTest, ConvertMemberDecoration_Offset) {
   auto* p = parser(std::vector<uint32_t>{});
 
-  auto result = p->ConvertMemberDecoration(1, 1, {SpvDecorationOffset, 8});
-  ASSERT_NE(result.get(), nullptr);
+  auto* result = p->ConvertMemberDecoration(1, 1, {SpvDecorationOffset, 8});
+  ASSERT_NE(result, nullptr);
   EXPECT_TRUE(result->IsOffset());
   auto* offset_deco = result->AsOffset();
   ASSERT_NE(offset_deco, nullptr);
@@ -72,8 +73,8 @@
 TEST_F(SpvParserTest, ConvertMemberDecoration_UnhandledDecoration) {
   auto* p = parser(std::vector<uint32_t>{});
 
-  auto result = p->ConvertMemberDecoration(12, 13, {12345678});
-  EXPECT_EQ(result.get(), nullptr);
+  auto* result = p->ConvertMemberDecoration(12, 13, {12345678});
+  EXPECT_EQ(result, nullptr);
   EXPECT_THAT(p->error(), Eq("unhandled member decoration: 12345678 on member "
                              "13 of SPIR-V type 12"));
 }
diff --git a/src/reader/spirv/parser_impl_test_helper.h b/src/reader/spirv/parser_impl_test_helper.h
index cc7d5cd..025471b 100644
--- a/src/reader/spirv/parser_impl_test_helper.h
+++ b/src/reader/spirv/parser_impl_test_helper.h
@@ -72,7 +72,7 @@
 /// @returnss the string dump of a function body.
 inline std::string ToString(const ast::BlockStatement* body) {
   std::ostringstream outs;
-  for (const auto& stmt : *body) {
+  for (const auto* stmt : *body) {
     stmt->to_str(outs, 0);
   }
   return outs.str();
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index d2e0653..50a1764 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -340,7 +340,7 @@
 // global_variable_decl
 //  : variable_decoration_list* variable_decl
 //  | variable_decoration_list* variable_decl EQUAL const_expr
-Maybe<std::unique_ptr<ast::Variable>> ParserImpl::global_variable_decl(
+Maybe<ast::Variable*> ParserImpl::global_variable_decl(
     ast::DecorationList& decos) {
   auto decl = variable_decl();
   if (decl.errored)
@@ -348,14 +348,14 @@
   if (!decl.matched)
     return Failure::kNoMatch;
 
-  auto var = std::move(decl.value);
+  auto* var = std::move(decl.value);
 
   auto var_decos = cast_decorations<ast::VariableDecoration>(decos);
   if (var_decos.errored)
     return Failure::kErrored;
 
   if (var_decos.value.size() > 0) {
-    auto dv = create<ast::DecoratedVariable>(std::move(var));
+    auto* dv = create<ast::DecoratedVariable>(std::move(var));
     dv->set_decorations(std::move(var_decos.value));
     var = std::move(dv);
   }
@@ -371,7 +371,7 @@
 
 // global_constant_decl
 //  : CONST variable_ident_decl EQUAL const_expr
-Maybe<std::unique_ptr<ast::Variable>> ParserImpl::global_constant_decl() {
+Maybe<ast::Variable*> ParserImpl::global_constant_decl() {
   if (!match(Token::Type::kConst))
     return Failure::kNoMatch;
 
@@ -381,8 +381,8 @@
   if (decl.errored)
     return Failure::kErrored;
 
-  auto var = create<ast::Variable>(decl->source, decl->name,
-                                   ast::StorageClass::kNone, decl->type);
+  auto* var = create<ast::Variable>(decl->source, decl->name,
+                                    ast::StorageClass::kNone, decl->type);
   var->set_is_const(true);
 
   if (!expect(use, Token::Type::kEqual))
@@ -399,7 +399,7 @@
 
 // variable_decl
 //   : VAR variable_storage_decoration? variable_ident_decl
-Maybe<std::unique_ptr<ast::Variable>> ParserImpl::variable_decl() {
+Maybe<ast::Variable*> ParserImpl::variable_decl() {
   if (!match(Token::Type::kVar))
     return Failure::kNoMatch;
 
@@ -1100,16 +1100,15 @@
         ast::StructMemberList members;
 
         while (synchronized_ && !peek().IsBraceRight() && !peek().IsEof()) {
-          auto member =
-              sync(Token::Type::kSemicolon,
-                   [&]() -> Expect<std::unique_ptr<ast::StructMember>> {
-                     auto decos = decoration_list();
-                     if (decos.errored)
-                       errored = true;
-                     if (!synchronized_)
-                       return Failure::kErrored;
-                     return expect_struct_member(decos.value);
-                   });
+          auto member = sync(Token::Type::kSemicolon,
+                             [&]() -> Expect<ast::StructMember*> {
+                               auto decos = decoration_list();
+                               if (decos.errored)
+                                 errored = true;
+                               if (!synchronized_)
+                                 return Failure::kErrored;
+                               return expect_struct_member(decos.value);
+                             });
 
           if (member.errored) {
             errored = true;
@@ -1127,7 +1126,7 @@
 
 // struct_member
 //   : struct_member_decoration_decl+ variable_ident_decl SEMICOLON
-Expect<std::unique_ptr<ast::StructMember>> ParserImpl::expect_struct_member(
+Expect<ast::StructMember*> ParserImpl::expect_struct_member(
     ast::DecorationList& decos) {
   auto decl = expect_variable_ident_decl("struct member");
   if (decl.errored)
@@ -1146,8 +1145,7 @@
 
 // function_decl
 //   : function_header body_stmt
-Maybe<std::unique_ptr<ast::Function>> ParserImpl::function_decl(
-    ast::DecorationList& decos) {
+Maybe<ast::Function*> ParserImpl::function_decl(ast::DecorationList& decos) {
   auto f = function_header();
   if (f.errored) {
     if (sync_to(Token::Type::kBraceLeft, /* consume: */ false)) {
@@ -1195,7 +1193,7 @@
 
 // function_header
 //   : FN IDENT PAREN_LEFT param_list PAREN_RIGHT ARROW function_type_decl
-Maybe<std::unique_ptr<ast::Function>> ParserImpl::function_header() {
+Maybe<ast::Function*> ParserImpl::function_header() {
   Source source;
   if (!match(Token::Type::kFn, &source))
     return Failure::kNoMatch;
@@ -1247,8 +1245,8 @@
 
   ast::VariableList ret;
   for (;;) {
-    auto var = create<ast::Variable>(decl->source, decl->name,
-                                     ast::StorageClass::kNone, decl->type);
+    auto* var = create<ast::Variable>(decl->source, decl->name,
+                                      ast::StorageClass::kNone, decl->type);
     // Formal parameters are treated like a const declaration where the
     // initializer value is provided by the call's argument.  The key point is
     // that it's not updatable after intially set.  This is unlike C or GLSL
@@ -1299,30 +1297,29 @@
 
 // body_stmt
 //   : BRACKET_LEFT statements BRACKET_RIGHT
-Expect<std::unique_ptr<ast::BlockStatement>> ParserImpl::expect_body_stmt() {
+Expect<ast::BlockStatement*> ParserImpl::expect_body_stmt() {
   return expect_brace_block("", [&] { return expect_statements(); });
 }
 
 // paren_rhs_stmt
 //   : PAREN_LEFT logical_or_expression PAREN_RIGHT
-Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_paren_rhs_stmt() {
-  return expect_paren_block(
-      "", [&]() -> Expect<std::unique_ptr<ast::Expression>> {
-        auto expr = logical_or_expression();
-        if (expr.errored)
-          return Failure::kErrored;
-        if (!expr.matched)
-          return add_error(peek(), "unable to parse expression");
+Expect<ast::Expression*> ParserImpl::expect_paren_rhs_stmt() {
+  return expect_paren_block("", [&]() -> Expect<ast::Expression*> {
+    auto expr = logical_or_expression();
+    if (expr.errored)
+      return Failure::kErrored;
+    if (!expr.matched)
+      return add_error(peek(), "unable to parse expression");
 
-        return std::move(expr.value);
-      });
+    return std::move(expr.value);
+  });
 }
 
 // statements
 //   : statement*
-Expect<std::unique_ptr<ast::BlockStatement>> ParserImpl::expect_statements() {
+Expect<ast::BlockStatement*> ParserImpl::expect_statements() {
   bool errored = false;
-  auto ret = create<ast::BlockStatement>();
+  auto* ret = create<ast::BlockStatement>();
 
   while (synchronized_) {
     auto stmt = statement();
@@ -1356,7 +1353,7 @@
 //      | continue_stmt SEMICOLON
 //      | DISCARD SEMICOLON
 //      | assignment_stmt SEMICOLON
-Maybe<std::unique_ptr<ast::Statement>> ParserImpl::statement() {
+Maybe<ast::Statement*> ParserImpl::statement() {
   while (match(Token::Type::kSemicolon)) {
     // Skip empty statements
   }
@@ -1412,8 +1409,8 @@
 //   | continue_stmt SEMICOLON
 //   | DISCARD SEMICOLON
 //   | assignment_stmt SEMICOLON
-Maybe<std::unique_ptr<ast::Statement>> ParserImpl::non_block_statement() {
-  auto stmt = [&]() -> Maybe<std::unique_ptr<ast::Statement>> {
+Maybe<ast::Statement*> ParserImpl::non_block_statement() {
+  auto stmt = [&]() -> Maybe<ast::Statement*> {
     auto ret_stmt = return_stmt();
     if (ret_stmt.errored)
       return Failure::kErrored;
@@ -1465,7 +1462,7 @@
 
 // return_stmt
 //   : RETURN logical_or_expression?
-Maybe<std::unique_ptr<ast::ReturnStatement>> ParserImpl::return_stmt() {
+Maybe<ast::ReturnStatement*> ParserImpl::return_stmt() {
   Source source;
   if (!match(Token::Type::kReturn, &source))
     return Failure::kNoMatch;
@@ -1485,7 +1482,7 @@
 //   : variable_decl
 //   | variable_decl EQUAL logical_or_expression
 //   | CONST variable_ident_decl EQUAL logical_or_expression
-Maybe<std::unique_ptr<ast::VariableDeclStatement>> ParserImpl::variable_stmt() {
+Maybe<ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
   if (match(Token::Type::kConst)) {
     auto decl = expect_variable_ident_decl("constant declaration");
     if (decl.errored)
@@ -1500,8 +1497,8 @@
     if (!constructor.matched)
       return add_error(peek(), "missing constructor for const declaration");
 
-    auto var = create<ast::Variable>(decl->source, decl->name,
-                                     ast::StorageClass::kNone, decl->type);
+    auto* var = create<ast::Variable>(decl->source, decl->name,
+                                      ast::StorageClass::kNone, decl->type);
     var->set_is_const(true);
     var->set_constructor(std::move(constructor.value));
 
@@ -1530,7 +1527,7 @@
 
 // if_stmt
 //   : IF paren_rhs_stmt body_stmt elseif_stmt? else_stmt?
-Maybe<std::unique_ptr<ast::IfStatement>> ParserImpl::if_stmt() {
+Maybe<ast::IfStatement*> ParserImpl::if_stmt() {
   Source source;
   if (!match(Token::Type::kIf, &source))
     return Failure::kNoMatch;
@@ -1551,8 +1548,8 @@
   if (el.errored)
     return Failure::kErrored;
 
-  auto stmt = create<ast::IfStatement>(source, std::move(condition.value),
-                                       std::move(body.value));
+  auto* stmt = create<ast::IfStatement>(source, std::move(condition.value),
+                                        std::move(body.value));
   if (el.matched) {
     elseif.value.push_back(std::move(el.value));
   }
@@ -1590,7 +1587,7 @@
 
 // else_stmt
 //   : ELSE body_stmt
-Maybe<std::unique_ptr<ast::ElseStatement>> ParserImpl::else_stmt() {
+Maybe<ast::ElseStatement*> ParserImpl::else_stmt() {
   Source source;
   if (!match(Token::Type::kElse, &source))
     return Failure::kNoMatch;
@@ -1604,7 +1601,7 @@
 
 // switch_stmt
 //   : SWITCH paren_rhs_stmt BRACKET_LEFT switch_body+ BRACKET_RIGHT
-Maybe<std::unique_ptr<ast::SwitchStatement>> ParserImpl::switch_stmt() {
+Maybe<ast::SwitchStatement*> ParserImpl::switch_stmt() {
   Source source;
   if (!match(Token::Type::kSwitch, &source))
     return Failure::kNoMatch;
@@ -1642,7 +1639,7 @@
 // switch_body
 //   : CASE case_selectors COLON BRACKET_LEFT case_body BRACKET_RIGHT
 //   | DEFAULT COLON BRACKET_LEFT case_body BRACKET_RIGHT
-Maybe<std::unique_ptr<ast::CaseStatement>> ParserImpl::switch_body() {
+Maybe<ast::CaseStatement*> ParserImpl::switch_body() {
   auto t = peek();
   if (!t.IsCase() && !t.IsDefault())
     return Failure::kNoMatch;
@@ -1650,7 +1647,7 @@
   auto source = t.source();
   next();  // Consume the peek
 
-  auto stmt = create<ast::CaseStatement>(create<ast::BlockStatement>());
+  auto* stmt = create<ast::CaseStatement>(create<ast::BlockStatement>());
   stmt->set_source(source);
   if (t.IsCase()) {
     auto selectors = expect_case_selectors();
@@ -1692,8 +1689,7 @@
     if (!cond->IsInt())
       return add_error(t, "invalid case selector must be an integer value");
 
-    std::unique_ptr<ast::IntLiteral> selector(cond.value.release()->AsInt());
-    selectors.push_back(std::move(selector));
+    selectors.push_back(cond.value->AsInt());
   }
 
   if (selectors.empty())
@@ -1706,8 +1702,8 @@
 //   :
 //   | statement case_body
 //   | FALLTHROUGH SEMICOLON
-Maybe<std::unique_ptr<ast::BlockStatement>> ParserImpl::case_body() {
-  auto ret = create<ast::BlockStatement>();
+Maybe<ast::BlockStatement*> ParserImpl::case_body() {
+  auto* ret = create<ast::BlockStatement>();
   for (;;) {
     Source source;
     if (match(Token::Type::kFallthrough, &source)) {
@@ -1732,29 +1728,28 @@
 
 // loop_stmt
 //   : LOOP BRACKET_LEFT statements continuing_stmt? BRACKET_RIGHT
-Maybe<std::unique_ptr<ast::LoopStatement>> ParserImpl::loop_stmt() {
+Maybe<ast::LoopStatement*> ParserImpl::loop_stmt() {
   Source source;
   if (!match(Token::Type::kLoop, &source))
     return Failure::kNoMatch;
 
-  return expect_brace_block(
-      "loop", [&]() -> Maybe<std::unique_ptr<ast::LoopStatement>> {
-        auto body = expect_statements();
-        if (body.errored)
-          return Failure::kErrored;
+  return expect_brace_block("loop", [&]() -> Maybe<ast::LoopStatement*> {
+    auto body = expect_statements();
+    if (body.errored)
+      return Failure::kErrored;
 
-        auto continuing = continuing_stmt();
-        if (continuing.errored)
-          return Failure::kErrored;
+    auto continuing = continuing_stmt();
+    if (continuing.errored)
+      return Failure::kErrored;
 
-        return create<ast::LoopStatement>(source, std::move(body.value),
-                                          std::move(continuing.value));
-      });
+    return create<ast::LoopStatement>(source, std::move(body.value),
+                                      std::move(continuing.value));
+  });
 }
 
-ForHeader::ForHeader(std::unique_ptr<ast::Statement> init,
-                     std::unique_ptr<ast::Expression> cond,
-                     std::unique_ptr<ast::Statement> cont)
+ForHeader::ForHeader(ast::Statement* init,
+                     ast::Expression* cond,
+                     ast::Statement* cont)
     : initializer(std::move(init)),
       condition(std::move(cond)),
       continuing(std::move(cont)) {}
@@ -1762,7 +1757,7 @@
 ForHeader::~ForHeader() = default;
 
 // (variable_stmt | assignment_stmt | func_call_stmt)?
-Maybe<std::unique_ptr<ast::Statement>> ParserImpl::for_header_initializer() {
+Maybe<ast::Statement*> ParserImpl::for_header_initializer() {
   auto call = func_call_stmt();
   if (call.errored)
     return Failure::kErrored;
@@ -1785,7 +1780,7 @@
 }
 
 // (assignment_stmt | func_call_stmt)?
-Maybe<std::unique_ptr<ast::Statement>> ParserImpl::for_header_continuing() {
+Maybe<ast::Statement*> ParserImpl::for_header_continuing() {
   auto call_stmt = func_call_stmt();
   if (call_stmt.errored)
     return Failure::kErrored;
@@ -1825,14 +1820,14 @@
   if (continuing.errored)
     return Failure::kErrored;
 
-  return create<ForHeader>(std::move(initializer.value),
-                           std::move(condition.value),
-                           std::move(continuing.value));
+  return std::make_unique<ForHeader>(std::move(initializer.value),
+                                     std::move(condition.value),
+                                     std::move(continuing.value));
 }
 
 // for_statement
 //   : FOR PAREN_LEFT for_header PAREN_RIGHT BRACE_LEFT statements BRACE_RIGHT
-Maybe<std::unique_ptr<ast::Statement>> ParserImpl::for_stmt() {
+Maybe<ast::Statement*> ParserImpl::for_stmt() {
   Source source;
   if (!match(Token::Type::kFor, &source))
     return Failure::kNoMatch;
@@ -1852,31 +1847,31 @@
   // as we would expect from the loop statement.
   if (header->condition != nullptr) {
     // !condition
-    auto not_condition = create<ast::UnaryOpExpression>(
+    auto* not_condition = create<ast::UnaryOpExpression>(
         header->condition->source(), ast::UnaryOp::kNot,
         std::move(header->condition));
     // { break; }
-    auto break_stmt = create<ast::BreakStatement>(not_condition->source());
-    auto break_body = create<ast::BlockStatement>(not_condition->source());
+    auto* break_stmt = create<ast::BreakStatement>(not_condition->source());
+    auto* break_body = create<ast::BlockStatement>(not_condition->source());
     break_body->append(std::move(break_stmt));
     // if (!condition) { break; }
-    auto break_if_not_condition = create<ast::IfStatement>(
+    auto* break_if_not_condition = create<ast::IfStatement>(
         not_condition->source(), std::move(not_condition),
         std::move(break_body));
     body->insert(0, std::move(break_if_not_condition));
   }
 
-  std::unique_ptr<ast::BlockStatement> continuing_body = nullptr;
+  ast::BlockStatement* continuing_body = nullptr;
   if (header->continuing != nullptr) {
     continuing_body = create<ast::BlockStatement>(header->continuing->source());
     continuing_body->append(std::move(header->continuing));
   }
 
-  auto loop = create<ast::LoopStatement>(source, std::move(body.value),
-                                         std::move(continuing_body));
+  auto* loop = create<ast::LoopStatement>(source, std::move(body.value),
+                                          std::move(continuing_body));
 
   if (header->initializer != nullptr) {
-    auto result = create<ast::BlockStatement>(source);
+    auto* result = create<ast::BlockStatement>(source);
     result->append(std::move(header->initializer));
     result->append(std::move(loop));
     return result;
@@ -1887,7 +1882,7 @@
 
 // func_call_stmt
 //    : IDENT PAREN_LEFT argument_expression_list* PAREN_RIGHT
-Maybe<std::unique_ptr<ast::CallStatement>> ParserImpl::func_call_stmt() {
+Maybe<ast::CallStatement*> ParserImpl::func_call_stmt() {
   auto t = peek();
   auto t2 = peek(1);
   if (!t.IsIdentifier() || !t2.IsParenLeft())
@@ -1919,7 +1914,7 @@
 
 // break_stmt
 //   : BREAK
-Maybe<std::unique_ptr<ast::BreakStatement>> ParserImpl::break_stmt() {
+Maybe<ast::BreakStatement*> ParserImpl::break_stmt() {
   Source source;
   if (!match(Token::Type::kBreak, &source))
     return Failure::kNoMatch;
@@ -1929,7 +1924,7 @@
 
 // continue_stmt
 //   : CONTINUE
-Maybe<std::unique_ptr<ast::ContinueStatement>> ParserImpl::continue_stmt() {
+Maybe<ast::ContinueStatement*> ParserImpl::continue_stmt() {
   Source source;
   if (!match(Token::Type::kContinue, &source))
     return Failure::kNoMatch;
@@ -1939,7 +1934,7 @@
 
 // continuing_stmt
 //   : CONTINUING body_stmt
-Maybe<std::unique_ptr<ast::BlockStatement>> ParserImpl::continuing_stmt() {
+Maybe<ast::BlockStatement*> ParserImpl::continuing_stmt() {
   if (!match(Token::Type::kContinuing))
     return create<ast::BlockStatement>();
 
@@ -1952,7 +1947,7 @@
 //   | const_literal
 //   | paren_rhs_stmt
 //   | BITCAST LESS_THAN type_decl GREATER_THAN paren_rhs_stmt
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::primary_expression() {
+Maybe<ast::Expression*> ParserImpl::primary_expression() {
   auto t = peek();
   auto source = t.source();
 
@@ -1994,8 +1989,7 @@
     return Failure::kErrored;
   if (type.matched) {
     auto expr = expect_paren_block(
-        "type constructor",
-        [&]() -> Expect<std::unique_ptr<ast::TypeConstructorExpression>> {
+        "type constructor", [&]() -> Expect<ast::TypeConstructorExpression*> {
           t = peek();
           if (t.IsParenRight() || t.IsEof())
             return create<ast::TypeConstructorExpression>(
@@ -2023,8 +2017,7 @@
 //   | BRACE_LEFT logical_or_expression BRACE_RIGHT postfix_expr
 //   | PAREN_LEFT argument_expression_list* PAREN_RIGHT postfix_expr
 //   | PERIOD IDENTIFIER postfix_expr
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::postfix_expr(
-    std::unique_ptr<ast::Expression> prefix) {
+Maybe<ast::Expression*> ParserImpl::postfix_expr(ast::Expression* prefix) {
   Source source;
   if (match(Token::Type::kBracketLeft, &source)) {
     auto param = logical_or_expression();
@@ -2073,7 +2066,7 @@
 
 // postfix_expression
 //   : primary_expression postfix_expr
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::postfix_expression() {
+Maybe<ast::Expression*> ParserImpl::postfix_expression() {
   auto prefix = primary_expression();
   if (prefix.errored)
     return Failure::kErrored;
@@ -2112,7 +2105,7 @@
 //   : postfix_expression
 //   | MINUS unary_expression
 //   | BANG unary_expression
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::unary_expression() {
+Maybe<ast::Expression*> ParserImpl::unary_expression() {
   auto t = peek();
   auto source = t.source();
   if (t.IsMinus() || t.IsBang()) {
@@ -2141,8 +2134,8 @@
 //   | STAR unary_expression multiplicative_expr
 //   | FORWARD_SLASH unary_expression multiplicative_expr
 //   | MODULO unary_expression multiplicative_expr
-Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_multiplicative_expr(
-    std::unique_ptr<ast::Expression> lhs) {
+Expect<ast::Expression*> ParserImpl::expect_multiplicative_expr(
+    ast::Expression* lhs) {
   auto t = peek();
 
   ast::BinaryOp op = ast::BinaryOp::kNone;
@@ -2173,8 +2166,7 @@
 
 // multiplicative_expression
 //   : unary_expression multiplicative_expr
-Maybe<std::unique_ptr<ast::Expression>>
-ParserImpl::multiplicative_expression() {
+Maybe<ast::Expression*> ParserImpl::multiplicative_expression() {
   auto lhs = unary_expression();
   if (lhs.errored)
     return Failure::kErrored;
@@ -2188,8 +2180,8 @@
 //   :
 //   | PLUS multiplicative_expression additive_expr
 //   | MINUS multiplicative_expression additive_expr
-Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_additive_expr(
-    std::unique_ptr<ast::Expression> lhs) {
+Expect<ast::Expression*> ParserImpl::expect_additive_expr(
+    ast::Expression* lhs) {
   auto t = peek();
 
   ast::BinaryOp op = ast::BinaryOp::kNone;
@@ -2215,7 +2207,7 @@
 
 // additive_expression
 //   : multiplicative_expression additive_expr
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::additive_expression() {
+Maybe<ast::Expression*> ParserImpl::additive_expression() {
   auto lhs = multiplicative_expression();
   if (lhs.errored)
     return Failure::kErrored;
@@ -2229,8 +2221,7 @@
 //   :
 //   | LESS_THAN LESS_THAN additive_expression shift_expr
 //   | GREATER_THAN GREATER_THAN additive_expression shift_expr
-Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_shift_expr(
-    std::unique_ptr<ast::Expression> lhs) {
+Expect<ast::Expression*> ParserImpl::expect_shift_expr(ast::Expression* lhs) {
   auto t = peek();
   auto source = t.source();
   auto t2 = peek(1);
@@ -2264,7 +2255,7 @@
 
 // shift_expression
 //   : additive_expression shift_expr
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::shift_expression() {
+Maybe<ast::Expression*> ParserImpl::shift_expression() {
   auto lhs = additive_expression();
   if (lhs.errored)
     return Failure::kErrored;
@@ -2280,8 +2271,8 @@
 //   | GREATER_THAN shift_expression relational_expr
 //   | LESS_THAN_EQUAL shift_expression relational_expr
 //   | GREATER_THAN_EQUAL shift_expression relational_expr
-Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_relational_expr(
-    std::unique_ptr<ast::Expression> lhs) {
+Expect<ast::Expression*> ParserImpl::expect_relational_expr(
+    ast::Expression* lhs) {
   auto t = peek();
   ast::BinaryOp op = ast::BinaryOp::kNone;
   if (t.IsLessThan())
@@ -2313,7 +2304,7 @@
 
 // relational_expression
 //   : shift_expression relational_expr
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::relational_expression() {
+Maybe<ast::Expression*> ParserImpl::relational_expression() {
   auto lhs = shift_expression();
   if (lhs.errored)
     return Failure::kErrored;
@@ -2327,8 +2318,8 @@
 //   :
 //   | EQUAL_EQUAL relational_expression equality_expr
 //   | NOT_EQUAL relational_expression equality_expr
-Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_equality_expr(
-    std::unique_ptr<ast::Expression> lhs) {
+Expect<ast::Expression*> ParserImpl::expect_equality_expr(
+    ast::Expression* lhs) {
   auto t = peek();
   ast::BinaryOp op = ast::BinaryOp::kNone;
   if (t.IsEqualEqual())
@@ -2356,7 +2347,7 @@
 
 // equality_expression
 //   : relational_expression equality_expr
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::equality_expression() {
+Maybe<ast::Expression*> ParserImpl::equality_expression() {
   auto lhs = relational_expression();
   if (lhs.errored)
     return Failure::kErrored;
@@ -2369,8 +2360,7 @@
 // and_expr
 //   :
 //   | AND equality_expression and_expr
-Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_and_expr(
-    std::unique_ptr<ast::Expression> lhs) {
+Expect<ast::Expression*> ParserImpl::expect_and_expr(ast::Expression* lhs) {
   auto t = peek();
   if (!t.IsAnd())
     return lhs;
@@ -2390,7 +2380,7 @@
 
 // and_expression
 //   : equality_expression and_expr
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::and_expression() {
+Maybe<ast::Expression*> ParserImpl::and_expression() {
   auto lhs = equality_expression();
   if (lhs.errored)
     return Failure::kErrored;
@@ -2403,8 +2393,8 @@
 // exclusive_or_expr
 //   :
 //   | XOR and_expression exclusive_or_expr
-Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_exclusive_or_expr(
-    std::unique_ptr<ast::Expression> lhs) {
+Expect<ast::Expression*> ParserImpl::expect_exclusive_or_expr(
+    ast::Expression* lhs) {
   Source source;
   if (!match(Token::Type::kXor, &source))
     return lhs;
@@ -2421,7 +2411,7 @@
 
 // exclusive_or_expression
 //   : and_expression exclusive_or_expr
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::exclusive_or_expression() {
+Maybe<ast::Expression*> ParserImpl::exclusive_or_expression() {
   auto lhs = and_expression();
   if (lhs.errored)
     return Failure::kErrored;
@@ -2434,8 +2424,8 @@
 // inclusive_or_expr
 //   :
 //   | OR exclusive_or_expression inclusive_or_expr
-Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_inclusive_or_expr(
-    std::unique_ptr<ast::Expression> lhs) {
+Expect<ast::Expression*> ParserImpl::expect_inclusive_or_expr(
+    ast::Expression* lhs) {
   Source source;
   if (!match(Token::Type::kOr))
     return lhs;
@@ -2452,7 +2442,7 @@
 
 // inclusive_or_expression
 //   : exclusive_or_expression inclusive_or_expr
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::inclusive_or_expression() {
+Maybe<ast::Expression*> ParserImpl::inclusive_or_expression() {
   auto lhs = exclusive_or_expression();
   if (lhs.errored)
     return Failure::kErrored;
@@ -2465,8 +2455,8 @@
 // logical_and_expr
 //   :
 //   | AND_AND inclusive_or_expression logical_and_expr
-Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_logical_and_expr(
-    std::unique_ptr<ast::Expression> lhs) {
+Expect<ast::Expression*> ParserImpl::expect_logical_and_expr(
+    ast::Expression* lhs) {
   auto t = peek();
   if (!t.IsAndAnd())
     return lhs;
@@ -2487,7 +2477,7 @@
 
 // logical_and_expression
 //   : inclusive_or_expression logical_and_expr
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::logical_and_expression() {
+Maybe<ast::Expression*> ParserImpl::logical_and_expression() {
   auto lhs = inclusive_or_expression();
   if (lhs.errored)
     return Failure::kErrored;
@@ -2500,8 +2490,8 @@
 // logical_or_expr
 //   :
 //   | OR_OR logical_and_expression logical_or_expr
-Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_logical_or_expr(
-    std::unique_ptr<ast::Expression> lhs) {
+Expect<ast::Expression*> ParserImpl::expect_logical_or_expr(
+    ast::Expression* lhs) {
   Source source;
   if (!match(Token::Type::kOrOr))
     return lhs;
@@ -2518,7 +2508,7 @@
 
 // logical_or_expression
 //   : logical_and_expression logical_or_expr
-Maybe<std::unique_ptr<ast::Expression>> ParserImpl::logical_or_expression() {
+Maybe<ast::Expression*> ParserImpl::logical_or_expression() {
   auto lhs = logical_and_expression();
   if (lhs.errored)
     return Failure::kErrored;
@@ -2530,7 +2520,7 @@
 
 // assignment_stmt
 //   : unary_expression EQUAL logical_or_expression
-Maybe<std::unique_ptr<ast::AssignmentStatement>> ParserImpl::assignment_stmt() {
+Maybe<ast::AssignmentStatement*> ParserImpl::assignment_stmt() {
   auto t = peek();
   auto source = t.source();
 
@@ -2559,7 +2549,7 @@
 //   | FLOAT_LITERAL
 //   | TRUE
 //   | FALSE
-Maybe<std::unique_ptr<ast::Literal>> ParserImpl::const_literal() {
+Maybe<ast::Literal*> ParserImpl::const_literal() {
   auto t = peek();
   if (match(Token::Type::kTrue)) {
     auto* type = ctx_.type_mgr().Get(std::make_unique<ast::type::BoolType>());
@@ -2587,13 +2577,12 @@
 // const_expr
 //   : type_decl PAREN_LEFT (const_expr COMMA)? const_expr PAREN_RIGHT
 //   | const_literal
-Expect<std::unique_ptr<ast::ConstructorExpression>>
-ParserImpl::expect_const_expr() {
+Expect<ast::ConstructorExpression*> ParserImpl::expect_const_expr() {
   return expect_const_expr_internal(0);
 }
 
-Expect<std::unique_ptr<ast::ConstructorExpression>>
-ParserImpl::expect_const_expr_internal(uint32_t depth) {
+Expect<ast::ConstructorExpression*> ParserImpl::expect_const_expr_internal(
+    uint32_t depth) {
   auto t = peek();
 
   if (depth > kMaxConstExprDepth) {
@@ -2706,7 +2695,7 @@
   });
 }
 
-Expect<std::unique_ptr<ast::Decoration>> ParserImpl::expect_decoration() {
+Expect<ast::Decoration*> ParserImpl::expect_decoration() {
   auto t = peek();
   auto deco = decoration();
   if (deco.errored)
@@ -2716,8 +2705,8 @@
   return add_error(t, "expected decoration");
 }
 
-Maybe<std::unique_ptr<ast::Decoration>> ParserImpl::decoration() {
-  using Result = Maybe<std::unique_ptr<ast::Decoration>>;
+Maybe<ast::Decoration*> ParserImpl::decoration() {
+  using Result = Maybe<ast::Decoration*>;
   auto t = next();
   if (t.IsLocation()) {
     const char* use = "location decoration";
@@ -2822,12 +2811,11 @@
 }
 
 template <typename T>
-Expect<std::vector<std::unique_ptr<T>>> ParserImpl::cast_decorations(
-    ast::DecorationList& in) {
+Expect<std::vector<T*>> ParserImpl::cast_decorations(ast::DecorationList& in) {
   bool ok = true;
-  std::vector<std::unique_ptr<T>> out;
+  std::vector<T*> out;
   out.reserve(in.size());
-  for (auto& deco : in) {
+  for (auto* deco : in) {
     if (!deco->Is<T>()) {
       std::stringstream msg;
       msg << deco->GetKind() << " decoration type cannot be used for "
diff --git a/src/reader/wgsl/parser_impl.h b/src/reader/wgsl/parser_impl.h
index 3edb6b2..daf4789 100644
--- a/src/reader/wgsl/parser_impl.h
+++ b/src/reader/wgsl/parser_impl.h
@@ -65,18 +65,16 @@
   /// @param init the initializer statement
   /// @param cond the condition statement
   /// @param cont the continuing statement
-  ForHeader(std::unique_ptr<ast::Statement> init,
-            std::unique_ptr<ast::Expression> cond,
-            std::unique_ptr<ast::Statement> cont);
+  ForHeader(ast::Statement* init, ast::Expression* cond, ast::Statement* cont);
 
   ~ForHeader();
 
   /// The for loop initializer
-  std::unique_ptr<ast::Statement> initializer;
+  ast::Statement* initializer = nullptr;
   /// The for loop condition
-  std::unique_ptr<ast::Expression> condition;
+  ast::Expression* condition = nullptr;
   /// The for loop continuing statement
-  std::unique_ptr<ast::Statement> continuing;
+  ast::Statement* continuing = nullptr;
 };
 
 /// ParserImpl for WGSL source data
@@ -301,14 +299,13 @@
   /// `variable_decoration_list*` provided as |decos|.
   /// @returns the variable parsed or nullptr
   /// @param decos the list of decorations for the variable declaration.
-  Maybe<std::unique_ptr<ast::Variable>> global_variable_decl(
-      ast::DecorationList& decos);
+  Maybe<ast::Variable*> global_variable_decl(ast::DecorationList& decos);
   /// Parses a `global_constant_decl` grammar element
   /// @returns the const object or nullptr
-  Maybe<std::unique_ptr<ast::Variable>> global_constant_decl();
+  Maybe<ast::Variable*> global_constant_decl();
   /// Parses a `variable_decl` grammar element
   /// @returns the parsed variable or nullptr otherwise
-  Maybe<std::unique_ptr<ast::Variable>> variable_decl();
+  Maybe<ast::Variable*> variable_decl();
   /// Parses a `variable_ident_decl` grammar element, erroring on parse
   /// failure.
   /// @param use a description of what was being parsed if an error was raised.
@@ -341,14 +338,12 @@
   /// failure.
   /// @param decos the list of decorations for the struct member.
   /// @returns the struct member or nullptr
-  Expect<std::unique_ptr<ast::StructMember>> expect_struct_member(
-      ast::DecorationList& decos);
+  Expect<ast::StructMember*> expect_struct_member(ast::DecorationList& decos);
   /// Parses a `function_decl` grammar element with the initial
   /// `function_decoration_decl*` provided as |decos|.
   /// @param decos the list of decorations for the function declaration.
   /// @returns the parsed function, nullptr otherwise
-  Maybe<std::unique_ptr<ast::Function>> function_decl(
-      ast::DecorationList& decos);
+  Maybe<ast::Function*> function_decl(ast::DecorationList& decos);
   /// Parses a `texture_sampler_types` grammar element
   /// @returns the parsed Type or nullptr if none matched.
   Maybe<ast::type::Type*> texture_sampler_types();
@@ -380,7 +375,7 @@
   Maybe<ast::type::Type*> function_type_decl();
   /// Parses a `function_header` grammar element
   /// @returns the parsed function nullptr otherwise
-  Maybe<std::unique_ptr<ast::Function>> function_header();
+  Maybe<ast::Function*> function_header();
   /// Parses a `param_list` grammar element, erroring on parse failure.
   /// @returns the parsed variables
   Expect<ast::VariableList> expect_param_list();
@@ -394,73 +389,73 @@
   Expect<ast::Builtin> expect_builtin();
   /// Parses a `body_stmt` grammar element, erroring on parse failure.
   /// @returns the parsed statements
-  Expect<std::unique_ptr<ast::BlockStatement>> expect_body_stmt();
+  Expect<ast::BlockStatement*> expect_body_stmt();
   /// Parses a `paren_rhs_stmt` grammar element, erroring on parse failure.
   /// @returns the parsed element or nullptr
-  Expect<std::unique_ptr<ast::Expression>> expect_paren_rhs_stmt();
+  Expect<ast::Expression*> expect_paren_rhs_stmt();
   /// Parses a `statements` grammar element
   /// @returns the statements parsed
-  Expect<std::unique_ptr<ast::BlockStatement>> expect_statements();
+  Expect<ast::BlockStatement*> expect_statements();
   /// Parses a `statement` grammar element
   /// @returns the parsed statement or nullptr
-  Maybe<std::unique_ptr<ast::Statement>> statement();
+  Maybe<ast::Statement*> statement();
   /// Parses a `break_stmt` grammar element
   /// @returns the parsed statement or nullptr
-  Maybe<std::unique_ptr<ast::BreakStatement>> break_stmt();
+  Maybe<ast::BreakStatement*> break_stmt();
   /// Parses a `return_stmt` grammar element
   /// @returns the parsed statement or nullptr
-  Maybe<std::unique_ptr<ast::ReturnStatement>> return_stmt();
+  Maybe<ast::ReturnStatement*> return_stmt();
   /// Parses a `continue_stmt` grammar element
   /// @returns the parsed statement or nullptr
-  Maybe<std::unique_ptr<ast::ContinueStatement>> continue_stmt();
+  Maybe<ast::ContinueStatement*> continue_stmt();
   /// Parses a `variable_stmt` grammar element
   /// @returns the parsed variable or nullptr
-  Maybe<std::unique_ptr<ast::VariableDeclStatement>> variable_stmt();
+  Maybe<ast::VariableDeclStatement*> variable_stmt();
   /// Parses a `if_stmt` grammar element
   /// @returns the parsed statement or nullptr
-  Maybe<std::unique_ptr<ast::IfStatement>> if_stmt();
+  Maybe<ast::IfStatement*> if_stmt();
   /// Parses a `elseif_stmt` grammar element
   /// @returns the parsed elements
   Maybe<ast::ElseStatementList> elseif_stmt();
   /// Parses a `else_stmt` grammar element
   /// @returns the parsed statement or nullptr
-  Maybe<std::unique_ptr<ast::ElseStatement>> else_stmt();
+  Maybe<ast::ElseStatement*> else_stmt();
   /// Parses a `switch_stmt` grammar element
   /// @returns the parsed statement or nullptr
-  Maybe<std::unique_ptr<ast::SwitchStatement>> switch_stmt();
+  Maybe<ast::SwitchStatement*> switch_stmt();
   /// Parses a `switch_body` grammar element
   /// @returns the parsed statement or nullptr
-  Maybe<std::unique_ptr<ast::CaseStatement>> switch_body();
+  Maybe<ast::CaseStatement*> switch_body();
   /// Parses a `case_selectors` grammar element
   /// @returns the list of literals
   Expect<ast::CaseSelectorList> expect_case_selectors();
   /// Parses a `case_body` grammar element
   /// @returns the parsed statements
-  Maybe<std::unique_ptr<ast::BlockStatement>> case_body();
+  Maybe<ast::BlockStatement*> case_body();
   /// Parses a `func_call_stmt` grammar element
   /// @returns the parsed function call or nullptr
-  Maybe<std::unique_ptr<ast::CallStatement>> func_call_stmt();
+  Maybe<ast::CallStatement*> func_call_stmt();
   /// Parses a `loop_stmt` grammar element
   /// @returns the parsed loop or nullptr
-  Maybe<std::unique_ptr<ast::LoopStatement>> loop_stmt();
+  Maybe<ast::LoopStatement*> loop_stmt();
   /// Parses a `for_header` grammar element, erroring on parse failure.
   /// @returns the parsed for header or nullptr
   Expect<std::unique_ptr<ForHeader>> expect_for_header();
   /// Parses a `for_stmt` grammar element
   /// @returns the parsed for loop or nullptr
-  Maybe<std::unique_ptr<ast::Statement>> for_stmt();
+  Maybe<ast::Statement*> for_stmt();
   /// Parses a `continuing_stmt` grammar element
   /// @returns the parsed statements
-  Maybe<std::unique_ptr<ast::BlockStatement>> continuing_stmt();
+  Maybe<ast::BlockStatement*> continuing_stmt();
   /// Parses a `const_literal` grammar element
   /// @returns the const literal parsed or nullptr if none found
-  Maybe<std::unique_ptr<ast::Literal>> const_literal();
+  Maybe<ast::Literal*> const_literal();
   /// Parses a `const_expr` grammar element, erroring on parse failure.
   /// @returns the parsed constructor expression or nullptr on error
-  Expect<std::unique_ptr<ast::ConstructorExpression>> expect_const_expr();
+  Expect<ast::ConstructorExpression*> expect_const_expr();
   /// Parses a `primary_expression` grammar element
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> primary_expression();
+  Maybe<ast::Expression*> primary_expression();
   /// Parses a `argument_expression_list` grammar element, erroring on parse
   /// failure.
   /// @returns the list of arguments
@@ -468,107 +463,96 @@
   /// Parses the recursive portion of the postfix_expression
   /// @param prefix the left side of the expression
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> postfix_expr(
-      std::unique_ptr<ast::Expression> prefix);
+  Maybe<ast::Expression*> postfix_expr(ast::Expression* prefix);
   /// Parses a `postfix_expression` grammar elment
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> postfix_expression();
+  Maybe<ast::Expression*> postfix_expression();
   /// Parses a `unary_expression` grammar element
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> unary_expression();
+  Maybe<ast::Expression*> unary_expression();
   /// Parses the recursive part of the `multiplicative_expression`, erroring on
   /// parse failure.
   /// @param lhs the left side of the expression
   /// @returns the parsed expression or nullptr
-  Expect<std::unique_ptr<ast::Expression>> expect_multiplicative_expr(
-      std::unique_ptr<ast::Expression> lhs);
+  Expect<ast::Expression*> expect_multiplicative_expr(ast::Expression* lhs);
   /// Parses the `multiplicative_expression` grammar element
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> multiplicative_expression();
+  Maybe<ast::Expression*> multiplicative_expression();
   /// Parses the recursive part of the `additive_expression`, erroring on parse
   /// failure.
   /// @param lhs the left side of the expression
   /// @returns the parsed expression or nullptr
-  Expect<std::unique_ptr<ast::Expression>> expect_additive_expr(
-      std::unique_ptr<ast::Expression> lhs);
+  Expect<ast::Expression*> expect_additive_expr(ast::Expression* lhs);
   /// Parses the `additive_expression` grammar element
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> additive_expression();
+  Maybe<ast::Expression*> additive_expression();
   /// Parses the recursive part of the `shift_expression`, erroring on parse
   /// failure.
   /// @param lhs the left side of the expression
   /// @returns the parsed expression or nullptr
-  Expect<std::unique_ptr<ast::Expression>> expect_shift_expr(
-      std::unique_ptr<ast::Expression> lhs);
+  Expect<ast::Expression*> expect_shift_expr(ast::Expression* lhs);
   /// Parses the `shift_expression` grammar element
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> shift_expression();
+  Maybe<ast::Expression*> shift_expression();
   /// Parses the recursive part of the `relational_expression`, erroring on
   /// parse failure.
   /// @param lhs the left side of the expression
   /// @returns the parsed expression or nullptr
-  Expect<std::unique_ptr<ast::Expression>> expect_relational_expr(
-      std::unique_ptr<ast::Expression> lhs);
+  Expect<ast::Expression*> expect_relational_expr(ast::Expression* lhs);
   /// Parses the `relational_expression` grammar element
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> relational_expression();
+  Maybe<ast::Expression*> relational_expression();
   /// Parses the recursive part of the `equality_expression`, erroring on parse
   /// failure.
   /// @param lhs the left side of the expression
   /// @returns the parsed expression or nullptr
-  Expect<std::unique_ptr<ast::Expression>> expect_equality_expr(
-      std::unique_ptr<ast::Expression> lhs);
+  Expect<ast::Expression*> expect_equality_expr(ast::Expression* lhs);
   /// Parses the `equality_expression` grammar element
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> equality_expression();
+  Maybe<ast::Expression*> equality_expression();
   /// Parses the recursive part of the `and_expression`, erroring on parse
   /// failure.
   /// @param lhs the left side of the expression
   /// @returns the parsed expression or nullptr
-  Expect<std::unique_ptr<ast::Expression>> expect_and_expr(
-      std::unique_ptr<ast::Expression> lhs);
+  Expect<ast::Expression*> expect_and_expr(ast::Expression* lhs);
   /// Parses the `and_expression` grammar element
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> and_expression();
+  Maybe<ast::Expression*> and_expression();
   /// Parses the recursive part of the `exclusive_or_expression`, erroring on
   /// parse failure.
   /// @param lhs the left side of the expression
   /// @returns the parsed expression or nullptr
-  Expect<std::unique_ptr<ast::Expression>> expect_exclusive_or_expr(
-      std::unique_ptr<ast::Expression> lhs);
+  Expect<ast::Expression*> expect_exclusive_or_expr(ast::Expression* lhs);
   /// Parses the `exclusive_or_expression` grammar elememnt
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> exclusive_or_expression();
+  Maybe<ast::Expression*> exclusive_or_expression();
   /// Parses the recursive part of the `inclusive_or_expression`, erroring on
   /// parse failure.
   /// @param lhs the left side of the expression
   /// @returns the parsed expression or nullptr
-  Expect<std::unique_ptr<ast::Expression>> expect_inclusive_or_expr(
-      std::unique_ptr<ast::Expression> lhs);
+  Expect<ast::Expression*> expect_inclusive_or_expr(ast::Expression* lhs);
   /// Parses the `inclusive_or_expression` grammar element
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> inclusive_or_expression();
+  Maybe<ast::Expression*> inclusive_or_expression();
   /// Parses the recursive part of the `logical_and_expression`, erroring on
   /// parse failure.
   /// @param lhs the left side of the expression
   /// @returns the parsed expression or nullptr
-  Expect<std::unique_ptr<ast::Expression>> expect_logical_and_expr(
-      std::unique_ptr<ast::Expression> lhs);
+  Expect<ast::Expression*> expect_logical_and_expr(ast::Expression* lhs);
   /// Parses a `logical_and_expression` grammar element
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> logical_and_expression();
+  Maybe<ast::Expression*> logical_and_expression();
   /// Parses the recursive part of the `logical_or_expression`, erroring on
   /// parse failure.
   /// @param lhs the left side of the expression
   /// @returns the parsed expression or nullptr
-  Expect<std::unique_ptr<ast::Expression>> expect_logical_or_expr(
-      std::unique_ptr<ast::Expression> lhs);
+  Expect<ast::Expression*> expect_logical_or_expr(ast::Expression* lhs);
   /// Parses a `logical_or_expression` grammar element
   /// @returns the parsed expression or nullptr
-  Maybe<std::unique_ptr<ast::Expression>> logical_or_expression();
+  Maybe<ast::Expression*> logical_or_expression();
   /// Parses a `assignment_stmt` grammar element
   /// @returns the parsed assignment or nullptr
-  Maybe<std::unique_ptr<ast::AssignmentStatement>> assignment_stmt();
+  Maybe<ast::AssignmentStatement*> assignment_stmt();
   /// Parses one or more bracketed decoration lists.
   /// @return the parsed decoration list, or an empty list on error.
   Maybe<ast::DecorationList> decoration_list();
@@ -585,12 +569,12 @@
   /// * `global_const_decoration`
   /// * `function_decoration`
   /// @return the parsed decoration, or nullptr.
-  Maybe<std::unique_ptr<ast::Decoration>> decoration();
+  Maybe<ast::Decoration*> decoration();
   /// Parses a single decoration, reporting an error if the next token does not
   /// represent a decoration.
   /// @see #decoration for the full list of decorations this method parses.
   /// @return the parsed decoration, or nullptr on error.
-  Expect<std::unique_ptr<ast::Decoration>> expect_decoration();
+  Expect<ast::Decoration*> expect_decoration();
 
  private:
   /// ReturnType resolves to the return type for the function or lambda F.
@@ -730,8 +714,7 @@
   /// Downcasts all the decorations in |list| to the type |T|, raising a parser
   /// error if any of the decorations aren't of the type |T|.
   template <typename T>
-  Expect<std::vector<std::unique_ptr<T>>> cast_decorations(
-      ast::DecorationList& in);
+  Expect<std::vector<T*>> cast_decorations(ast::DecorationList& in);
   /// Reports an error if the decoration list |list| is not empty.
   /// Used to ensure that all decorations are consumed.
   bool expect_decorations_consumed(const ast::DecorationList& list);
@@ -742,20 +725,22 @@
       ast::ArrayDecorationList decos);
   Expect<ast::type::Type*> expect_type_decl_matrix(Token t);
 
-  Expect<std::unique_ptr<ast::ConstructorExpression>>
-  expect_const_expr_internal(uint32_t depth);
+  Expect<ast::ConstructorExpression*> expect_const_expr_internal(
+      uint32_t depth);
 
   Expect<ast::type::Type*> expect_type(const std::string& use);
 
-  Maybe<std::unique_ptr<ast::Statement>> non_block_statement();
-  Maybe<std::unique_ptr<ast::Statement>> for_header_initializer();
-  Maybe<std::unique_ptr<ast::Statement>> for_header_continuing();
+  Maybe<ast::Statement*> non_block_statement();
+  Maybe<ast::Statement*> for_header_initializer();
+  Maybe<ast::Statement*> for_header_continuing();
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) const {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx_.create<T>(std::forward<ARGS>(args)...);
   }
 
   Context& ctx_;
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 3250490..46b4f36 100644
--- a/src/reader/wgsl/parser_impl_function_decoration_list_test.cc
+++ b/src/reader/wgsl/parser_impl_function_decoration_list_test.cc
@@ -30,8 +30,8 @@
   EXPECT_TRUE(decos.matched);
   ASSERT_EQ(decos.value.size(), 2u);
 
-  auto deco_0 = ast::As<ast::FunctionDecoration>(std::move(decos.value[0]));
-  auto deco_1 = ast::As<ast::FunctionDecoration>(std::move(decos.value[1]));
+  auto* deco_0 = ast::As<ast::FunctionDecoration>(std::move(decos.value[0]));
+  auto* deco_1 = ast::As<ast::FunctionDecoration>(std::move(decos.value[1]));
   ASSERT_NE(deco_0, nullptr);
   ASSERT_NE(deco_1, nullptr);
 
diff --git a/src/reader/wgsl/parser_impl_function_decoration_test.cc b/src/reader/wgsl/parser_impl_function_decoration_test.cc
index 0518569..75991b2 100644
--- a/src/reader/wgsl/parser_impl_function_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_function_decoration_test.cc
@@ -30,7 +30,7 @@
   EXPECT_FALSE(deco.errored);
   ASSERT_NE(deco.value, nullptr) << p->error();
   ASSERT_FALSE(p->has_error());
-  auto func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
+  auto* func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
   ASSERT_NE(func_deco, nullptr);
   ASSERT_TRUE(func_deco->IsWorkgroup());
 
@@ -50,7 +50,7 @@
   EXPECT_FALSE(deco.errored);
   ASSERT_NE(deco.value, nullptr) << p->error();
   ASSERT_FALSE(p->has_error());
-  auto func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
+  auto* func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
   ASSERT_NE(func_deco, nullptr) << p->error();
   ASSERT_TRUE(func_deco->IsWorkgroup());
 
@@ -70,7 +70,7 @@
   EXPECT_FALSE(deco.errored);
   ASSERT_NE(deco.value, nullptr) << p->error();
   ASSERT_FALSE(p->has_error());
-  auto func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
+  auto* func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
   ASSERT_NE(func_deco, nullptr);
   ASSERT_TRUE(func_deco->IsWorkgroup());
 
@@ -257,7 +257,7 @@
   EXPECT_FALSE(deco.errored);
   ASSERT_NE(deco.value, nullptr) << p->error();
   ASSERT_FALSE(p->has_error());
-  auto func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
+  auto* func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
   ASSERT_NE(func_deco, nullptr);
   ASSERT_TRUE(func_deco->IsStage());
   EXPECT_EQ(func_deco->AsStage()->value(), ast::PipelineStage::kCompute);
diff --git a/src/reader/wgsl/parser_impl_global_decl_test.cc b/src/reader/wgsl/parser_impl_global_decl_test.cc
index f85eb71..ddd0f1d 100644
--- a/src/reader/wgsl/parser_impl_global_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_global_decl_test.cc
@@ -37,7 +37,7 @@
   auto m = p->module();
   ASSERT_EQ(m.global_variables().size(), 1u);
 
-  auto* v = m.global_variables()[0].get();
+  auto* v = m.global_variables()[0];
   EXPECT_EQ(v->name(), "a");
 }
 
@@ -63,7 +63,7 @@
   auto m = p->module();
   ASSERT_EQ(m.global_variables().size(), 1u);
 
-  auto* v = m.global_variables()[0].get();
+  auto* v = m.global_variables()[0];
   EXPECT_EQ(v->name(), "a");
 }
 
diff --git a/src/reader/wgsl/parser_impl_statement_test.cc b/src/reader/wgsl/parser_impl_statement_test.cc
index bdef088..166a949 100644
--- a/src/reader/wgsl/parser_impl_statement_test.cc
+++ b/src/reader/wgsl/parser_impl_statement_test.cc
@@ -34,7 +34,7 @@
 
 TEST_F(ParserImplTest, Statement_Semicolon) {
   auto* p = parser(";");
-  auto e = p->statement();
+  p->statement();
   ASSERT_FALSE(p->has_error()) << p->error();
 }
 
diff --git a/src/reader/wgsl/parser_impl_struct_body_decl_test.cc b/src/reader/wgsl/parser_impl_struct_body_decl_test.cc
index f46cc30..a125074 100644
--- a/src/reader/wgsl/parser_impl_struct_body_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_body_decl_test.cc
@@ -32,7 +32,7 @@
   ASSERT_FALSE(m.errored);
   ASSERT_EQ(m.value.size(), 1u);
 
-  const auto& mem = m.value[0];
+  const auto* mem = m.value[0];
   EXPECT_EQ(mem->name(), "a");
   EXPECT_EQ(mem->type(), i32);
   EXPECT_EQ(mem->decorations().size(), 0u);
diff --git a/src/reader/wgsl/parser_impl_struct_decoration_decl_test.cc b/src/reader/wgsl/parser_impl_struct_decoration_decl_test.cc
index f33356d..8c8b988 100644
--- a/src/reader/wgsl/parser_impl_struct_decoration_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_decoration_decl_test.cc
@@ -28,7 +28,7 @@
   EXPECT_FALSE(decos.errored);
   EXPECT_TRUE(decos.matched);
   ASSERT_EQ(decos.value.size(), 1u);
-  auto struct_deco = ast::As<ast::StructDecoration>(std::move(decos.value[0]));
+  auto* struct_deco = ast::As<ast::StructDecoration>(std::move(decos.value[0]));
   EXPECT_TRUE(struct_deco->IsBlock());
 }
 
diff --git a/src/reader/wgsl/parser_impl_struct_decoration_test.cc b/src/reader/wgsl/parser_impl_struct_decoration_test.cc
index f04658e..ba37441 100644
--- a/src/reader/wgsl/parser_impl_struct_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_decoration_test.cc
@@ -43,7 +43,7 @@
   EXPECT_TRUE(deco.matched);
   EXPECT_FALSE(deco.errored);
   ASSERT_NE(deco.value, nullptr);
-  auto struct_deco = ast::As<ast::StructDecoration>(std::move(deco.value));
+  auto* struct_deco = ast::As<ast::StructDecoration>(std::move(deco.value));
   ASSERT_NE(struct_deco, nullptr);
   EXPECT_EQ(struct_deco->IsBlock(), params.is_block);
 }
diff --git a/src/reader/wgsl/parser_impl_struct_member_decoration_decl_test.cc b/src/reader/wgsl/parser_impl_struct_member_decoration_decl_test.cc
index df92f11..2e696d3 100644
--- a/src/reader/wgsl/parser_impl_struct_member_decoration_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_member_decoration_decl_test.cc
@@ -48,7 +48,7 @@
   EXPECT_FALSE(decos.errored);
   EXPECT_TRUE(decos.matched);
   ASSERT_EQ(decos.value.size(), 1u);
-  auto deco = ast::As<ast::StructMemberDecoration>(std::move(decos.value[0]));
+  auto* deco = ast::As<ast::StructMemberDecoration>(std::move(decos.value[0]));
   ASSERT_NE(deco, nullptr);
   EXPECT_TRUE(deco->IsOffset());
 }
diff --git a/src/reader/wgsl/parser_impl_struct_member_decoration_test.cc b/src/reader/wgsl/parser_impl_struct_member_decoration_test.cc
index 8872c8e..adb21db 100644
--- a/src/reader/wgsl/parser_impl_struct_member_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_member_decoration_test.cc
@@ -30,7 +30,7 @@
   ASSERT_NE(deco.value, nullptr);
   ASSERT_FALSE(p->has_error());
 
-  auto member_deco =
+  auto* member_deco =
       ast::As<ast::StructMemberDecoration>(std::move(deco.value));
   ASSERT_NE(member_deco, nullptr);
   ASSERT_TRUE(member_deco->IsOffset());
diff --git a/src/reader/wgsl/parser_impl_variable_decoration_list_test.cc b/src/reader/wgsl/parser_impl_variable_decoration_list_test.cc
index a9271b9..9f53688 100644
--- a/src/reader/wgsl/parser_impl_variable_decoration_list_test.cc
+++ b/src/reader/wgsl/parser_impl_variable_decoration_list_test.cc
@@ -31,8 +31,8 @@
   ASSERT_TRUE(decos.matched);
   ASSERT_EQ(decos.value.size(), 2u);
 
-  auto deco_0 = ast::As<ast::VariableDecoration>(std::move(decos.value[0]));
-  auto deco_1 = ast::As<ast::VariableDecoration>(std::move(decos.value[1]));
+  auto* deco_0 = ast::As<ast::VariableDecoration>(std::move(decos.value[0]));
+  auto* deco_1 = ast::As<ast::VariableDecoration>(std::move(decos.value[1]));
   ASSERT_NE(deco_0, nullptr);
   ASSERT_NE(deco_1, nullptr);
 
diff --git a/src/reader/wgsl/parser_impl_variable_decoration_test.cc b/src/reader/wgsl/parser_impl_variable_decoration_test.cc
index f99ae14..6ac7ac3 100644
--- a/src/reader/wgsl/parser_impl_variable_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_variable_decoration_test.cc
@@ -31,7 +31,7 @@
   EXPECT_TRUE(deco.matched);
   EXPECT_FALSE(deco.errored);
   ASSERT_NE(deco.value, nullptr);
-  auto var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
+  auto* var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
   ASSERT_NE(var_deco, nullptr);
   ASSERT_FALSE(p->has_error());
   ASSERT_TRUE(var_deco->IsLocation());
@@ -101,7 +101,7 @@
   EXPECT_TRUE(deco.matched);
   EXPECT_FALSE(deco.errored);
   ASSERT_NE(deco.value, nullptr);
-  auto var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
+  auto* var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
   ASSERT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(var_deco, nullptr);
   ASSERT_TRUE(var_deco->IsBuiltin());
@@ -180,7 +180,7 @@
   EXPECT_TRUE(deco.matched);
   EXPECT_FALSE(deco.errored);
   ASSERT_NE(deco.value, nullptr);
-  auto var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
+  auto* var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
   ASSERT_NE(var_deco, nullptr);
   ASSERT_FALSE(p->has_error());
   ASSERT_TRUE(var_deco->IsBinding());
@@ -237,9 +237,9 @@
   EXPECT_TRUE(deco.matched);
   EXPECT_FALSE(deco.errored);
   ASSERT_NE(deco.value, nullptr);
-  auto var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
+  auto* var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
   ASSERT_FALSE(p->has_error());
-  ASSERT_NE(var_deco.get(), nullptr);
+  ASSERT_NE(var_deco, nullptr);
   ASSERT_TRUE(var_deco->IsSet());
 
   auto* set = var_deco->AsSet();
diff --git a/src/transform/bound_array_accessors_transform.cc b/src/transform/bound_array_accessors_transform.cc
index 2f1e32a..cbc4bac 100644
--- a/src/transform/bound_array_accessors_transform.cc
+++ b/src/transform/bound_array_accessors_transform.cc
@@ -57,7 +57,7 @@
   // constant expression. There can't be any array accessors as per the current
   // grammar.
 
-  for (auto& func : mod_->functions()) {
+  for (auto* func : mod_->functions()) {
     scope_stack_.push_scope();
     if (!ProcessStatement(func->body())) {
       return false;
@@ -72,8 +72,8 @@
     auto* as = stmt->AsAssign();
     return ProcessExpression(as->lhs()) && ProcessExpression(as->rhs());
   } else if (stmt->IsBlock()) {
-    for (auto& s : *(stmt->AsBlock())) {
-      if (!ProcessStatement(s.get())) {
+    for (auto* s : *(stmt->AsBlock())) {
+      if (!ProcessStatement(s)) {
         return false;
       }
     }
@@ -97,8 +97,8 @@
     if (!ProcessExpression(e->condition()) || !ProcessStatement(e->body())) {
       return false;
     }
-    for (auto& s : e->else_statements()) {
-      if (!ProcessStatement(s.get())) {
+    for (auto* s : e->else_statements()) {
+      if (!ProcessStatement(s)) {
         return false;
       }
     }
@@ -118,8 +118,8 @@
       return false;
     }
 
-    for (auto& c : s->body()) {
-      if (!ProcessStatement(c.get())) {
+    for (auto* c : s->body()) {
+      if (!ProcessStatement(c)) {
         return false;
       }
     }
@@ -146,8 +146,8 @@
     if (!ProcessExpression(c->func())) {
       return false;
     }
-    for (auto& e : c->params()) {
-      if (!ProcessExpression(e.get())) {
+    for (auto* e : c->params()) {
+      if (!ProcessExpression(e)) {
         return false;
       }
     }
@@ -156,8 +156,8 @@
   } else if (expr->IsConstructor()) {
     auto* c = expr->AsConstructor();
     if (c->IsTypeConstructor()) {
-      for (auto& e : c->AsTypeConstructor()->values()) {
-        if (!ProcessExpression(e.get())) {
+      for (auto* e : c->AsTypeConstructor()->values()) {
+        if (!ProcessExpression(e)) {
           return false;
         }
       }
@@ -241,7 +241,7 @@
     auto* u32 = ctx_->type_mgr().Get(std::make_unique<ast::type::U32Type>());
 
     ast::ExpressionList cast_expr;
-    cast_expr.push_back(expr->take_idx_expr());
+    cast_expr.push_back(expr->idx_expr());
 
     ast::ExpressionList params;
     params.push_back(
@@ -249,7 +249,7 @@
     params.push_back(create<ast::ScalarConstructorExpression>(
         create<ast::UintLiteral>(u32, size - 1)));
 
-    auto call_expr = create<ast::CallExpression>(
+    auto* call_expr = create<ast::CallExpression>(
         create<ast::IdentifierExpression>("min"), std::move(params));
     call_expr->set_result_type(u32);
 
diff --git a/src/transform/bound_array_accessors_transform_test.cc b/src/transform/bound_array_accessors_transform_test.cc
index 26c8973..d0613b7 100644
--- a/src/transform/bound_array_accessors_transform_test.cc
+++ b/src/transform/bound_array_accessors_transform_test.cc
@@ -52,15 +52,15 @@
   BoundArrayAccessorsTest() : td_(&ctx_, &mod_), transform_(&ctx_, &mod_) {}
 
   ast::BlockStatement* SetupFunctionAndBody() {
-    auto block = create<ast::BlockStatement>();
-    body_ = block.get();
-    auto func = create<ast::Function>("func", ast::VariableList{}, &void_type_,
+    auto* block = create<ast::BlockStatement>();
+    body_ = block;
+    auto* func = create<ast::Function>("func", ast::VariableList{}, &void_type_,
                                       std::move(block));
     mod_.AddFunction(std::move(func));
     return body_;
   }
 
-  void DeclareVariable(std::unique_ptr<ast::Variable> var) {
+  void DeclareVariable(ast::Variable* var) {
     ASSERT_NE(body_, nullptr);
     body_->append(create<ast::VariableDeclStatement>(std::move(var)));
   }
@@ -69,11 +69,13 @@
 
   BoundArrayAccessorsTransform* transform() { return &transform_; }
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx_.create<T>(std::forward<ARGS>(args)...);
   }
 
  private:
@@ -101,18 +103,18 @@
   DeclareVariable(
       create<ast::Variable>("a", ast::StorageClass::kFunction, &ary));
 
-  auto c_var = create<ast::Variable>("c", ast::StorageClass::kFunction, &u32);
+  auto* c_var = create<ast::Variable>("c", ast::StorageClass::kFunction, &u32);
   c_var->set_is_const(true);
   DeclareVariable(std::move(c_var));
 
-  auto access_idx = create<ast::IdentifierExpression>("c");
-  auto* access_ptr = access_idx.get();
+  auto* access_idx = create<ast::IdentifierExpression>("c");
+  auto* access_ptr = access_idx;
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::IdentifierExpression>("a"), std::move(access_idx));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &ptr_type);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &ptr_type);
   b->set_constructor(std::move(accessor));
   b->set_is_const(true);
   DeclareVariable(std::move(b));
@@ -134,7 +136,7 @@
   auto* tc = idx->params()[0]->AsConstructor()->AsTypeConstructor();
   EXPECT_TRUE(tc->type()->IsU32());
   ASSERT_EQ(tc->values().size(), 1u);
-  ASSERT_EQ(tc->values()[0].get(), access_ptr);
+  ASSERT_EQ(tc->values()[0], access_ptr);
 
   ASSERT_TRUE(idx->params()[1]->IsConstructor());
   ASSERT_TRUE(idx->params()[1]->AsConstructor()->IsScalarConstructor());
@@ -167,17 +169,17 @@
   DeclareVariable(
       create<ast::Variable>("i", ast::StorageClass::kFunction, &u32));
 
-  auto b_access_idx = create<ast::IdentifierExpression>("i");
-  auto* b_access_ptr = b_access_idx.get();
+  auto* b_access_idx = create<ast::IdentifierExpression>("i");
+  auto* b_access_ptr = b_access_idx;
 
-  auto a_access_idx = create<ast::ArrayAccessorExpression>(
+  auto* a_access_idx = create<ast::ArrayAccessorExpression>(
       create<ast::IdentifierExpression>("b"), std::move(b_access_idx));
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::IdentifierExpression>("a"), std::move(a_access_idx));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("c", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("c", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -199,7 +201,7 @@
   EXPECT_TRUE(tc->type()->IsU32());
   ASSERT_EQ(tc->values().size(), 1u);
 
-  auto* sub = tc->values()[0].get();
+  auto* sub = tc->values()[0];
   ASSERT_TRUE(sub->IsArrayAccessor());
   ASSERT_TRUE(sub->AsArrayAccessor()->idx_expr()->IsCall());
 
@@ -212,7 +214,7 @@
   tc = sub_idx->params()[0]->AsConstructor()->AsTypeConstructor();
   EXPECT_TRUE(tc->type()->IsU32());
   ASSERT_EQ(tc->values().size(), 1u);
-  ASSERT_EQ(tc->values()[0].get(), b_access_ptr);
+  ASSERT_EQ(tc->values()[0], b_access_ptr);
 
   ASSERT_TRUE(sub_idx->params()[1]->IsConstructor());
   ASSERT_TRUE(sub_idx->params()[1]->AsConstructor()->IsScalarConstructor());
@@ -244,13 +246,13 @@
   DeclareVariable(
       create<ast::Variable>("a", ast::StorageClass::kFunction, &ary));
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::IdentifierExpression>("a"),
       create<ast::ScalarConstructorExpression>(
           create<ast::UintLiteral>(&u32, 1u)));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -286,20 +288,20 @@
   DeclareVariable(
       create<ast::Variable>("c", ast::StorageClass::kFunction, &u32));
 
-  auto access_idx = create<ast::BinaryExpression>(
+  auto* access_idx = create<ast::BinaryExpression>(
       ast::BinaryOp::kAdd, create<ast::IdentifierExpression>("c"),
       create<ast::BinaryExpression>(ast::BinaryOp::kSubtract,
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::UintLiteral>(&u32, 2)),
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::UintLiteral>(&u32, 3))));
-  auto* access_ptr = access_idx.get();
+  auto* access_ptr = access_idx;
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::IdentifierExpression>("a"), std::move(access_idx));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -320,7 +322,7 @@
   auto* tc = idx->params()[0]->AsConstructor()->AsTypeConstructor();
   EXPECT_TRUE(tc->type()->IsU32());
   ASSERT_EQ(tc->values().size(), 1u);
-  ASSERT_EQ(tc->values()[0].get(), access_ptr);
+  ASSERT_EQ(tc->values()[0], access_ptr);
 
   ASSERT_TRUE(idx->params()[1]->IsConstructor());
   ASSERT_TRUE(idx->params()[1]->AsConstructor()->IsScalarConstructor());
@@ -346,13 +348,13 @@
   DeclareVariable(
       create<ast::Variable>("a", ast::StorageClass::kFunction, &ary));
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::IdentifierExpression>("a"),
       create<ast::ScalarConstructorExpression>(
           create<ast::SintLiteral>(&i32, -1)));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -385,13 +387,13 @@
   DeclareVariable(
       create<ast::Variable>("a", ast::StorageClass::kFunction, &ary));
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::IdentifierExpression>("a"),
       create<ast::ScalarConstructorExpression>(
           create<ast::UintLiteral>(&u32, 3u)));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -424,13 +426,13 @@
   DeclareVariable(
       create<ast::Variable>("a", ast::StorageClass::kFunction, &vec));
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::IdentifierExpression>("a"),
       create<ast::ScalarConstructorExpression>(
           create<ast::UintLiteral>(&u32, 1u)));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -466,20 +468,20 @@
   DeclareVariable(
       create<ast::Variable>("c", ast::StorageClass::kFunction, &u32));
 
-  auto access_idx = create<ast::BinaryExpression>(
+  auto* access_idx = create<ast::BinaryExpression>(
       ast::BinaryOp::kAdd, create<ast::IdentifierExpression>("c"),
       create<ast::BinaryExpression>(ast::BinaryOp::kSubtract,
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::UintLiteral>(&u32, 2)),
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::UintLiteral>(&u32, 3))));
-  auto* access_ptr = access_idx.get();
+  auto* access_ptr = access_idx;
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::IdentifierExpression>("a"), std::move(access_idx));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -499,7 +501,7 @@
   auto* tc = idx->params()[0]->AsConstructor()->AsTypeConstructor();
   EXPECT_TRUE(tc->type()->IsU32());
   ASSERT_EQ(tc->values().size(), 1u);
-  ASSERT_EQ(tc->values()[0].get(), access_ptr);
+  ASSERT_EQ(tc->values()[0], access_ptr);
 
   ASSERT_TRUE(idx->params()[1]->IsConstructor());
   ASSERT_TRUE(idx->params()[1]->AsConstructor()->IsScalarConstructor());
@@ -525,13 +527,13 @@
   DeclareVariable(
       create<ast::Variable>("a", ast::StorageClass::kFunction, &vec));
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::IdentifierExpression>("a"),
       create<ast::ScalarConstructorExpression>(
           create<ast::SintLiteral>(&i32, -1)));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -564,13 +566,13 @@
   DeclareVariable(
       create<ast::Variable>("a", ast::StorageClass::kFunction, &vec));
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::IdentifierExpression>("a"),
       create<ast::ScalarConstructorExpression>(
           create<ast::UintLiteral>(&u32, 3u)));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -603,16 +605,16 @@
   DeclareVariable(
       create<ast::Variable>("a", ast::StorageClass::kFunction, &mat));
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::ArrayAccessorExpression>(
           create<ast::IdentifierExpression>("a"),
           create<ast::ScalarConstructorExpression>(
               create<ast::UintLiteral>(&u32, 2u))),
       create<ast::ScalarConstructorExpression>(
           create<ast::UintLiteral>(&u32, 1u)));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -661,23 +663,23 @@
   DeclareVariable(
       create<ast::Variable>("c", ast::StorageClass::kFunction, &u32));
 
-  auto access_idx = create<ast::BinaryExpression>(
+  auto* access_idx = create<ast::BinaryExpression>(
       ast::BinaryOp::kAdd, create<ast::IdentifierExpression>("c"),
       create<ast::BinaryExpression>(ast::BinaryOp::kSubtract,
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::UintLiteral>(&u32, 2)),
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::UintLiteral>(&u32, 3))));
-  auto* access_ptr = access_idx.get();
+  auto* access_ptr = access_idx;
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::ArrayAccessorExpression>(
           create<ast::IdentifierExpression>("a"), std::move(access_idx)),
       create<ast::ScalarConstructorExpression>(
           create<ast::UintLiteral>(&u32, 1u)));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -701,7 +703,7 @@
   auto* tc = idx->params()[0]->AsConstructor()->AsTypeConstructor();
   EXPECT_TRUE(tc->type()->IsU32());
   ASSERT_EQ(tc->values().size(), 1u);
-  ASSERT_EQ(tc->values()[0].get(), access_ptr);
+  ASSERT_EQ(tc->values()[0], access_ptr);
 
   ASSERT_TRUE(idx->params()[1]->IsConstructor());
   ASSERT_TRUE(idx->params()[1]->AsConstructor()->IsScalarConstructor());
@@ -740,24 +742,24 @@
   DeclareVariable(
       create<ast::Variable>("c", ast::StorageClass::kFunction, &u32));
 
-  auto access_idx = create<ast::BinaryExpression>(
+  auto* access_idx = create<ast::BinaryExpression>(
       ast::BinaryOp::kAdd, create<ast::IdentifierExpression>("c"),
       create<ast::BinaryExpression>(ast::BinaryOp::kSubtract,
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::UintLiteral>(&u32, 2)),
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::UintLiteral>(&u32, 3))));
-  auto* access_ptr = access_idx.get();
+  auto* access_ptr = access_idx;
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::ArrayAccessorExpression>(
           create<ast::IdentifierExpression>("a"),
           create<ast::ScalarConstructorExpression>(
               create<ast::UintLiteral>(&u32, 1u))),
       std::move(access_idx));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -788,7 +790,7 @@
   auto* tc = idx->params()[0]->AsConstructor()->AsTypeConstructor();
   EXPECT_TRUE(tc->type()->IsU32());
   ASSERT_EQ(tc->values().size(), 1u);
-  ASSERT_EQ(tc->values()[0].get(), access_ptr);
+  ASSERT_EQ(tc->values()[0], access_ptr);
 
   ASSERT_TRUE(idx->params()[1]->IsConstructor());
   ASSERT_TRUE(idx->params()[1]->AsConstructor()->IsScalarConstructor());
@@ -816,16 +818,16 @@
   DeclareVariable(
       create<ast::Variable>("a", ast::StorageClass::kFunction, &mat));
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::ArrayAccessorExpression>(
           create<ast::IdentifierExpression>("a"),
           create<ast::ScalarConstructorExpression>(
               create<ast::SintLiteral>(&i32, -1))),
       create<ast::ScalarConstructorExpression>(
           create<ast::SintLiteral>(&i32, 1)));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -870,16 +872,16 @@
   DeclareVariable(
       create<ast::Variable>("a", ast::StorageClass::kFunction, &mat));
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::ArrayAccessorExpression>(
           create<ast::IdentifierExpression>("a"),
           create<ast::ScalarConstructorExpression>(
               create<ast::SintLiteral>(&i32, 2))),
       create<ast::ScalarConstructorExpression>(
           create<ast::SintLiteral>(&i32, -1)));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -925,16 +927,16 @@
   DeclareVariable(
       create<ast::Variable>("a", ast::StorageClass::kFunction, &mat));
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::ArrayAccessorExpression>(
           create<ast::IdentifierExpression>("a"),
           create<ast::ScalarConstructorExpression>(
               create<ast::UintLiteral>(&u32, 5u))),
       create<ast::ScalarConstructorExpression>(
           create<ast::UintLiteral>(&u32, 1u)));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
@@ -980,16 +982,16 @@
   DeclareVariable(
       create<ast::Variable>("a", ast::StorageClass::kFunction, &mat));
 
-  auto accessor = create<ast::ArrayAccessorExpression>(
+  auto* accessor = create<ast::ArrayAccessorExpression>(
       create<ast::ArrayAccessorExpression>(
           create<ast::IdentifierExpression>("a"),
           create<ast::ScalarConstructorExpression>(
               create<ast::UintLiteral>(&u32, 2u))),
       create<ast::ScalarConstructorExpression>(
           create<ast::UintLiteral>(&u32, 5u)));
-  auto* ptr = accessor.get();
+  auto* ptr = accessor;
 
-  auto b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kFunction, &f32);
   b->set_constructor(std::move(accessor));
   DeclareVariable(std::move(b));
 
diff --git a/src/transform/transformer.h b/src/transform/transformer.h
index 417e732..7608db6 100644
--- a/src/transform/transformer.h
+++ b/src/transform/transformer.h
@@ -41,11 +41,13 @@
   const std::string& error() { return error_; }
 
  protected:
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) const {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx_->create<T>(std::forward<ARGS>(args)...);
   }
 
   /// The context
diff --git a/src/transform/vertex_pulling_transform.cc b/src/transform/vertex_pulling_transform.cc
index 4b38195..f057ada 100644
--- a/src/transform/vertex_pulling_transform.cc
+++ b/src/transform/vertex_pulling_transform.cc
@@ -126,12 +126,12 @@
   }
 
   // Look for an existing vertex index builtin
-  for (auto& v : mod_->global_variables()) {
+  for (auto* v : mod_->global_variables()) {
     if (!v->IsDecorated() || v->storage_class() != ast::StorageClass::kInput) {
       continue;
     }
 
-    for (auto& d : v->AsDecorated()->decorations()) {
+    for (auto* d : v->AsDecorated()->decorations()) {
       if (d->IsBuiltin() &&
           d->AsBuiltin()->value() == ast::Builtin::kVertexIdx) {
         vertex_index_name_ = v->name();
@@ -143,7 +143,7 @@
   // We didn't find a vertex index builtin, so create one
   vertex_index_name_ = kDefaultVertexIndexName;
 
-  auto var = create<ast::DecoratedVariable>(create<ast::Variable>(
+  auto* var = create<ast::DecoratedVariable>(create<ast::Variable>(
       vertex_index_name_, ast::StorageClass::kInput, GetI32Type()));
 
   ast::VariableDecorationList decorations;
@@ -168,12 +168,12 @@
   }
 
   // Look for an existing instance index builtin
-  for (auto& v : mod_->global_variables()) {
+  for (auto* v : mod_->global_variables()) {
     if (!v->IsDecorated() || v->storage_class() != ast::StorageClass::kInput) {
       continue;
     }
 
-    for (auto& d : v->AsDecorated()->decorations()) {
+    for (auto* d : v->AsDecorated()->decorations()) {
       if (d->IsBuiltin() &&
           d->AsBuiltin()->value() == ast::Builtin::kInstanceIdx) {
         instance_index_name_ = v->name();
@@ -185,7 +185,7 @@
   // We didn't find an instance index builtin, so create one
   instance_index_name_ = kDefaultInstanceIndexName;
 
-  auto var = create<ast::DecoratedVariable>(create<ast::Variable>(
+  auto* var = create<ast::DecoratedVariable>(create<ast::Variable>(
       instance_index_name_, ast::StorageClass::kInput, GetI32Type()));
 
   ast::VariableDecorationList decorations;
@@ -197,12 +197,12 @@
 }
 
 void VertexPullingTransform::ConvertVertexInputVariablesToPrivate() {
-  for (auto& v : mod_->global_variables()) {
+  for (auto*& v : mod_->global_variables()) {
     if (!v->IsDecorated() || v->storage_class() != ast::StorageClass::kInput) {
       continue;
     }
 
-    for (auto& d : v->AsDecorated()->decorations()) {
+    for (auto* d : v->AsDecorated()->decorations()) {
       if (!d->IsLocation()) {
         continue;
       }
@@ -213,7 +213,7 @@
       // in the AST.
       v = create<ast::Variable>(v->name(), ast::StorageClass::kPrivate,
                                 v->type());
-      location_to_var_[location] = v.get();
+      location_to_var_[location] = v;
       break;
     }
   }
@@ -247,7 +247,7 @@
 
   for (uint32_t i = 0; i < vertex_state_->vertex_buffers.size(); ++i) {
     // The decorated variable with struct type
-    auto var = create<ast::DecoratedVariable>(
+    auto* var = create<ast::DecoratedVariable>(
         create<ast::Variable>(GetVertexBufferName(i),
                               ast::StorageClass::kStorageBuffer, struct_type));
 
@@ -268,10 +268,10 @@
   // location.
 
   // A block statement allowing us to use append instead of insert
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
 
   // Declare the |kPullingPosVarName| variable in the shader
-  auto pos_declaration =
+  auto* pos_declaration =
       create<ast::VariableDeclStatement>(create<ast::Variable>(
           kPullingPosVarName, ast::StorageClass::kFunction, GetI32Type()));
 
@@ -293,13 +293,13 @@
       auto* v = it->second;
 
       // Identifier to index by
-      auto index_identifier = create<ast::IdentifierExpression>(
+      auto* index_identifier = create<ast::IdentifierExpression>(
           buffer_layout.step_mode == InputStepMode::kVertex
               ? vertex_index_name_
               : instance_index_name_);
 
       // An expression for the start of the read in the buffer in bytes
-      auto pos_value = create<ast::BinaryExpression>(
+      auto* pos_value = create<ast::BinaryExpression>(
           ast::BinaryOp::kAdd,
           create<ast::BinaryExpression>(
               ast::BinaryOp::kMultiply, std::move(index_identifier),
@@ -307,7 +307,7 @@
           GenUint(static_cast<uint32_t>(attribute_desc.offset)));
 
       // Update position of the read
-      auto set_pos_expr = create<ast::AssignmentStatement>(
+      auto* set_pos_expr = create<ast::AssignmentStatement>(
           CreatePullingPositionIdent(), std::move(pos_value));
       block->append(std::move(set_pos_expr));
 
@@ -320,20 +320,17 @@
   vertex_func->body()->insert(0, std::move(block));
 }
 
-std::unique_ptr<ast::Expression> VertexPullingTransform::GenUint(
-    uint32_t value) {
+ast::Expression* VertexPullingTransform::GenUint(uint32_t value) {
   return create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(GetU32Type(), value));
 }
 
-std::unique_ptr<ast::Expression>
-VertexPullingTransform::CreatePullingPositionIdent() {
+ast::Expression* VertexPullingTransform::CreatePullingPositionIdent() {
   return create<ast::IdentifierExpression>(kPullingPosVarName);
 }
 
-std::unique_ptr<ast::Expression> VertexPullingTransform::AccessByFormat(
-    uint32_t buffer,
-    VertexFormat format) {
+ast::Expression* VertexPullingTransform::AccessByFormat(uint32_t buffer,
+                                                        VertexFormat format) {
   // TODO(idanr): this doesn't account for the format of the attribute in the
   // shader. ex: vec<u32> in shader, and attribute claims VertexFormat::Float4
   // right now, we would try to assign a vec4<f32> to this attribute, but we
@@ -359,9 +356,8 @@
   }
 }
 
-std::unique_ptr<ast::Expression> VertexPullingTransform::AccessU32(
-    uint32_t buffer,
-    std::unique_ptr<ast::Expression> pos) {
+ast::Expression* VertexPullingTransform::AccessU32(uint32_t buffer,
+                                                   ast::Expression* pos) {
   // Here we divide by 4, since the buffer is uint32 not uint8. The input buffer
   // has byte offsets for each attribute, and we will convert it to u32 indexes
   // by dividing. Then, that element is going to be read, and if needed,
@@ -375,26 +371,23 @@
                                     GenUint(4)));
 }
 
-std::unique_ptr<ast::Expression> VertexPullingTransform::AccessI32(
-    uint32_t buffer,
-    std::unique_ptr<ast::Expression> pos) {
+ast::Expression* VertexPullingTransform::AccessI32(uint32_t buffer,
+                                                   ast::Expression* pos) {
   // as<T> reinterprets bits
   return create<ast::BitcastExpression>(GetI32Type(),
                                         AccessU32(buffer, std::move(pos)));
 }
 
-std::unique_ptr<ast::Expression> VertexPullingTransform::AccessF32(
-    uint32_t buffer,
-    std::unique_ptr<ast::Expression> pos) {
+ast::Expression* VertexPullingTransform::AccessF32(uint32_t buffer,
+                                                   ast::Expression* pos) {
   // as<T> reinterprets bits
   return create<ast::BitcastExpression>(GetF32Type(),
                                         AccessU32(buffer, std::move(pos)));
 }
 
-std::unique_ptr<ast::Expression> VertexPullingTransform::AccessPrimitive(
-    uint32_t buffer,
-    std::unique_ptr<ast::Expression> pos,
-    VertexFormat format) {
+ast::Expression* VertexPullingTransform::AccessPrimitive(uint32_t buffer,
+                                                         ast::Expression* pos,
+                                                         VertexFormat format) {
   // This function uses a position expression to read, rather than using the
   // position variable. This allows us to read from offset positions relative to
   // |kPullingPosVarName|. We can't call AccessByFormat because it reads only
@@ -411,18 +404,17 @@
   }
 }
 
-std::unique_ptr<ast::Expression> VertexPullingTransform::AccessVec(
-    uint32_t buffer,
-    uint32_t element_stride,
-    ast::type::Type* base_type,
-    VertexFormat base_format,
-    uint32_t count) {
+ast::Expression* VertexPullingTransform::AccessVec(uint32_t buffer,
+                                                   uint32_t element_stride,
+                                                   ast::type::Type* base_type,
+                                                   VertexFormat base_format,
+                                                   uint32_t count) {
   ast::ExpressionList expr_list;
   for (uint32_t i = 0; i < count; ++i) {
     // Offset read position by element_stride for each component
-    auto cur_pos = create<ast::BinaryExpression>(ast::BinaryOp::kAdd,
-                                                 CreatePullingPositionIdent(),
-                                                 GenUint(element_stride * i));
+    auto* cur_pos = create<ast::BinaryExpression>(ast::BinaryOp::kAdd,
+                                                  CreatePullingPositionIdent(),
+                                                  GenUint(element_stride * i));
     expr_list.push_back(
         AccessPrimitive(buffer, std::move(cur_pos), base_format));
   }
diff --git a/src/transform/vertex_pulling_transform.h b/src/transform/vertex_pulling_transform.h
index 16eace9..b92219d 100644
--- a/src/transform/vertex_pulling_transform.h
+++ b/src/transform/vertex_pulling_transform.h
@@ -189,49 +189,41 @@
 
   /// Generates an expression holding a constant uint
   /// @param value uint value
-  std::unique_ptr<ast::Expression> GenUint(uint32_t value);
+  ast::Expression* GenUint(uint32_t value);
 
   /// Generates an expression to read the shader value |kPullingPosVarName|
-  std::unique_ptr<ast::Expression> CreatePullingPositionIdent();
+  ast::Expression* CreatePullingPositionIdent();
 
   /// Generates an expression reading from a buffer a specific format.
   /// This reads the value wherever |kPullingPosVarName| points to at the time
   /// of the read.
   /// @param buffer the index of the vertex buffer
   /// @param format the format to read
-  std::unique_ptr<ast::Expression> AccessByFormat(uint32_t buffer,
-                                                  VertexFormat format);
+  ast::Expression* AccessByFormat(uint32_t buffer, VertexFormat format);
 
   /// Generates an expression reading a uint32 from a vertex buffer
   /// @param buffer the index of the vertex buffer
   /// @param pos an expression for the position of the access, in bytes
-  std::unique_ptr<ast::Expression> AccessU32(
-      uint32_t buffer,
-      std::unique_ptr<ast::Expression> pos);
+  ast::Expression* AccessU32(uint32_t buffer, ast::Expression* pos);
 
   /// Generates an expression reading an int32 from a vertex buffer
   /// @param buffer the index of the vertex buffer
   /// @param pos an expression for the position of the access, in bytes
-  std::unique_ptr<ast::Expression> AccessI32(
-      uint32_t buffer,
-      std::unique_ptr<ast::Expression> pos);
+  ast::Expression* AccessI32(uint32_t buffer, ast::Expression* pos);
 
   /// Generates an expression reading a float from a vertex buffer
   /// @param buffer the index of the vertex buffer
   /// @param pos an expression for the position of the access, in bytes
-  std::unique_ptr<ast::Expression> AccessF32(
-      uint32_t buffer,
-      std::unique_ptr<ast::Expression> pos);
+  ast::Expression* AccessF32(uint32_t buffer, ast::Expression* pos);
 
   /// Generates an expression reading a basic type (u32, i32, f32) from a vertex
   /// buffer
   /// @param buffer the index of the vertex buffer
   /// @param pos an expression for the position of the access, in bytes
   /// @param format the underlying vertex format
-  std::unique_ptr<ast::Expression> AccessPrimitive(
-      uint32_t buffer,
-      std::unique_ptr<ast::Expression> pos,
-      VertexFormat format);
+  ast::Expression* AccessPrimitive(uint32_t buffer,
+                                   ast::Expression* pos,
+                                   VertexFormat format);
 
   /// Generates an expression reading a vec2/3/4 from a vertex buffer.
   /// This reads the value wherever |kPullingPosVarName| points to at the time
@@ -241,11 +233,11 @@
   /// @param base_type underlying AST type
   /// @param base_format underlying vertex format
   /// @param count how many elements the vector has
-  std::unique_ptr<ast::Expression> AccessVec(uint32_t buffer,
-                                             uint32_t element_stride,
-                                             ast::type::Type* base_type,
-                                             VertexFormat base_format,
-                                             uint32_t count);
+  ast::Expression* AccessVec(uint32_t buffer,
+                             uint32_t element_stride,
+                             ast::type::Type* base_type,
+                             VertexFormat base_format,
+                             uint32_t count);
 
   // Used to grab corresponding types from the type manager
   ast::type::Type* GetU32Type();
diff --git a/src/transform/vertex_pulling_transform_test.cc b/src/transform/vertex_pulling_transform_test.cc
index 25e731d..8f9b3b6 100644
--- a/src/transform/vertex_pulling_transform_test.cc
+++ b/src/transform/vertex_pulling_transform_test.cc
@@ -35,18 +35,18 @@
 class VertexPullingTransformHelper {
  public:
   VertexPullingTransformHelper() {
-    mod_ = create<ast::Module>();
+    mod_ = std::make_unique<ast::Module>();
     transform_ = std::make_unique<VertexPullingTransform>(&ctx_, mod_.get());
   }
 
   // Create basic module with an entry point and vertex function
   void InitBasicModule() {
-    auto func = create<ast::Function>(
+    auto* func = create<ast::Function>(
         "main", ast::VariableList{},
         ctx_.type_mgr().Get(std::make_unique<ast::type::VoidType>()),
         create<ast::BlockStatement>());
     func->add_decoration(
-        create<ast::StageDecoration>(ast::PipelineStage ::kVertex, Source{}));
+        create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
     mod()->AddFunction(std::move(func));
   }
 
@@ -66,7 +66,7 @@
   void AddVertexInputVariable(uint32_t location,
                               std::string name,
                               ast::type::Type* type) {
-    auto var = create<ast::DecoratedVariable>(
+    auto* var = create<ast::DecoratedVariable>(
         create<ast::Variable>(name, ast::StorageClass::kInput, type));
 
     ast::VariableDecorationList decorations;
@@ -80,11 +80,13 @@
   ast::Module* mod() { return mod_.get(); }
   VertexPullingTransform* transform() { return transform_.get(); }
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx_.create<T>(std::forward<ARGS>(args)...);
   }
 
  private:
@@ -117,7 +119,7 @@
 }
 
 TEST_F(VertexPullingTransformTest, Error_EntryPointWrongStage) {
-  auto func = create<ast::Function>(
+  auto* func = create<ast::Function>(
       "main", ast::VariableList{},
       ctx()->type_mgr().Get(std::make_unique<ast::type::VoidType>()),
       create<ast::BlockStatement>());
@@ -400,7 +402,7 @@
 
   ast::type::I32Type i32;
   {
-    auto vertex_index_var =
+    auto* vertex_index_var =
         create<ast::DecoratedVariable>(create<ast::Variable>(
             "custom_vertex_index", ast::StorageClass::kInput, &i32));
 
@@ -413,7 +415,7 @@
   }
 
   {
-    auto instance_index_var =
+    auto* instance_index_var =
         create<ast::DecoratedVariable>(create<ast::Variable>(
             "custom_instance_index", ast::StorageClass::kInput, &i32));
 
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index 6b5e673..a4d2382 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -95,8 +95,8 @@
     }
   }
 
-  for (const auto& var : mod_->global_variables()) {
-    variable_stack_.set_global(var->name(), var.get());
+  for (auto* var : mod_->global_variables()) {
+    variable_stack_.set_global(var->name(), var);
 
     if (var->has_constructor()) {
       if (!DetermineResultType(var->constructor())) {
@@ -111,7 +111,7 @@
 
   // Walk over the caller to callee information and update functions with which
   // entry points call those functions.
-  for (const auto& func : mod_->functions()) {
+  for (auto* func : mod_->functions()) {
     if (!func->IsEntryPoint()) {
       continue;
     }
@@ -133,8 +133,8 @@
 }
 
 bool TypeDeterminer::DetermineFunctions(const ast::FunctionList& funcs) {
-  for (const auto& func : funcs) {
-    if (!DetermineFunction(func.get())) {
+  for (auto* func : funcs) {
+    if (!DetermineFunction(func)) {
       return false;
     }
   }
@@ -147,8 +147,8 @@
   current_function_ = func;
 
   variable_stack_.push_scope();
-  for (const auto& param : func->params()) {
-    variable_stack_.set(param->name(), param.get());
+  for (auto* param : func->params()) {
+    variable_stack_.set(param->name(), param);
   }
 
   if (!DetermineStatements(func->body())) {
@@ -162,12 +162,12 @@
 }
 
 bool TypeDeterminer::DetermineStatements(const ast::BlockStatement* stmts) {
-  for (const auto& stmt : *stmts) {
-    if (!DetermineVariableStorageClass(stmt.get())) {
+  for (auto* stmt : *stmts) {
+    if (!DetermineVariableStorageClass(stmt)) {
       return false;
     }
 
-    if (!DetermineResultType(stmt.get())) {
+    if (!DetermineResultType(stmt)) {
       return false;
     }
   }
@@ -238,8 +238,8 @@
       return false;
     }
 
-    for (const auto& else_stmt : i->else_statements()) {
-      if (!DetermineResultType(else_stmt.get())) {
+    for (auto* else_stmt : i->else_statements()) {
+      if (!DetermineResultType(else_stmt)) {
         return false;
       }
     }
@@ -259,8 +259,8 @@
     if (!DetermineResultType(s->condition())) {
       return false;
     }
-    for (const auto& case_stmt : s->body()) {
-      if (!DetermineResultType(case_stmt.get())) {
+    for (auto* case_stmt : s->body()) {
+      if (!DetermineResultType(case_stmt)) {
         return false;
       }
     }
@@ -278,8 +278,8 @@
 }
 
 bool TypeDeterminer::DetermineResultType(const ast::ExpressionList& list) {
-  for (const auto& expr : list) {
-    if (!DetermineResultType(expr.get())) {
+  for (auto* expr : list) {
+    if (!DetermineResultType(expr)) {
       return false;
     }
   }
@@ -573,7 +573,7 @@
       return true;
     }
 
-    auto& texture_param = expr->params()[0];
+    auto* texture_param = expr->params()[0];
     if (!texture_param->result_type()->UnwrapPtrIfNeeded()->IsTexture()) {
       set_error(expr->source(), "invalid first argument for " + ident->name());
       return false;
@@ -748,8 +748,8 @@
 bool TypeDeterminer::DetermineConstructor(ast::ConstructorExpression* expr) {
   if (expr->IsTypeConstructor()) {
     auto* ty = expr->AsTypeConstructor();
-    for (const auto& value : ty->values()) {
-      if (!DetermineResultType(value.get())) {
+    for (auto* value : ty->values()) {
+      if (!DetermineResultType(value)) {
         return false;
       }
     }
@@ -949,7 +949,7 @@
     auto* strct = data_type->AsStruct()->impl();
     auto name = expr->member()->name();
 
-    for (const auto& member : strct->members()) {
+    for (auto* member : strct->members()) {
       if (member->name() == name) {
         ret = member->type();
         break;
diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc
index 089a14c..ec0535e 100644
--- a/src/type_determiner_test.cc
+++ b/src/type_determiner_test.cc
@@ -88,11 +88,13 @@
   ast::Module* mod() { return &mod_; }
   Context* ctx() { return &ctx_; }
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx_.create<T>(std::forward<ARGS>(args)...);
   }
 
  private:
@@ -129,13 +131,13 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* lhs_ptr = lhs.get();
+  auto* lhs_ptr = lhs;
 
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.3f));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
 
@@ -151,15 +153,15 @@
   ast::type::I32Type i32;
   ast::type::F32Type f32;
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* lhs_ptr = lhs.get();
+  auto* lhs_ptr = lhs;
 
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.3f));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::AssignmentStatement>(std::move(lhs), std::move(rhs)));
 
@@ -178,13 +180,13 @@
   ast::type::I32Type i32;
   ast::type::F32Type f32;
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* lhs_ptr = lhs.get();
+  auto* lhs_ptr = lhs;
 
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.3f));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
   ast::BlockStatement block;
   block.append(
@@ -201,15 +203,15 @@
   ast::type::I32Type i32;
   ast::type::F32Type f32;
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* lhs_ptr = lhs.get();
+  auto* lhs_ptr = lhs;
 
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.3f));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::AssignmentStatement>(std::move(lhs), std::move(rhs)));
 
@@ -230,19 +232,19 @@
   ast::type::I32Type i32;
   ast::type::F32Type f32;
 
-  auto else_lhs = create<ast::ScalarConstructorExpression>(
+  auto* else_lhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* else_lhs_ptr = else_lhs.get();
+  auto* else_lhs_ptr = else_lhs;
 
-  auto else_rhs = create<ast::ScalarConstructorExpression>(
+  auto* else_rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.3f));
-  auto* else_rhs_ptr = else_rhs.get();
+  auto* else_rhs_ptr = else_rhs;
 
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(create<ast::AssignmentStatement>(std::move(else_lhs),
                                                      std::move(else_rhs)));
 
-  auto else_stmt =
+  auto* else_stmt =
       create<ast::ElseStatement>(create<ast::ScalarConstructorExpression>(
                                      create<ast::SintLiteral>(&i32, 3)),
                                  std::move(else_body));
@@ -250,15 +252,15 @@
   ast::ElseStatementList else_stmts;
   else_stmts.push_back(std::move(else_stmt));
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* lhs_ptr = lhs.get();
+  auto* lhs_ptr = lhs;
 
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.3f));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::AssignmentStatement>(std::move(lhs), std::move(rhs)));
 
@@ -284,27 +286,27 @@
   ast::type::I32Type i32;
   ast::type::F32Type f32;
 
-  auto body_lhs = create<ast::ScalarConstructorExpression>(
+  auto* body_lhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* body_lhs_ptr = body_lhs.get();
+  auto* body_lhs_ptr = body_lhs;
 
-  auto body_rhs = create<ast::ScalarConstructorExpression>(
+  auto* body_rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.3f));
-  auto* body_rhs_ptr = body_rhs.get();
+  auto* body_rhs_ptr = body_rhs;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(std::move(body_lhs),
                                                 std::move(body_rhs)));
 
-  auto continuing_lhs = create<ast::ScalarConstructorExpression>(
+  auto* continuing_lhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* continuing_lhs_ptr = continuing_lhs.get();
+  auto* continuing_lhs_ptr = continuing_lhs;
 
-  auto continuing_rhs = create<ast::ScalarConstructorExpression>(
+  auto* continuing_rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.3f));
-  auto* continuing_rhs_ptr = continuing_rhs.get();
+  auto* continuing_rhs_ptr = continuing_rhs;
 
-  auto continuing = create<ast::BlockStatement>();
+  auto* continuing = create<ast::BlockStatement>();
   continuing->append(create<ast::AssignmentStatement>(
       std::move(continuing_lhs), std::move(continuing_rhs)));
 
@@ -324,9 +326,9 @@
 TEST_F(TypeDeterminerTest, Stmt_Return) {
   ast::type::I32Type i32;
 
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* cond_ptr = cond.get();
+  auto* cond_ptr = cond;
 
   ast::ReturnStatement ret(std::move(cond));
 
@@ -345,15 +347,15 @@
   ast::type::I32Type i32;
   ast::type::F32Type f32;
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* lhs_ptr = lhs.get();
+  auto* lhs_ptr = lhs;
 
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.3f));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::AssignmentStatement>(std::move(lhs), std::move(rhs)));
 
@@ -381,17 +383,17 @@
   ast::type::F32Type f32;
 
   ast::VariableList params;
-  auto func = create<ast::Function>("my_func", std::move(params), &f32,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("my_func", std::move(params), &f32,
+                                     create<ast::BlockStatement>());
   mod()->AddFunction(std::move(func));
 
   // Register the function
   EXPECT_TRUE(td()->Determine());
 
   ast::ExpressionList call_params;
-  auto expr = create<ast::CallExpression>(
+  auto* expr = create<ast::CallExpression>(
       create<ast::IdentifierExpression>("my_func"), std::move(call_params));
-  auto* expr_ptr = expr.get();
+  auto* expr_ptr = expr;
 
   ast::CallStatement call(std::move(expr));
   EXPECT_TRUE(td()->DetermineResultType(&call));
@@ -404,21 +406,21 @@
   // fn func() -> void { return; }
   ast::type::F32Type f32;
   ast::ExpressionList call_params;
-  auto call_expr =
+  auto* call_expr =
       create<ast::CallExpression>(create<ast::IdentifierExpression>(
                                       Source{Source::Location{12, 34}}, "func"),
                                   std::move(call_params));
   ast::VariableList params0;
-  auto main_body = create<ast::BlockStatement>();
+  auto* main_body = create<ast::BlockStatement>();
   main_body->append(create<ast::CallStatement>(std::move(call_expr)));
   main_body->append(create<ast::ReturnStatement>());
-  auto func_main = create<ast::Function>("main", std::move(params0), &f32,
-                                         std::move(main_body));
+  auto* func_main = create<ast::Function>("main", std::move(params0), &f32,
+                                          std::move(main_body));
   mod()->AddFunction(std::move(func_main));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func =
+  auto* func =
       create<ast::Function>("func", std::move(params0), &f32, std::move(body));
   mod()->AddFunction(std::move(func));
 
@@ -429,7 +431,7 @@
 
 TEST_F(TypeDeterminerTest, Stmt_VariableDecl) {
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
   auto* init_ptr = var->constructor();
@@ -443,7 +445,7 @@
 
 TEST_F(TypeDeterminerTest, Stmt_VariableDecl_ModuleScope) {
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
   auto* init_ptr = var->constructor();
@@ -468,9 +470,9 @@
   ast::type::F32Type f32;
   ast::type::ArrayType ary(&f32, 3);
 
-  auto idx = create<ast::ScalarConstructorExpression>(
+  auto* idx = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto var =
+  auto* var =
       create<ast::Variable>("my_var", ast::StorageClass::kFunction, &ary);
   mod()->AddGlobalVariable(std::move(var));
 
@@ -493,9 +495,9 @@
   ast::type::ArrayType ary(&f32, 3);
   ast::type::AliasType aary("myarrty", &ary);
 
-  auto idx = create<ast::ScalarConstructorExpression>(
+  auto* idx = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto var =
+  auto* var =
       create<ast::Variable>("my_var", ast::StorageClass::kFunction, &aary);
   mod()->AddGlobalVariable(std::move(var));
 
@@ -517,9 +519,9 @@
   ast::type::F32Type f32;
   ast::type::ArrayType ary(&f32, 3);
 
-  auto idx = create<ast::ScalarConstructorExpression>(
+  auto* idx = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto var =
+  auto* var =
       create<ast::Variable>("my_var", ast::StorageClass::kFunction, &ary);
   var->set_is_const(true);
   mod()->AddGlobalVariable(std::move(var));
@@ -539,9 +541,9 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat(&f32, 3, 2);
 
-  auto idx = create<ast::ScalarConstructorExpression>(
+  auto* idx = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &mat);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &mat);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -563,11 +565,11 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat(&f32, 3, 2);
 
-  auto idx1 = create<ast::ScalarConstructorExpression>(
+  auto* idx1 = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto idx2 = create<ast::ScalarConstructorExpression>(
+  auto* idx2 = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1));
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &mat);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &mat);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -591,9 +593,9 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec(&f32, 3);
 
-  auto idx = create<ast::ScalarConstructorExpression>(
+  auto* idx = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &vec);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &vec);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -626,8 +628,8 @@
   ast::type::F32Type f32;
 
   ast::VariableList params;
-  auto func = create<ast::Function>("my_func", std::move(params), &f32,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("my_func", std::move(params), &f32,
+                                     create<ast::BlockStatement>());
   mod()->AddFunction(std::move(func));
 
   // Register the function
@@ -645,8 +647,8 @@
   ast::type::F32Type f32;
 
   ast::VariableList params;
-  auto func = create<ast::Function>("my_func", std::move(params), &f32,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("my_func", std::move(params), &f32,
+                                     create<ast::BlockStatement>());
   mod()->AddFunction(std::move(func));
 
   // Register the function
@@ -656,7 +658,7 @@
   call_params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.4)));
 
-  auto* param_ptr = call_params.back().get();
+  auto* param_ptr = call_params.back();
 
   ast::CallExpression call(create<ast::IdentifierExpression>("my_func"),
                            std::move(call_params));
@@ -730,7 +732,7 @@
 
 TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalVariable) {
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -745,7 +747,7 @@
 
 TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalConstant) {
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
   var->set_is_const(true);
   mod()->AddGlobalVariable(std::move(var));
 
@@ -761,13 +763,13 @@
 TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable_Const) {
   ast::type::F32Type f32;
 
-  auto my_var = create<ast::IdentifierExpression>("my_var");
-  auto* my_var_ptr = my_var.get();
+  auto* my_var = create<ast::IdentifierExpression>("my_var");
+  auto* my_var_ptr = my_var;
 
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
   var->set_is_const(true);
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::AssignmentStatement>(
       std::move(my_var), create<ast::IdentifierExpression>("my_var")));
@@ -783,10 +785,10 @@
 TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable) {
   ast::type::F32Type f32;
 
-  auto my_var = create<ast::IdentifierExpression>("my_var");
-  auto* my_var_ptr = my_var.get();
+  auto* my_var = create<ast::IdentifierExpression>("my_var");
+  auto* my_var_ptr = my_var;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(
       create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32)));
 
@@ -806,10 +808,10 @@
   ast::type::F32Type f32;
   ast::type::PointerType ptr(&f32, ast::StorageClass::kFunction);
 
-  auto my_var = create<ast::IdentifierExpression>("my_var");
-  auto* my_var_ptr = my_var.get();
+  auto* my_var = create<ast::IdentifierExpression>("my_var");
+  auto* my_var_ptr = my_var;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(
       create<ast::Variable>("my_var", ast::StorageClass::kNone, &ptr)));
 
@@ -829,8 +831,8 @@
   ast::type::F32Type f32;
 
   ast::VariableList params;
-  auto func = create<ast::Function>("my_func", std::move(params), &f32,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("my_func", std::move(params), &f32,
+                                     create<ast::BlockStatement>());
   mod()->AddFunction(std::move(func));
 
   // Register the function
@@ -850,22 +852,22 @@
 TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables) {
   ast::type::F32Type f32;
 
-  auto in_var =
+  auto* in_var =
       create<ast::Variable>("in_var", ast::StorageClass::kInput, &f32);
-  auto out_var =
+  auto* out_var =
       create<ast::Variable>("out_var", ast::StorageClass::kOutput, &f32);
-  auto sb_var =
+  auto* sb_var =
       create<ast::Variable>("sb_var", ast::StorageClass::kStorageBuffer, &f32);
-  auto wg_var =
+  auto* wg_var =
       create<ast::Variable>("wg_var", ast::StorageClass::kWorkgroup, &f32);
-  auto priv_var =
+  auto* priv_var =
       create<ast::Variable>("priv_var", ast::StorageClass::kPrivate, &f32);
 
-  auto* in_ptr = in_var.get();
-  auto* out_ptr = out_var.get();
-  auto* sb_ptr = sb_var.get();
-  auto* wg_ptr = wg_var.get();
-  auto* priv_ptr = priv_var.get();
+  auto* in_ptr = in_var;
+  auto* out_ptr = out_var;
+  auto* sb_ptr = sb_var;
+  auto* wg_ptr = wg_var;
+  auto* priv_ptr = priv_var;
 
   mod()->AddGlobalVariable(std::move(in_var));
   mod()->AddGlobalVariable(std::move(out_var));
@@ -874,7 +876,7 @@
   mod()->AddGlobalVariable(std::move(priv_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("out_var"),
       create<ast::IdentifierExpression>("in_var")));
@@ -887,9 +889,9 @@
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("priv_var"),
       create<ast::IdentifierExpression>("priv_var")));
-  auto func = create<ast::Function>("my_func", std::move(params), &f32,
-                                    std::move(body));
-  auto* func_ptr = func.get();
+  auto* func = create<ast::Function>("my_func", std::move(params), &f32,
+                                     std::move(body));
+  auto* func_ptr = func;
 
   mod()->AddFunction(std::move(func));
 
@@ -908,22 +910,22 @@
 TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables_SubFunction) {
   ast::type::F32Type f32;
 
-  auto in_var =
+  auto* in_var =
       create<ast::Variable>("in_var", ast::StorageClass::kInput, &f32);
-  auto out_var =
+  auto* out_var =
       create<ast::Variable>("out_var", ast::StorageClass::kOutput, &f32);
-  auto sb_var =
+  auto* sb_var =
       create<ast::Variable>("sb_var", ast::StorageClass::kStorageBuffer, &f32);
-  auto wg_var =
+  auto* wg_var =
       create<ast::Variable>("wg_var", ast::StorageClass::kWorkgroup, &f32);
-  auto priv_var =
+  auto* priv_var =
       create<ast::Variable>("priv_var", ast::StorageClass::kPrivate, &f32);
 
-  auto* in_ptr = in_var.get();
-  auto* out_ptr = out_var.get();
-  auto* sb_ptr = sb_var.get();
-  auto* wg_ptr = wg_var.get();
-  auto* priv_ptr = priv_var.get();
+  auto* in_ptr = in_var;
+  auto* out_ptr = out_var;
+  auto* sb_ptr = sb_var;
+  auto* wg_ptr = wg_var;
+  auto* priv_ptr = priv_var;
 
   mod()->AddGlobalVariable(std::move(in_var));
   mod()->AddGlobalVariable(std::move(out_var));
@@ -931,7 +933,7 @@
   mod()->AddGlobalVariable(std::move(wg_var));
   mod()->AddGlobalVariable(std::move(priv_var));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("out_var"),
       create<ast::IdentifierExpression>("in_var")));
@@ -945,8 +947,8 @@
       create<ast::IdentifierExpression>("priv_var"),
       create<ast::IdentifierExpression>("priv_var")));
   ast::VariableList params;
-  auto func = create<ast::Function>("my_func", std::move(params), &f32,
-                                    std::move(body));
+  auto* func = create<ast::Function>("my_func", std::move(params), &f32,
+                                     std::move(body));
 
   mod()->AddFunction(std::move(func));
 
@@ -955,9 +957,9 @@
       create<ast::IdentifierExpression>("out_var"),
       create<ast::CallExpression>(create<ast::IdentifierExpression>("my_func"),
                                   ast::ExpressionList{})));
-  auto func2 =
+  auto* func2 =
       create<ast::Function>("func", std::move(params), &f32, std::move(body));
-  auto* func2_ptr = func2.get();
+  auto* func2_ptr = func2;
 
   mod()->AddFunction(std::move(func2));
 
@@ -976,10 +978,10 @@
 TEST_F(TypeDeterminerTest, Function_NotRegisterFunctionVariable) {
   ast::type::F32Type f32;
 
-  auto var =
+  auto* var =
       create<ast::Variable>("in_var", ast::StorageClass::kFunction, &f32);
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("var"),
@@ -987,9 +989,9 @@
           create<ast::FloatLiteral>(&f32, 1.f))));
 
   ast::VariableList params;
-  auto func = create<ast::Function>("my_func", std::move(params), &f32,
-                                    std::move(body));
-  auto* func_ptr = func.get();
+  auto* func = create<ast::Function>("my_func", std::move(params), &f32,
+                                     std::move(body));
+  auto* func_ptr = func;
 
   mod()->AddFunction(std::move(func));
 
@@ -1013,19 +1015,19 @@
   members.push_back(
       create<ast::StructMember>("second_member", &f32, std::move(decos)));
 
-  auto strct = create<ast::Struct>(std::move(members));
+  auto* strct = create<ast::Struct>(std::move(members));
 
   ast::type::StructType st("S", std::move(strct));
 
-  auto var = create<ast::Variable>("my_struct", ast::StorageClass::kNone, &st);
+  auto* var = create<ast::Variable>("my_struct", ast::StorageClass::kNone, &st);
 
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
   EXPECT_TRUE(td()->Determine());
 
-  auto ident = create<ast::IdentifierExpression>("my_struct");
-  auto mem_ident = create<ast::IdentifierExpression>("second_member");
+  auto* ident = create<ast::IdentifierExpression>("my_struct");
+  auto* mem_ident = create<ast::IdentifierExpression>("second_member");
 
   ast::MemberAccessorExpression mem(std::move(ident), std::move(mem_ident));
   EXPECT_TRUE(td()->DetermineResultType(&mem));
@@ -1047,12 +1049,12 @@
   members.push_back(
       create<ast::StructMember>("second_member", &f32, std::move(decos)));
 
-  auto strct = create<ast::Struct>(std::move(members));
+  auto* strct = create<ast::Struct>(std::move(members));
 
   auto st = std::make_unique<ast::type::StructType>("alias", std::move(strct));
   ast::type::AliasType alias("alias", st.get());
 
-  auto var =
+  auto* var =
       create<ast::Variable>("my_struct", ast::StorageClass::kNone, &alias);
 
   mod()->AddGlobalVariable(std::move(var));
@@ -1060,8 +1062,8 @@
   // Register the global
   EXPECT_TRUE(td()->Determine());
 
-  auto ident = create<ast::IdentifierExpression>("my_struct");
-  auto mem_ident = create<ast::IdentifierExpression>("second_member");
+  auto* ident = create<ast::IdentifierExpression>("my_struct");
+  auto* mem_ident = create<ast::IdentifierExpression>("second_member");
 
   ast::MemberAccessorExpression mem(std::move(ident), std::move(mem_ident));
   EXPECT_TRUE(td()->DetermineResultType(&mem));
@@ -1076,14 +1078,14 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec3(&f32, 3);
 
-  auto var = create<ast::Variable>("my_vec", ast::StorageClass::kNone, &vec3);
+  auto* var = create<ast::Variable>("my_vec", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
   EXPECT_TRUE(td()->Determine());
 
-  auto ident = create<ast::IdentifierExpression>("my_vec");
-  auto swizzle = create<ast::IdentifierExpression>("xy");
+  auto* ident = create<ast::IdentifierExpression>("my_vec");
+  auto* swizzle = create<ast::IdentifierExpression>("xy");
 
   ast::MemberAccessorExpression mem(std::move(ident), std::move(swizzle));
   EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
@@ -1097,14 +1099,14 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec3(&f32, 3);
 
-  auto var = create<ast::Variable>("my_vec", ast::StorageClass::kNone, &vec3);
+  auto* var = create<ast::Variable>("my_vec", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
   EXPECT_TRUE(td()->Determine());
 
-  auto ident = create<ast::IdentifierExpression>("my_vec");
-  auto swizzle = create<ast::IdentifierExpression>("x");
+  auto* ident = create<ast::IdentifierExpression>("my_vec");
+  auto* swizzle = create<ast::IdentifierExpression>("x");
 
   ast::MemberAccessorExpression mem(std::move(ident), std::move(swizzle));
   EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
@@ -1150,7 +1152,7 @@
   b_members.push_back(
       create<ast::StructMember>("foo", &vec4, std::move(decos)));
 
-  auto strctB = create<ast::Struct>(std::move(b_members));
+  auto* strctB = create<ast::Struct>(std::move(b_members));
   ast::type::StructType stB("B", std::move(strctB));
 
   ast::type::VectorType vecB(&stB, 3);
@@ -1159,22 +1161,22 @@
   a_members.push_back(
       create<ast::StructMember>("mem", &vecB, std::move(decos)));
 
-  auto strctA = create<ast::Struct>(std::move(a_members));
+  auto* strctA = create<ast::Struct>(std::move(a_members));
 
   ast::type::StructType stA("A", std::move(strctA));
 
-  auto var = create<ast::Variable>("c", ast::StorageClass::kNone, &stA);
+  auto* var = create<ast::Variable>("c", ast::StorageClass::kNone, &stA);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
   EXPECT_TRUE(td()->Determine());
 
-  auto ident = create<ast::IdentifierExpression>("c");
-  auto mem_ident = create<ast::IdentifierExpression>("mem");
-  auto foo_ident = create<ast::IdentifierExpression>("foo");
-  auto idx = create<ast::ScalarConstructorExpression>(
+  auto* ident = create<ast::IdentifierExpression>("c");
+  auto* mem_ident = create<ast::IdentifierExpression>("mem");
+  auto* foo_ident = create<ast::IdentifierExpression>("foo");
+  auto* idx = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 0));
-  auto swizzle = create<ast::IdentifierExpression>("yx");
+  auto* swizzle = create<ast::IdentifierExpression>("yx");
 
   ast::MemberAccessorExpression mem(
       create<ast::MemberAccessorExpression>(
@@ -1198,7 +1200,7 @@
 
   ast::type::I32Type i32;
 
-  auto var = create<ast::Variable>("val", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("val", ast::StorageClass::kNone, &i32);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -1218,7 +1220,7 @@
   ast::type::I32Type i32;
   ast::type::VectorType vec3(&i32, 3);
 
-  auto var = create<ast::Variable>("val", ast::StorageClass::kNone, &vec3);
+  auto* var = create<ast::Variable>("val", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -1251,7 +1253,8 @@
 
   ast::type::BoolType bool_type;
 
-  auto var = create<ast::Variable>("val", ast::StorageClass::kNone, &bool_type);
+  auto* var =
+      create<ast::Variable>("val", ast::StorageClass::kNone, &bool_type);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -1271,7 +1274,7 @@
   ast::type::BoolType bool_type;
   ast::type::VectorType vec3(&bool_type, 3);
 
-  auto var = create<ast::Variable>("val", ast::StorageClass::kNone, &vec3);
+  auto* var = create<ast::Variable>("val", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -1297,7 +1300,7 @@
 
   ast::type::I32Type i32;
 
-  auto var = create<ast::Variable>("val", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("val", ast::StorageClass::kNone, &i32);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -1317,7 +1320,7 @@
   ast::type::I32Type i32;
   ast::type::VectorType vec3(&i32, 3);
 
-  auto var = create<ast::Variable>("val", ast::StorageClass::kNone, &vec3);
+  auto* var = create<ast::Variable>("val", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -1344,7 +1347,7 @@
 TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Scalar) {
   ast::type::I32Type i32;
 
-  auto var = create<ast::Variable>("val", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("val", ast::StorageClass::kNone, &i32);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -1363,8 +1366,9 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec3(&f32, 3);
 
-  auto scalar = create<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
-  auto vector =
+  auto* scalar =
+      create<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
+  auto* vector =
       create<ast::Variable>("vector", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(scalar));
   mod()->AddGlobalVariable(std::move(vector));
@@ -1387,8 +1391,9 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec3(&f32, 3);
 
-  auto scalar = create<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
-  auto vector =
+  auto* scalar =
+      create<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
+  auto* vector =
       create<ast::Variable>("vector", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(scalar));
   mod()->AddGlobalVariable(std::move(vector));
@@ -1411,7 +1416,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec3(&f32, 3);
 
-  auto vector =
+  auto* vector =
       create<ast::Variable>("vector", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(vector));
 
@@ -1433,8 +1438,9 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat3x2(&f32, 3, 2);
 
-  auto scalar = create<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
-  auto matrix =
+  auto* scalar =
+      create<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
+  auto* matrix =
       create<ast::Variable>("matrix", ast::StorageClass::kNone, &mat3x2);
   mod()->AddGlobalVariable(std::move(scalar));
   mod()->AddGlobalVariable(std::move(matrix));
@@ -1460,8 +1466,9 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat3x2(&f32, 3, 2);
 
-  auto scalar = create<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
-  auto matrix =
+  auto* scalar =
+      create<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
+  auto* matrix =
       create<ast::Variable>("matrix", ast::StorageClass::kNone, &mat3x2);
   mod()->AddGlobalVariable(std::move(scalar));
   mod()->AddGlobalVariable(std::move(matrix));
@@ -1488,9 +1495,9 @@
   ast::type::VectorType vec3(&f32, 2);
   ast::type::MatrixType mat3x2(&f32, 3, 2);
 
-  auto vector =
+  auto* vector =
       create<ast::Variable>("vector", ast::StorageClass::kNone, &vec3);
-  auto matrix =
+  auto* matrix =
       create<ast::Variable>("matrix", ast::StorageClass::kNone, &mat3x2);
   mod()->AddGlobalVariable(std::move(vector));
   mod()->AddGlobalVariable(std::move(matrix));
@@ -1514,9 +1521,9 @@
   ast::type::VectorType vec3(&f32, 3);
   ast::type::MatrixType mat3x2(&f32, 3, 2);
 
-  auto vector =
+  auto* vector =
       create<ast::Variable>("vector", ast::StorageClass::kNone, &vec3);
-  auto matrix =
+  auto* matrix =
       create<ast::Variable>("matrix", ast::StorageClass::kNone, &mat3x2);
   mod()->AddGlobalVariable(std::move(vector));
   mod()->AddGlobalVariable(std::move(matrix));
@@ -1540,9 +1547,9 @@
   ast::type::MatrixType mat4x3(&f32, 4, 3);
   ast::type::MatrixType mat3x4(&f32, 3, 4);
 
-  auto matrix1 =
+  auto* matrix1 =
       create<ast::Variable>("mat4x3", ast::StorageClass::kNone, &mat4x3);
-  auto matrix2 =
+  auto* matrix2 =
       create<ast::Variable>("mat3x4", ast::StorageClass::kNone, &mat3x4);
   mod()->AddGlobalVariable(std::move(matrix1));
   mod()->AddGlobalVariable(std::move(matrix2));
@@ -1570,7 +1577,7 @@
 
   ast::type::F32Type f32;
 
-  auto var = create<ast::Variable>("ident", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("ident", ast::StorageClass::kNone, &f32);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -1593,7 +1600,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto var = create<ast::Variable>("ident", ast::StorageClass::kNone, &vec4);
+  auto* var = create<ast::Variable>("ident", ast::StorageClass::kNone, &vec4);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -1634,8 +1641,8 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto var1 = create<ast::Variable>("ident1", ast::StorageClass::kNone, &vec4);
-  auto var2 = create<ast::Variable>("ident2", ast::StorageClass::kNone, &vec4);
+  auto* var1 = create<ast::Variable>("ident1", ast::StorageClass::kNone, &vec4);
+  auto* var2 = create<ast::Variable>("ident2", ast::StorageClass::kNone, &vec4);
   mod()->AddGlobalVariable(std::move(var1));
   mod()->AddGlobalVariable(std::move(var2));
 
@@ -1670,7 +1677,7 @@
   ast::type::BoolType bool_type;
   ast::type::VectorType vec3(&bool_type, 3);
 
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &vec3);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(var));
 
   ast::ExpressionList call_params;
@@ -1697,7 +1704,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec3(&f32, 3);
 
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &vec3);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(var));
 
   ast::ExpressionList call_params;
@@ -1721,7 +1728,7 @@
 
   ast::type::F32Type f32;
 
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
   mod()->AddGlobalVariable(std::move(var));
 
   ast::ExpressionList call_params;
@@ -1742,7 +1749,7 @@
 
   ast::type::F32Type f32;
 
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
   mod()->AddGlobalVariable(std::move(var));
 
   ast::ExpressionList call_params;
@@ -1760,7 +1767,7 @@
 
   ast::type::F32Type f32;
 
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
   mod()->AddGlobalVariable(std::move(var));
 
   ast::ExpressionList call_params;
@@ -1829,7 +1836,7 @@
   void add_call_param(std::string name,
                       ast::type::Type* type,
                       ast::ExpressionList* call_params) {
-    auto var = create<ast::Variable>(name, ast::StorageClass::kNone, type);
+    auto* var = create<ast::Variable>(name, ast::StorageClass::kNone, type);
     mod()->AddGlobalVariable(std::move(var));
     call_params->push_back(create<ast::IdentifierExpression>(name));
   }
@@ -2143,7 +2150,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec3(&f32, 3);
 
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &vec3);
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(var));
 
   ast::ExpressionList call_params;
@@ -2166,8 +2173,8 @@
   ast::type::VectorType vec3(&f32, 3);
   ast::type::VectorType bool_vec3(&bool_type, 3);
 
-  auto var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &vec3);
-  auto bool_var =
+  auto* var = create<ast::Variable>("my_var", ast::StorageClass::kNone, &vec3);
+  auto* bool_var =
       create<ast::Variable>("bool_var", ast::StorageClass::kNone, &bool_vec3);
   mod()->AddGlobalVariable(std::move(var));
   mod()->AddGlobalVariable(std::move(bool_var));
@@ -2193,7 +2200,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec3(&f32, 3);
 
-  auto var = create<ast::Variable>("v", ast::StorageClass::kNone, &vec3);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(var));
 
   ast::ExpressionList call_params;
@@ -2213,7 +2220,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec3(&f32, 3);
 
-  auto var = create<ast::Variable>("v", ast::StorageClass::kNone, &vec3);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kNone, &vec3);
   mod()->AddGlobalVariable(std::move(var));
 
   ast::ExpressionList call_params;
@@ -2237,8 +2244,8 @@
   ast::type::VectorType vec3(&f32, 3);
   ast::type::VectorType vec2(&f32, 2);
 
-  auto var1 = create<ast::Variable>("v3", ast::StorageClass::kNone, &vec3);
-  auto var2 = create<ast::Variable>("v2", ast::StorageClass::kNone, &vec2);
+  auto* var1 = create<ast::Variable>("v3", ast::StorageClass::kNone, &vec3);
+  auto* var2 = create<ast::Variable>("v2", ast::StorageClass::kNone, &vec2);
   mod()->AddGlobalVariable(std::move(var1));
   mod()->AddGlobalVariable(std::move(var2));
 
@@ -2267,7 +2274,7 @@
   ast::type::VectorType vec3(&f32, 3);
   ast::type::VectorType vec2(&f32, 2);
 
-  auto var2 = create<ast::Variable>("v2", ast::StorageClass::kNone, &vec2);
+  auto* var2 = create<ast::Variable>("v2", ast::StorageClass::kNone, &vec2);
   mod()->AddGlobalVariable(std::move(var2));
 
   ast::ExpressionList call_params;
@@ -2287,7 +2294,7 @@
   ast::type::VectorType vec3(&f32, 3);
   ast::type::VectorType vec2(&f32, 2);
 
-  auto var2 = create<ast::Variable>("v2", ast::StorageClass::kNone, &vec2);
+  auto* var2 = create<ast::Variable>("v2", ast::StorageClass::kNone, &vec2);
   mod()->AddGlobalVariable(std::move(var2));
 
   ast::ExpressionList call_params;
@@ -2312,7 +2319,7 @@
 
   ast::type::VectorType vec4(&f32, 4);
 
-  auto var = create<ast::Variable>("ident", ast::StorageClass::kNone, &vec4);
+  auto* var = create<ast::Variable>("ident", ast::StorageClass::kNone, &vec4);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -2333,13 +2340,13 @@
 TEST_F(TypeDeterminerTest, StorageClass_SetsIfMissing) {
   ast::type::I32Type i32;
 
-  auto var = create<ast::Variable>("var", ast::StorageClass::kNone, &i32);
-  auto* var_ptr = var.get();
-  auto stmt = create<ast::VariableDeclStatement>(std::move(var));
+  auto* var = create<ast::Variable>("var", ast::StorageClass::kNone, &i32);
+  auto* var_ptr = var;
+  auto* stmt = create<ast::VariableDeclStatement>(std::move(var));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(std::move(stmt));
-  auto func =
+  auto* func =
       create<ast::Function>("func", ast::VariableList{}, &i32, std::move(body));
 
   mod()->AddFunction(std::move(func));
@@ -2351,14 +2358,14 @@
 TEST_F(TypeDeterminerTest, StorageClass_DoesNotSetOnConst) {
   ast::type::I32Type i32;
 
-  auto var = create<ast::Variable>("var", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("var", ast::StorageClass::kNone, &i32);
   var->set_is_const(true);
-  auto* var_ptr = var.get();
-  auto stmt = create<ast::VariableDeclStatement>(std::move(var));
+  auto* var_ptr = var;
+  auto* stmt = create<ast::VariableDeclStatement>(std::move(var));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(std::move(stmt));
-  auto func =
+  auto* func =
       create<ast::Function>("func", ast::VariableList{}, &i32, std::move(body));
 
   mod()->AddFunction(std::move(func));
@@ -2370,12 +2377,12 @@
 TEST_F(TypeDeterminerTest, StorageClass_NonFunctionClassError) {
   ast::type::I32Type i32;
 
-  auto var = create<ast::Variable>("var", ast::StorageClass::kWorkgroup, &i32);
-  auto stmt = create<ast::VariableDeclStatement>(std::move(var));
+  auto* var = create<ast::Variable>("var", ast::StorageClass::kWorkgroup, &i32);
+  auto* stmt = create<ast::VariableDeclStatement>(std::move(var));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(std::move(stmt));
-  auto func =
+  auto* func =
       create<ast::Function>("func", ast::VariableList{}, &i32, std::move(body));
 
   mod()->AddFunction(std::move(func));
@@ -2493,8 +2500,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -2520,8 +2527,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -2539,7 +2546,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -2553,7 +2560,7 @@
 
   ast::ExpressionList params;
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -2573,7 +2580,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -2618,8 +2625,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -2645,8 +2652,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -2664,8 +2671,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, -11)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -2691,8 +2698,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -2710,8 +2717,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 1)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -2737,8 +2744,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -2756,7 +2763,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, false)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -2770,7 +2777,7 @@
 
   ast::ExpressionList params;
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -2790,7 +2797,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -2812,8 +2819,8 @@
 
   ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
 
-  auto ident = create<ast::IdentifierExpression>("length");
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>("length");
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -2837,8 +2844,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals)));
 
-  auto ident = create<ast::IdentifierExpression>("length");
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>("length");
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -2853,7 +2860,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
 
-  auto ident = create<ast::IdentifierExpression>("length");
+  auto* ident = create<ast::IdentifierExpression>("length");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -2865,7 +2872,7 @@
 TEST_F(TypeDeterminerTest, ImportData_Length_Error_NoParams) {
   ast::ExpressionList params;
 
-  auto ident = create<ast::IdentifierExpression>("length");
+  auto* ident = create<ast::IdentifierExpression>("length");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -2883,7 +2890,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>("length");
+  auto* ident = create<ast::IdentifierExpression>("length");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -2903,8 +2910,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -2940,8 +2947,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_2)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -2961,7 +2968,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -2975,7 +2982,7 @@
 
   ast::ExpressionList params;
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -2991,7 +2998,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3026,7 +3033,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec3, std::move(vals_2)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3054,7 +3061,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3074,7 +3081,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3099,8 +3106,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>("distance");
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>("distance");
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -3134,8 +3141,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_2)));
 
-  auto ident = create<ast::IdentifierExpression>("distance");
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>("distance");
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -3152,7 +3159,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
-  auto ident = create<ast::IdentifierExpression>("distance");
+  auto* ident = create<ast::IdentifierExpression>("distance");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3164,7 +3171,7 @@
 TEST_F(TypeDeterminerTest, ImportData_Distance_Error_NoParams) {
   ast::ExpressionList params;
 
-  auto ident = create<ast::IdentifierExpression>("distance");
+  auto* ident = create<ast::IdentifierExpression>("distance");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3178,7 +3185,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>("distance");
+  auto* ident = create<ast::IdentifierExpression>("distance");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3211,7 +3218,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec3, std::move(vals_2)));
 
-  auto ident = create<ast::IdentifierExpression>("distance");
+  auto* ident = create<ast::IdentifierExpression>("distance");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3236,7 +3243,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals)));
 
-  auto ident = create<ast::IdentifierExpression>("distance");
+  auto* ident = create<ast::IdentifierExpression>("distance");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3253,7 +3260,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>("distance");
+  auto* ident = create<ast::IdentifierExpression>("distance");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3287,8 +3294,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_2)));
 
-  auto ident = create<ast::IdentifierExpression>("cross");
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>("cross");
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -3306,7 +3313,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0f)));
 
-  auto ident = create<ast::IdentifierExpression>("cross");
+  auto* ident = create<ast::IdentifierExpression>("cross");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3340,7 +3347,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_2)));
 
-  auto ident = create<ast::IdentifierExpression>("cross");
+  auto* ident = create<ast::IdentifierExpression>("cross");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3350,7 +3357,7 @@
 
 TEST_F(TypeDeterminerTest, ImportData_Cross_Error_MissingParams) {
   ast::ExpressionList params;
-  auto ident = create<ast::IdentifierExpression>("cross");
+  auto* ident = create<ast::IdentifierExpression>("cross");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3374,7 +3381,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_1)));
 
-  auto ident = create<ast::IdentifierExpression>("cross");
+  auto* ident = create<ast::IdentifierExpression>("cross");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3418,7 +3425,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_3)));
 
-  auto ident = create<ast::IdentifierExpression>("cross");
+  auto* ident = create<ast::IdentifierExpression>("cross");
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3440,8 +3447,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -3487,8 +3494,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_3)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -3510,7 +3517,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 3)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3524,7 +3531,7 @@
 
   ast::ExpressionList params;
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3540,7 +3547,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3558,7 +3565,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3603,7 +3610,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec3, std::move(vals_3)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3633,7 +3640,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3655,7 +3662,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3687,8 +3694,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -3734,8 +3741,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_3)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -3757,8 +3764,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -3804,8 +3811,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_3)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -3827,8 +3834,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 1)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -3874,8 +3881,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_3)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -3897,7 +3904,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3911,7 +3918,7 @@
 
   ast::ExpressionList params;
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3927,7 +3934,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3945,7 +3952,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -3990,7 +3997,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec3, std::move(vals_3)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4020,7 +4027,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4042,7 +4049,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4066,8 +4073,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -4093,8 +4100,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -4112,7 +4119,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4126,7 +4133,7 @@
 
   ast::ExpressionList params;
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4146,7 +4153,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4174,8 +4181,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -4194,8 +4201,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 1)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -4214,8 +4221,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -4251,8 +4258,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_2)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -4289,8 +4296,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_2)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -4327,8 +4334,8 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals_2)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -4348,7 +4355,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, false)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4362,7 +4369,7 @@
 
   ast::ExpressionList params;
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4378,7 +4385,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4413,7 +4420,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec3, std::move(vals_2)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4441,7 +4448,7 @@
   params.push_back(
       create<ast::TypeConstructorExpression>(&vec, std::move(vals)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4461,7 +4468,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4479,7 +4486,7 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat(&f32, 3, 3);
 
-  auto var = create<ast::Variable>("var", ast::StorageClass::kFunction, &mat);
+  auto* var = create<ast::Variable>("var", ast::StorageClass::kFunction, &mat);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -4488,8 +4495,8 @@
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("var"));
 
-  auto ident = create<ast::IdentifierExpression>("determinant");
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>("determinant");
+  auto* ident_ptr = ident;
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
@@ -4504,7 +4511,7 @@
 
   ast::type::F32Type f32;
 
-  auto var = create<ast::Variable>("var", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("var", ast::StorageClass::kFunction, &f32);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -4513,7 +4520,7 @@
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("var"));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4526,7 +4533,7 @@
 
   ast::ExpressionList params;
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4540,7 +4547,7 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat(&f32, 3, 3);
 
-  auto var = create<ast::Variable>("var", ast::StorageClass::kFunction, &mat);
+  auto* var = create<ast::Variable>("var", ast::StorageClass::kFunction, &mat);
   mod()->AddGlobalVariable(std::move(var));
 
   // Register the global
@@ -4550,7 +4557,7 @@
   params.push_back(create<ast::IdentifierExpression>("var"));
   params.push_back(create<ast::IdentifierExpression>("var"));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression call(std::move(ident), std::move(params));
 
   EXPECT_FALSE(td()->DetermineResultType(&call));
@@ -4578,28 +4585,28 @@
   // ep_2 -> {}
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
-  auto func_b =
+  auto* body = create<ast::BlockStatement>();
+  auto* func_b =
       create<ast::Function>("b", std::move(params), &f32, std::move(body));
-  auto* func_b_ptr = func_b.get();
+  auto* func_b_ptr = func_b;
 
   body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("second"),
       create<ast::CallExpression>(create<ast::IdentifierExpression>("b"),
                                   ast::ExpressionList{})));
-  auto func_c =
+  auto* func_c =
       create<ast::Function>("c", std::move(params), &f32, std::move(body));
-  auto* func_c_ptr = func_c.get();
+  auto* func_c_ptr = func_c;
 
   body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("first"),
       create<ast::CallExpression>(create<ast::IdentifierExpression>("c"),
                                   ast::ExpressionList{})));
-  auto func_a =
+  auto* func_a =
       create<ast::Function>("a", std::move(params), &f32, std::move(body));
-  auto* func_a_ptr = func_a.get();
+  auto* func_a_ptr = func_a;
 
   body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
@@ -4610,22 +4617,22 @@
       create<ast::IdentifierExpression>("call_b"),
       create<ast::CallExpression>(create<ast::IdentifierExpression>("b"),
                                   ast::ExpressionList{})));
-  auto ep_1 =
+  auto* ep_1 =
       create<ast::Function>("ep_1", std::move(params), &f32, std::move(body));
   ep_1->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
-  auto* ep_1_ptr = ep_1.get();
+  auto* ep_1_ptr = ep_1;
 
   body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("call_c"),
       create<ast::CallExpression>(create<ast::IdentifierExpression>("c"),
                                   ast::ExpressionList{})));
-  auto ep_2 =
+  auto* ep_2 =
       create<ast::Function>("ep_2", std::move(params), &f32, std::move(body));
   ep_2->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
-  auto* ep_2_ptr = ep_2.get();
+  auto* ep_2_ptr = ep_2;
 
   mod()->AddFunction(std::move(func_b));
   mod()->AddFunction(std::move(func_c));
diff --git a/src/validator/validator_control_block_test.cc b/src/validator/validator_control_block_test.cc
index a80e656..5f8eb86 100644
--- a/src/validator/validator_control_block_test.cc
+++ b/src/validator/validator_control_block_test.cc
@@ -43,24 +43,24 @@
   //   default: {}
   // }
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&f32, 3.14f)));
 
-  auto cond =
+  auto* cond =
       create<ast::IdentifierExpression>(Source{Source::Location{12, 34}}, "a");
   ast::CaseSelectorList default_csl;
-  auto block_default = create<ast::BlockStatement>();
+  auto* block_default = create<ast::BlockStatement>();
   ast::CaseStatementList body;
   body.push_back(create<ast::CaseStatement>(std::move(default_csl),
                                             std::move(block_default)));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<ast::VariableDeclStatement>(std::move(var)));
   block->append(create<ast::SwitchStatement>(std::move(cond), std::move(body)));
 
-  EXPECT_TRUE(td()->DetermineStatements(block.get())) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block.get()));
+  EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
+  EXPECT_FALSE(v()->ValidateStatements(block));
   EXPECT_EQ(v()->error(),
             "12:34: v-0025: switch statement selector expression must be "
             "of a scalar integer type");
@@ -72,24 +72,24 @@
   //   case 1: {}
   // }
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
-  auto cond = create<ast::IdentifierExpression>("a");
+  auto* cond = create<ast::IdentifierExpression>("a");
   ast::CaseSelectorList csl;
   csl.push_back(create<ast::SintLiteral>(&i32, 1));
   ast::CaseStatementList body;
   body.push_back(create<ast::CaseStatement>(std::move(csl),
                                             create<ast::BlockStatement>()));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<ast::VariableDeclStatement>(std::move(var)));
   block->append(create<ast::SwitchStatement>(Source{Source::Location{12, 34}},
                                              std::move(cond), std::move(body)));
 
-  EXPECT_TRUE(td()->DetermineStatements(block.get())) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block.get()));
+  EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
+  EXPECT_FALSE(v()->ValidateStatements(block));
   EXPECT_EQ(v()->error(),
             "12:34: v-0008: switch statement must have exactly one default "
             "clause");
@@ -103,37 +103,37 @@
   //   default: {}
   // }
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
   ast::CaseStatementList switch_body;
-  auto cond = create<ast::IdentifierExpression>("a");
+  auto* cond = create<ast::IdentifierExpression>("a");
 
   ast::CaseSelectorList default_csl_1;
-  auto block_default_1 = create<ast::BlockStatement>();
+  auto* block_default_1 = create<ast::BlockStatement>();
   switch_body.push_back(create<ast::CaseStatement>(std::move(default_csl_1),
                                                    std::move(block_default_1)));
 
   ast::CaseSelectorList csl_case_1;
   csl_case_1.push_back(create<ast::SintLiteral>(&i32, 1));
-  auto block_case_1 = create<ast::BlockStatement>();
+  auto* block_case_1 = create<ast::BlockStatement>();
   switch_body.push_back(create<ast::CaseStatement>(std::move(csl_case_1),
                                                    std::move(block_case_1)));
 
   ast::CaseSelectorList default_csl_2;
-  auto block_default_2 = create<ast::BlockStatement>();
+  auto* block_default_2 = create<ast::BlockStatement>();
   switch_body.push_back(create<ast::CaseStatement>(std::move(default_csl_2),
                                                    std::move(block_default_2)));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<ast::VariableDeclStatement>(std::move(var)));
   block->append(create<ast::SwitchStatement>(Source{Source::Location{12, 34}},
                                              std::move(cond),
                                              std::move(switch_body)));
 
-  EXPECT_TRUE(td()->DetermineStatements(block.get())) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block.get()));
+  EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
+  EXPECT_FALSE(v()->ValidateStatements(block));
   EXPECT_EQ(v()->error(),
             "12:34: v-0008: switch statement must have exactly one default "
             "clause");
@@ -148,12 +148,12 @@
   // }
   ast::type::U32Type u32;
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
   ast::CaseStatementList switch_body;
-  auto cond = create<ast::IdentifierExpression>("a");
+  auto* cond = create<ast::IdentifierExpression>("a");
 
   ast::CaseSelectorList csl;
   csl.push_back(create<ast::UintLiteral>(&u32, 1));
@@ -162,17 +162,17 @@
       create<ast::BlockStatement>()));
 
   ast::CaseSelectorList default_csl;
-  auto block_default = create<ast::BlockStatement>();
+  auto* block_default = create<ast::BlockStatement>();
   switch_body.push_back(create<ast::CaseStatement>(std::move(default_csl),
                                                    std::move(block_default)));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<ast::VariableDeclStatement>(std::move(var)));
   block->append(
       create<ast::SwitchStatement>(std::move(cond), std::move(switch_body)));
 
-  EXPECT_TRUE(td()->DetermineStatements(block.get())) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block.get()));
+  EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
+  EXPECT_FALSE(v()->ValidateStatements(block));
   EXPECT_EQ(v()->error(),
             "12:34: v-0026: the case selector values must have the same "
             "type as the selector expression.");
@@ -187,12 +187,12 @@
   // }
   ast::type::U32Type u32;
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &u32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &u32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 2)));
 
   ast::CaseStatementList switch_body;
-  auto cond = create<ast::IdentifierExpression>("a");
+  auto* cond = create<ast::IdentifierExpression>("a");
 
   ast::CaseSelectorList csl;
   csl.push_back(create<ast::SintLiteral>(&i32, -1));
@@ -201,17 +201,17 @@
       create<ast::BlockStatement>()));
 
   ast::CaseSelectorList default_csl;
-  auto block_default = create<ast::BlockStatement>();
+  auto* block_default = create<ast::BlockStatement>();
   switch_body.push_back(create<ast::CaseStatement>(std::move(default_csl),
                                                    std::move(block_default)));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<ast::VariableDeclStatement>(std::move(var)));
   block->append(
       create<ast::SwitchStatement>(std::move(cond), std::move(switch_body)));
 
-  EXPECT_TRUE(td()->DetermineStatements(block.get())) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block.get()));
+  EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
+  EXPECT_FALSE(v()->ValidateStatements(block));
   EXPECT_EQ(v()->error(),
             "12:34: v-0026: the case selector values must have the same "
             "type as the selector expression.");
@@ -225,12 +225,12 @@
   //   default: {}
   // }
   ast::type::U32Type u32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &u32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &u32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 3)));
 
   ast::CaseStatementList switch_body;
-  auto cond = create<ast::IdentifierExpression>("a");
+  auto* cond = create<ast::IdentifierExpression>("a");
 
   ast::CaseSelectorList csl_1;
   csl_1.push_back(create<ast::UintLiteral>(&u32, 0));
@@ -245,17 +245,17 @@
       create<ast::BlockStatement>()));
 
   ast::CaseSelectorList default_csl;
-  auto block_default = create<ast::BlockStatement>();
+  auto* block_default = create<ast::BlockStatement>();
   switch_body.push_back(create<ast::CaseStatement>(std::move(default_csl),
                                                    std::move(block_default)));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<ast::VariableDeclStatement>(std::move(var)));
   block->append(
       create<ast::SwitchStatement>(std::move(cond), std::move(switch_body)));
 
-  EXPECT_TRUE(td()->DetermineStatements(block.get())) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block.get()));
+  EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
+  EXPECT_FALSE(v()->ValidateStatements(block));
   EXPECT_EQ(v()->error(),
             "12:34: v-0027: a literal value must not appear more than once "
             "in the case selectors for a switch statement: '2'");
@@ -269,12 +269,12 @@
   //   default: {}
   // }
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
   ast::CaseStatementList switch_body;
-  auto cond = create<ast::IdentifierExpression>("a");
+  auto* cond = create<ast::IdentifierExpression>("a");
 
   ast::CaseSelectorList csl_1;
   csl_1.push_back(create<ast::SintLiteral>(&i32, 10));
@@ -291,17 +291,17 @@
       create<ast::BlockStatement>()));
 
   ast::CaseSelectorList default_csl;
-  auto block_default = create<ast::BlockStatement>();
+  auto* block_default = create<ast::BlockStatement>();
   switch_body.push_back(create<ast::CaseStatement>(std::move(default_csl),
                                                    std::move(block_default)));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<ast::VariableDeclStatement>(std::move(var)));
   block->append(
       create<ast::SwitchStatement>(std::move(cond), std::move(switch_body)));
 
-  EXPECT_TRUE(td()->DetermineStatements(block.get())) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block.get()));
+  EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
+  EXPECT_FALSE(v()->ValidateStatements(block));
   EXPECT_EQ(v()->error(),
             "12:34: v-0027: a literal value must not appear more than once in "
             "the case selectors for a switch statement: '10'");
@@ -313,25 +313,25 @@
   //   default: { fallthrough; }
   // }
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
-  auto cond = create<ast::IdentifierExpression>("a");
+  auto* cond = create<ast::IdentifierExpression>("a");
   ast::CaseSelectorList default_csl;
-  auto block_default = create<ast::BlockStatement>();
+  auto* block_default = create<ast::BlockStatement>();
   block_default->append(
       create<ast::FallthroughStatement>(Source{Source::Location{12, 34}}));
   ast::CaseStatementList body;
   body.push_back(create<ast::CaseStatement>(std::move(default_csl),
                                             std::move(block_default)));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<ast::VariableDeclStatement>(std::move(var)));
   block->append(create<ast::SwitchStatement>(std::move(cond), std::move(body)));
 
-  EXPECT_TRUE(td()->DetermineStatements(block.get())) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(block.get()));
+  EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
+  EXPECT_FALSE(v()->ValidateStatements(block));
   EXPECT_EQ(v()->error(),
             "12:34: v-0028: a fallthrough statement must not appear as the "
             "last statement in last clause of a switch");
@@ -344,29 +344,29 @@
   //   case 5: {}
   // }
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
-  auto cond = create<ast::IdentifierExpression>("a");
+  auto* cond = create<ast::IdentifierExpression>("a");
   ast::CaseSelectorList default_csl;
-  auto block_default = create<ast::BlockStatement>();
+  auto* block_default = create<ast::BlockStatement>();
   ast::CaseStatementList body;
   body.push_back(create<ast::CaseStatement>(Source{Source::Location{12, 34}},
                                             std::move(default_csl),
                                             std::move(block_default)));
   ast::CaseSelectorList case_csl;
   case_csl.push_back(create<ast::SintLiteral>(&i32, 5));
-  auto block_case = create<ast::BlockStatement>();
+  auto* block_case = create<ast::BlockStatement>();
   body.push_back(
       create<ast::CaseStatement>(std::move(case_csl), std::move(block_case)));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<ast::VariableDeclStatement>(std::move(var)));
   block->append(create<ast::SwitchStatement>(std::move(cond), std::move(body)));
 
-  EXPECT_TRUE(td()->DetermineStatements(block.get())) << td()->error();
-  EXPECT_TRUE(v()->ValidateStatements(block.get())) << v()->error();
+  EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
+  EXPECT_TRUE(v()->ValidateStatements(block)) << v()->error();
 }
 
 TEST_F(ValidateControlBlockTest, SwitchCaseAlias_Pass) {
@@ -379,26 +379,26 @@
   ast::type::U32Type u32;
   ast::type::AliasType my_int{"MyInt", &u32};
 
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &my_int);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &my_int);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&u32, 2)));
 
-  auto cond = create<ast::IdentifierExpression>("a");
+  auto* cond = create<ast::IdentifierExpression>("a");
   ast::CaseSelectorList default_csl;
-  auto block_default = create<ast::BlockStatement>();
+  auto* block_default = create<ast::BlockStatement>();
   ast::CaseStatementList body;
   body.push_back(create<ast::CaseStatement>(Source{Source::Location{12, 34}},
                                             std::move(default_csl),
                                             std::move(block_default)));
 
-  auto block = create<ast::BlockStatement>();
+  auto* block = create<ast::BlockStatement>();
   block->append(create<ast::VariableDeclStatement>(std::move(var)));
   block->append(create<ast::SwitchStatement>(std::move(cond), std::move(body)));
 
   mod()->AddConstructedType(&my_int);
 
-  EXPECT_TRUE(td()->DetermineStatements(block.get())) << td()->error();
-  EXPECT_TRUE(v()->ValidateStatements(block.get())) << v()->error();
+  EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
+  EXPECT_TRUE(v()->ValidateStatements(block)) << v()->error();
 }
 
 }  // namespace
diff --git a/src/validator/validator_function_test.cc b/src/validator/validator_function_test.cc
index 97abf87..7c431a0 100644
--- a/src/validator/validator_function_test.cc
+++ b/src/validator/validator_function_test.cc
@@ -39,15 +39,15 @@
   // [[stage(vertex)]]
   // fn func -> void { var a:i32 = 2; }
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
   ast::VariableList params;
   ast::type::VoidType void_type;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
-  auto func =
+  auto* func =
       create<ast::Function>(Source{Source::Location{12, 34}}, "func",
                             std::move(params), &void_type, std::move(body));
   func->add_decoration(
@@ -64,9 +64,9 @@
   // fn func -> void {}
   ast::type::VoidType void_type;
   ast::VariableList params;
-  auto func = create<ast::Function>(Source{Source::Location{12, 34}}, "func",
-                                    std::move(params), &void_type,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>(Source{Source::Location{12, 34}}, "func",
+                                     std::move(params), &void_type,
+                                     create<ast::BlockStatement>());
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
@@ -79,16 +79,16 @@
   // fn func -> int { var a:i32 = 2; }
 
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
   ast::VariableList params;
   ast::type::VoidType void_type;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
-  auto func = create<ast::Function>(Source{Source::Location{12, 34}}, "func",
-                                    std::move(params), &i32, std::move(body));
+  auto* func = create<ast::Function>(Source{Source::Location{12, 34}}, "func",
+                                     std::move(params), &i32, std::move(body));
   mod()->AddFunction(std::move(func));
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
@@ -103,9 +103,9 @@
   ast::type::VoidType void_type;
   ast::type::I32Type i32;
   ast::VariableList params;
-  auto func = create<ast::Function>(Source{Source::Location{12, 34}}, "func",
-                                    std::move(params), &i32,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>(Source{Source::Location{12, 34}}, "func",
+                                     std::move(params), &i32,
+                                     create<ast::BlockStatement>());
   mod()->AddFunction(std::move(func));
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
@@ -121,10 +121,10 @@
   ast::type::VoidType void_type;
   ast::VariableList params;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("func", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("func", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
@@ -138,14 +138,14 @@
   ast::type::VoidType void_type;
   ast::type::I32Type i32;
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
-  auto return_expr = create<ast::ScalarConstructorExpression>(
+  auto* body = create<ast::BlockStatement>();
+  auto* return_expr = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
 
   body->append(create<ast::ReturnStatement>(Source{Source::Location{12, 34}},
                                             std::move(return_expr)));
-  auto func = create<ast::Function>("func", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("func", std::move(params), &void_type,
+                                     std::move(body));
   mod()->AddFunction(std::move(func));
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
@@ -161,13 +161,13 @@
   ast::type::I32Type i32;
   ast::type::F32Type f32;
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
-  auto return_expr = create<ast::ScalarConstructorExpression>(
+  auto* body = create<ast::BlockStatement>();
+  auto* return_expr = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
 
   body->append(create<ast::ReturnStatement>(Source{Source::Location{12, 34}},
                                             std::move(return_expr)));
-  auto func =
+  auto* func =
       create<ast::Function>("func", std::move(params), &f32, std::move(body));
   mod()->AddFunction(std::move(func));
 
@@ -186,21 +186,21 @@
   ast::type::I32Type i32;
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
-  auto return_expr = create<ast::ScalarConstructorExpression>(
+  auto* body = create<ast::BlockStatement>();
+  auto* return_expr = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
 
   body->append(create<ast::ReturnStatement>(std::move(return_expr)));
-  auto func =
+  auto* func =
       create<ast::Function>("func", std::move(params), &i32, std::move(body));
 
   ast::VariableList params_copy;
-  auto body_copy = create<ast::BlockStatement>();
-  auto return_expr_copy = create<ast::ScalarConstructorExpression>(
+  auto* body_copy = create<ast::BlockStatement>();
+  auto* return_expr_copy = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
 
   body_copy->append(create<ast::ReturnStatement>(std::move(return_expr_copy)));
-  auto func_copy =
+  auto* func_copy =
       create<ast::Function>(Source{Source::Location{12, 34}}, "func",
                             std::move(params_copy), &i32, std::move(body_copy));
 
@@ -218,14 +218,14 @@
   ast::type::F32Type f32;
   ast::type::VoidType void_type;
   ast::ExpressionList call_params;
-  auto call_expr = create<ast::CallExpression>(
+  auto* call_expr = create<ast::CallExpression>(
       Source{Source::Location{12, 34}},
       create<ast::IdentifierExpression>("func"), std::move(call_params));
   ast::VariableList params0;
-  auto body0 = create<ast::BlockStatement>();
+  auto* body0 = create<ast::BlockStatement>();
   body0->append(create<ast::CallStatement>(std::move(call_expr)));
   body0->append(create<ast::ReturnStatement>());
-  auto func0 =
+  auto* func0 =
       create<ast::Function>("func", std::move(params0), &f32, std::move(body0));
   mod()->AddFunction(std::move(func0));
 
@@ -237,20 +237,20 @@
 TEST_F(ValidateFunctionTest, RecursionIsNotAllowedExpr_Fail) {
   // fn func() -> i32 {var a: i32 = func(); return 2; }
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   ast::ExpressionList call_params;
-  auto call_expr = create<ast::CallExpression>(
+  auto* call_expr = create<ast::CallExpression>(
       Source{Source::Location{12, 34}},
       create<ast::IdentifierExpression>("func"), std::move(call_params));
   var->set_constructor(std::move(call_expr));
   ast::VariableList params0;
-  auto body0 = create<ast::BlockStatement>();
+  auto* body0 = create<ast::BlockStatement>();
   body0->append(create<ast::VariableDeclStatement>(std::move(var)));
-  auto return_expr = create<ast::ScalarConstructorExpression>(
+  auto* return_expr = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
 
   body0->append(create<ast::ReturnStatement>(std::move(return_expr)));
-  auto func0 =
+  auto* func0 =
       create<ast::Function>("func", std::move(params0), &i32, std::move(body0));
   mod()->AddFunction(std::move(func0));
 
@@ -264,12 +264,12 @@
   // fn vtx_main() -> i32 { return 0; }
   ast::type::I32Type i32;
   ast::VariableList params;
-  auto return_expr = create<ast::ScalarConstructorExpression>(
+  auto* return_expr = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 0));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>(std::move(return_expr)));
-  auto func =
+  auto* func =
       create<ast::Function>(Source{Source::Location{12, 34}}, "vtx_main",
                             std::move(params), &i32, std::move(body));
   func->add_decoration(
@@ -289,9 +289,9 @@
   ast::type::VoidType void_type;
   ast::VariableList params;
   params.push_back(create<ast::Variable>("a", ast::StorageClass::kNone, &i32));
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func =
+  auto* func =
       create<ast::Function>(Source{Source::Location{12, 34}}, "vtx_func",
                             std::move(params), &void_type, std::move(body));
   func->add_decoration(
@@ -311,9 +311,9 @@
   // fn main() -> void { return; }
   ast::type::VoidType void_type;
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func =
+  auto* func =
       create<ast::Function>(Source{Source::Location{12, 34}}, "main",
                             std::move(params), &void_type, std::move(body));
   func->add_decoration(
@@ -333,10 +333,10 @@
   // fn vtx_func() -> void { return; }
   ast::type::VoidType void_type;
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("vtx_func", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("vtx_func", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
@@ -349,10 +349,10 @@
   // fn vtx_func() -> void { return; }
   ast::type::VoidType void_type;
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("vtx_func", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("vtx_func", std::move(params), &void_type,
+                                     std::move(body));
   mod()->AddFunction(std::move(func));
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
diff --git a/src/validator/validator_impl.cc b/src/validator/validator_impl.cc
index 92bbb58..9edaf50 100644
--- a/src/validator/validator_impl.cc
+++ b/src/validator/validator_impl.cc
@@ -61,7 +61,7 @@
 
 bool ValidatorImpl::ValidateGlobalVariables(
     const ast::VariableList& global_vars) {
-  for (const auto& var : global_vars) {
+  for (auto* var : global_vars) {
     if (variable_stack_.has(var->name())) {
       set_error(var->source(),
                 "v-0011: redeclared global identifier '" + var->name() + "'");
@@ -78,22 +78,22 @@
                 "v-global01: global constants shouldn't have a storage class");
       return false;
     }
-    variable_stack_.set_global(var->name(), var.get());
+    variable_stack_.set_global(var->name(), var);
   }
   return true;
 }
 
 bool ValidatorImpl::ValidateFunctions(const ast::FunctionList& funcs) {
-  for (const auto& func : funcs) {
+  for (auto* func : funcs) {
     if (function_stack_.has(func->name())) {
       set_error(func->source(),
                 "v-0016: function names must be unique '" + func->name() + "'");
       return false;
     }
 
-    function_stack_.set(func->name(), func.get());
-    current_function_ = func.get();
-    if (!ValidateFunction(func.get())) {
+    function_stack_.set(func->name(), func);
+    current_function_ = func;
+    if (!ValidateFunction(func)) {
       return false;
     }
     current_function_ = nullptr;
@@ -104,7 +104,7 @@
 
 bool ValidatorImpl::ValidateEntryPoint(const ast::FunctionList& funcs) {
   auto shader_is_present = false;
-  for (const auto& func : funcs) {
+  for (auto* func : funcs) {
     if (func->IsEntryPoint()) {
       shader_is_present = true;
       if (!func->params().empty()) {
@@ -121,7 +121,7 @@
         return false;
       }
       auto stage_deco_count = 0;
-      for (const auto& deco : func->decorations()) {
+      for (auto* deco : func->decorations()) {
         if (deco->IsStage()) {
           stage_deco_count++;
         }
@@ -146,8 +146,8 @@
 bool ValidatorImpl::ValidateFunction(const ast::Function* func) {
   variable_stack_.push_scope();
 
-  for (const auto& param : func->params()) {
-    variable_stack_.set(param->name(), param.get());
+  for (auto* param : func->params()) {
+    variable_stack_.set(param->name(), param);
   }
   if (!ValidateStatements(func->body())) {
     return false;
@@ -190,8 +190,8 @@
   if (!block) {
     return false;
   }
-  for (const auto& stmt : *block) {
-    if (!ValidateStatement(stmt.get())) {
+  for (auto* stmt : *block) {
+    if (!ValidateStatement(stmt)) {
       return false;
     }
   }
@@ -261,19 +261,19 @@
 
   int default_counter = 0;
   std::unordered_set<int32_t> selector_set;
-  for (const auto& case_stmt : s->body()) {
-    if (!ValidateStatement(case_stmt.get())) {
+  for (auto* case_stmt : s->body()) {
+    if (!ValidateStatement(case_stmt)) {
       return false;
     }
 
-    if (case_stmt.get()->IsDefault()) {
+    if (case_stmt->IsDefault()) {
       default_counter++;
     }
 
-    for (const auto& selector : case_stmt.get()->selectors()) {
-      auto* selector_ptr = selector.get();
+    for (auto* selector : case_stmt->selectors()) {
+      auto* selector_ptr = selector;
       if (cond_type != selector_ptr->type()) {
-        set_error(case_stmt.get()->source(),
+        set_error(case_stmt->source(),
                   "v-0026: the case selector values must have the same "
                   "type as the selector expression.");
         return false;
@@ -286,7 +286,7 @@
         auto v_str = selector_ptr->type()->IsU32()
                          ? selector_ptr->AsUint()->to_str()
                          : selector_ptr->AsSint()->to_str();
-        set_error(case_stmt.get()->source(),
+        set_error(case_stmt->source(),
                   "v-0027: a literal value must not appear more than once in "
                   "the case selectors for a switch statement: '" +
                       v_str + "'");
@@ -302,7 +302,7 @@
     return false;
   }
 
-  auto* last_clause = s->body().back().get();
+  auto* last_clause = s->body().back();
   auto* last_stmt_of_last_clause = last_clause->AsCase()->body()->last();
   if (last_stmt_of_last_clause && last_stmt_of_last_clause->IsFallthrough()) {
     set_error(last_stmt_of_last_clause->source(),
diff --git a/src/validator/validator_test.cc b/src/validator/validator_test.cc
index 4e955f9..6b0b688 100644
--- a/src/validator/validator_test.cc
+++ b/src/validator/validator_test.cc
@@ -64,9 +64,9 @@
   // 1 = my_var;
   ast::type::I32Type i32;
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1));
-  auto rhs = create<ast::IdentifierExpression>("my_var");
+  auto* rhs = create<ast::IdentifierExpression>("my_var");
   ast::AssignmentStatement assign(Source{Source::Location{12, 34}},
                                   std::move(lhs), std::move(rhs));
 
@@ -80,14 +80,14 @@
   // b = 2;
   ast::type::I32Type i32;
 
-  auto lhs =
+  auto* lhs =
       create<ast::IdentifierExpression>(Source{Source::Location{12, 34}}, "b");
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto assign = create<ast::AssignmentStatement>(
+  auto* assign = create<ast::AssignmentStatement>(
       Source{Source::Location{12, 34}}, std::move(lhs), std::move(rhs));
 
-  EXPECT_FALSE(td()->DetermineResultType(assign.get()));
+  EXPECT_FALSE(td()->DetermineResultType(assign));
   EXPECT_EQ(td()->error(),
             "12:34: v-0006: identifier must be declared before use: b");
 }
@@ -98,16 +98,16 @@
   // }
   ast::type::I32Type i32;
 
-  auto lhs =
+  auto* lhs =
       create<ast::IdentifierExpression>(Source{Source::Location{12, 34}}, "b");
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       Source{Source::Location{12, 34}}, std::move(lhs), std::move(rhs)));
 
-  EXPECT_FALSE(td()->DetermineStatements(body.get()));
+  EXPECT_FALSE(td()->DetermineStatements(body));
   EXPECT_EQ(td()->error(),
             "12:34: v-0006: identifier must be declared before use: b");
 }
@@ -116,19 +116,19 @@
   // var a :i32 = 2;
   // a = 2
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
-  auto lhs = create<ast::IdentifierExpression>("a");
-  auto* lhs_ptr = lhs.get();
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::IdentifierExpression>("a");
+  auto* lhs_ptr = lhs;
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
   ast::AssignmentStatement assign(Source{Source::Location{12, 34}},
                                   std::move(lhs), std::move(rhs));
-  td()->RegisterVariableForTesting(var.get());
+  td()->RegisterVariableForTesting(var);
   EXPECT_TRUE(td()->DetermineResultType(&assign)) << td()->error();
   ASSERT_NE(lhs_ptr->result_type(), nullptr);
   ASSERT_NE(rhs_ptr->result_type(), nullptr);
@@ -143,18 +143,18 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
-  auto lhs = create<ast::IdentifierExpression>("a");
-  auto* lhs_ptr = lhs.get();
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::IdentifierExpression>("a");
+  auto* lhs_ptr = lhs;
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.3f));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
   ast::AssignmentStatement assign(Source{Source::Location{12, 34}},
                                   std::move(lhs), std::move(rhs));
-  td()->RegisterVariableForTesting(var.get());
+  td()->RegisterVariableForTesting(var);
   EXPECT_TRUE(td()->DetermineResultType(&assign)) << td()->error();
   ASSERT_NE(lhs_ptr->result_type(), nullptr);
   ASSERT_NE(rhs_ptr->result_type(), nullptr);
@@ -172,26 +172,26 @@
   //  a = 2
   // }
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
-  auto lhs = create<ast::IdentifierExpression>("a");
-  auto* lhs_ptr = lhs.get();
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::IdentifierExpression>("a");
+  auto* lhs_ptr = lhs;
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::AssignmentStatement>(
       Source{Source::Location{12, 34}}, std::move(lhs), std::move(rhs)));
 
-  EXPECT_TRUE(td()->DetermineStatements(body.get())) << td()->error();
+  EXPECT_TRUE(td()->DetermineStatements(body)) << td()->error();
   ASSERT_NE(lhs_ptr->result_type(), nullptr);
   ASSERT_NE(rhs_ptr->result_type(), nullptr);
 
-  EXPECT_TRUE(v()->ValidateStatements(body.get())) << v()->error();
+  EXPECT_TRUE(v()->ValidateStatements(body)) << v()->error();
 }
 
 TEST_F(ValidatorTest, AssignIncompatibleTypesInBlockStatement_Fail) {
@@ -202,14 +202,14 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
-  auto lhs = create<ast::IdentifierExpression>("a");
-  auto* lhs_ptr = lhs.get();
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::IdentifierExpression>("a");
+  auto* lhs_ptr = lhs;
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.3f));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
   ast::BlockStatement block;
   block.append(create<ast::VariableDeclStatement>(std::move(var)));
@@ -230,7 +230,7 @@
 TEST_F(ValidatorTest, GlobalVariableWithStorageClass_Pass) {
   // var<in> gloabl_var: f32;
   ast::type::F32Type f32;
-  auto global_var =
+  auto* global_var =
       create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
                             ast::StorageClass::kInput, &f32);
   mod()->AddGlobalVariable(std::move(global_var));
@@ -241,7 +241,7 @@
 TEST_F(ValidatorTest, GlobalVariableNoStorageClass_Fail) {
   // var gloabl_var: f32;
   ast::type::F32Type f32;
-  auto global_var =
+  auto* global_var =
       create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
                             ast::StorageClass::kNone, &f32);
   mod()->AddGlobalVariable(std::move(global_var));
@@ -253,7 +253,7 @@
 TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) {
   // const<in> gloabl_var: f32;
   ast::type::F32Type f32;
-  auto global_var =
+  auto* global_var =
       create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
                             ast::StorageClass::kInput, &f32);
   global_var->set_is_const(true);
@@ -269,7 +269,7 @@
 TEST_F(ValidatorTest, GlobalConstNoStorageClass_Pass) {
   // const gloabl_var: f32;
   ast::type::F32Type f32;
-  auto global_var =
+  auto* global_var =
       create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
                             ast::StorageClass::kNone, &f32);
   global_var->set_is_const(true);
@@ -285,24 +285,24 @@
   //   not_global_var = 3.14f;
   // }
   ast::type::F32Type f32;
-  auto global_var =
+  auto* global_var =
       create<ast::Variable>("global_var", ast::StorageClass::kPrivate, &f32);
   global_var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.1)));
   mod()->AddGlobalVariable(std::move(global_var));
 
-  auto lhs = create<ast::IdentifierExpression>(Source{Source::Location{12, 34}},
-                                               "not_global_var");
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::IdentifierExpression>(
+      Source{Source::Location{12, 34}}, "not_global_var");
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.14f));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       Source{Source::Location{12, 34}}, std::move(lhs), std::move(rhs)));
 
-  auto func = create<ast::Function>("my_func", std::move(params), &f32,
-                                    std::move(body));
+  auto* func = create<ast::Function>("my_func", std::move(params), &f32,
+                                     std::move(body));
   mod()->AddFunction(std::move(func));
 
   EXPECT_FALSE(v()->Validate(mod()));
@@ -318,24 +318,24 @@
   ast::type::F32Type f32;
   ast::type::VoidType void_type;
 
-  auto global_var =
+  auto* global_var =
       create<ast::Variable>("global_var", ast::StorageClass::kPrivate, &f32);
   global_var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.1)));
   mod()->AddGlobalVariable(std::move(global_var));
 
-  auto lhs = create<ast::IdentifierExpression>("global_var");
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::IdentifierExpression>("global_var");
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.14f));
 
   ast::VariableList params;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       Source{Source::Location{12, 34}}, std::move(lhs), std::move(rhs)));
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("my_func", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("my_func", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
@@ -350,33 +350,33 @@
   //   a = 3.14;
   // }
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::type::BoolType bool_type;
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
 
-  auto lhs =
+  auto* lhs =
       create<ast::IdentifierExpression>(Source{Source::Location{12, 34}}, "a");
-  auto* lhs_ptr = lhs.get();
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs_ptr = lhs;
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.14f));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
-  auto outer_body = create<ast::BlockStatement>();
+  auto* outer_body = create<ast::BlockStatement>();
   outer_body->append(
       create<ast::IfStatement>(std::move(cond), std::move(body)));
   outer_body->append(create<ast::AssignmentStatement>(
       Source{Source::Location{12, 34}}, std::move(lhs), std::move(rhs)));
 
-  EXPECT_TRUE(td()->DetermineStatements(outer_body.get())) << td()->error();
+  EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
   ASSERT_NE(lhs_ptr->result_type(), nullptr);
   ASSERT_NE(rhs_ptr->result_type(), nullptr);
-  EXPECT_FALSE(v()->ValidateStatements(outer_body.get()));
+  EXPECT_FALSE(v()->ValidateStatements(outer_body));
   EXPECT_EQ(v()->error(), "12:34: v-0006: 'a' is not declared");
 }
 
@@ -386,31 +386,31 @@
   //   if (true) { a = 3.14; }
   // }
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
 
-  auto lhs =
+  auto* lhs =
       create<ast::IdentifierExpression>(Source{Source::Location{12, 34}}, "a");
-  auto* lhs_ptr = lhs.get();
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs_ptr = lhs;
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.14f));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
   ast::type::BoolType bool_type;
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       Source{Source::Location{12, 34}}, std::move(lhs), std::move(rhs)));
 
-  auto outer_body = create<ast::BlockStatement>();
+  auto* outer_body = create<ast::BlockStatement>();
   outer_body->append(create<ast::VariableDeclStatement>(std::move(var)));
   outer_body->append(
       create<ast::IfStatement>(std::move(cond), std::move(body)));
-  EXPECT_TRUE(td()->DetermineStatements(outer_body.get())) << td()->error();
+  EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
   ASSERT_NE(lhs_ptr->result_type(), nullptr);
   ASSERT_NE(rhs_ptr->result_type(), nullptr);
-  EXPECT_TRUE(v()->ValidateStatements(outer_body.get())) << v()->error();
+  EXPECT_TRUE(v()->ValidateStatements(outer_body)) << v()->error();
 }
 
 TEST_F(ValidatorTest, GlobalVariableUnique_Pass) {
@@ -418,13 +418,13 @@
   // var global_var1 : i32 = 0;
   ast::type::F32Type f32;
   ast::type::I32Type i32;
-  auto var0 =
+  auto* var0 =
       create<ast::Variable>("global_var0", ast::StorageClass::kPrivate, &f32);
   var0->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 0.1)));
   mod()->AddGlobalVariable(std::move(var0));
 
-  auto var1 =
+  auto* var1 =
       create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var1",
                             ast::StorageClass::kPrivate, &f32);
   var1->set_constructor(create<ast::ScalarConstructorExpression>(
@@ -440,13 +440,13 @@
   // var global_var : i32 = 0;
   ast::type::F32Type f32;
   ast::type::I32Type i32;
-  auto var0 =
+  auto* var0 =
       create<ast::Variable>("global_var", ast::StorageClass::kPrivate, &f32);
   var0->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 0.1)));
   mod()->AddGlobalVariable(std::move(var0));
 
-  auto var1 =
+  auto* var1 =
       create<ast::Variable>(Source{Source::Location{12, 34}}, "global_var",
                             ast::StorageClass::kPrivate, &f32);
   var1->set_constructor(create<ast::ScalarConstructorExpression>(
@@ -464,27 +464,27 @@
   //  a = 2
   // }
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
   var->set_is_const(true);
 
-  auto lhs = create<ast::IdentifierExpression>("a");
-  auto* lhs_ptr = lhs.get();
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::IdentifierExpression>("a");
+  auto* lhs_ptr = lhs;
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::AssignmentStatement>(
       Source{Source::Location{12, 34}}, std::move(lhs), std::move(rhs)));
 
-  EXPECT_TRUE(td()->DetermineStatements(body.get())) << td()->error();
+  EXPECT_TRUE(td()->DetermineStatements(body)) << td()->error();
   ASSERT_NE(lhs_ptr->result_type(), nullptr);
   ASSERT_NE(rhs_ptr->result_type(), nullptr);
 
-  EXPECT_FALSE(v()->ValidateStatements(body.get()));
+  EXPECT_FALSE(v()->ValidateStatements(body));
   EXPECT_EQ(v()->error(), "12:34: v-0021: cannot re-assign a constant: 'a'");
 }
 
@@ -497,22 +497,22 @@
 
   ast::type::VoidType void_type;
   ast::type::F32Type f32;
-  auto global_var =
+  auto* global_var =
       create<ast::Variable>("a", ast::StorageClass::kPrivate, &f32);
   global_var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.1)));
   mod()->AddGlobalVariable(std::move(global_var));
 
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(
       Source{Source::Location{12, 34}}, std::move(var)));
-  auto func = create<ast::Function>("my_func", std::move(params), &void_type,
-                                    std::move(body));
-  auto* func_ptr = func.get();
+  auto* func = create<ast::Function>("my_func", std::move(params), &void_type,
+                                     std::move(body));
+  auto* func_ptr = func;
   mod()->AddFunction(std::move(func));
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
@@ -529,22 +529,23 @@
   ast::type::VoidType void_type;
   ast::type::I32Type i32;
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
 
-  auto var_a_float = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var_a_float =
+      create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var_a_float->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 0.1)));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::VariableDeclStatement>(
       Source{Source::Location{12, 34}}, std::move(var_a_float)));
-  auto func = create<ast::Function>("my_func", std::move(params), &void_type,
-                                    std::move(body));
-  auto* func_ptr = func.get();
+  auto* func = create<ast::Function>("my_func", std::move(params), &void_type,
+                                     std::move(body));
+  auto* func_ptr = func;
   mod()->AddFunction(std::move(func));
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
@@ -559,28 +560,29 @@
   // var a : f32 = 3.14;
   // }
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::type::BoolType bool_type;
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
 
-  auto var_a_float = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var_a_float =
+      create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var_a_float->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.14)));
 
-  auto outer_body = create<ast::BlockStatement>();
+  auto* outer_body = create<ast::BlockStatement>();
   outer_body->append(
       create<ast::IfStatement>(std::move(cond), std::move(body)));
   outer_body->append(create<ast::VariableDeclStatement>(
       Source{Source::Location{12, 34}}, std::move(var_a_float)));
 
-  EXPECT_TRUE(td()->DetermineStatements(outer_body.get())) << td()->error();
-  EXPECT_TRUE(v()->ValidateStatements(outer_body.get())) << v()->error();
+  EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
+  EXPECT_TRUE(v()->ValidateStatements(outer_body)) << v()->error();
 }
 
 TEST_F(ValidatorTest, DISABLED_RedeclaredIdentifierInnerScope_False) {
@@ -591,29 +593,30 @@
   // if (true) { var a : f32 = 2.0; }
   // }
   ast::type::F32Type f32;
-  auto var_a_float = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var_a_float =
+      create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var_a_float->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.14)));
 
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::type::BoolType bool_type;
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(
       Source{Source::Location{12, 34}}, std::move(var)));
 
-  auto outer_body = create<ast::BlockStatement>();
+  auto* outer_body = create<ast::BlockStatement>();
   outer_body->append(
       create<ast::VariableDeclStatement>(std::move(var_a_float)));
   outer_body->append(
       create<ast::IfStatement>(std::move(cond), std::move(body)));
 
-  EXPECT_TRUE(td()->DetermineStatements(outer_body.get())) << td()->error();
-  EXPECT_FALSE(v()->ValidateStatements(outer_body.get()));
+  EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
+  EXPECT_FALSE(v()->ValidateStatements(outer_body));
   EXPECT_EQ(v()->error(), "12:34: v-0014: redeclared identifier 'a'");
 }
 
@@ -622,29 +625,29 @@
   // func1 { var a : f32 = 3.0; return; }
   ast::type::F32Type f32;
   ast::type::VoidType void_type;
-  auto var0 = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var0 = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var0->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
 
-  auto var1 = create<ast::Variable>("a", ast::StorageClass::kNone, &void_type);
+  auto* var1 = create<ast::Variable>("a", ast::StorageClass::kNone, &void_type);
   var1->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0)));
 
   ast::VariableList params0;
-  auto body0 = create<ast::BlockStatement>();
+  auto* body0 = create<ast::BlockStatement>();
   body0->append(create<ast::VariableDeclStatement>(
       Source{Source::Location{12, 34}}, std::move(var0)));
   body0->append(create<ast::ReturnStatement>());
-  auto func0 = create<ast::Function>("func0", std::move(params0), &void_type,
-                                     std::move(body0));
+  auto* func0 = create<ast::Function>("func0", std::move(params0), &void_type,
+                                      std::move(body0));
 
   ast::VariableList params1;
-  auto body1 = create<ast::BlockStatement>();
+  auto* body1 = create<ast::BlockStatement>();
   body1->append(create<ast::VariableDeclStatement>(
       Source{Source::Location{13, 34}}, std::move(var1)));
   body1->append(create<ast::ReturnStatement>());
-  auto func1 = create<ast::Function>("func1", std::move(params1), &void_type,
-                                     std::move(body1));
+  auto* func1 = create<ast::Function>("func1", std::move(params1), &void_type,
+                                      std::move(body1));
   func1->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
 
@@ -661,24 +664,24 @@
   // a = 2;
   // }
   ast::type::I32Type i32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &i32);
 
-  td()->RegisterVariableForTesting(var.get());
-  auto lhs = create<ast::IdentifierExpression>("a");
-  auto* lhs_ptr = lhs.get();
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  td()->RegisterVariableForTesting(var);
+  auto* lhs = create<ast::IdentifierExpression>("a");
+  auto* lhs_ptr = lhs;
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
-  auto* rhs_ptr = rhs.get();
+  auto* rhs_ptr = rhs;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::AssignmentStatement>(
       Source{Source::Location{12, 34}}, std::move(lhs), std::move(rhs)));
 
-  EXPECT_TRUE(td()->DetermineStatements(body.get())) << td()->error();
+  EXPECT_TRUE(td()->DetermineStatements(body)) << td()->error();
   ASSERT_NE(lhs_ptr->result_type(), nullptr);
   ASSERT_NE(rhs_ptr->result_type(), nullptr);
-  EXPECT_TRUE(v()->ValidateStatements(body.get())) << v()->error();
+  EXPECT_TRUE(v()->ValidateStatements(body)) << v()->error();
 }
 
 }  // namespace
diff --git a/src/validator/validator_test_helper.h b/src/validator/validator_test_helper.h
index 26e91f3..92edc34 100644
--- a/src/validator/validator_test_helper.h
+++ b/src/validator/validator_test_helper.h
@@ -41,11 +41,13 @@
   /// @return a pointer to the test module
   ast::Module* mod() { return &mod_; }
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx_.create<T>(std::forward<ARGS>(args)...);
   }
 
  private:
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index 726757b..d0279cb 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -118,8 +118,8 @@
 }
 
 bool GeneratorImpl::Generate(std::ostream& out) {
-  for (const auto& global : module_->global_variables()) {
-    register_global(global.get());
+  for (auto* global : module_->global_variables()) {
+    register_global(global);
   }
 
   for (auto* const ty : module_->constructed_types()) {
@@ -131,38 +131,38 @@
     out << std::endl;
   }
 
-  for (const auto& var : module_->global_variables()) {
+  for (auto* var : module_->global_variables()) {
     if (!var->is_const()) {
       continue;
     }
-    if (!EmitProgramConstVariable(out, var.get())) {
+    if (!EmitProgramConstVariable(out, var)) {
       return false;
     }
   }
 
   std::unordered_set<std::string> emitted_globals;
   // Make sure all entry point data is emitted before the entry point functions
-  for (const auto& func : module_->functions()) {
+  for (auto* func : module_->functions()) {
     if (!func->IsEntryPoint()) {
       continue;
     }
 
-    if (!EmitEntryPointData(out, func.get(), emitted_globals)) {
+    if (!EmitEntryPointData(out, func, emitted_globals)) {
       return false;
     }
   }
 
-  for (const auto& func : module_->functions()) {
-    if (!EmitFunction(out, func.get())) {
+  for (auto* func : module_->functions()) {
+    if (!EmitFunction(out, func)) {
       return false;
     }
   }
 
-  for (const auto& func : module_->functions()) {
+  for (auto* func : module_->functions()) {
     if (!func->IsEntryPoint()) {
       continue;
     }
-    if (!EmitEntryPointFunction(out, func.get())) {
+    if (!EmitEntryPointFunction(out, func)) {
       return false;
     }
     out << std::endl;
@@ -450,8 +450,8 @@
   out << "{" << std::endl;
   increment_indent();
 
-  for (const auto& s : *stmt) {
-    if (!EmitStatement(out, s.get())) {
+  for (auto* s : *stmt) {
+    if (!EmitStatement(out, s)) {
       return false;
     }
   }
@@ -625,13 +625,13 @@
       out << name << "(";
 
       bool first = true;
-      for (const auto& param : params) {
+      for (auto* param : params) {
         if (!first) {
           out << ", ";
         }
         first = false;
 
-        if (!EmitExpression(pre, out, param.get())) {
+        if (!EmitExpression(pre, out, param)) {
           return false;
         }
       }
@@ -675,13 +675,13 @@
   }
 
   const auto& params = expr->params();
-  for (const auto& param : params) {
+  for (auto* param : params) {
     if (!first) {
       out << ", ";
     }
     first = false;
 
-    if (!EmitExpression(pre, out, param.get())) {
+    if (!EmitExpression(pre, out, param)) {
       return false;
     }
   }
@@ -758,7 +758,7 @@
     out << "default:";
   } else {
     bool first = true;
-    for (const auto& selector : stmt->selectors()) {
+    for (auto* selector : stmt->selectors()) {
       if (!first) {
         out << std::endl;
         make_indent(out);
@@ -766,7 +766,7 @@
       first = false;
 
       out << "case ";
-      if (!EmitLiteral(out, selector.get())) {
+      if (!EmitLiteral(out, selector)) {
         return false;
       }
       out << ":";
@@ -777,8 +777,8 @@
 
   increment_indent();
 
-  for (const auto& s : *(stmt->body())) {
-    if (!EmitStatement(out, s.get())) {
+  for (auto* s : *stmt->body()) {
+    if (!EmitStatement(out, s)) {
       return false;
     }
   }
@@ -831,13 +831,13 @@
     }
   } else {
     bool first = true;
-    for (const auto& e : expr->values()) {
+    for (auto* e : expr->values()) {
       if (!first) {
         out << ", ";
       }
       first = false;
 
-      if (!EmitExpression(pre, out, e.get())) {
+      if (!EmitExpression(pre, out, e)) {
         return false;
       }
     }
@@ -943,7 +943,7 @@
     return false;
   }
 
-  for (const auto& e : stmt->else_statements()) {
+  for (auto* e : stmt->else_statements()) {
     if (e->HasCondition()) {
       if_out << " else {" << std::endl;
 
@@ -968,7 +968,7 @@
   }
   if_out << std::endl;
 
-  for (const auto& e : stmt->else_statements()) {
+  for (auto* e : stmt->else_statements()) {
     if (!e->HasCondition()) {
       continue;
     }
@@ -1114,7 +1114,7 @@
     }
   }
 
-  for (const auto& v : func->params()) {
+  for (auto* v : func->params()) {
     if (!first) {
       out << ", ";
     }
@@ -1414,8 +1414,8 @@
   }
 
   generating_entry_point_ = true;
-  for (const auto& s : *(func->body())) {
-    if (!EmitStatement(out, s.get())) {
+  for (auto* s : *func->body()) {
+    if (!EmitStatement(out, s)) {
       return false;
     }
   }
@@ -1503,7 +1503,7 @@
     // first pass, if we have a continuing, we pull all declarations outside
     // the for loop into the continuing scope. Then, the variable declarations
     // will be turned into assignments.
-    for (const auto& s : *(stmt->body())) {
+    for (auto* s : *stmt->body()) {
       if (!s->IsVariableDecl()) {
         continue;
       }
@@ -1530,7 +1530,7 @@
     out << std::endl;
   }
 
-  for (const auto& s : *(stmt->body())) {
+  for (auto* s : *(stmt->body())) {
     // If we have a continuing block we've already emitted the variable
     // declaration before the loop, so treat it as an assignment.
     if (s->IsVariableDecl() && stmt->has_continuing()) {
@@ -1559,7 +1559,7 @@
       continue;
     }
 
-    if (!EmitStatement(out, s.get())) {
+    if (!EmitStatement(out, s)) {
       return false;
     }
   }
@@ -1927,8 +1927,8 @@
 
   increment_indent();
 
-  for (const auto& s : stmt->body()) {
-    if (!EmitCase(out, s.get())) {
+  for (auto* s : stmt->body()) {
+    if (!EmitCase(out, s)) {
       return false;
     }
   }
@@ -2060,7 +2060,7 @@
   out << "struct " << name << " {" << std::endl;
 
   increment_indent();
-  for (const auto& mem : str->impl()->members()) {
+  for (auto* mem : str->impl()->members()) {
     make_indent(out);
     // TODO(dsinclair): Handle [[offset]] annotation on structs
     // https://bugs.chromium.org/p/tint/issues/detail?id=184
diff --git a/src/writer/hlsl/generator_impl_alias_type_test.cc b/src/writer/hlsl/generator_impl_alias_type_test.cc
index 2d80431..da36b1f 100644
--- a/src/writer/hlsl/generator_impl_alias_type_test.cc
+++ b/src/writer/hlsl/generator_impl_alias_type_test.cc
@@ -58,7 +58,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &i32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("A", std::move(str));
diff --git a/src/writer/hlsl/generator_impl_array_accessor_test.cc b/src/writer/hlsl/generator_impl_array_accessor_test.cc
index 5842e7d..a3e6e59 100644
--- a/src/writer/hlsl/generator_impl_array_accessor_test.cc
+++ b/src/writer/hlsl/generator_impl_array_accessor_test.cc
@@ -31,9 +31,9 @@
 
 TEST_F(HlslGeneratorImplTest_Expression, EmitExpression_ArrayAccessor) {
   ast::type::I32Type i32;
-  auto lit = create<ast::SintLiteral>(&i32, 5);
-  auto idx = create<ast::ScalarConstructorExpression>(std::move(lit));
-  auto ary = create<ast::IdentifierExpression>("ary");
+  auto* lit = create<ast::SintLiteral>(&i32, 5);
+  auto* idx = create<ast::ScalarConstructorExpression>(std::move(lit));
+  auto* ary = create<ast::IdentifierExpression>("ary");
 
   ast::ArrayAccessorExpression expr(std::move(ary), std::move(idx));
 
@@ -42,8 +42,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Expression, EmitArrayAccessor) {
-  auto ary = create<ast::IdentifierExpression>("ary");
-  auto idx = create<ast::IdentifierExpression>("idx");
+  auto* ary = create<ast::IdentifierExpression>("ary");
+  auto* idx = create<ast::IdentifierExpression>("idx");
 
   ast::ArrayAccessorExpression expr(std::move(ary), std::move(idx));
 
diff --git a/src/writer/hlsl/generator_impl_assign_test.cc b/src/writer/hlsl/generator_impl_assign_test.cc
index 37103d4..bb13cc0 100644
--- a/src/writer/hlsl/generator_impl_assign_test.cc
+++ b/src/writer/hlsl/generator_impl_assign_test.cc
@@ -28,8 +28,8 @@
 using HlslGeneratorImplTest_Assign = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Assign, Emit_Assign) {
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
 
   gen.increment_indent();
diff --git a/src/writer/hlsl/generator_impl_binary_test.cc b/src/writer/hlsl/generator_impl_binary_test.cc
index 32918bd..ca333ca 100644
--- a/src/writer/hlsl/generator_impl_binary_test.cc
+++ b/src/writer/hlsl/generator_impl_binary_test.cc
@@ -54,8 +54,8 @@
 TEST_P(HlslBinaryTest, Emit) {
   auto params = GetParam();
 
-  auto left = create<ast::IdentifierExpression>("left");
-  auto right = create<ast::IdentifierExpression>("right");
+  auto* left = create<ast::IdentifierExpression>("left");
+  auto* right = create<ast::IdentifierExpression>("right");
 
   ast::BinaryExpression expr(params.op, std::move(left), std::move(right));
 
@@ -84,8 +84,8 @@
         BinaryData{"(left % right)", ast::BinaryOp::kModulo}));
 
 TEST_F(HlslGeneratorImplTest_Binary, Logical_And) {
-  auto left = create<ast::IdentifierExpression>("left");
-  auto right = create<ast::IdentifierExpression>("right");
+  auto* left = create<ast::IdentifierExpression>("left");
+  auto* right = create<ast::IdentifierExpression>("right");
 
   ast::BinaryExpression expr(ast::BinaryOp::kLogicalAnd, std::move(left),
                              std::move(right));
@@ -101,10 +101,10 @@
 
 TEST_F(HlslGeneratorImplTest_Binary, Logical_Multi) {
   // (a && b) || (c || d)
-  auto a = create<ast::IdentifierExpression>("a");
-  auto b = create<ast::IdentifierExpression>("b");
-  auto c = create<ast::IdentifierExpression>("c");
-  auto d = create<ast::IdentifierExpression>("d");
+  auto* a = create<ast::IdentifierExpression>("a");
+  auto* b = create<ast::IdentifierExpression>("b");
+  auto* c = create<ast::IdentifierExpression>("c");
+  auto* d = create<ast::IdentifierExpression>("d");
 
   ast::BinaryExpression expr(
       ast::BinaryOp::kLogicalOr,
@@ -131,8 +131,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Logical_Or) {
-  auto left = create<ast::IdentifierExpression>("left");
-  auto right = create<ast::IdentifierExpression>("right");
+  auto* left = create<ast::IdentifierExpression>("left");
+  auto* right = create<ast::IdentifierExpression>("right");
 
   ast::BinaryExpression expr(ast::BinaryOp::kLogicalOr, std::move(left),
                              std::move(right));
@@ -157,17 +157,17 @@
 
   ast::type::I32Type i32;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::ReturnStatement>(create<ast::ScalarConstructorExpression>(
           create<ast::SintLiteral>(&i32, 3))));
-  auto else_stmt = create<ast::ElseStatement>(std::move(body));
+  auto* else_stmt = create<ast::ElseStatement>(std::move(body));
 
   body = create<ast::BlockStatement>();
   body->append(
       create<ast::ReturnStatement>(create<ast::ScalarConstructorExpression>(
           create<ast::SintLiteral>(&i32, 2))));
-  auto else_if_stmt = create<ast::ElseStatement>(
+  auto* else_if_stmt = create<ast::ElseStatement>(
       create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr,
                                     create<ast::IdentifierExpression>("b"),
                                     create<ast::IdentifierExpression>("c")),
@@ -212,9 +212,9 @@
 
 TEST_F(HlslGeneratorImplTest_Binary, Return_WithLogical) {
   // return (a && b) || c;
-  auto a = create<ast::IdentifierExpression>("a");
-  auto b = create<ast::IdentifierExpression>("b");
-  auto c = create<ast::IdentifierExpression>("c");
+  auto* a = create<ast::IdentifierExpression>("a");
+  auto* b = create<ast::IdentifierExpression>("b");
+  auto* c = create<ast::IdentifierExpression>("c");
 
   ast::ReturnStatement expr(create<ast::BinaryExpression>(
       ast::BinaryOp::kLogicalOr,
@@ -237,10 +237,10 @@
 
 TEST_F(HlslGeneratorImplTest_Binary, Assign_WithLogical) {
   // a = (b || c) && d;
-  auto a = create<ast::IdentifierExpression>("a");
-  auto b = create<ast::IdentifierExpression>("b");
-  auto c = create<ast::IdentifierExpression>("c");
-  auto d = create<ast::IdentifierExpression>("d");
+  auto* a = create<ast::IdentifierExpression>("a");
+  auto* b = create<ast::IdentifierExpression>("b");
+  auto* c = create<ast::IdentifierExpression>("c");
+  auto* d = create<ast::IdentifierExpression>("d");
 
   ast::AssignmentStatement expr(
       std::move(a),
@@ -267,11 +267,11 @@
   // var a : bool = (b && c) || d;
   ast::type::BoolType bool_type;
 
-  auto b = create<ast::IdentifierExpression>("b");
-  auto c = create<ast::IdentifierExpression>("c");
-  auto d = create<ast::IdentifierExpression>("d");
+  auto* b = create<ast::IdentifierExpression>("b");
+  auto* c = create<ast::IdentifierExpression>("c");
+  auto* d = create<ast::IdentifierExpression>("d");
 
-  auto var =
+  auto* var =
       create<ast::Variable>("a", ast::StorageClass::kFunction, &bool_type);
   var->set_constructor(create<ast::BinaryExpression>(
       ast::BinaryOp::kLogicalOr,
@@ -298,9 +298,9 @@
   // as<i32>(a && (b || c))
   ast::type::I32Type i32;
 
-  auto a = create<ast::IdentifierExpression>("a");
-  auto b = create<ast::IdentifierExpression>("b");
-  auto c = create<ast::IdentifierExpression>("c");
+  auto* a = create<ast::IdentifierExpression>("a");
+  auto* b = create<ast::IdentifierExpression>("b");
+  auto* c = create<ast::IdentifierExpression>("c");
 
   ast::BitcastExpression expr(
       &i32, create<ast::BinaryExpression>(
@@ -326,8 +326,8 @@
 
   ast::type::VoidType void_type;
 
-  auto func = create<ast::Function>("foo", ast::VariableList{}, &void_type,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("foo", ast::VariableList{}, &void_type,
+                                     create<ast::BlockStatement>());
   mod.AddFunction(std::move(func));
 
   ast::ExpressionList params;
diff --git a/src/writer/hlsl/generator_impl_bitcast_test.cc b/src/writer/hlsl/generator_impl_bitcast_test.cc
index cfa6aec..d9b431c 100644
--- a/src/writer/hlsl/generator_impl_bitcast_test.cc
+++ b/src/writer/hlsl/generator_impl_bitcast_test.cc
@@ -31,7 +31,7 @@
 
 TEST_F(HlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Float) {
   ast::type::F32Type f32;
-  auto id = create<ast::IdentifierExpression>("id");
+  auto* id = create<ast::IdentifierExpression>("id");
   ast::BitcastExpression bitcast(&f32, std::move(id));
 
   ASSERT_TRUE(gen.EmitExpression(pre, out, &bitcast)) << gen.error();
@@ -40,7 +40,7 @@
 
 TEST_F(HlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Int) {
   ast::type::I32Type i32;
-  auto id = create<ast::IdentifierExpression>("id");
+  auto* id = create<ast::IdentifierExpression>("id");
   ast::BitcastExpression bitcast(&i32, std::move(id));
 
   ASSERT_TRUE(gen.EmitExpression(pre, out, &bitcast)) << gen.error();
@@ -49,7 +49,7 @@
 
 TEST_F(HlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Uint) {
   ast::type::U32Type u32;
-  auto id = create<ast::IdentifierExpression>("id");
+  auto* id = create<ast::IdentifierExpression>("id");
   ast::BitcastExpression bitcast(&u32, std::move(id));
 
   ASSERT_TRUE(gen.EmitExpression(pre, out, &bitcast)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_call_test.cc b/src/writer/hlsl/generator_impl_call_test.cc
index afac31a..8f816a7 100644
--- a/src/writer/hlsl/generator_impl_call_test.cc
+++ b/src/writer/hlsl/generator_impl_call_test.cc
@@ -32,11 +32,11 @@
 TEST_F(HlslGeneratorImplTest_Call, EmitExpression_Call_WithoutParams) {
   ast::type::VoidType void_type;
 
-  auto id = create<ast::IdentifierExpression>("my_func");
+  auto* id = create<ast::IdentifierExpression>("my_func");
   ast::CallExpression call(std::move(id), {});
 
-  auto func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
+                                     create<ast::BlockStatement>());
   mod.AddFunction(std::move(func));
 
   ASSERT_TRUE(gen.EmitExpression(pre, out, &call)) << gen.error();
@@ -46,14 +46,14 @@
 TEST_F(HlslGeneratorImplTest_Call, EmitExpression_Call_WithParams) {
   ast::type::VoidType void_type;
 
-  auto id = create<ast::IdentifierExpression>("my_func");
+  auto* id = create<ast::IdentifierExpression>("my_func");
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("param1"));
   params.push_back(create<ast::IdentifierExpression>("param2"));
   ast::CallExpression call(std::move(id), std::move(params));
 
-  auto func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
+                                     create<ast::BlockStatement>());
   mod.AddFunction(std::move(func));
 
   ASSERT_TRUE(gen.EmitExpression(pre, out, &call)) << gen.error();
@@ -63,15 +63,15 @@
 TEST_F(HlslGeneratorImplTest_Call, EmitStatement_Call) {
   ast::type::VoidType void_type;
 
-  auto id = create<ast::IdentifierExpression>("my_func");
+  auto* id = create<ast::IdentifierExpression>("my_func");
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("param1"));
   params.push_back(create<ast::IdentifierExpression>("param2"));
   ast::CallStatement call(
       create<ast::CallExpression>(std::move(id), std::move(params)));
 
-  auto func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
+                                     create<ast::BlockStatement>());
   mod.AddFunction(std::move(func));
   gen.increment_indent();
   ASSERT_TRUE(gen.EmitStatement(out, &call)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_case_test.cc b/src/writer/hlsl/generator_impl_case_test.cc
index bffb1e5..a63a570 100644
--- a/src/writer/hlsl/generator_impl_case_test.cc
+++ b/src/writer/hlsl/generator_impl_case_test.cc
@@ -33,7 +33,7 @@
 TEST_F(HlslGeneratorImplTest_Case, Emit_Case) {
   ast::type::I32Type i32;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::BreakStatement>());
 
   ast::CaseSelectorList lit;
@@ -68,7 +68,7 @@
 TEST_F(HlslGeneratorImplTest_Case, Emit_Case_WithFallthrough) {
   ast::type::I32Type i32;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::FallthroughStatement>());
 
   ast::CaseSelectorList lit;
@@ -87,7 +87,7 @@
 TEST_F(HlslGeneratorImplTest_Case, Emit_Case_MultipleSelectors) {
   ast::type::I32Type i32;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::BreakStatement>());
 
   ast::CaseSelectorList lit;
@@ -106,7 +106,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Case, Emit_Case_Default) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::BreakStatement>());
   ast::CaseStatement c(std::move(body));
 
diff --git a/src/writer/hlsl/generator_impl_constructor_test.cc b/src/writer/hlsl/generator_impl_constructor_test.cc
index 96ccff7..02f307b 100644
--- a/src/writer/hlsl/generator_impl_constructor_test.cc
+++ b/src/writer/hlsl/generator_impl_constructor_test.cc
@@ -37,7 +37,7 @@
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Bool) {
   ast::type::BoolType bool_type;
-  auto lit = create<ast::BoolLiteral>(&bool_type, false);
+  auto* lit = create<ast::BoolLiteral>(&bool_type, false);
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(pre, out, &expr)) << gen.error();
@@ -46,7 +46,7 @@
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Int) {
   ast::type::I32Type i32;
-  auto lit = create<ast::SintLiteral>(&i32, -12345);
+  auto* lit = create<ast::SintLiteral>(&i32, -12345);
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(pre, out, &expr)) << gen.error();
@@ -55,7 +55,7 @@
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_UInt) {
   ast::type::U32Type u32;
-  auto lit = create<ast::UintLiteral>(&u32, 56779);
+  auto* lit = create<ast::UintLiteral>(&u32, 56779);
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(pre, out, &expr)) << gen.error();
@@ -65,7 +65,8 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Float) {
   ast::type::F32Type f32;
   // Use a number close to 1<<30 but whose decimal representation ends in 0.
-  auto lit = create<ast::FloatLiteral>(&f32, static_cast<float>((1 << 30) - 4));
+  auto* lit =
+      create<ast::FloatLiteral>(&f32, static_cast<float>((1 << 30) - 4));
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(pre, out, &expr)) << gen.error();
@@ -75,7 +76,7 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Float) {
   ast::type::F32Type f32;
 
-  auto lit = create<ast::FloatLiteral>(&f32, -1.2e-5);
+  auto* lit = create<ast::FloatLiteral>(&f32, -1.2e-5);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
@@ -88,7 +89,7 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Bool) {
   ast::type::BoolType b;
 
-  auto lit = create<ast::BoolLiteral>(&b, true);
+  auto* lit = create<ast::BoolLiteral>(&b, true);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
@@ -101,7 +102,7 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Int) {
   ast::type::I32Type i32;
 
-  auto lit = create<ast::SintLiteral>(&i32, -12345);
+  auto* lit = create<ast::SintLiteral>(&i32, -12345);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
@@ -114,7 +115,7 @@
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Uint) {
   ast::type::U32Type u32;
 
-  auto lit = create<ast::UintLiteral>(&u32, 12345);
+  auto* lit = create<ast::UintLiteral>(&u32, 12345);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
@@ -128,9 +129,9 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec(&f32, 3);
 
-  auto lit1 = create<ast::FloatLiteral>(&f32, 1.f);
-  auto lit2 = create<ast::FloatLiteral>(&f32, 2.f);
-  auto lit3 = create<ast::FloatLiteral>(&f32, 3.f);
+  auto* lit1 = create<ast::FloatLiteral>(&f32, 1.f);
+  auto* lit2 = create<ast::FloatLiteral>(&f32, 2.f);
+  auto* lit3 = create<ast::FloatLiteral>(&f32, 3.f);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit1)));
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit2)));
@@ -165,11 +166,11 @@
   ast::ExpressionList mat_values;
 
   for (size_t i = 0; i < 2; i++) {
-    auto lit1 =
+    auto* lit1 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(1 + (i * 2)));
-    auto lit2 =
+    auto* lit2 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(2 + (i * 2)));
-    auto lit3 =
+    auto* lit3 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(3 + (i * 2)));
 
     ast::ExpressionList values;
@@ -201,11 +202,11 @@
   ast::ExpressionList ary_values;
 
   for (size_t i = 0; i < 3; i++) {
-    auto lit1 =
+    auto* lit1 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(1 + (i * 3)));
-    auto lit2 =
+    auto* lit2 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(2 + (i * 3)));
-    auto lit3 =
+    auto* lit3 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(3 + (i * 3)));
 
     ast::ExpressionList values;
diff --git a/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc b/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
index 594442f..8c0419a 100644
--- a/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
+++ b/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
@@ -53,26 +53,26 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("foo"),
       create<ast::IdentifierExpression>("foo")));
@@ -80,11 +80,11 @@
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("bar")));
 
-  auto func = create<ast::Function>("vtx_main", std::move(params), &f32,
-                                    std::move(body));
+  auto* func = create<ast::Function>("vtx_main", std::move(params), &f32,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
@@ -113,27 +113,27 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("foo"),
       create<ast::IdentifierExpression>("foo")));
@@ -141,11 +141,11 @@
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("bar")));
 
-  auto func = create<ast::Function>("vtx_main", std::move(params), &f32,
-                                    std::move(body));
+  auto* func = create<ast::Function>("vtx_main", std::move(params), &f32,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
@@ -174,27 +174,27 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("foo"),
       create<ast::IdentifierExpression>("foo")));
@@ -202,11 +202,11 @@
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("bar")));
 
-  auto func =
+  auto* func =
       create<ast::Function>("main", std::move(params), &f32, std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
@@ -235,26 +235,26 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("foo"),
       create<ast::IdentifierExpression>("foo")));
@@ -262,11 +262,11 @@
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("bar")));
 
-  auto func =
+  auto* func =
       create<ast::Function>("main", std::move(params), &f32, std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
@@ -292,26 +292,26 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("foo"),
       create<ast::IdentifierExpression>("foo")));
@@ -319,11 +319,11 @@
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("bar")));
 
-  auto func =
+  auto* func =
       create<ast::Function>("main", std::move(params), &f32, std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
@@ -344,26 +344,26 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("foo"),
       create<ast::IdentifierExpression>("foo")));
@@ -371,11 +371,11 @@
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("bar")));
 
-  auto func =
+  auto* func =
       create<ast::Function>("main", std::move(params), &f32, std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
@@ -403,7 +403,7 @@
   ast::type::VoidType void_type;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kInput, &vec4));
 
   ast::VariableDecorationList decos;
@@ -411,31 +411,31 @@
       create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  auto depth_var = create<ast::DecoratedVariable>(
+  auto* depth_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("depth", ast::StorageClass::kOutput, &f32));
   decos.push_back(
       create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  td.RegisterVariableForTesting(depth_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  td.RegisterVariableForTesting(depth_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
   mod.AddGlobalVariable(std::move(depth_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("depth"),
       create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("coord"),
           create<ast::IdentifierExpression>("x"))));
 
-  auto func = create<ast::Function>("main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
diff --git a/src/writer/hlsl/generator_impl_function_test.cc b/src/writer/hlsl/generator_impl_function_test.cc
index dd0c106..d987ff3 100644
--- a/src/writer/hlsl/generator_impl_function_test.cc
+++ b/src/writer/hlsl/generator_impl_function_test.cc
@@ -57,10 +57,10 @@
 TEST_F(HlslGeneratorImplTest_Function, Emit_Function) {
   ast::type::VoidType void_type;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
+                                     std::move(body));
 
   mod.AddFunction(std::move(func));
   gen.increment_indent();
@@ -76,10 +76,10 @@
 TEST_F(HlslGeneratorImplTest_Function, Emit_Function_Name_Collision) {
   ast::type::VoidType void_type;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("GeometryShader", ast::VariableList{},
-                                    &void_type, std::move(body));
+  auto* func = create<ast::Function>("GeometryShader", ast::VariableList{},
+                                     &void_type, std::move(body));
 
   mod.AddFunction(std::move(func));
   gen.increment_indent();
@@ -102,10 +102,10 @@
 
   ast::type::VoidType void_type;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("my_func", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("my_func", std::move(params), &void_type,
+                                     std::move(body));
 
   mod.AddFunction(std::move(func));
   gen.increment_indent();
@@ -123,32 +123,32 @@
   ast::type::VoidType void_type;
   ast::type::F32Type f32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("foo")));
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -179,7 +179,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kInput, &vec4));
 
   ast::VariableDecorationList decos;
@@ -187,28 +187,28 @@
       create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  auto depth_var = create<ast::DecoratedVariable>(
+  auto* depth_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("depth", ast::StorageClass::kOutput, &f32));
   decos.push_back(
       create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  td.RegisterVariableForTesting(depth_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  td.RegisterVariableForTesting(depth_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
   mod.AddGlobalVariable(std::move(depth_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("depth"),
       create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("coord"),
           create<ast::IdentifierExpression>("x"))));
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -239,7 +239,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kUniform, &vec4));
 
   ast::VariableDecorationList decos;
@@ -247,20 +247,20 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ast::VariableList params;
-  auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("coord"),
       create<ast::IdentifierExpression>("x")));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -290,12 +290,12 @@
   members.push_back(create<ast::StructMember>(
       "coord", &vec4, ast::StructMemberDecorationList{}));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Uniforms", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("uniforms", ast::StorageClass::kUniform, &s));
 
   mod.AddConstructedType(&s);
@@ -305,22 +305,22 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ast::VariableList params;
-  auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::MemberAccessorExpression>(
       create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("uniforms"),
           create<ast::IdentifierExpression>("coord")),
       create<ast::IdentifierExpression>("x")));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -357,13 +357,13 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
   ast::type::AccessControlType ac(ast::AccessControl::kReadWrite, &s);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
@@ -371,20 +371,20 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ast::VariableList params;
-  auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("coord"),
       create<ast::IdentifierExpression>("b")));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -417,13 +417,13 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
   ast::type::AccessControlType ac(ast::AccessControl::kReadOnly, &s);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
@@ -431,20 +431,20 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ast::VariableList params;
-  auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("coord"),
       create<ast::IdentifierExpression>("b")));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -477,13 +477,13 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
   ast::type::AccessControlType ac(ast::AccessControl::kReadWrite, &s);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
@@ -491,23 +491,23 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
 
   ast::VariableList params;
-  auto assign = create<ast::AssignmentStatement>(
+  auto* assign = create<ast::AssignmentStatement>(
       create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("coord"),
           create<ast::IdentifierExpression>("b")),
       create<ast::ScalarConstructorExpression>(
           create<ast::FloatLiteral>(&f32, 2.0f)));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(std::move(assign));
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -531,26 +531,26 @@
   ast::type::VoidType void_type;
   ast::type::F32Type f32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  auto val_var = create<ast::DecoratedVariable>(
+  auto* val_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("val", ast::StorageClass::kOutput, &f32));
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   val_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
-  td.RegisterVariableForTesting(val_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
+  td.RegisterVariableForTesting(val_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
@@ -560,7 +560,7 @@
   params.push_back(
       create<ast::Variable>("param", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("foo")));
@@ -569,8 +569,8 @@
       create<ast::IdentifierExpression>("param")));
   body->append(
       create<ast::ReturnStatement>(create<ast::IdentifierExpression>("foo")));
-  auto sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
-                                        std::move(body));
+  auto* sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
+                                         std::move(body));
 
   mod.AddFunction(std::move(sub_func));
 
@@ -584,8 +584,8 @@
       create<ast::CallExpression>(create<ast::IdentifierExpression>("sub_func"),
                                   std::move(expr))));
   body->append(create<ast::ReturnStatement>());
-  auto func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
-                                      std::move(body));
+  auto* func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
+                                       std::move(body));
   func_1->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -623,7 +623,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto depth_var = create<ast::DecoratedVariable>(
+  auto* depth_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("depth", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
@@ -631,7 +631,7 @@
       create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(depth_var.get());
+  td.RegisterVariableForTesting(depth_var);
 
   mod.AddGlobalVariable(std::move(depth_var));
 
@@ -639,11 +639,11 @@
   params.push_back(
       create<ast::Variable>("param", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::ReturnStatement>(create<ast::IdentifierExpression>("param")));
-  auto sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
-                                        std::move(body));
+  auto* sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
+                                         std::move(body));
 
   mod.AddFunction(std::move(sub_func));
 
@@ -657,8 +657,8 @@
       create<ast::CallExpression>(create<ast::IdentifierExpression>("sub_func"),
                                   std::move(expr))));
   body->append(create<ast::ReturnStatement>());
-  auto func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
-                                      std::move(body));
+  auto* func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
+                                       std::move(body));
   func_1->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -690,7 +690,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kInput, &vec4));
 
   ast::VariableDecorationList decos;
@@ -698,14 +698,14 @@
       create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  auto depth_var = create<ast::DecoratedVariable>(
+  auto* depth_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("depth", ast::StorageClass::kOutput, &f32));
   decos.push_back(
       create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  td.RegisterVariableForTesting(depth_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  td.RegisterVariableForTesting(depth_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
   mod.AddGlobalVariable(std::move(depth_var));
@@ -714,7 +714,7 @@
   params.push_back(
       create<ast::Variable>("param", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("depth"),
       create<ast::MemberAccessorExpression>(
@@ -722,8 +722,8 @@
           create<ast::IdentifierExpression>("x"))));
   body->append(
       create<ast::ReturnStatement>(create<ast::IdentifierExpression>("param")));
-  auto sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
-                                        std::move(body));
+  auto* sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
+                                         std::move(body));
 
   mod.AddFunction(std::move(sub_func));
 
@@ -737,8 +737,8 @@
       create<ast::CallExpression>(create<ast::IdentifierExpression>("sub_func"),
                                   std::move(expr))));
   body->append(create<ast::ReturnStatement>());
-  auto func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
-                                      std::move(body));
+  auto* func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
+                                       std::move(body));
   func_1->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -774,7 +774,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kUniform, &vec4));
 
   ast::VariableDecorationList decos;
@@ -782,7 +782,7 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
 
@@ -790,13 +790,13 @@
   params.push_back(
       create<ast::Variable>("param", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::ReturnStatement>(create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("coord"),
           create<ast::IdentifierExpression>("x"))));
-  auto sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
-                                        std::move(body));
+  auto* sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
+                                         std::move(body));
 
   mod.AddFunction(std::move(sub_func));
 
@@ -804,15 +804,15 @@
   expr.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0f)));
 
-  auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::CallExpression>(
       create<ast::IdentifierExpression>("sub_func"), std::move(expr)));
 
   body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -842,7 +842,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
   ast::type::AccessControlType ac(ast::AccessControl::kReadWrite, &vec4);
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
@@ -850,7 +850,7 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
 
@@ -858,13 +858,13 @@
   params.push_back(
       create<ast::Variable>("param", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::ReturnStatement>(create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("coord"),
           create<ast::IdentifierExpression>("x"))));
-  auto sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
-                                        std::move(body));
+  auto* sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
+                                         std::move(body));
 
   mod.AddFunction(std::move(sub_func));
 
@@ -872,15 +872,15 @@
   expr.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0f)));
 
-  auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::CallExpression>(
       create<ast::IdentifierExpression>("sub_func"), std::move(expr)));
 
   body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -908,23 +908,23 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(bar_var);
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("bar"),
       create<ast::ScalarConstructorExpression>(
           create<ast::FloatLiteral>(&f32, 1.0f))));
 
-  auto list = create<ast::BlockStatement>();
+  auto* list = create<ast::BlockStatement>();
   list->append(create<ast::ReturnStatement>());
 
   body->append(create<ast::IfStatement>(
@@ -936,8 +936,8 @@
       std::move(list)));
 
   body->append(create<ast::ReturnStatement>());
-  auto func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
-                                      std::move(body));
+  auto* func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
+                                       std::move(body));
   func_1->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -965,8 +965,8 @@
        Emit_FunctionDecoration_EntryPoint_WithNameCollision) {
   ast::type::VoidType void_type;
 
-  auto func = create<ast::Function>("GeometryShader", ast::VariableList{},
-                                    &void_type, create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("GeometryShader", ast::VariableList{},
+                                     &void_type, create<ast::BlockStatement>());
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -984,10 +984,10 @@
   ast::type::VoidType void_type;
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
@@ -1008,10 +1008,10 @@
   ast::type::VoidType void_type;
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
   func->add_decoration(create<ast::WorkgroupDecoration>(2u, 4u, 6u, Source{}));
@@ -1037,10 +1037,10 @@
 
   ast::type::VoidType void_type;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("my_func", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("my_func", std::move(params), &void_type,
+                                     std::move(body));
 
   mod.AddFunction(std::move(func));
   gen.increment_indent();
@@ -1082,12 +1082,12 @@
   ast::StructDecorationList s_decos;
   s_decos.push_back(create<ast::StructBlockDecoration>(Source{}));
 
-  auto str = create<ast::Struct>(std::move(s_decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(s_decos), std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
   ast::type::AccessControlType ac(ast::AccessControl::kReadWrite, &s);
 
-  auto data_var = create<ast::DecoratedVariable>(
+  auto* data_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
@@ -1096,21 +1096,21 @@
   data_var->set_decorations(std::move(decos));
 
   mod.AddConstructedType(&s);
-  td.RegisterVariableForTesting(data_var.get());
+  td.RegisterVariableForTesting(data_var);
   mod.AddGlobalVariable(std::move(data_var));
 
   {
     ast::VariableList params;
-    auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+    auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
     var->set_constructor(create<ast::MemberAccessorExpression>(
         create<ast::IdentifierExpression>("data"),
         create<ast::IdentifierExpression>("d")));
 
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
     body->append(create<ast::VariableDeclStatement>(std::move(var)));
     body->append(create<ast::ReturnStatement>());
-    auto func = create<ast::Function>("a", std::move(params), &void_type,
-                                      std::move(body));
+    auto* func = create<ast::Function>("a", std::move(params), &void_type,
+                                       std::move(body));
     func->add_decoration(
         create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
@@ -1119,16 +1119,16 @@
 
   {
     ast::VariableList params;
-    auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+    auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
     var->set_constructor(create<ast::MemberAccessorExpression>(
         create<ast::IdentifierExpression>("data"),
         create<ast::IdentifierExpression>("d")));
 
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
     body->append(create<ast::VariableDeclStatement>(std::move(var)));
     body->append(create<ast::ReturnStatement>());
-    auto func = create<ast::Function>("b", std::move(params), &void_type,
-                                      std::move(body));
+    auto* func = create<ast::Function>("b", std::move(params), &void_type,
+                                       std::move(body));
     func->add_decoration(
         create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
diff --git a/src/writer/hlsl/generator_impl_if_test.cc b/src/writer/hlsl/generator_impl_if_test.cc
index f1a4277..e494c8d 100644
--- a/src/writer/hlsl/generator_impl_if_test.cc
+++ b/src/writer/hlsl/generator_impl_if_test.cc
@@ -27,8 +27,8 @@
 using HlslGeneratorImplTest_If = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_If, Emit_If) {
-  auto cond = create<ast::IdentifierExpression>("cond");
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>("cond");
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
@@ -42,16 +42,16 @@
 }
 
 TEST_F(HlslGeneratorImplTest_If, Emit_IfWithElseIf) {
-  auto else_cond = create<ast::IdentifierExpression>("else_cond");
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_cond = create<ast::IdentifierExpression>("else_cond");
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(create<ast::ReturnStatement>());
 
   ast::ElseStatementList elses;
   elses.push_back(
       create<ast::ElseStatement>(std::move(else_cond), std::move(else_body)));
 
-  auto cond = create<ast::IdentifierExpression>("cond");
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>("cond");
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
@@ -71,14 +71,14 @@
 }
 
 TEST_F(HlslGeneratorImplTest_If, Emit_IfWithElse) {
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(create<ast::ReturnStatement>());
 
   ast::ElseStatementList elses;
   elses.push_back(create<ast::ElseStatement>(std::move(else_body)));
 
-  auto cond = create<ast::IdentifierExpression>("cond");
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>("cond");
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
@@ -96,12 +96,12 @@
 }
 
 TEST_F(HlslGeneratorImplTest_If, Emit_IfWithMultiple) {
-  auto else_cond = create<ast::IdentifierExpression>("else_cond");
+  auto* else_cond = create<ast::IdentifierExpression>("else_cond");
 
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(create<ast::ReturnStatement>());
 
-  auto else_body_2 = create<ast::BlockStatement>();
+  auto* else_body_2 = create<ast::BlockStatement>();
   else_body_2->append(create<ast::ReturnStatement>());
 
   ast::ElseStatementList elses;
@@ -109,8 +109,8 @@
       create<ast::ElseStatement>(std::move(else_cond), std::move(else_body)));
   elses.push_back(create<ast::ElseStatement>(std::move(else_body_2)));
 
-  auto cond = create<ast::IdentifierExpression>("cond");
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>("cond");
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
diff --git a/src/writer/hlsl/generator_impl_import_test.cc b/src/writer/hlsl/generator_impl_import_test.cc
index 7df6c9e..aa6f7d5 100644
--- a/src/writer/hlsl/generator_impl_import_test.cc
+++ b/src/writer/hlsl/generator_impl_import_test.cc
@@ -57,7 +57,7 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident = create<ast::IdentifierExpression>(param.name);
   ast::CallExpression expr(std::move(ident), std::move(params));
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -272,7 +272,7 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat(&f32, 3, 3);
 
-  auto var = create<ast::Variable>("var", ast::StorageClass::kFunction, &mat);
+  auto* var = create<ast::Variable>("var", ast::StorageClass::kFunction, &mat);
 
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("var"));
diff --git a/src/writer/hlsl/generator_impl_intrinsic_test.cc b/src/writer/hlsl/generator_impl_intrinsic_test.cc
index 6b4a678..38aebb3 100644
--- a/src/writer/hlsl/generator_impl_intrinsic_test.cc
+++ b/src/writer/hlsl/generator_impl_intrinsic_test.cc
@@ -76,8 +76,8 @@
   ast::type::VectorType vec2(&f32, 2);
   ast::type::VectorType vec3(&f32, 3);
 
-  auto a = create<ast::Variable>("a", ast::StorageClass::kNone, &vec2);
-  auto b = create<ast::Variable>("b", ast::StorageClass::kNone, &vec3);
+  auto* a = create<ast::Variable>("a", ast::StorageClass::kNone, &vec2);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kNone, &vec3);
 
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("a"));
@@ -86,8 +86,8 @@
   ast::CallExpression call(create<ast::IdentifierExpression>("outer_product"),
                            std::move(params));
 
-  td.RegisterVariableForTesting(a.get());
-  td.RegisterVariableForTesting(b.get());
+  td.RegisterVariableForTesting(a);
+  td.RegisterVariableForTesting(b);
 
   mod.AddGlobalVariable(std::move(a));
   mod.AddGlobalVariable(std::move(b));
diff --git a/src/writer/hlsl/generator_impl_loop_test.cc b/src/writer/hlsl/generator_impl_loop_test.cc
index 7416cd1..05579df 100644
--- a/src/writer/hlsl/generator_impl_loop_test.cc
+++ b/src/writer/hlsl/generator_impl_loop_test.cc
@@ -34,7 +34,7 @@
 using HlslGeneratorImplTest_Loop = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Loop, Emit_Loop) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
 
   ast::LoopStatement l(std::move(body), {});
@@ -48,10 +48,10 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Loop, Emit_LoopWithContinuing) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
 
-  auto continuing = create<ast::BlockStatement>();
+  auto* continuing = create<ast::BlockStatement>();
   continuing->append(create<ast::ReturnStatement>());
 
   ast::LoopStatement l(std::move(body), std::move(continuing));
@@ -75,20 +75,20 @@
 TEST_F(HlslGeneratorImplTest_Loop, Emit_LoopNestedWithContinuing) {
   ast::type::F32Type f32;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
 
-  auto continuing = create<ast::BlockStatement>();
+  auto* continuing = create<ast::BlockStatement>();
   continuing->append(create<ast::ReturnStatement>());
 
-  auto inner =
+  auto* inner =
       create<ast::LoopStatement>(std::move(body), std::move(continuing));
 
   body = create<ast::BlockStatement>();
   body->append(std::move(inner));
 
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
 
   continuing = create<ast::BlockStatement>();
   continuing->append(
@@ -146,19 +146,19 @@
 
   ast::type::F32Type f32;
 
-  auto var = create<ast::Variable>("lhs", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("lhs", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.4)));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::VariableDeclStatement>(
       create<ast::Variable>("other", ast::StorageClass::kFunction, &f32)));
 
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
 
-  auto continuing = create<ast::BlockStatement>();
+  auto* continuing = create<ast::BlockStatement>();
   continuing->append(
       create<ast::AssignmentStatement>(std::move(lhs), std::move(rhs)));
 
diff --git a/src/writer/hlsl/generator_impl_member_accessor_test.cc b/src/writer/hlsl/generator_impl_member_accessor_test.cc
index 61f1df5..74ea63f 100644
--- a/src/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -54,21 +54,21 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(create<ast::StructMember>("mem", &f32, std::move(deco)));
 
-  auto strct = create<ast::Struct>();
+  auto* strct = create<ast::Struct>();
   strct->set_members(std::move(members));
 
   ast::type::StructType s("Str", std::move(strct));
 
-  auto str_var = create<ast::DecoratedVariable>(
+  auto* str_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("str", ast::StorageClass::kPrivate, &s));
 
-  auto str = create<ast::IdentifierExpression>("str");
-  auto mem = create<ast::IdentifierExpression>("mem");
+  auto* str = create<ast::IdentifierExpression>("str");
+  auto* mem = create<ast::IdentifierExpression>("mem");
 
   ast::MemberAccessorExpression expr(std::move(str), std::move(mem));
 
-  td.RegisterVariableForTesting(str_var.get());
-  gen.register_global(str_var.get());
+  td.RegisterVariableForTesting(str_var);
+  gen.register_global(str_var);
   mod.AddGlobalVariable(std::move(str_var));
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -98,19 +98,19 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
   ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
                                      create<ast::IdentifierExpression>("b"));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -142,19 +142,19 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
   ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
                                      create<ast::IdentifierExpression>("a"));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -189,27 +189,27 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("a", &mat, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto b_var = create<ast::Variable>("b", ast::StorageClass::kPrivate, &mat);
+  auto* b_var = create<ast::Variable>("b", ast::StorageClass::kPrivate, &mat);
 
-  auto coord_var =
+  auto* coord_var =
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s);
 
-  auto lhs = create<ast::MemberAccessorExpression>(
+  auto* lhs = create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("data"),
       create<ast::IdentifierExpression>("a"));
-  auto rhs = create<ast::IdentifierExpression>("b");
+  auto* rhs = create<ast::IdentifierExpression>("b");
 
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  td.RegisterVariableForTesting(b_var.get());
-  gen.register_global(coord_var.get());
-  gen.register_global(b_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  td.RegisterVariableForTesting(b_var);
+  gen.register_global(coord_var);
+  gen.register_global(b_var);
   mod.AddGlobalVariable(std::move(coord_var));
   mod.AddGlobalVariable(std::move(b_var));
 
@@ -249,24 +249,24 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("a", &mat, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
-  auto lhs = create<ast::MemberAccessorExpression>(
+  auto* lhs = create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("data"),
       create<ast::IdentifierExpression>("a"));
-  auto rhs =
+  auto* rhs =
       create<ast::TypeConstructorExpression>(&mat, ast::ExpressionList{});
 
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -305,19 +305,19 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("a", &mat, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
   ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
                                      create<ast::IdentifierExpression>("a"));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -356,19 +356,19 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("a", &mat, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
   ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
                                      create<ast::IdentifierExpression>("a"));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -400,19 +400,19 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(create<ast::StructMember>("a", &mat, std::move(deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
   ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
                                      create<ast::IdentifierExpression>("a"));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -447,12 +447,12 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(create<ast::StructMember>("a", &mat, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
   ast::ArrayAccessorExpression expr(
@@ -465,8 +465,8 @@
       create<ast::ScalarConstructorExpression>(
           create<ast::SintLiteral>(&i32, 1)));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -497,12 +497,12 @@
   a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(create<ast::StructMember>("a", &ary, std::move(a_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
   ast::ArrayAccessorExpression expr(
@@ -512,8 +512,8 @@
       create<ast::ScalarConstructorExpression>(
           create<ast::SintLiteral>(&i32, 2)));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -544,12 +544,12 @@
   a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(create<ast::StructMember>("a", &ary, std::move(a_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
   ast::ArrayAccessorExpression expr(
@@ -567,8 +567,8 @@
           create<ast::ScalarConstructorExpression>(
               create<ast::SintLiteral>(&i32, 3))));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -601,24 +601,24 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
-  auto lhs = create<ast::MemberAccessorExpression>(
+  auto* lhs = create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("data"),
       create<ast::IdentifierExpression>("b"));
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0f));
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
 
@@ -650,27 +650,27 @@
   a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(create<ast::StructMember>("a", &ary, std::move(a_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
-  auto lhs = create<ast::ArrayAccessorExpression>(
+  auto* lhs = create<ast::ArrayAccessorExpression>(
       create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("data"),
           create<ast::IdentifierExpression>("a")),
       create<ast::ScalarConstructorExpression>(
           create<ast::SintLiteral>(&i32, 2)));
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
 
@@ -703,24 +703,24 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
-  auto lhs = create<ast::MemberAccessorExpression>(
+  auto* lhs = create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("data"),
       create<ast::IdentifierExpression>("a"));
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2));
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
 
@@ -755,16 +755,16 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(create<ast::StructMember>("b", &fvec3, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -802,32 +802,32 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(create<ast::StructMember>("b", &fvec3, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
-  auto lit1 = create<ast::FloatLiteral>(&f32, 1.f);
-  auto lit2 = create<ast::FloatLiteral>(&f32, 2.f);
-  auto lit3 = create<ast::FloatLiteral>(&f32, 3.f);
+  auto* lit1 = create<ast::FloatLiteral>(&f32, 1.f);
+  auto* lit2 = create<ast::FloatLiteral>(&f32, 2.f);
+  auto* lit3 = create<ast::FloatLiteral>(&f32, 3.f);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit1)));
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit2)));
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit3)));
 
-  auto lhs = create<ast::MemberAccessorExpression>(
+  auto* lhs = create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("data"),
       create<ast::IdentifierExpression>("b"));
-  auto rhs = create<ast::TypeConstructorExpression>(&fvec3, std::move(values));
+  auto* rhs = create<ast::TypeConstructorExpression>(&fvec3, std::move(values));
 
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
 
@@ -867,7 +867,7 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(create<ast::StructMember>("b", &fvec3, std::move(deco)));
 
-  auto data_str = create<ast::Struct>();
+  auto* data_str = create<ast::Struct>();
   data_str->set_members(std::move(members));
 
   ast::type::StructType data("Data", std::move(data_str));
@@ -880,16 +880,16 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(create<ast::StructMember>("c", &ary, std::move(deco)));
 
-  auto pre_str = create<ast::Struct>();
+  auto* pre_str = create<ast::Struct>();
   pre_str->set_members(std::move(members));
 
   ast::type::StructType pre_struct("Pre", std::move(pre_str));
 
-  auto coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
+  auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
       "data", ast::StorageClass::kStorageBuffer, &pre_struct));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -936,7 +936,7 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(create<ast::StructMember>("b", &fvec3, std::move(deco)));
 
-  auto data_str = create<ast::Struct>();
+  auto* data_str = create<ast::Struct>();
   data_str->set_members(std::move(members));
 
   ast::type::StructType data("Data", std::move(data_str));
@@ -949,16 +949,16 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(create<ast::StructMember>("c", &ary, std::move(deco)));
 
-  auto pre_str = create<ast::Struct>();
+  auto* pre_str = create<ast::Struct>();
   pre_str->set_members(std::move(members));
 
   ast::type::StructType pre_struct("Pre", std::move(pre_str));
 
-  auto coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
+  auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
       "data", ast::StorageClass::kStorageBuffer, &pre_struct));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -1008,7 +1008,7 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(create<ast::StructMember>("b", &fvec3, std::move(deco)));
 
-  auto data_str = create<ast::Struct>();
+  auto* data_str = create<ast::Struct>();
   data_str->set_members(std::move(members));
 
   ast::type::StructType data("Data", std::move(data_str));
@@ -1021,16 +1021,16 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(create<ast::StructMember>("c", &ary, std::move(deco)));
 
-  auto pre_str = create<ast::Struct>();
+  auto* pre_str = create<ast::Struct>();
   pre_str->set_members(std::move(members));
 
   ast::type::StructType pre_struct("Pre", std::move(pre_str));
 
-  auto coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
+  auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
       "data", ast::StorageClass::kStorageBuffer, &pre_struct));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -1079,7 +1079,7 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(create<ast::StructMember>("b", &fvec3, std::move(deco)));
 
-  auto data_str = create<ast::Struct>();
+  auto* data_str = create<ast::Struct>();
   data_str->set_members(std::move(members));
 
   ast::type::StructType data("Data", std::move(data_str));
@@ -1092,16 +1092,16 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(create<ast::StructMember>("c", &ary, std::move(deco)));
 
-  auto pre_str = create<ast::Struct>();
+  auto* pre_str = create<ast::Struct>();
   pre_str->set_members(std::move(members));
 
   ast::type::StructType pre_struct("Pre", std::move(pre_str));
 
-  auto coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
+  auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
       "data", ast::StorageClass::kStorageBuffer, &pre_struct));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
@@ -1151,7 +1151,7 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(create<ast::StructMember>("b", &fvec3, std::move(deco)));
 
-  auto data_str = create<ast::Struct>();
+  auto* data_str = create<ast::Struct>();
   data_str->set_members(std::move(members));
 
   ast::type::StructType data("Data", std::move(data_str));
@@ -1164,21 +1164,21 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(create<ast::StructMember>("c", &ary, std::move(deco)));
 
-  auto pre_str = create<ast::Struct>();
+  auto* pre_str = create<ast::Struct>();
   pre_str->set_members(std::move(members));
 
   ast::type::StructType pre_struct("Pre", std::move(pre_str));
 
-  auto coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
+  auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
       "data", ast::StorageClass::kStorageBuffer, &pre_struct));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
-  auto lhs = create<ast::MemberAccessorExpression>(
+  auto* lhs = create<ast::MemberAccessorExpression>(
       create<ast::ArrayAccessorExpression>(
           create<ast::MemberAccessorExpression>(
               create<ast::IdentifierExpression>("data"),
@@ -1187,15 +1187,15 @@
               create<ast::SintLiteral>(&i32, 2))),
       create<ast::IdentifierExpression>("b"));
 
-  auto lit1 = create<ast::FloatLiteral>(&f32, 1.f);
-  auto lit2 = create<ast::FloatLiteral>(&f32, 2.f);
-  auto lit3 = create<ast::FloatLiteral>(&f32, 3.f);
+  auto* lit1 = create<ast::FloatLiteral>(&f32, 1.f);
+  auto* lit2 = create<ast::FloatLiteral>(&f32, 2.f);
+  auto* lit3 = create<ast::FloatLiteral>(&f32, 3.f);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit1)));
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit2)));
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit3)));
 
-  auto rhs = create<ast::TypeConstructorExpression>(&fvec3, std::move(values));
+  auto* rhs = create<ast::TypeConstructorExpression>(&fvec3, std::move(values));
 
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
 
@@ -1235,7 +1235,7 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(create<ast::StructMember>("b", &fvec3, std::move(deco)));
 
-  auto data_str = create<ast::Struct>();
+  auto* data_str = create<ast::Struct>();
   data_str->set_members(std::move(members));
 
   ast::type::StructType data("Data", std::move(data_str));
@@ -1248,21 +1248,21 @@
   deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(create<ast::StructMember>("c", &ary, std::move(deco)));
 
-  auto pre_str = create<ast::Struct>();
+  auto* pre_str = create<ast::Struct>();
   pre_str->set_members(std::move(members));
 
   ast::type::StructType pre_struct("Pre", std::move(pre_str));
 
-  auto coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
+  auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
       "data", ast::StorageClass::kStorageBuffer, &pre_struct));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  gen.register_global(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  gen.register_global(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ASSERT_TRUE(td.Determine()) << td.error();
 
-  auto lhs = create<ast::MemberAccessorExpression>(
+  auto* lhs = create<ast::MemberAccessorExpression>(
       create<ast::MemberAccessorExpression>(
           create<ast::ArrayAccessorExpression>(
               create<ast::MemberAccessorExpression>(
@@ -1273,7 +1273,7 @@
           create<ast::IdentifierExpression>("b")),
       create<ast::IdentifierExpression>("y"));
 
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&i32, 1.f));
 
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
diff --git a/src/writer/hlsl/generator_impl_module_constant_test.cc b/src/writer/hlsl/generator_impl_module_constant_test.cc
index f4e2e43..98e900f 100644
--- a/src/writer/hlsl/generator_impl_module_constant_test.cc
+++ b/src/writer/hlsl/generator_impl_module_constant_test.cc
@@ -45,12 +45,12 @@
   exprs.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto var = create<ast::Variable>("pos", ast::StorageClass::kNone, &ary);
+  auto* var = create<ast::Variable>("pos", ast::StorageClass::kNone, &ary);
   var->set_is_const(true);
   var->set_constructor(
       create<ast::TypeConstructorExpression>(&ary, std::move(exprs)));
 
-  ASSERT_TRUE(gen.EmitProgramConstVariable(out, var.get())) << gen.error();
+  ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
   EXPECT_EQ(
       result(),
       "static const float pos[3] = {1.00000000f, 2.00000000f, 3.00000000f};\n");
@@ -62,14 +62,14 @@
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::ConstantIdDecoration>(23, Source{}));
 
-  auto var = create<ast::DecoratedVariable>(
+  auto* var = create<ast::DecoratedVariable>(
       create<ast::Variable>("pos", ast::StorageClass::kNone, &f32));
   var->set_decorations(std::move(decos));
   var->set_is_const(true);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  ASSERT_TRUE(gen.EmitProgramConstVariable(out, var.get())) << gen.error();
+  ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
   EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23
 #define WGSL_SPEC_CONSTANT_23 3.00000000f
 #endif
@@ -84,12 +84,12 @@
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::ConstantIdDecoration>(23, Source{}));
 
-  auto var = create<ast::DecoratedVariable>(
+  auto* var = create<ast::DecoratedVariable>(
       create<ast::Variable>("pos", ast::StorageClass::kNone, &f32));
   var->set_decorations(std::move(decos));
   var->set_is_const(true);
 
-  ASSERT_TRUE(gen.EmitProgramConstVariable(out, var.get())) << gen.error();
+  ASSERT_TRUE(gen.EmitProgramConstVariable(out, var)) << gen.error();
   EXPECT_EQ(result(), R"(#ifndef WGSL_SPEC_CONSTANT_23
 #error spec constant required for constant id 23
 #endif
diff --git a/src/writer/hlsl/generator_impl_return_test.cc b/src/writer/hlsl/generator_impl_return_test.cc
index 7488c3c..75473b0 100644
--- a/src/writer/hlsl/generator_impl_return_test.cc
+++ b/src/writer/hlsl/generator_impl_return_test.cc
@@ -36,7 +36,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Return, Emit_ReturnWithValue) {
-  auto expr = create<ast::IdentifierExpression>("expr");
+  auto* expr = create<ast::IdentifierExpression>("expr");
   ast::ReturnStatement r(std::move(expr));
   gen.increment_indent();
 
diff --git a/src/writer/hlsl/generator_impl_switch_test.cc b/src/writer/hlsl/generator_impl_switch_test.cc
index a80d7e9..4104939 100644
--- a/src/writer/hlsl/generator_impl_switch_test.cc
+++ b/src/writer/hlsl/generator_impl_switch_test.cc
@@ -31,25 +31,25 @@
 using HlslGeneratorImplTest_Switch = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Switch, Emit_Switch) {
-  auto def_body = create<ast::BlockStatement>();
+  auto* def_body = create<ast::BlockStatement>();
   def_body->append(create<ast::BreakStatement>());
-  auto def = create<ast::CaseStatement>(std::move(def_body));
+  auto* def = create<ast::CaseStatement>(std::move(def_body));
 
   ast::type::I32Type i32;
   ast::CaseSelectorList case_val;
   case_val.push_back(create<ast::SintLiteral>(&i32, 5));
 
-  auto case_body = create<ast::BlockStatement>();
+  auto* case_body = create<ast::BlockStatement>();
   case_body->append(create<ast::BreakStatement>());
 
-  auto case_stmt =
+  auto* case_stmt =
       create<ast::CaseStatement>(std::move(case_val), std::move(case_body));
 
   ast::CaseStatementList body;
   body.push_back(std::move(case_stmt));
   body.push_back(std::move(def));
 
-  auto cond = create<ast::IdentifierExpression>("cond");
+  auto* cond = create<ast::IdentifierExpression>("cond");
   ast::SwitchStatement s(std::move(cond), std::move(body));
   gen.increment_indent();
 
diff --git a/src/writer/hlsl/generator_impl_test.cc b/src/writer/hlsl/generator_impl_test.cc
index 9e09772..7f11b76 100644
--- a/src/writer/hlsl/generator_impl_test.cc
+++ b/src/writer/hlsl/generator_impl_test.cc
@@ -29,8 +29,8 @@
 
 TEST_F(HlslGeneratorImplTest, Generate) {
   ast::type::VoidType void_type;
-  auto func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
+                                     create<ast::BlockStatement>());
   mod.AddFunction(std::move(func));
 
   ASSERT_TRUE(gen.Generate(out)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_type_test.cc b/src/writer/hlsl/generator_impl_type_test.cc
index 2fec741..b507f6b 100644
--- a/src/writer/hlsl/generator_impl_type_test.cc
+++ b/src/writer/hlsl/generator_impl_type_test.cc
@@ -181,7 +181,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -206,7 +206,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -231,7 +231,7 @@
   decos.push_back(create<ast::StructMemberOffsetDecoration>(128, Source{}));
   members.push_back(create<ast::StructMember>("c", &f32, std::move(decos)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -259,7 +259,7 @@
   members.push_back(
       create<ast::StructMember>("float", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -288,7 +288,7 @@
   ast::StructDecorationList decos;
   decos.push_back(create<ast::StructBlockDecoration>(Source{}));
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
 
   ast::type::StructType s("S", std::move(str));
 
diff --git a/src/writer/hlsl/generator_impl_unary_op_test.cc b/src/writer/hlsl/generator_impl_unary_op_test.cc
index 8fbf826..30b25d0 100644
--- a/src/writer/hlsl/generator_impl_unary_op_test.cc
+++ b/src/writer/hlsl/generator_impl_unary_op_test.cc
@@ -37,7 +37,7 @@
 TEST_P(HlslUnaryOpTest, Emit) {
   auto params = GetParam();
 
-  auto expr = create<ast::IdentifierExpression>("expr");
+  auto* expr = create<ast::IdentifierExpression>("expr");
   ast::UnaryOpExpression op(params.op, std::move(expr));
 
   ASSERT_TRUE(gen.EmitExpression(pre, out, &op)) << gen.error();
diff --git a/src/writer/hlsl/generator_impl_variable_decl_statement_test.cc b/src/writer/hlsl/generator_impl_variable_decl_statement_test.cc
index 651efd4..f48ea87 100644
--- a/src/writer/hlsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/writer/hlsl/generator_impl_variable_decl_statement_test.cc
@@ -34,7 +34,7 @@
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement) {
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
 
   ast::VariableDeclStatement stmt(std::move(var));
   gen.increment_indent();
@@ -45,7 +45,7 @@
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var->set_is_const(true);
 
   ast::VariableDeclStatement stmt(std::move(var));
@@ -59,7 +59,7 @@
   ast::type::F32Type f32;
   ast::type::ArrayType ary(&f32, 5);
 
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &ary);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &ary);
 
   ast::VariableDeclStatement stmt(std::move(var));
   gen.increment_indent();
@@ -71,7 +71,7 @@
 TEST_F(HlslGeneratorImplTest_VariableDecl,
        Emit_VariableDeclStatement_Function) {
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kFunction, &f32);
 
   ast::VariableDeclStatement stmt(std::move(var));
   gen.increment_indent();
@@ -82,7 +82,7 @@
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) {
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kPrivate, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kPrivate, &f32);
 
   ast::VariableDeclStatement stmt(std::move(var));
   gen.increment_indent();
@@ -93,10 +93,10 @@
 
 TEST_F(HlslGeneratorImplTest_VariableDecl,
        Emit_VariableDeclStatement_Initializer_Private) {
-  auto ident = create<ast::IdentifierExpression>("initializer");
+  auto* ident = create<ast::IdentifierExpression>("initializer");
 
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var->set_constructor(std::move(ident));
 
   ast::VariableDeclStatement stmt(std::move(var));
@@ -111,10 +111,10 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList values;
-  auto zero_vec =
+  auto* zero_vec =
       create<ast::TypeConstructorExpression>(&vec, std::move(values));
 
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &vec);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &vec);
   var->set_constructor(std::move(zero_vec));
 
   ast::VariableDeclStatement stmt(std::move(var));
@@ -129,10 +129,10 @@
   ast::type::MatrixType mat(&f32, 3, 2);
 
   ast::ExpressionList values;
-  auto zero_mat =
+  auto* zero_mat =
       create<ast::TypeConstructorExpression>(&mat, std::move(values));
 
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &mat);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &mat);
   var->set_constructor(std::move(zero_mat));
 
   ast::VariableDeclStatement stmt(std::move(var));
diff --git a/src/writer/hlsl/test_helper.h b/src/writer/hlsl/test_helper.h
index 121f497..b55f542 100644
--- a/src/writer/hlsl/test_helper.h
+++ b/src/writer/hlsl/test_helper.h
@@ -43,11 +43,13 @@
   /// @returns the pre result string
   std::string pre_result() const { return pre.str(); }
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer  template <typename T, typename... ARGS>
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx.create<T>(std::forward<ARGS>(args)...);
   }
 
   /// The context
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 38c2f48..eecb08e 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -111,8 +111,8 @@
 bool GeneratorImpl::Generate() {
   out_ << "#include <metal_stdlib>" << std::endl << std::endl;
 
-  for (const auto& global : module_->global_variables()) {
-    global_variables_.set(global->name(), global.get());
+  for (auto* global : module_->global_variables()) {
+    global_variables_.set(global->name(), global);
   }
 
   for (auto* const ty : module_->constructed_types()) {
@@ -124,37 +124,37 @@
     out_ << std::endl;
   }
 
-  for (const auto& var : module_->global_variables()) {
+  for (auto* var : module_->global_variables()) {
     if (!var->is_const()) {
       continue;
     }
-    if (!EmitProgramConstVariable(var.get())) {
+    if (!EmitProgramConstVariable(var)) {
       return false;
     }
   }
 
   // Make sure all entry point data is emitted before the entry point functions
-  for (const auto& func : module_->functions()) {
+  for (auto* func : module_->functions()) {
     if (!func->IsEntryPoint()) {
       continue;
     }
 
-    if (!EmitEntryPointData(func.get())) {
+    if (!EmitEntryPointData(func)) {
       return false;
     }
   }
 
-  for (const auto& func : module_->functions()) {
-    if (!EmitFunction(func.get())) {
+  for (auto* func : module_->functions()) {
+    if (!EmitFunction(func)) {
       return false;
     }
   }
 
-  for (const auto& func : module_->functions()) {
+  for (auto* func : module_->functions()) {
     if (!func->IsEntryPoint()) {
       continue;
     }
-    if (!EmitEntryPointFunction(func.get())) {
+    if (!EmitEntryPointFunction(func)) {
       return false;
     }
     out_ << std::endl;
@@ -167,7 +167,7 @@
     ast::type::StructType* type) {
   auto* stct = type->AsStruct()->impl();
   uint32_t largest_alignment = 0;
-  for (const auto& mem : stct->members()) {
+  for (auto* mem : stct->members()) {
     auto align = calculate_alignment_size(mem->type());
     if (align == 0) {
       return 0;
@@ -214,8 +214,8 @@
     uint32_t count = 0;
     uint32_t largest_alignment = 0;
     // Offset decorations in WGSL must be in increasing order.
-    for (const auto& mem : stct->members()) {
-      for (const auto& deco : mem->decorations()) {
+    for (auto* mem : stct->members()) {
+      for (auto* deco : mem->decorations()) {
         if (deco->IsOffset()) {
           count = deco->AsOffset()->offset();
         }
@@ -557,13 +557,13 @@
       out_ << name << "(";
 
       bool first = true;
-      for (const auto& param : params) {
+      for (auto* param : params) {
         if (!first) {
           out_ << ", ";
         }
         first = false;
 
-        if (!EmitExpression(param.get())) {
+        if (!EmitExpression(param)) {
           return false;
         }
       }
@@ -637,13 +637,13 @@
   }
 
   const auto& params = expr->params();
-  for (const auto& param : params) {
+  for (auto* param : params) {
     if (!first) {
       out_ << ", ";
     }
     first = false;
 
-    if (!EmitExpression(param.get())) {
+    if (!EmitExpression(param)) {
       return false;
     }
   }
@@ -738,7 +738,7 @@
     out_ << "default:";
   } else {
     bool first = true;
-    for (const auto& selector : stmt->selectors()) {
+    for (auto* selector : stmt->selectors()) {
       if (!first) {
         out_ << std::endl;
         make_indent();
@@ -746,7 +746,7 @@
       first = false;
 
       out_ << "case ";
-      if (!EmitLiteral(selector.get())) {
+      if (!EmitLiteral(selector)) {
         return false;
       }
       out_ << ":";
@@ -757,8 +757,8 @@
 
   increment_indent();
 
-  for (const auto& s : *(stmt->body())) {
-    if (!EmitStatement(s.get())) {
+  for (auto* s : *stmt->body()) {
+    if (!EmitStatement(s)) {
       return false;
     }
   }
@@ -806,13 +806,13 @@
     }
   } else {
     bool first = true;
-    for (const auto& e : expr->values()) {
+    for (auto* e : expr->values()) {
       if (!first) {
         out_ << ", ";
       }
       first = false;
 
-      if (!EmitExpression(e.get())) {
+      if (!EmitExpression(e)) {
         return false;
       }
     }
@@ -1206,7 +1206,7 @@
     out_ << "& " << var->name();
   }
 
-  for (const auto& v : func->params()) {
+  for (auto* v : func->params()) {
     if (!first) {
       out_ << ", ";
     }
@@ -1378,8 +1378,8 @@
   }
 
   generating_entry_point_ = true;
-  for (const auto& s : *(func->body())) {
-    if (!EmitStatement(s.get())) {
+  for (auto* s : *func->body()) {
+    if (!EmitStatement(s)) {
       return false;
     }
   }
@@ -1445,7 +1445,7 @@
     // first pass, if we have a continuing, we pull all declarations outside
     // the for loop into the continuing scope. Then, the variable declarations
     // will be turned into assignments.
-    for (const auto& s : *(stmt->body())) {
+    for (auto* s : *(stmt->body())) {
       if (!s->IsVariableDecl()) {
         continue;
       }
@@ -1472,7 +1472,7 @@
     out_ << std::endl;
   }
 
-  for (const auto& s : *(stmt->body())) {
+  for (auto* s : *(stmt->body())) {
     // If we have a continuing block we've already emitted the variable
     // declaration before the loop, so treat it as an assignment.
     if (s->IsVariableDecl() && stmt->has_continuing()) {
@@ -1493,7 +1493,7 @@
       continue;
     }
 
-    if (!EmitStatement(s.get())) {
+    if (!EmitStatement(s)) {
       return false;
     }
   }
@@ -1547,8 +1547,8 @@
     return false;
   }
 
-  for (const auto& e : stmt->else_statements()) {
-    if (!EmitElse(e.get())) {
+  for (auto* e : stmt->else_statements()) {
+    if (!EmitElse(e)) {
       return false;
     }
   }
@@ -1591,8 +1591,8 @@
   out_ << "{" << std::endl;
   increment_indent();
 
-  for (const auto& s : *stmt) {
-    if (!EmitStatement(s.get())) {
+  for (auto* s : *stmt) {
+    if (!EmitStatement(s)) {
       return false;
     }
   }
@@ -1681,8 +1681,8 @@
 
   increment_indent();
 
-  for (const auto& s : stmt->body()) {
-    if (!EmitCase(s.get())) {
+  for (auto* s : stmt->body()) {
+    if (!EmitCase(s)) {
       return false;
     }
   }
@@ -1843,9 +1843,9 @@
   increment_indent();
   uint32_t current_offset = 0;
   uint32_t pad_count = 0;
-  for (const auto& mem : str->impl()->members()) {
+  for (auto* mem : str->impl()->members()) {
     make_indent();
-    for (const auto& deco : mem->decorations()) {
+    for (auto* deco : mem->decorations()) {
       if (deco->IsOffset()) {
         uint32_t offset = deco->AsOffset()->offset();
         if (offset != current_offset) {
diff --git a/src/writer/msl/generator_impl_alias_type_test.cc b/src/writer/msl/generator_impl_alias_type_test.cc
index 68df284..e7b5eff 100644
--- a/src/writer/msl/generator_impl_alias_type_test.cc
+++ b/src/writer/msl/generator_impl_alias_type_test.cc
@@ -61,7 +61,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &i32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("a", std::move(str));
@@ -86,7 +86,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &i32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("b", std::move(str));
diff --git a/src/writer/msl/generator_impl_array_accessor_test.cc b/src/writer/msl/generator_impl_array_accessor_test.cc
index 7cf559c..b9e47e9 100644
--- a/src/writer/msl/generator_impl_array_accessor_test.cc
+++ b/src/writer/msl/generator_impl_array_accessor_test.cc
@@ -33,9 +33,9 @@
 
 TEST_F(MslGeneratorImplTest, EmitExpression_ArrayAccessor) {
   ast::type::I32Type i32;
-  auto lit = create<ast::SintLiteral>(&i32, 5);
-  auto idx = create<ast::ScalarConstructorExpression>(std::move(lit));
-  auto ary = create<ast::IdentifierExpression>("ary");
+  auto* lit = create<ast::SintLiteral>(&i32, 5);
+  auto* idx = create<ast::ScalarConstructorExpression>(std::move(lit));
+  auto* ary = create<ast::IdentifierExpression>("ary");
 
   ast::ArrayAccessorExpression expr(std::move(ary), std::move(idx));
 
@@ -44,8 +44,8 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitArrayAccessor) {
-  auto ary = create<ast::IdentifierExpression>("ary");
-  auto idx = create<ast::IdentifierExpression>("idx");
+  auto* ary = create<ast::IdentifierExpression>("ary");
+  auto* idx = create<ast::IdentifierExpression>("idx");
 
   ast::ArrayAccessorExpression expr(std::move(ary), std::move(idx));
 
diff --git a/src/writer/msl/generator_impl_assign_test.cc b/src/writer/msl/generator_impl_assign_test.cc
index 3518795..00ed1fb 100644
--- a/src/writer/msl/generator_impl_assign_test.cc
+++ b/src/writer/msl/generator_impl_assign_test.cc
@@ -30,8 +30,8 @@
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, Emit_Assign) {
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
 
   gen.increment_indent();
diff --git a/src/writer/msl/generator_impl_binary_test.cc b/src/writer/msl/generator_impl_binary_test.cc
index 43ce820..ac234e8 100644
--- a/src/writer/msl/generator_impl_binary_test.cc
+++ b/src/writer/msl/generator_impl_binary_test.cc
@@ -38,8 +38,8 @@
 TEST_P(MslBinaryTest, Emit) {
   auto params = GetParam();
 
-  auto left = create<ast::IdentifierExpression>("left");
-  auto right = create<ast::IdentifierExpression>("right");
+  auto* left = create<ast::IdentifierExpression>("left");
+  auto* right = create<ast::IdentifierExpression>("right");
 
   ast::BinaryExpression expr(params.op, std::move(left), std::move(right));
 
diff --git a/src/writer/msl/generator_impl_bitcast_test.cc b/src/writer/msl/generator_impl_bitcast_test.cc
index f20338c..776311e 100644
--- a/src/writer/msl/generator_impl_bitcast_test.cc
+++ b/src/writer/msl/generator_impl_bitcast_test.cc
@@ -31,7 +31,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitExpression_Bitcast) {
   ast::type::F32Type f32;
-  auto id = create<ast::IdentifierExpression>("id");
+  auto* id = create<ast::IdentifierExpression>("id");
   ast::BitcastExpression bitcast(&f32, std::move(id));
 
   ASSERT_TRUE(gen.EmitExpression(&bitcast)) << gen.error();
diff --git a/src/writer/msl/generator_impl_call_test.cc b/src/writer/msl/generator_impl_call_test.cc
index 6a6b07c..dee21a9 100644
--- a/src/writer/msl/generator_impl_call_test.cc
+++ b/src/writer/msl/generator_impl_call_test.cc
@@ -34,11 +34,11 @@
 TEST_F(MslGeneratorImplTest, EmitExpression_Call_WithoutParams) {
   ast::type::VoidType void_type;
 
-  auto id = create<ast::IdentifierExpression>("my_func");
+  auto* id = create<ast::IdentifierExpression>("my_func");
   ast::CallExpression call(std::move(id), {});
 
-  auto func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
+                                     create<ast::BlockStatement>());
   mod.AddFunction(std::move(func));
 
   ASSERT_TRUE(gen.EmitExpression(&call)) << gen.error();
@@ -48,14 +48,14 @@
 TEST_F(MslGeneratorImplTest, EmitExpression_Call_WithParams) {
   ast::type::VoidType void_type;
 
-  auto id = create<ast::IdentifierExpression>("my_func");
+  auto* id = create<ast::IdentifierExpression>("my_func");
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("param1"));
   params.push_back(create<ast::IdentifierExpression>("param2"));
   ast::CallExpression call(std::move(id), std::move(params));
 
-  auto func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
+                                     create<ast::BlockStatement>());
   mod.AddFunction(std::move(func));
 
   ASSERT_TRUE(gen.EmitExpression(&call)) << gen.error();
@@ -65,15 +65,15 @@
 TEST_F(MslGeneratorImplTest, EmitStatement_Call) {
   ast::type::VoidType void_type;
 
-  auto id = create<ast::IdentifierExpression>("my_func");
+  auto* id = create<ast::IdentifierExpression>("my_func");
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("param1"));
   params.push_back(create<ast::IdentifierExpression>("param2"));
   ast::CallStatement call(
       create<ast::CallExpression>(std::move(id), std::move(params)));
 
-  auto func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
+                                     create<ast::BlockStatement>());
   mod.AddFunction(std::move(func));
 
   gen.increment_indent();
diff --git a/src/writer/msl/generator_impl_case_test.cc b/src/writer/msl/generator_impl_case_test.cc
index 0ffaa21..7419f16 100644
--- a/src/writer/msl/generator_impl_case_test.cc
+++ b/src/writer/msl/generator_impl_case_test.cc
@@ -35,7 +35,7 @@
 TEST_F(MslGeneratorImplTest, Emit_Case) {
   ast::type::I32Type i32;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::BreakStatement>());
 
   ast::CaseSelectorList lit;
@@ -70,7 +70,7 @@
 TEST_F(MslGeneratorImplTest, Emit_Case_WithFallthrough) {
   ast::type::I32Type i32;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::FallthroughStatement>());
 
   ast::CaseSelectorList lit;
@@ -89,7 +89,7 @@
 TEST_F(MslGeneratorImplTest, Emit_Case_MultipleSelectors) {
   ast::type::I32Type i32;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::BreakStatement>());
 
   ast::CaseSelectorList lit;
@@ -108,7 +108,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_Case_Default) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::BreakStatement>());
   ast::CaseStatement c(std::move(body));
 
diff --git a/src/writer/msl/generator_impl_constructor_test.cc b/src/writer/msl/generator_impl_constructor_test.cc
index 4ca41d8..41a8b75 100644
--- a/src/writer/msl/generator_impl_constructor_test.cc
+++ b/src/writer/msl/generator_impl_constructor_test.cc
@@ -39,7 +39,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Bool) {
   ast::type::BoolType bool_type;
-  auto lit = create<ast::BoolLiteral>(&bool_type, false);
+  auto* lit = create<ast::BoolLiteral>(&bool_type, false);
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(&expr)) << gen.error();
@@ -48,7 +48,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Int) {
   ast::type::I32Type i32;
-  auto lit = create<ast::SintLiteral>(&i32, -12345);
+  auto* lit = create<ast::SintLiteral>(&i32, -12345);
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(&expr)) << gen.error();
@@ -57,7 +57,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_UInt) {
   ast::type::U32Type u32;
-  auto lit = create<ast::UintLiteral>(&u32, 56779);
+  auto* lit = create<ast::UintLiteral>(&u32, 56779);
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(&expr)) << gen.error();
@@ -67,7 +67,8 @@
 TEST_F(MslGeneratorImplTest, EmitConstructor_Float) {
   ast::type::F32Type f32;
   // Use a number close to 1<<30 but whose decimal representation ends in 0.
-  auto lit = create<ast::FloatLiteral>(&f32, static_cast<float>((1 << 30) - 4));
+  auto* lit =
+      create<ast::FloatLiteral>(&f32, static_cast<float>((1 << 30) - 4));
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(&expr)) << gen.error();
@@ -77,7 +78,7 @@
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Float) {
   ast::type::F32Type f32;
 
-  auto lit = create<ast::FloatLiteral>(&f32, -1.2e-5);
+  auto* lit = create<ast::FloatLiteral>(&f32, -1.2e-5);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
@@ -90,7 +91,7 @@
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Bool) {
   ast::type::BoolType b;
 
-  auto lit = create<ast::BoolLiteral>(&b, true);
+  auto* lit = create<ast::BoolLiteral>(&b, true);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
@@ -103,7 +104,7 @@
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Int) {
   ast::type::I32Type i32;
 
-  auto lit = create<ast::SintLiteral>(&i32, -12345);
+  auto* lit = create<ast::SintLiteral>(&i32, -12345);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
@@ -116,7 +117,7 @@
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Uint) {
   ast::type::U32Type u32;
 
-  auto lit = create<ast::UintLiteral>(&u32, 12345);
+  auto* lit = create<ast::UintLiteral>(&u32, 12345);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
@@ -130,9 +131,9 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec(&f32, 3);
 
-  auto lit1 = create<ast::FloatLiteral>(&f32, 1.f);
-  auto lit2 = create<ast::FloatLiteral>(&f32, 2.f);
-  auto lit3 = create<ast::FloatLiteral>(&f32, 3.f);
+  auto* lit1 = create<ast::FloatLiteral>(&f32, 1.f);
+  auto* lit2 = create<ast::FloatLiteral>(&f32, 2.f);
+  auto* lit3 = create<ast::FloatLiteral>(&f32, 3.f);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit1)));
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit2)));
@@ -166,11 +167,11 @@
   ast::ExpressionList mat_values;
 
   for (size_t i = 0; i < 2; i++) {
-    auto lit1 =
+    auto* lit1 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(1 + (i * 2)));
-    auto lit2 =
+    auto* lit2 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(2 + (i * 2)));
-    auto lit3 =
+    auto* lit3 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(3 + (i * 2)));
 
     ast::ExpressionList values;
@@ -201,11 +202,11 @@
   ast::ExpressionList ary_values;
 
   for (size_t i = 0; i < 3; i++) {
-    auto lit1 =
+    auto* lit1 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(1 + (i * 3)));
-    auto lit2 =
+    auto* lit2 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(2 + (i * 3)));
-    auto lit3 =
+    auto* lit3 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(3 + (i * 3)));
 
     ast::ExpressionList values;
diff --git a/src/writer/msl/generator_impl_function_entry_point_data_test.cc b/src/writer/msl/generator_impl_function_entry_point_data_test.cc
index 3bf391f..3652697 100644
--- a/src/writer/msl/generator_impl_function_entry_point_data_test.cc
+++ b/src/writer/msl/generator_impl_function_entry_point_data_test.cc
@@ -52,26 +52,26 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("foo"),
       create<ast::IdentifierExpression>("foo")));
@@ -79,11 +79,11 @@
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("bar")));
 
-  auto func = create<ast::Function>("vtx_main", std::move(params), &f32,
-                                    std::move(body));
+  auto* func = create<ast::Function>("vtx_main", std::move(params), &f32,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
@@ -110,26 +110,26 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("foo"),
       create<ast::IdentifierExpression>("foo")));
@@ -137,11 +137,11 @@
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("bar")));
 
-  auto func = create<ast::Function>("vtx_main", std::move(params), &f32,
-                                    std::move(body));
+  auto* func = create<ast::Function>("vtx_main", std::move(params), &f32,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
@@ -168,37 +168,37 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("foo"),
       create<ast::IdentifierExpression>("foo")));
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("bar")));
-  auto func =
+  auto* func =
       create<ast::Function>("main", std::move(params), &f32, std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
@@ -225,26 +225,26 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("foo"),
       create<ast::IdentifierExpression>("foo")));
@@ -252,11 +252,11 @@
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("bar")));
 
-  auto func =
+  auto* func =
       create<ast::Function>("main", std::move(params), &f32, std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
@@ -280,26 +280,26 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("foo"),
       create<ast::IdentifierExpression>("foo")));
@@ -307,11 +307,11 @@
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("bar")));
 
-  auto func =
+  auto* func =
       create<ast::Function>("main", std::move(params), &f32, std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
@@ -330,26 +330,26 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("foo"),
       create<ast::IdentifierExpression>("foo")));
@@ -357,11 +357,11 @@
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("bar")));
 
-  auto func =
+  auto* func =
       create<ast::Function>("main", std::move(params), &f32, std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
@@ -386,7 +386,7 @@
   ast::type::VoidType void_type;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kInput, &vec4));
 
   ast::VariableDecorationList decos;
@@ -394,32 +394,32 @@
       create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  auto depth_var = create<ast::DecoratedVariable>(
+  auto* depth_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("depth", ast::StorageClass::kOutput, &f32));
   decos.push_back(
       create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  td.RegisterVariableForTesting(depth_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  td.RegisterVariableForTesting(depth_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
   mod.AddGlobalVariable(std::move(depth_var));
 
   ast::VariableList params;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("depth"),
       create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("coord"),
           create<ast::IdentifierExpression>("x"))));
 
-  auto func = create<ast::Function>("main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
-  auto* func_ptr = func.get();
+  auto* func_ptr = func;
 
   mod.AddFunction(std::move(func));
 
diff --git a/src/writer/msl/generator_impl_function_test.cc b/src/writer/msl/generator_impl_function_test.cc
index 6f13cf9..7a2ae42 100644
--- a/src/writer/msl/generator_impl_function_test.cc
+++ b/src/writer/msl/generator_impl_function_test.cc
@@ -60,10 +60,10 @@
 TEST_F(MslGeneratorImplTest, Emit_Function) {
   ast::type::VoidType void_type;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
+                                     std::move(body));
 
   mod.AddFunction(std::move(func));
   gen.increment_indent();
@@ -81,10 +81,10 @@
 TEST_F(MslGeneratorImplTest, Emit_Function_Name_Collision) {
   ast::type::VoidType void_type;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("main", ast::VariableList{}, &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("main", ast::VariableList{}, &void_type,
+                                     std::move(body));
 
   mod.AddFunction(std::move(func));
   gen.increment_indent();
@@ -109,10 +109,10 @@
 
   ast::type::VoidType void_type;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("my_func", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("my_func", std::move(params), &void_type,
+                                     std::move(body));
 
   mod.AddFunction(std::move(func));
   gen.increment_indent();
@@ -131,33 +131,33 @@
   ast::type::VoidType void_type;
   ast::type::F32Type f32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("foo")));
   body->append(create<ast::ReturnStatement>());
 
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -191,7 +191,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kInput, &vec4));
 
   ast::VariableDecorationList decos;
@@ -199,20 +199,20 @@
       create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  auto depth_var = create<ast::DecoratedVariable>(
+  auto* depth_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("depth", ast::StorageClass::kOutput, &f32));
   decos.push_back(
       create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  td.RegisterVariableForTesting(depth_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  td.RegisterVariableForTesting(depth_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
   mod.AddGlobalVariable(std::move(depth_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("depth"),
       create<ast::MemberAccessorExpression>(
@@ -220,8 +220,8 @@
           create<ast::IdentifierExpression>("x"))));
   body->append(create<ast::ReturnStatement>());
 
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -250,7 +250,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kUniform, &vec4));
 
   ast::VariableDecorationList decos;
@@ -258,22 +258,22 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
 
   ast::VariableList params;
-  auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("coord"),
       create<ast::IdentifierExpression>("x")));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::ReturnStatement>());
 
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -307,7 +307,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
@@ -315,7 +315,7 @@
 
   mod.AddConstructedType(&s);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
@@ -323,22 +323,22 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
 
   ast::VariableList params;
-  auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("coord"),
       create<ast::IdentifierExpression>("b")));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::ReturnStatement>());
 
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -376,7 +376,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
@@ -384,7 +384,7 @@
 
   mod.AddConstructedType(&s);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
@@ -392,23 +392,23 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
 
   ast::VariableList params;
 
-  auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("coord"),
       create<ast::IdentifierExpression>("b")));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::ReturnStatement>());
 
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -438,26 +438,26 @@
   ast::type::VoidType void_type;
   ast::type::F32Type f32;
 
-  auto foo_var = create<ast::DecoratedVariable>(
+  auto* foo_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  auto val_var = create<ast::DecoratedVariable>(
+  auto* val_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("val", ast::StorageClass::kOutput, &f32));
   decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   val_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(foo_var.get());
-  td.RegisterVariableForTesting(bar_var.get());
-  td.RegisterVariableForTesting(val_var.get());
+  td.RegisterVariableForTesting(foo_var);
+  td.RegisterVariableForTesting(bar_var);
+  td.RegisterVariableForTesting(val_var);
 
   mod.AddGlobalVariable(std::move(foo_var));
   mod.AddGlobalVariable(std::move(bar_var));
@@ -467,7 +467,7 @@
   params.push_back(
       create<ast::Variable>("param", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("bar"),
       create<ast::IdentifierExpression>("foo")));
@@ -476,8 +476,8 @@
       create<ast::IdentifierExpression>("param")));
   body->append(
       create<ast::ReturnStatement>(create<ast::IdentifierExpression>("foo")));
-  auto sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
-                                        std::move(body));
+  auto* sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
+                                         std::move(body));
 
   mod.AddFunction(std::move(sub_func));
 
@@ -491,8 +491,8 @@
       create<ast::CallExpression>(create<ast::IdentifierExpression>("sub_func"),
                                   std::move(expr))));
   body->append(create<ast::ReturnStatement>());
-  auto func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
-                                      std::move(body));
+  auto* func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
+                                       std::move(body));
   func_1->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -533,7 +533,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto depth_var = create<ast::DecoratedVariable>(
+  auto* depth_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("depth", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
@@ -541,7 +541,7 @@
       create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(depth_var.get());
+  td.RegisterVariableForTesting(depth_var);
 
   mod.AddGlobalVariable(std::move(depth_var));
 
@@ -549,11 +549,11 @@
   params.push_back(
       create<ast::Variable>("param", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::ReturnStatement>(create<ast::IdentifierExpression>("param")));
-  auto sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
-                                        std::move(body));
+  auto* sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
+                                         std::move(body));
 
   mod.AddFunction(std::move(sub_func));
 
@@ -568,8 +568,8 @@
                                   std::move(expr))));
   body->append(create<ast::ReturnStatement>());
 
-  auto func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
-                                      std::move(body));
+  auto* func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
+                                       std::move(body));
   func_1->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -604,7 +604,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kInput, &vec4));
 
   ast::VariableDecorationList decos;
@@ -612,14 +612,14 @@
       create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  auto depth_var = create<ast::DecoratedVariable>(
+  auto* depth_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("depth", ast::StorageClass::kOutput, &f32));
   decos.push_back(
       create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
-  td.RegisterVariableForTesting(depth_var.get());
+  td.RegisterVariableForTesting(coord_var);
+  td.RegisterVariableForTesting(depth_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
   mod.AddGlobalVariable(std::move(depth_var));
@@ -628,7 +628,7 @@
   params.push_back(
       create<ast::Variable>("param", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("depth"),
       create<ast::MemberAccessorExpression>(
@@ -636,8 +636,8 @@
           create<ast::IdentifierExpression>("x"))));
   body->append(
       create<ast::ReturnStatement>(create<ast::IdentifierExpression>("param")));
-  auto sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
-                                        std::move(body));
+  auto* sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
+                                         std::move(body));
 
   mod.AddFunction(std::move(sub_func));
 
@@ -651,8 +651,8 @@
       create<ast::CallExpression>(create<ast::IdentifierExpression>("sub_func"),
                                   std::move(expr))));
   body->append(create<ast::ReturnStatement>());
-  auto func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
-                                      std::move(body));
+  auto* func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
+                                       std::move(body));
   func_1->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -686,7 +686,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec4(&f32, 4);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kUniform, &vec4));
 
   ast::VariableDecorationList decos;
@@ -694,7 +694,7 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
 
   mod.AddGlobalVariable(std::move(coord_var));
 
@@ -702,13 +702,13 @@
   params.push_back(
       create<ast::Variable>("param", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::ReturnStatement>(create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("coord"),
           create<ast::IdentifierExpression>("x"))));
-  auto sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
-                                        std::move(body));
+  auto* sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
+                                         std::move(body));
 
   mod.AddFunction(std::move(sub_func));
 
@@ -716,7 +716,7 @@
   expr.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0f)));
 
-  auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::CallExpression>(
       create<ast::IdentifierExpression>("sub_func"), std::move(expr)));
 
@@ -724,8 +724,8 @@
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::ReturnStatement>());
 
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -762,7 +762,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
@@ -770,7 +770,7 @@
 
   mod.AddConstructedType(&s);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
@@ -778,20 +778,20 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ast::VariableList params;
   params.push_back(
       create<ast::Variable>("param", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::ReturnStatement>(create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("coord"),
           create<ast::IdentifierExpression>("b"))));
-  auto sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
-                                        std::move(body));
+  auto* sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
+                                         std::move(body));
 
   mod.AddFunction(std::move(sub_func));
 
@@ -799,7 +799,7 @@
   expr.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0f)));
 
-  auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::CallExpression>(
       create<ast::IdentifierExpression>("sub_func"), std::move(expr)));
 
@@ -807,8 +807,8 @@
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::ReturnStatement>());
 
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -851,7 +851,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
@@ -859,7 +859,7 @@
 
   mod.AddConstructedType(&s);
 
-  auto coord_var = create<ast::DecoratedVariable>(
+  auto* coord_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
@@ -867,20 +867,20 @@
   decos.push_back(create<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(coord_var.get());
+  td.RegisterVariableForTesting(coord_var);
   mod.AddGlobalVariable(std::move(coord_var));
 
   ast::VariableList params;
   params.push_back(
       create<ast::Variable>("param", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::ReturnStatement>(create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("coord"),
           create<ast::IdentifierExpression>("b"))));
-  auto sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
-                                        std::move(body));
+  auto* sub_func = create<ast::Function>("sub_func", std::move(params), &f32,
+                                         std::move(body));
 
   mod.AddFunction(std::move(sub_func));
 
@@ -888,7 +888,7 @@
   expr.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0f)));
 
-  auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::CallExpression>(
       create<ast::IdentifierExpression>("sub_func"), std::move(expr)));
 
@@ -896,8 +896,8 @@
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::ReturnStatement>());
 
-  auto func = create<ast::Function>("frag_main", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("frag_main", std::move(params), &void_type,
+                                     std::move(body));
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -931,23 +931,23 @@
   ast::type::F32Type f32;
   ast::type::I32Type i32;
 
-  auto bar_var = create<ast::DecoratedVariable>(
+  auto* bar_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
-  td.RegisterVariableForTesting(bar_var.get());
+  td.RegisterVariableForTesting(bar_var);
   mod.AddGlobalVariable(std::move(bar_var));
 
   ast::VariableList params;
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("bar"),
       create<ast::ScalarConstructorExpression>(
           create<ast::FloatLiteral>(&f32, 1.0f))));
 
-  auto list = create<ast::BlockStatement>();
+  auto* list = create<ast::BlockStatement>();
   list->append(create<ast::ReturnStatement>());
 
   body->append(create<ast::IfStatement>(
@@ -960,8 +960,8 @@
 
   body->append(create<ast::ReturnStatement>());
 
-  auto func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
-                                      std::move(body));
+  auto* func_1 = create<ast::Function>("ep_1", std::move(params), &void_type,
+                                       std::move(body));
   func_1->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
@@ -991,8 +991,8 @@
        Emit_FunctionDecoration_EntryPoint_WithNameCollision) {
   ast::type::VoidType void_type;
 
-  auto func = create<ast::Function>("main", ast::VariableList{}, &void_type,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("main", ast::VariableList{}, &void_type,
+                                     create<ast::BlockStatement>());
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
@@ -1016,10 +1016,10 @@
 
   ast::type::VoidType void_type;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
-  auto func = create<ast::Function>("my_func", std::move(params), &void_type,
-                                    std::move(body));
+  auto* func = create<ast::Function>("my_func", std::move(params), &void_type,
+                                     std::move(body));
 
   mod.AddFunction(std::move(func));
 
@@ -1064,12 +1064,12 @@
   ast::StructDecorationList s_decos;
   s_decos.push_back(create<ast::StructBlockDecoration>(Source{}));
 
-  auto str = create<ast::Struct>(std::move(s_decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(s_decos), std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
   ast::type::AccessControlType ac(ast::AccessControl::kReadWrite, &s);
 
-  auto data_var = create<ast::DecoratedVariable>(
+  auto* data_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
@@ -1079,22 +1079,22 @@
 
   mod.AddConstructedType(&s);
 
-  td.RegisterVariableForTesting(data_var.get());
+  td.RegisterVariableForTesting(data_var);
   mod.AddGlobalVariable(std::move(data_var));
 
   {
     ast::VariableList params;
-    auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+    auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
     var->set_constructor(create<ast::MemberAccessorExpression>(
         create<ast::IdentifierExpression>("data"),
         create<ast::IdentifierExpression>("d")));
 
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
     body->append(create<ast::VariableDeclStatement>(std::move(var)));
     body->append(create<ast::ReturnStatement>());
 
-    auto func = create<ast::Function>("a", std::move(params), &void_type,
-                                      std::move(body));
+    auto* func = create<ast::Function>("a", std::move(params), &void_type,
+                                       std::move(body));
     func->add_decoration(
         create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
@@ -1103,17 +1103,17 @@
 
   {
     ast::VariableList params;
-    auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+    auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
     var->set_constructor(create<ast::MemberAccessorExpression>(
         create<ast::IdentifierExpression>("data"),
         create<ast::IdentifierExpression>("d")));
 
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
     body->append(create<ast::VariableDeclStatement>(std::move(var)));
     body->append(create<ast::ReturnStatement>());
 
-    auto func = create<ast::Function>("b", std::move(params), &void_type,
-                                      std::move(body));
+    auto* func = create<ast::Function>("b", std::move(params), &void_type,
+                                       std::move(body));
     func->add_decoration(
         create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
diff --git a/src/writer/msl/generator_impl_if_test.cc b/src/writer/msl/generator_impl_if_test.cc
index ad81e36..eec75df 100644
--- a/src/writer/msl/generator_impl_if_test.cc
+++ b/src/writer/msl/generator_impl_if_test.cc
@@ -29,8 +29,8 @@
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, Emit_If) {
-  auto cond = create<ast::IdentifierExpression>("cond");
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>("cond");
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
@@ -45,16 +45,16 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_IfWithElseIf) {
-  auto else_cond = create<ast::IdentifierExpression>("else_cond");
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_cond = create<ast::IdentifierExpression>("else_cond");
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(create<ast::ReturnStatement>());
 
   ast::ElseStatementList elses;
   elses.push_back(
       create<ast::ElseStatement>(std::move(else_cond), std::move(else_body)));
 
-  auto cond = create<ast::IdentifierExpression>("cond");
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>("cond");
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
@@ -72,14 +72,14 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_IfWithElse) {
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(create<ast::ReturnStatement>());
 
   ast::ElseStatementList elses;
   elses.push_back(create<ast::ElseStatement>(std::move(else_body)));
 
-  auto cond = create<ast::IdentifierExpression>("cond");
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>("cond");
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
@@ -97,12 +97,12 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_IfWithMultiple) {
-  auto else_cond = create<ast::IdentifierExpression>("else_cond");
+  auto* else_cond = create<ast::IdentifierExpression>("else_cond");
 
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(create<ast::ReturnStatement>());
 
-  auto else_body_2 = create<ast::BlockStatement>();
+  auto* else_body_2 = create<ast::BlockStatement>();
   else_body_2->append(create<ast::ReturnStatement>());
 
   ast::ElseStatementList elses;
@@ -110,8 +110,8 @@
       create<ast::ElseStatement>(std::move(else_cond), std::move(else_body)));
   elses.push_back(create<ast::ElseStatement>(std::move(else_body_2)));
 
-  auto cond = create<ast::IdentifierExpression>("cond");
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>("cond");
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
diff --git a/src/writer/msl/generator_impl_import_test.cc b/src/writer/msl/generator_impl_import_test.cc
index 7408f5e..3920f50 100644
--- a/src/writer/msl/generator_impl_import_test.cc
+++ b/src/writer/msl/generator_impl_import_test.cc
@@ -58,8 +58,8 @@
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
 
-  auto ident = create<ast::IdentifierExpression>(param.name);
-  auto* ident_ptr = ident.get();
+  auto* ident = create<ast::IdentifierExpression>(param.name);
+  auto* ident_ptr = ident;
 
   ast::CallExpression call(std::move(ident), std::move(params));
 
@@ -268,7 +268,7 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat(&f32, 3, 3);
 
-  auto var = create<ast::Variable>("var", ast::StorageClass::kFunction, &mat);
+  auto* var = create<ast::Variable>("var", ast::StorageClass::kFunction, &mat);
 
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("var"));
diff --git a/src/writer/msl/generator_impl_intrinsic_test.cc b/src/writer/msl/generator_impl_intrinsic_test.cc
index 4dc9c82..5821b5b 100644
--- a/src/writer/msl/generator_impl_intrinsic_test.cc
+++ b/src/writer/msl/generator_impl_intrinsic_test.cc
@@ -71,8 +71,8 @@
   ast::type::VectorType vec2(&f32, 2);
   ast::type::VectorType vec3(&f32, 3);
 
-  auto a = create<ast::Variable>("a", ast::StorageClass::kNone, &vec2);
-  auto b = create<ast::Variable>("b", ast::StorageClass::kNone, &vec3);
+  auto* a = create<ast::Variable>("a", ast::StorageClass::kNone, &vec2);
+  auto* b = create<ast::Variable>("b", ast::StorageClass::kNone, &vec3);
 
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("a"));
@@ -81,8 +81,8 @@
   ast::CallExpression call(create<ast::IdentifierExpression>("outer_product"),
                            std::move(params));
 
-  td.RegisterVariableForTesting(a.get());
-  td.RegisterVariableForTesting(b.get());
+  td.RegisterVariableForTesting(a);
+  td.RegisterVariableForTesting(b);
 
   mod.AddGlobalVariable(std::move(a));
   mod.AddGlobalVariable(std::move(b));
diff --git a/src/writer/msl/generator_impl_loop_test.cc b/src/writer/msl/generator_impl_loop_test.cc
index 09da2c0..faabd7b 100644
--- a/src/writer/msl/generator_impl_loop_test.cc
+++ b/src/writer/msl/generator_impl_loop_test.cc
@@ -36,7 +36,7 @@
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, Emit_Loop) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
 
   ast::LoopStatement l(std::move(body), {});
@@ -51,10 +51,10 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_LoopWithContinuing) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
 
-  auto continuing = create<ast::BlockStatement>();
+  auto* continuing = create<ast::BlockStatement>();
   continuing->append(create<ast::ReturnStatement>());
 
   ast::LoopStatement l(std::move(body), std::move(continuing));
@@ -79,20 +79,20 @@
 TEST_F(MslGeneratorImplTest, Emit_LoopNestedWithContinuing) {
   ast::type::F32Type f32;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
 
-  auto continuing = create<ast::BlockStatement>();
+  auto* continuing = create<ast::BlockStatement>();
   continuing->append(create<ast::ReturnStatement>());
 
-  auto inner =
+  auto* inner =
       create<ast::LoopStatement>(std::move(body), std::move(continuing));
 
   body = create<ast::BlockStatement>();
   body->append(std::move(inner));
 
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
 
   continuing = create<ast::BlockStatement>();
   continuing->append(
@@ -151,19 +151,19 @@
 
   ast::type::F32Type f32;
 
-  auto var = create<ast::Variable>("lhs", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("lhs", ast::StorageClass::kFunction, &f32);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.4)));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::VariableDeclStatement>(std::move(var)));
   body->append(create<ast::VariableDeclStatement>(
       create<ast::Variable>("other", ast::StorageClass::kFunction, &f32)));
 
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
 
-  auto continuing = create<ast::BlockStatement>();
+  auto* continuing = create<ast::BlockStatement>();
   continuing->append(
       create<ast::AssignmentStatement>(std::move(lhs), std::move(rhs)));
 
diff --git a/src/writer/msl/generator_impl_member_accessor_test.cc b/src/writer/msl/generator_impl_member_accessor_test.cc
index cd5fa2e..d0d1dc9 100644
--- a/src/writer/msl/generator_impl_member_accessor_test.cc
+++ b/src/writer/msl/generator_impl_member_accessor_test.cc
@@ -29,8 +29,8 @@
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor) {
-  auto str = create<ast::IdentifierExpression>("str");
-  auto mem = create<ast::IdentifierExpression>("mem");
+  auto* str = create<ast::IdentifierExpression>("str");
+  auto* mem = create<ast::IdentifierExpression>("mem");
 
   ast::MemberAccessorExpression expr(std::move(str), std::move(mem));
 
diff --git a/src/writer/msl/generator_impl_module_constant_test.cc b/src/writer/msl/generator_impl_module_constant_test.cc
index 570783c..b0b392e 100644
--- a/src/writer/msl/generator_impl_module_constant_test.cc
+++ b/src/writer/msl/generator_impl_module_constant_test.cc
@@ -47,12 +47,12 @@
   exprs.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto var = create<ast::Variable>("pos", ast::StorageClass::kNone, &ary);
+  auto* var = create<ast::Variable>("pos", ast::StorageClass::kNone, &ary);
   var->set_is_const(true);
   var->set_constructor(
       create<ast::TypeConstructorExpression>(&ary, std::move(exprs)));
 
-  ASSERT_TRUE(gen.EmitProgramConstVariable(var.get())) << gen.error();
+  ASSERT_TRUE(gen.EmitProgramConstVariable(var)) << gen.error();
   EXPECT_EQ(
       gen.result(),
       "constant float pos[3] = {1.00000000f, 2.00000000f, 3.00000000f};\n");
@@ -64,14 +64,14 @@
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::ConstantIdDecoration>(23, Source{}));
 
-  auto var = create<ast::DecoratedVariable>(
+  auto* var = create<ast::DecoratedVariable>(
       create<ast::Variable>("pos", ast::StorageClass::kNone, &f32));
   var->set_decorations(std::move(decos));
   var->set_is_const(true);
   var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  ASSERT_TRUE(gen.EmitProgramConstVariable(var.get())) << gen.error();
+  ASSERT_TRUE(gen.EmitProgramConstVariable(var)) << gen.error();
   EXPECT_EQ(gen.result(), "constant float pos [[function_constant(23)]];\n");
 }
 
diff --git a/src/writer/msl/generator_impl_return_test.cc b/src/writer/msl/generator_impl_return_test.cc
index c3541e0..651440d 100644
--- a/src/writer/msl/generator_impl_return_test.cc
+++ b/src/writer/msl/generator_impl_return_test.cc
@@ -39,7 +39,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_ReturnWithValue) {
-  auto expr = create<ast::IdentifierExpression>("expr");
+  auto* expr = create<ast::IdentifierExpression>("expr");
   ast::ReturnStatement r(std::move(expr));
 
   gen.increment_indent();
diff --git a/src/writer/msl/generator_impl_switch_test.cc b/src/writer/msl/generator_impl_switch_test.cc
index d71b534..7511f62 100644
--- a/src/writer/msl/generator_impl_switch_test.cc
+++ b/src/writer/msl/generator_impl_switch_test.cc
@@ -33,25 +33,25 @@
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, Emit_Switch) {
-  auto def_body = create<ast::BlockStatement>();
+  auto* def_body = create<ast::BlockStatement>();
   def_body->append(create<ast::BreakStatement>());
-  auto def = create<ast::CaseStatement>(std::move(def_body));
+  auto* def = create<ast::CaseStatement>(std::move(def_body));
 
   ast::type::I32Type i32;
   ast::CaseSelectorList case_val;
   case_val.push_back(create<ast::SintLiteral>(&i32, 5));
 
-  auto case_body = create<ast::BlockStatement>();
+  auto* case_body = create<ast::BlockStatement>();
   case_body->append(create<ast::BreakStatement>());
 
-  auto case_stmt =
+  auto* case_stmt =
       create<ast::CaseStatement>(std::move(case_val), std::move(case_body));
 
   ast::CaseStatementList body;
   body.push_back(std::move(case_stmt));
   body.push_back(std::move(def));
 
-  auto cond = create<ast::IdentifierExpression>("cond");
+  auto* cond = create<ast::IdentifierExpression>("cond");
   ast::SwitchStatement s(std::move(cond), std::move(body));
 
   gen.increment_indent();
diff --git a/src/writer/msl/generator_impl_test.cc b/src/writer/msl/generator_impl_test.cc
index 1da1144..d974ec9 100644
--- a/src/writer/msl/generator_impl_test.cc
+++ b/src/writer/msl/generator_impl_test.cc
@@ -50,8 +50,8 @@
 TEST_F(MslGeneratorImplTest, Generate) {
   ast::type::VoidType void_type;
 
-  auto func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
-                                    create<ast::BlockStatement>());
+  auto* func = create<ast::Function>("my_func", ast::VariableList{}, &void_type,
+                                     create<ast::BlockStatement>());
   func->add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
   mod.AddFunction(std::move(func));
@@ -168,7 +168,7 @@
   decos.push_back(create<ast::StructMemberOffsetDecoration>(128, Source{}));
   members.push_back(create<ast::StructMember>("c", &f32, std::move(decos)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -193,7 +193,7 @@
   decos.push_back(create<ast::StructMemberOffsetDecoration>(32, Source{}));
   members.push_back(create<ast::StructMember>("c", &f32, std::move(decos)));
 
-  auto inner_str = create<ast::Struct>();
+  auto* inner_str = create<ast::Struct>();
   inner_str->set_members(std::move(members));
 
   ast::type::StructType inner_s("Inner", std::move(inner_str));
@@ -207,7 +207,7 @@
   decos.push_back(create<ast::StructMemberOffsetDecoration>(64, Source{}));
   members.push_back(create<ast::StructMember>("f", &f32, std::move(decos)));
 
-  auto outer_str = create<ast::Struct>();
+  auto* outer_str = create<ast::Struct>();
   outer_str->set_members(std::move(members));
 
   ast::type::StructType outer_s("Outer", std::move(outer_str));
diff --git a/src/writer/msl/generator_impl_type_test.cc b/src/writer/msl/generator_impl_type_test.cc
index 0136f0f..1716eda 100644
--- a/src/writer/msl/generator_impl_type_test.cc
+++ b/src/writer/msl/generator_impl_type_test.cc
@@ -183,7 +183,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -204,7 +204,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -233,7 +233,7 @@
   decos.push_back(create<ast::StructMemberOffsetDecoration>(128, Source{}));
   members.push_back(create<ast::StructMember>("c", &f32, std::move(decos)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -262,7 +262,7 @@
   members.push_back(
       create<ast::StructMember>("float", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -290,7 +290,7 @@
 
   ast::StructDecorationList decos;
   decos.push_back(create<ast::StructBlockDecoration>(Source{}));
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
 
   ast::type::StructType s("S", std::move(str));
 
diff --git a/src/writer/msl/generator_impl_unary_op_test.cc b/src/writer/msl/generator_impl_unary_op_test.cc
index aa24674..ec78362 100644
--- a/src/writer/msl/generator_impl_unary_op_test.cc
+++ b/src/writer/msl/generator_impl_unary_op_test.cc
@@ -39,7 +39,7 @@
 TEST_P(MslUnaryOpTest, Emit) {
   auto params = GetParam();
 
-  auto expr = create<ast::IdentifierExpression>("expr");
+  auto* expr = create<ast::IdentifierExpression>("expr");
   ast::UnaryOpExpression op(params.op, std::move(expr));
 
   ASSERT_TRUE(gen.EmitExpression(&op)) << gen.error();
diff --git a/src/writer/msl/generator_impl_variable_decl_statement_test.cc b/src/writer/msl/generator_impl_variable_decl_statement_test.cc
index 11e6da0..2681ae2 100644
--- a/src/writer/msl/generator_impl_variable_decl_statement_test.cc
+++ b/src/writer/msl/generator_impl_variable_decl_statement_test.cc
@@ -42,7 +42,7 @@
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement) {
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
 
   ast::VariableDeclStatement stmt(std::move(var));
 
@@ -54,7 +54,7 @@
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) {
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var->set_is_const(true);
 
   ast::VariableDeclStatement stmt(std::move(var));
@@ -69,7 +69,7 @@
   ast::type::F32Type f32;
   ast::type::ArrayType ary(&f32, 5);
 
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &ary);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &ary);
 
   ast::VariableDeclStatement stmt(std::move(var));
 
@@ -90,12 +90,12 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
 
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &s);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &s);
 
   ast::VariableDeclStatement stmt(std::move(var));
 
@@ -110,7 +110,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec(&f32, 2);
 
-  auto var = create<ast::Variable>("a", ast::StorageClass::kFunction, &vec);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kFunction, &vec);
 
   ast::VariableDeclStatement stmt(std::move(var));
 
@@ -123,7 +123,7 @@
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Matrix) {
   ast::type::F32Type f32;
   ast::type::MatrixType mat(&f32, 2, 3);
-  auto var = create<ast::Variable>("a", ast::StorageClass::kFunction, &mat);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kFunction, &mat);
 
   ast::VariableDeclStatement stmt(std::move(var));
 
@@ -135,7 +135,7 @@
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kPrivate, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kPrivate, &f32);
 
   ast::VariableDeclStatement stmt(std::move(var));
 
@@ -146,10 +146,10 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_Private) {
-  auto ident = create<ast::IdentifierExpression>("initializer");
+  auto* ident = create<ast::IdentifierExpression>("initializer");
 
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
   var->set_constructor(std::move(ident));
 
   ast::VariableDeclStatement stmt(std::move(var));
@@ -164,10 +164,10 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList values;
-  auto zero_vec =
+  auto* zero_vec =
       create<ast::TypeConstructorExpression>(&vec, std::move(values));
 
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &vec);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &vec);
   var->set_constructor(std::move(zero_vec));
 
   ast::VariableDeclStatement stmt(std::move(var));
diff --git a/src/writer/msl/test_helper.h b/src/writer/msl/test_helper.h
index 5ab2756..14402ac 100644
--- a/src/writer/msl/test_helper.h
+++ b/src/writer/msl/test_helper.h
@@ -35,11 +35,13 @@
   TestHelperBase() : td(&ctx, &mod), gen(&ctx, &mod) {}
   ~TestHelperBase() = default;
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx.create<T>(std::forward<ARGS>(args)...);
   }
 
   /// The context
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 1470632..518e9ce 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -284,14 +284,14 @@
                     {Operand::Int(SpvAddressingModelLogical),
                      Operand::Int(SpvMemoryModelGLSL450)});
 
-  for (const auto& var : mod_->global_variables()) {
-    if (!GenerateGlobalVariable(var.get())) {
+  for (auto* var : mod_->global_variables()) {
+    if (!GenerateGlobalVariable(var)) {
       return false;
     }
   }
 
-  for (const auto& func : mod_->functions()) {
-    if (!GenerateFunction(func.get())) {
+  for (auto* func : mod_->functions()) {
+    if (!GenerateFunction(func)) {
       return false;
     }
   }
@@ -528,7 +528,7 @@
        Operand::Int(func_type_id)}};
 
   InstructionList params;
-  for (const auto& param : func->params()) {
+  for (auto* param : func->params()) {
     auto param_op = result_op();
     auto param_id = param_op.to_i();
 
@@ -548,8 +548,8 @@
 
   push_function(Function{definition_inst, result_op(), std::move(params)});
 
-  for (const auto& stmt : *(func->body())) {
-    if (!GenerateStatement(stmt.get())) {
+  for (auto* stmt : *func->body()) {
+    if (!GenerateStatement(stmt)) {
       return false;
     }
   }
@@ -586,7 +586,7 @@
   }
 
   OperandList ops = {func_op, Operand::Int(ret_id)};
-  for (const auto& param : func->params()) {
+  for (auto* param : func->params()) {
     auto param_type_id = GenerateTypeIfNeeded(param->type());
     if (param_type_id == 0) {
       return 0;
@@ -754,7 +754,7 @@
   push_type(spv::Op::OpVariable, std::move(ops));
 
   if (var->IsDecorated()) {
-    for (const auto& deco : var->AsDecorated()->decorations()) {
+    for (auto* deco : var->AsDecorated()->decorations()) {
       if (deco->IsBuiltin()) {
         push_annot(spv::Op::OpDecorate,
                    {Operand::Int(var_id), Operand::Int(SpvDecorationBuiltIn),
@@ -842,7 +842,7 @@
 
     uint32_t i = 0;
     for (; i < strct->members().size(); ++i) {
-      const auto& member = strct->members()[i];
+      auto* member = strct->members()[i];
       if (member->name() == name) {
         break;
       }
@@ -1151,7 +1151,7 @@
   auto* tc = expr->AsConstructor()->AsTypeConstructor();
   auto* result_type = tc->type()->UnwrapAll();
   for (size_t i = 0; i < tc->values().size(); ++i) {
-    auto* e = tc->values()[i].get();
+    auto* e = tc->values()[i];
 
     if (!e->IsConstructor()) {
       if (is_global_init) {
@@ -1224,7 +1224,7 @@
          result_type->AsVector()->size() == value_type->AsVector()->size());
   }
   if (can_cast_or_copy) {
-    return GenerateCastOrCopy(result_type, values[0].get());
+    return GenerateCastOrCopy(result_type, values[0]);
   }
 
   auto type_id = GenerateTypeIfNeeded(init->type());
@@ -1240,13 +1240,13 @@
   }
 
   OperandList ops;
-  for (const auto& e : values) {
+  for (auto* e : values) {
     uint32_t id = 0;
     if (constructor_is_const) {
       id = GenerateConstructorExpression(nullptr, e->AsConstructor(),
                                          is_global_init);
     } else {
-      id = GenerateExpression(e.get());
+      id = GenerateExpression(e);
       id = GenerateLoadIfNeeded(e->result_type(), id);
     }
     if (id == 0) {
@@ -1268,7 +1268,7 @@
     // Both scalars, but not the same type so we need to generate a conversion
     // of the value.
     if (value_type->is_scalar() && result_type->is_scalar()) {
-      id = GenerateCastOrCopy(result_type, values[0].get());
+      id = GenerateCastOrCopy(result_type, values[0]);
       out << "_" << id;
       ops.push_back(Operand::Int(id));
       continue;
@@ -1686,8 +1686,8 @@
 
 bool Builder::GenerateBlockStatement(const ast::BlockStatement* stmt) {
   scope_stack_.push_scope();
-  for (const auto& block_stmt : *stmt) {
-    if (!GenerateStatement(block_stmt.get())) {
+  for (auto* block_stmt : *stmt) {
+    if (!GenerateStatement(block_stmt)) {
       return false;
     }
   }
@@ -1725,8 +1725,8 @@
   }
   ops.push_back(Operand::Int(func_id));
 
-  for (const auto& param : expr->params()) {
-    auto id = GenerateExpression(param.get());
+  for (auto* param : expr->params()) {
+    auto id = GenerateExpression(param);
     if (id == 0) {
       return 0;
     }
@@ -1851,8 +1851,8 @@
     return 0;
   }
 
-  for (const auto& p : call->params()) {
-    auto val_id = GenerateExpression(p.get());
+  for (auto* p : call->params()) {
+    auto val_id = GenerateExpression(p);
     if (val_id == 0) {
       return 0;
     }
@@ -1875,7 +1875,7 @@
                                            uint32_t result_id,
                                            OperandList wgsl_params) {
   auto* texture_type =
-      call->params()[0].get()->result_type()->UnwrapAll()->AsTexture();
+      call->params()[0]->result_type()->UnwrapAll()->AsTexture();
 
   // TODO(dsinclair): Remove the LOD param from textureLoad on storage textures
   // when https://github.com/gpuweb/gpuweb/pull/1032 gets merged.
@@ -2036,7 +2036,7 @@
   if (false_block_id != merge_block_id) {
     GenerateLabel(false_block_id);
 
-    auto* else_stmt = else_stmts[cur_else_idx].get();
+    auto* else_stmt = else_stmts[cur_else_idx];
     // Handle the else case by just outputting the statements.
     if (!else_stmt->HasCondition()) {
       if (!GenerateBlockStatement(else_stmt->body())) {
@@ -2085,7 +2085,7 @@
   OperandList params = {Operand::Int(cond_id), Operand::Int(default_block_id)};
 
   std::vector<uint32_t> case_ids;
-  for (const auto& item : stmt->body()) {
+  for (const auto* item : stmt->body()) {
     if (item->IsDefault()) {
       case_ids.push_back(default_block_id);
       continue;
@@ -2095,7 +2095,7 @@
     auto block_id = block.to_i();
 
     case_ids.push_back(block_id);
-    for (const auto& selector : item->selectors()) {
+    for (auto* selector : item->selectors()) {
       if (!selector->IsSint()) {
         error_ = "expected integer literal for switch case label";
         return false;
@@ -2118,7 +2118,7 @@
   // branch, otherwise the branch is to the merge block which comes after
   // the switch statement.
   for (uint32_t i = 0; i < body.size(); i++) {
-    auto& item = body[i];
+    auto* item = body[i];
 
     if (item->IsDefault()) {
       generated_default = true;
@@ -2498,7 +2498,7 @@
 
   auto& members = impl->members();
   for (uint32_t i = 0; i < members.size(); ++i) {
-    auto mem_id = GenerateStructMember(struct_id, i, members[i].get());
+    auto mem_id = GenerateStructMember(struct_id, i, members[i]);
     if (mem_id == 0) {
       return false;
     }
@@ -2531,7 +2531,7 @@
               Operand::String(ctx_->namer()->NameFor(member->name()))});
 
   bool has_layout = false;
-  for (const auto& deco : member->decorations()) {
+  for (auto* deco : member->decorations()) {
     if (deco->IsOffset()) {
       push_annot(spv::Op::OpMemberDecorate,
                  {Operand::Int(struct_id), Operand::Int(idx),
diff --git a/src/writer/spirv/builder_accessor_expression_test.cc b/src/writer/spirv/builder_accessor_expression_test.cc
index 5da3d17..705c66c 100644
--- a/src/writer/spirv/builder_accessor_expression_test.cc
+++ b/src/writer/spirv/builder_accessor_expression_test.cc
@@ -56,8 +56,8 @@
 
   ast::Variable var("ary", ast::StorageClass::kFunction, &vec3);
 
-  auto ary = create<ast::IdentifierExpression>("ary");
-  auto idx_expr = create<ast::ScalarConstructorExpression>(
+  auto* ary = create<ast::IdentifierExpression>("ary");
+  auto* idx_expr = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1));
 
   ast::ArrayAccessorExpression expr(std::move(ary), std::move(idx_expr));
@@ -98,8 +98,8 @@
   ast::Variable var("ary", ast::StorageClass::kFunction, &vec3);
   ast::Variable idx("idx", ast::StorageClass::kFunction, &i32);
 
-  auto ary = create<ast::IdentifierExpression>("ary");
-  auto idx_expr = create<ast::IdentifierExpression>("idx");
+  auto* ary = create<ast::IdentifierExpression>("ary");
+  auto* idx_expr = create<ast::IdentifierExpression>("idx");
 
   ast::ArrayAccessorExpression expr(std::move(ary), std::move(idx_expr));
 
@@ -142,7 +142,7 @@
 
   ast::Variable var("ary", ast::StorageClass::kFunction, &vec3);
 
-  auto ary = create<ast::IdentifierExpression>("ary");
+  auto* ary = create<ast::IdentifierExpression>("ary");
 
   ast::ArrayAccessorExpression expr(
       std::move(ary),
@@ -287,7 +287,7 @@
   members.push_back(create<ast::StructMember>("a", &f32, std::move(decos)));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   ast::Variable var("ident", ast::StorageClass::kFunction, &s_type);
@@ -478,13 +478,13 @@
 
   ast::Variable var("ident", ast::StorageClass::kFunction, &s_type);
 
-  auto lhs = create<ast::MemberAccessorExpression>(
+  auto* lhs = create<ast::MemberAccessorExpression>(
       create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("ident"),
           create<ast::IdentifierExpression>("inner")),
       create<ast::IdentifierExpression>("a"));
 
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.f));
 
   ast::AssignmentStatement expr(std::move(lhs), std::move(rhs));
@@ -549,9 +549,9 @@
   ast::Variable var("ident", ast::StorageClass::kFunction, &s_type);
   ast::Variable store("store", ast::StorageClass::kFunction, &f32);
 
-  auto lhs = create<ast::IdentifierExpression>("store");
+  auto* lhs = create<ast::IdentifierExpression>("store");
 
-  auto rhs = create<ast::MemberAccessorExpression>(
+  auto* rhs = create<ast::MemberAccessorExpression>(
       create<ast::MemberAccessorExpression>(
           create<ast::IdentifierExpression>("ident"),
           create<ast::IdentifierExpression>("inner")),
@@ -795,7 +795,7 @@
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
   members.push_back(create<ast::StructMember>("baz", &vec3, std::move(decos)));
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType c_type("C", std::move(s));
 
   members.push_back(
diff --git a/src/writer/spirv/builder_assign_test.cc b/src/writer/spirv/builder_assign_test.cc
index 58229b0..7d60224 100644
--- a/src/writer/spirv/builder_assign_test.cc
+++ b/src/writer/spirv/builder_assign_test.cc
@@ -47,8 +47,8 @@
 
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
 
-  auto ident = create<ast::IdentifierExpression>("var");
-  auto val = create<ast::ScalarConstructorExpression>(
+  auto* ident = create<ast::IdentifierExpression>("var");
+  auto* val = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0f));
 
   ast::AssignmentStatement assign(std::move(ident), std::move(val));
@@ -81,9 +81,9 @@
 
   ast::Variable v("var", ast::StorageClass::kOutput, &vec);
 
-  auto ident = create<ast::IdentifierExpression>("var");
+  auto* ident = create<ast::IdentifierExpression>("var");
   ast::ExpressionList vals;
-  auto val = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto* val = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
   ast::AssignmentStatement assign(std::move(ident), std::move(val));
 
@@ -119,13 +119,13 @@
       create<ast::FloatLiteral>(&f32, 1.0f)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0f)));
-  auto first = create<ast::TypeConstructorExpression>(&vec2, std::move(vals));
+  auto* first = create<ast::TypeConstructorExpression>(&vec2, std::move(vals));
 
   vals.push_back(std::move(first));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* init = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::Variable v("var", ast::StorageClass::kOutput, &vec3);
 
@@ -173,7 +173,7 @@
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* init = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::Variable v("var", ast::StorageClass::kOutput, &vec3);
 
@@ -219,16 +219,16 @@
   members.push_back(create<ast::StructMember>("a", &f32, std::move(decos)));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   ast::Variable v("ident", ast::StorageClass::kFunction, &s_type);
 
-  auto ident = create<ast::MemberAccessorExpression>(
+  auto* ident = create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("ident"),
       create<ast::IdentifierExpression>("b"));
 
-  auto val = create<ast::ScalarConstructorExpression>(
+  auto* val = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 4.0f));
 
   ast::AssignmentStatement assign(std::move(ident), std::move(val));
@@ -266,7 +266,7 @@
 
   ast::Variable v("var", ast::StorageClass::kOutput, &vec3);
 
-  auto ident = create<ast::IdentifierExpression>("var");
+  auto* ident = create<ast::IdentifierExpression>("var");
 
   ast::ExpressionList vals;
   vals.push_back(create<ast::ScalarConstructorExpression>(
@@ -276,7 +276,7 @@
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto val = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* val = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::AssignmentStatement assign(std::move(ident), std::move(val));
 
@@ -313,10 +313,10 @@
 
   ast::Variable v("var", ast::StorageClass::kOutput, &vec3);
 
-  auto ident = create<ast::MemberAccessorExpression>(
+  auto* ident = create<ast::MemberAccessorExpression>(
       create<ast::IdentifierExpression>("var"),
       create<ast::IdentifierExpression>("y"));
-  auto val = create<ast::ScalarConstructorExpression>(
+  auto* val = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0f));
 
   ast::AssignmentStatement assign(std::move(ident), std::move(val));
@@ -358,11 +358,11 @@
 
   ast::Variable v("var", ast::StorageClass::kOutput, &vec3);
 
-  auto ident = create<ast::ArrayAccessorExpression>(
+  auto* ident = create<ast::ArrayAccessorExpression>(
       create<ast::IdentifierExpression>("var"),
       create<ast::ScalarConstructorExpression>(
           create<ast::SintLiteral>(&i32, 1)));
-  auto val = create<ast::ScalarConstructorExpression>(
+  auto* val = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0f));
 
   ast::AssignmentStatement assign(std::move(ident), std::move(val));
diff --git a/src/writer/spirv/builder_binary_expression_test.cc b/src/writer/spirv/builder_binary_expression_test.cc
index 1b4d2cd..7a1f473 100644
--- a/src/writer/spirv/builder_binary_expression_test.cc
+++ b/src/writer/spirv/builder_binary_expression_test.cc
@@ -57,9 +57,9 @@
 
   ast::type::I32Type i32;
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 3));
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 4));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
@@ -89,7 +89,7 @@
       create<ast::SintLiteral>(&i32, 1)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
-  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
@@ -97,7 +97,7 @@
       create<ast::SintLiteral>(&i32, 1)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
-  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -121,8 +121,8 @@
 
   ast::Variable var("param", ast::StorageClass::kFunction, &i32);
 
-  auto lhs = create<ast::IdentifierExpression>("param");
-  auto rhs = create<ast::IdentifierExpression>("param");
+  auto* lhs = create<ast::IdentifierExpression>("param");
+  auto* rhs = create<ast::IdentifierExpression>("param");
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -169,9 +169,9 @@
 
   ast::type::U32Type u32;
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 3));
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 4));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
@@ -201,7 +201,7 @@
       create<ast::UintLiteral>(&u32, 1)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 1)));
-  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 1)));
@@ -209,7 +209,7 @@
       create<ast::UintLiteral>(&u32, 1)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 1)));
-  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -247,9 +247,9 @@
 
   ast::type::F32Type f32;
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.2f));
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 4.5f));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
@@ -279,7 +279,7 @@
       create<ast::FloatLiteral>(&f32, 1.f)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
-  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
@@ -287,7 +287,7 @@
       create<ast::FloatLiteral>(&f32, 1.f)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
-  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -319,9 +319,9 @@
 
   ast::type::U32Type u32;
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 3));
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 4));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
@@ -353,7 +353,7 @@
       create<ast::UintLiteral>(&u32, 1)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 1)));
-  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 1)));
@@ -361,7 +361,7 @@
       create<ast::UintLiteral>(&u32, 1)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::UintLiteral>(&u32, 1)));
-  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -397,9 +397,9 @@
 
   ast::type::I32Type i32;
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 3));
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 4));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
@@ -431,7 +431,7 @@
       create<ast::SintLiteral>(&i32, 1)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
-  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
@@ -439,7 +439,7 @@
       create<ast::SintLiteral>(&i32, 1)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
-  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -475,9 +475,9 @@
 
   ast::type::F32Type f32;
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.2f));
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 4.5f));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
@@ -509,7 +509,7 @@
       create<ast::FloatLiteral>(&f32, 1.f)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
-  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
@@ -517,7 +517,7 @@
       create<ast::FloatLiteral>(&f32, 1.f)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
-  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -558,9 +558,9 @@
       create<ast::FloatLiteral>(&f32, 1.f)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
-  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f));
 
   ast::BinaryExpression expr(ast::BinaryOp::kMultiply, std::move(lhs),
@@ -584,7 +584,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec3(&f32, 3);
 
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f));
 
   ast::ExpressionList vals;
@@ -594,7 +594,7 @@
       create<ast::FloatLiteral>(&f32, 1.f)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
-  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(ast::BinaryOp::kMultiply, std::move(lhs),
                              std::move(rhs));
@@ -617,12 +617,12 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat3(&f32, 3, 3);
 
-  auto var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
-  auto lhs = create<ast::IdentifierExpression>("mat");
-  auto rhs = create<ast::ScalarConstructorExpression>(
+  auto* var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
+  auto* lhs = create<ast::IdentifierExpression>("mat");
+  auto* rhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
 
   ast::BinaryExpression expr(ast::BinaryOp::kMultiply, std::move(lhs),
                              std::move(rhs));
@@ -630,7 +630,7 @@
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 8u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
@@ -650,12 +650,12 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat3(&f32, 3, 3);
 
-  auto var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
-  auto lhs = create<ast::ScalarConstructorExpression>(
+  auto* var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
+  auto* lhs = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f));
-  auto rhs = create<ast::IdentifierExpression>("mat");
+  auto* rhs = create<ast::IdentifierExpression>("mat");
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
 
   ast::BinaryExpression expr(ast::BinaryOp::kMultiply, std::move(lhs),
                              std::move(rhs));
@@ -663,7 +663,7 @@
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 8u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
@@ -684,8 +684,8 @@
   ast::type::VectorType vec3(&f32, 3);
   ast::type::MatrixType mat3(&f32, 3, 3);
 
-  auto var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
-  auto lhs = create<ast::IdentifierExpression>("mat");
+  auto* var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
+  auto* lhs = create<ast::IdentifierExpression>("mat");
 
   ast::ExpressionList vals;
   vals.push_back(create<ast::ScalarConstructorExpression>(
@@ -694,9 +694,9 @@
       create<ast::FloatLiteral>(&f32, 1.f)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
-  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
 
   ast::BinaryExpression expr(ast::BinaryOp::kMultiply, std::move(lhs),
                              std::move(rhs));
@@ -704,7 +704,7 @@
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 9u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
@@ -726,7 +726,7 @@
   ast::type::VectorType vec3(&f32, 3);
   ast::type::MatrixType mat3(&f32, 3, 3);
 
-  auto var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
+  auto* var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
 
   ast::ExpressionList vals;
   vals.push_back(create<ast::ScalarConstructorExpression>(
@@ -735,11 +735,11 @@
       create<ast::FloatLiteral>(&f32, 1.f)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
-  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  auto rhs = create<ast::IdentifierExpression>("mat");
+  auto* rhs = create<ast::IdentifierExpression>("mat");
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
 
   ast::BinaryExpression expr(ast::BinaryOp::kMultiply, std::move(lhs),
                              std::move(rhs));
@@ -747,7 +747,7 @@
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 9u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
@@ -769,11 +769,11 @@
   ast::type::VectorType vec3(&f32, 3);
   ast::type::MatrixType mat3(&f32, 3, 3);
 
-  auto var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
-  auto lhs = create<ast::IdentifierExpression>("mat");
-  auto rhs = create<ast::IdentifierExpression>("mat");
+  auto* var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
+  auto* lhs = create<ast::IdentifierExpression>("mat");
+  auto* rhs = create<ast::IdentifierExpression>("mat");
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
 
   ast::BinaryExpression expr(ast::BinaryOp::kMultiply, std::move(lhs),
                              std::move(rhs));
@@ -781,7 +781,7 @@
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 8u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
@@ -800,14 +800,14 @@
 TEST_F(BuilderTest, Binary_LogicalAnd) {
   ast::type::I32Type i32;
 
-  auto lhs =
+  auto* lhs =
       create<ast::BinaryExpression>(ast::BinaryOp::kEqual,
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::SintLiteral>(&i32, 1)),
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::SintLiteral>(&i32, 2)));
 
-  auto rhs =
+  auto* rhs =
       create<ast::BinaryExpression>(ast::BinaryOp::kEqual,
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::SintLiteral>(&i32, 3)),
@@ -846,20 +846,20 @@
 TEST_F(BuilderTest, Binary_LogicalAnd_WithLoads) {
   ast::type::BoolType bool_type;
 
-  auto a_var =
+  auto* a_var =
       create<ast::Variable>("a", ast::StorageClass::kFunction, &bool_type);
   a_var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true)));
-  auto b_var =
+  auto* b_var =
       create<ast::Variable>("b", ast::StorageClass::kFunction, &bool_type);
   b_var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, false)));
 
-  auto lhs = create<ast::IdentifierExpression>("a");
-  auto rhs = create<ast::IdentifierExpression>("b");
+  auto* lhs = create<ast::IdentifierExpression>("a");
+  auto* rhs = create<ast::IdentifierExpression>("b");
 
-  td.RegisterVariableForTesting(a_var.get());
-  td.RegisterVariableForTesting(b_var.get());
+  td.RegisterVariableForTesting(a_var);
+  td.RegisterVariableForTesting(b_var);
 
   ast::BinaryExpression expr(ast::BinaryOp::kLogicalAnd, std::move(lhs),
                              std::move(rhs));
@@ -869,8 +869,8 @@
   b.push_function(Function{});
   b.GenerateLabel(b.next_id());
 
-  ASSERT_TRUE(b.GenerateGlobalVariable(a_var.get())) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(b_var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(a_var)) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(b_var)) << b.error();
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 12u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
@@ -896,14 +896,14 @@
 TEST_F(BuilderTest, Binary_LogicalOr) {
   ast::type::I32Type i32;
 
-  auto lhs =
+  auto* lhs =
       create<ast::BinaryExpression>(ast::BinaryOp::kEqual,
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::SintLiteral>(&i32, 1)),
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::SintLiteral>(&i32, 2)));
 
-  auto rhs =
+  auto* rhs =
       create<ast::BinaryExpression>(ast::BinaryOp::kEqual,
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::SintLiteral>(&i32, 3)),
@@ -942,20 +942,20 @@
 TEST_F(BuilderTest, Binary_LogicalOr_WithLoads) {
   ast::type::BoolType bool_type;
 
-  auto a_var =
+  auto* a_var =
       create<ast::Variable>("a", ast::StorageClass::kFunction, &bool_type);
   a_var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true)));
-  auto b_var =
+  auto* b_var =
       create<ast::Variable>("b", ast::StorageClass::kFunction, &bool_type);
   b_var->set_constructor(create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, false)));
 
-  auto lhs = create<ast::IdentifierExpression>("a");
-  auto rhs = create<ast::IdentifierExpression>("b");
+  auto* lhs = create<ast::IdentifierExpression>("a");
+  auto* rhs = create<ast::IdentifierExpression>("b");
 
-  td.RegisterVariableForTesting(a_var.get());
-  td.RegisterVariableForTesting(b_var.get());
+  td.RegisterVariableForTesting(a_var);
+  td.RegisterVariableForTesting(b_var);
 
   ast::BinaryExpression expr(ast::BinaryOp::kLogicalOr, std::move(lhs),
                              std::move(rhs));
@@ -965,8 +965,8 @@
   b.push_function(Function{});
   b.GenerateLabel(b.next_id());
 
-  ASSERT_TRUE(b.GenerateGlobalVariable(a_var.get())) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(b_var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(a_var)) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(b_var)) << b.error();
 
   EXPECT_EQ(b.GenerateBinaryExpression(&expr), 12u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
diff --git a/src/writer/spirv/builder_block_test.cc b/src/writer/spirv/builder_block_test.cc
index 505642b..8e5d888 100644
--- a/src/writer/spirv/builder_block_test.cc
+++ b/src/writer/spirv/builder_block_test.cc
@@ -49,7 +49,7 @@
       create<ast::ScalarConstructorExpression>(
           create<ast::FloatLiteral>(&f32, 1.0f))));
 
-  auto inner = create<ast::BlockStatement>();
+  auto* inner = create<ast::BlockStatement>();
   inner->append(create<ast::VariableDeclStatement>(
       create<ast::Variable>("var", ast::StorageClass::kFunction, &f32)));
   inner->append(create<ast::AssignmentStatement>(
diff --git a/src/writer/spirv/builder_call_test.cc b/src/writer/spirv/builder_call_test.cc
index a7afb76..fcd1cd6 100644
--- a/src/writer/spirv/builder_call_test.cc
+++ b/src/writer/spirv/builder_call_test.cc
@@ -49,7 +49,7 @@
   func_params.push_back(
       create<ast::Variable>("b", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>(create<ast::BinaryExpression>(
       ast::BinaryOp::kAdd, create<ast::IdentifierExpression>("a"),
       create<ast::IdentifierExpression>("b"))));
@@ -109,7 +109,7 @@
   func_params.push_back(
       create<ast::Variable>("b", ast::StorageClass::kFunction, &f32));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>(create<ast::BinaryExpression>(
       ast::BinaryOp::kAdd, create<ast::IdentifierExpression>("a"),
       create<ast::IdentifierExpression>("b"))));
diff --git a/src/writer/spirv/builder_constructor_expression_test.cc b/src/writer/spirv/builder_constructor_expression_test.cc
index c94080e..783d8dd 100644
--- a/src/writer/spirv/builder_constructor_expression_test.cc
+++ b/src/writer/spirv/builder_constructor_expression_test.cc
@@ -52,7 +52,7 @@
 
 TEST_F(BuilderTest, Constructor_Const) {
   ast::type::F32Type f32;
-  auto fl = create<ast::FloatLiteral>(&f32, 42.2f);
+  auto* fl = create<ast::FloatLiteral>(&f32, 42.2f);
   ast::ScalarConstructorExpression c(std::move(fl));
 
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, &c, true), 2u);
@@ -100,13 +100,13 @@
       create<ast::SintLiteral>(&i32, 1)));
 
   ast::ExpressionList vals;
-  vals.push_back(create<ast::TypeConstructorExpression>(
-      &f32, std::move(type_vals)));
+  vals.push_back(
+      create<ast::TypeConstructorExpression>(&f32, std::move(type_vals)));
 
   type_vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
-  vals.push_back(create<ast::TypeConstructorExpression>(
-      &f32, std::move(type_vals)));
+  vals.push_back(
+      create<ast::TypeConstructorExpression>(&f32, std::move(type_vals)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vals));
 
@@ -162,8 +162,8 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec(&f32, 2);
 
-  auto var = create<ast::Variable>(
-      "ident", ast::StorageClass::kFunction, &f32);
+  auto* var =
+      create<ast::Variable>("ident", ast::StorageClass::kFunction, &f32);
 
   ast::ExpressionList vals;
   vals.push_back(create<ast::ScalarConstructorExpression>(
@@ -172,11 +172,11 @@
 
   ast::TypeConstructorExpression t(&vec, std::move(vals));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
   EXPECT_TRUE(td.DetermineResultType(&t)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateFunctionVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateExpression(&t), 8u);
   ASSERT_FALSE(b.has_error()) << b.error();
@@ -233,12 +233,12 @@
 TEST_F(BuilderTest, Constructor_Type_NonConst_Value_Fails) {
   ast::type::F32Type f32;
   ast::type::VectorType vec(&f32, 2);
-  auto rel = create<ast::BinaryExpression>(
-      ast::BinaryOp::kAdd,
-      create<ast::ScalarConstructorExpression>(
-          create<ast::FloatLiteral>(&f32, 3.0f)),
-      create<ast::ScalarConstructorExpression>(
-          create<ast::FloatLiteral>(&f32, 3.0f)));
+  auto* rel =
+      create<ast::BinaryExpression>(ast::BinaryOp::kAdd,
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::FloatLiteral>(&f32, 3.0f)),
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::FloatLiteral>(&f32, 3.0f)));
 
   ast::ExpressionList vals;
   vals.push_back(create<ast::ScalarConstructorExpression>(
@@ -408,8 +408,8 @@
   ast::ExpressionList params;
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec_params)));
 
   ast::TypeConstructorExpression cast(&vec3, std::move(params));
 
@@ -443,8 +443,8 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec_params)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
 
@@ -512,8 +512,8 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec_params)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
 
@@ -549,8 +549,8 @@
   ast::ExpressionList params;
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec_params)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
 
@@ -586,8 +586,8 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec_params)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
   params.push_back(create<ast::ScalarConstructorExpression>(
@@ -631,10 +631,10 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec2_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec2_params)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
 
@@ -674,8 +674,8 @@
   ast::ExpressionList params;
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec3, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec3, std::move(vec_params)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
 
@@ -712,8 +712,8 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec3, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec3, std::move(vec_params)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
 
@@ -752,8 +752,8 @@
   ast::ExpressionList params;
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec_params)));
 
   ast::TypeConstructorExpression cast(&vec3, std::move(params));
 
@@ -788,8 +788,8 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec_params)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
 
@@ -830,8 +830,8 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec_params)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
 
@@ -868,8 +868,8 @@
   ast::ExpressionList params;
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec_params)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
 
@@ -906,8 +906,8 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec_params)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
   params.push_back(create<ast::ScalarConstructorExpression>(
@@ -952,10 +952,10 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec2, std::move(vec2_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec2, std::move(vec2_params)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
 
@@ -996,8 +996,8 @@
   ast::ExpressionList params;
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec3, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec3, std::move(vec_params)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
 
@@ -1036,8 +1036,8 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec3, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec3, std::move(vec_params)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
 
@@ -1082,10 +1082,10 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec2_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec2_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
 
@@ -1127,12 +1127,12 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec2_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec3_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec2_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec3_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
 
@@ -1180,14 +1180,14 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec2_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec3_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec4_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec2_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec3_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec4_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
 
@@ -1227,10 +1227,10 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec2_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec2_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
 
@@ -1278,12 +1278,12 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec2_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec3_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec2_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec3_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
 
@@ -1339,14 +1339,14 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec2_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec3_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec4_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec2_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec3_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec4_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
 
@@ -1390,10 +1390,10 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec2_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec2_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
 
@@ -1447,12 +1447,12 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec2_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec3_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec2_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec3_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
 
@@ -1516,14 +1516,14 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec2_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec3_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec4_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec2_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec3_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec4_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
 
@@ -1595,10 +1595,10 @@
       create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
-  params.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec2_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
+  params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec2_params)));
 
   ast::TypeConstructorExpression cast(&ary, std::move(params));
 
@@ -1624,12 +1624,10 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      create<ast::StructMember>("a", &f32, std::move(decos)));
-  members.push_back(
-      create<ast::StructMember>("b", &vec, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &f32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("b", &vec, std::move(decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   ast::ExpressionList vec_vals;
@@ -1643,8 +1641,8 @@
   ast::ExpressionList vals;
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2)));
-  vals.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_vals)));
+  vals.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_vals)));
 
   ast::TypeConstructorExpression t(&s_type, std::move(vals));
 
@@ -1804,10 +1802,9 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      create<ast::StructMember>("a", &f32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &f32, std::move(decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   ast::ExpressionList vals;
@@ -1976,19 +1973,18 @@
   ast::type::I32Type i32;
   ast::type::VectorType ivec3(&i32, 3);
 
-  auto var =
-      create<ast::Variable>("i", ast::StorageClass::kPrivate, &uvec3);
+  auto* var = create<ast::Variable>("i", ast::StorageClass::kPrivate, &uvec3);
 
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("i"));
 
   ast::TypeConstructorExpression cast(&ivec3, std::move(params));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(&cast), 6u) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
@@ -2011,19 +2007,18 @@
   ast::type::F32Type f32;
   ast::type::VectorType fvec3(&f32, 3);
 
-  auto var =
-      create<ast::Variable>("i", ast::StorageClass::kPrivate, &fvec3);
+  auto* var = create<ast::Variable>("i", ast::StorageClass::kPrivate, &fvec3);
 
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("i"));
 
   ast::TypeConstructorExpression cast(&ivec3, std::move(params));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(&cast), 6u) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
@@ -2046,19 +2041,18 @@
   ast::type::I32Type i32;
   ast::type::VectorType ivec3(&i32, 3);
 
-  auto var =
-      create<ast::Variable>("i", ast::StorageClass::kPrivate, &ivec3);
+  auto* var = create<ast::Variable>("i", ast::StorageClass::kPrivate, &ivec3);
 
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("i"));
 
   ast::TypeConstructorExpression cast(&uvec3, std::move(params));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(&cast), 6u) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
@@ -2081,19 +2075,18 @@
   ast::type::F32Type f32;
   ast::type::VectorType fvec3(&f32, 3);
 
-  auto var =
-      create<ast::Variable>("i", ast::StorageClass::kPrivate, &fvec3);
+  auto* var = create<ast::Variable>("i", ast::StorageClass::kPrivate, &fvec3);
 
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("i"));
 
   ast::TypeConstructorExpression cast(&uvec3, std::move(params));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(&cast), 6u) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
@@ -2116,19 +2109,18 @@
   ast::type::F32Type f32;
   ast::type::VectorType fvec3(&f32, 3);
 
-  auto var =
-      create<ast::Variable>("i", ast::StorageClass::kPrivate, &ivec3);
+  auto* var = create<ast::Variable>("i", ast::StorageClass::kPrivate, &ivec3);
 
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("i"));
 
   ast::TypeConstructorExpression cast(&fvec3, std::move(params));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(&cast), 6u) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
@@ -2151,19 +2143,18 @@
   ast::type::F32Type f32;
   ast::type::VectorType fvec3(&f32, 3);
 
-  auto var =
-      create<ast::Variable>("i", ast::StorageClass::kPrivate, &uvec3);
+  auto* var = create<ast::Variable>("i", ast::StorageClass::kPrivate, &uvec3);
 
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("i"));
 
   ast::TypeConstructorExpression cast(&fvec3, std::move(params));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(&cast), 6u) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
@@ -2239,8 +2230,7 @@
       create<ast::FloatLiteral>(&f32, 2.f)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.f)));
-  auto first =
-      create<ast::TypeConstructorExpression>(&vec, std::move(params));
+  auto* first = create<ast::TypeConstructorExpression>(&vec, std::move(params));
 
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
@@ -2248,7 +2238,7 @@
       create<ast::FloatLiteral>(&f32, 2.f)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.f)));
-  auto second =
+  auto* second =
       create<ast::TypeConstructorExpression>(&vec, std::move(params));
 
   ast::ExpressionList ary_params;
@@ -2273,13 +2263,13 @@
   ast::ExpressionList params;
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0)));
-  vec_params.push_back(create<ast::TypeConstructorExpression>(
-      &f32, std::move(params)));
+  vec_params.push_back(
+      create<ast::TypeConstructorExpression>(&f32, std::move(params)));
 
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(create<ast::TypeConstructorExpression>(
-      &f32, std::move(params)));
+  vec_params.push_back(
+      create<ast::TypeConstructorExpression>(&f32, std::move(params)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vec_params));
 
@@ -2300,13 +2290,13 @@
   ast::ExpressionList params;
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
-  vec_params.push_back(create<ast::TypeConstructorExpression>(
-      &f32, std::move(params)));
+  vec_params.push_back(
+      create<ast::TypeConstructorExpression>(&f32, std::move(params)));
 
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
-  vec_params.push_back(create<ast::TypeConstructorExpression>(
-      &f32, std::move(params)));
+  vec_params.push_back(
+      create<ast::TypeConstructorExpression>(&f32, std::move(params)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vec_params));
 
@@ -2374,8 +2364,7 @@
       create<ast::FloatLiteral>(&f32, 2.f)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.f)));
-  auto first =
-      create<ast::TypeConstructorExpression>(&vec, std::move(params));
+  auto* first = create<ast::TypeConstructorExpression>(&vec, std::move(params));
 
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.f)));
@@ -2383,7 +2372,7 @@
       create<ast::FloatLiteral>(&f32, 2.f)));
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.f)));
-  auto second =
+  auto* second =
       create<ast::TypeConstructorExpression>(&vec, std::move(params));
 
   ast::ExpressionList ary_params;
@@ -2408,13 +2397,13 @@
   ast::ExpressionList params;
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
-  vec_params.push_back(create<ast::TypeConstructorExpression>(
-      &f32, std::move(params)));
+  vec_params.push_back(
+      create<ast::TypeConstructorExpression>(&f32, std::move(params)));
 
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
-  vec_params.push_back(create<ast::TypeConstructorExpression>(
-      &f32, std::move(params)));
+  vec_params.push_back(
+      create<ast::TypeConstructorExpression>(&f32, std::move(params)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vec_params));
 
@@ -2435,13 +2424,13 @@
   ast::ExpressionList params;
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1)));
-  vec_params.push_back(create<ast::TypeConstructorExpression>(
-      &f32, std::move(params)));
+  vec_params.push_back(
+      create<ast::TypeConstructorExpression>(&f32, std::move(params)));
 
   params.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 2)));
-  vec_params.push_back(create<ast::TypeConstructorExpression>(
-      &f32, std::move(params)));
+  vec_params.push_back(
+      create<ast::TypeConstructorExpression>(&f32, std::move(params)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vec_params));
 
@@ -2476,12 +2465,10 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      create<ast::StructMember>("a", &f32, std::move(decos)));
-  members.push_back(
-      create<ast::StructMember>("b", &vec, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &f32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("b", &vec, std::move(decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   ast::ExpressionList vec_vals;
@@ -2495,8 +2482,8 @@
   ast::ExpressionList vals;
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2)));
-  vals.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_vals)));
+  vals.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_vals)));
 
   ast::TypeConstructorExpression t(&s_type, std::move(vals));
 
@@ -2512,12 +2499,10 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      create<ast::StructMember>("a", &f32, std::move(decos)));
-  members.push_back(
-      create<ast::StructMember>("b", &vec, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &f32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("b", &vec, std::move(decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   ast::ExpressionList vec_vals;
@@ -2530,8 +2515,8 @@
   ast::ExpressionList vals;
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2)));
-  vals.push_back(create<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_vals)));
+  vals.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_vals)));
 
   ast::TypeConstructorExpression t(&s_type, std::move(vals));
 
diff --git a/src/writer/spirv/builder_function_decoration_test.cc b/src/writer/spirv/builder_function_decoration_test.cc
index 740c5d7..716e620 100644
--- a/src/writer/spirv/builder_function_decoration_test.cc
+++ b/src/writer/spirv/builder_function_decoration_test.cc
@@ -95,15 +95,15 @@
   ast::Function func("main", {}, &void_type, create<ast::BlockStatement>());
   func.add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
-  auto v_in = create<ast::Variable>("my_in", ast::StorageClass::kInput, &f32);
-  auto v_out =
+  auto* v_in = create<ast::Variable>("my_in", ast::StorageClass::kInput, &f32);
+  auto* v_out =
       create<ast::Variable>("my_out", ast::StorageClass::kOutput, &f32);
-  auto v_wg =
+  auto* v_wg =
       create<ast::Variable>("my_wg", ast::StorageClass::kWorkgroup, &f32);
 
-  EXPECT_TRUE(b.GenerateGlobalVariable(v_in.get())) << b.error();
-  EXPECT_TRUE(b.GenerateGlobalVariable(v_out.get())) << b.error();
-  EXPECT_TRUE(b.GenerateGlobalVariable(v_wg.get())) << b.error();
+  EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error();
+  EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error();
+  EXPECT_TRUE(b.GenerateGlobalVariable(v_wg)) << b.error();
 
   mod.AddGlobalVariable(std::move(v_in));
   mod.AddGlobalVariable(std::move(v_out));
@@ -139,7 +139,7 @@
   func.add_decoration(
       create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::AssignmentStatement>(
       create<ast::IdentifierExpression>("my_out"),
       create<ast::IdentifierExpression>("my_in")));
@@ -152,21 +152,21 @@
       create<ast::IdentifierExpression>("my_in")));
   func.set_body(std::move(body));
 
-  auto v_in = create<ast::Variable>("my_in", ast::StorageClass::kInput, &f32);
-  auto v_out =
+  auto* v_in = create<ast::Variable>("my_in", ast::StorageClass::kInput, &f32);
+  auto* v_out =
       create<ast::Variable>("my_out", ast::StorageClass::kOutput, &f32);
-  auto v_wg =
+  auto* v_wg =
       create<ast::Variable>("my_wg", ast::StorageClass::kWorkgroup, &f32);
 
-  td.RegisterVariableForTesting(v_in.get());
-  td.RegisterVariableForTesting(v_out.get());
-  td.RegisterVariableForTesting(v_wg.get());
+  td.RegisterVariableForTesting(v_in);
+  td.RegisterVariableForTesting(v_out);
+  td.RegisterVariableForTesting(v_wg);
 
   ASSERT_TRUE(td.DetermineFunction(&func)) << td.error();
 
-  EXPECT_TRUE(b.GenerateGlobalVariable(v_in.get())) << b.error();
-  EXPECT_TRUE(b.GenerateGlobalVariable(v_out.get())) << b.error();
-  EXPECT_TRUE(b.GenerateGlobalVariable(v_wg.get())) << b.error();
+  EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error();
+  EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error();
+  EXPECT_TRUE(b.GenerateGlobalVariable(v_wg)) << b.error();
 
   mod.AddGlobalVariable(std::move(v_in));
   mod.AddGlobalVariable(std::move(v_out));
diff --git a/src/writer/spirv/builder_function_test.cc b/src/writer/spirv/builder_function_test.cc
index 62d3c92..7ff4676 100644
--- a/src/writer/spirv/builder_function_test.cc
+++ b/src/writer/spirv/builder_function_test.cc
@@ -69,20 +69,20 @@
   ast::type::I32Type i32;
 
   ast::VariableList params;
-  auto var_a = create<ast::Variable>("a", ast::StorageClass::kFunction, &f32);
+  auto* var_a = create<ast::Variable>("a", ast::StorageClass::kFunction, &f32);
   var_a->set_is_const(true);
   params.push_back(std::move(var_a));
-  auto var_b = create<ast::Variable>("b", ast::StorageClass::kFunction, &i32);
+  auto* var_b = create<ast::Variable>("b", ast::StorageClass::kFunction, &i32);
   var_b->set_is_const(true);
   params.push_back(std::move(var_b));
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::ReturnStatement>(create<ast::IdentifierExpression>("a")));
   ast::Function func("a_func", std::move(params), &f32, std::move(body));
 
-  td.RegisterVariableForTesting(func.params()[0].get());
-  td.RegisterVariableForTesting(func.params()[1].get());
+  td.RegisterVariableForTesting(func.params()[0]);
+  td.RegisterVariableForTesting(func.params()[1]);
   EXPECT_TRUE(td.DetermineFunction(&func));
 
   ASSERT_TRUE(b.GenerateFunction(&func));
@@ -104,7 +104,7 @@
 TEST_F(BuilderTest, Function_WithBody) {
   ast::type::VoidType void_type;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ReturnStatement>());
 
   ast::Function func("a_func", {}, &void_type, std::move(body));
@@ -170,12 +170,12 @@
   ast::StructDecorationList s_decos;
   s_decos.push_back(create<ast::StructBlockDecoration>(Source{}));
 
-  auto str = create<ast::Struct>(std::move(s_decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(s_decos), std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
   ast::type::AccessControlType ac(ast::AccessControl::kReadWrite, &s);
 
-  auto data_var = create<ast::DecoratedVariable>(
+  auto* data_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
@@ -185,22 +185,22 @@
 
   mod.AddConstructedType(&s);
 
-  td.RegisterVariableForTesting(data_var.get());
+  td.RegisterVariableForTesting(data_var);
   mod.AddGlobalVariable(std::move(data_var));
 
   {
     ast::VariableList params;
-    auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+    auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
     var->set_constructor(create<ast::MemberAccessorExpression>(
         create<ast::IdentifierExpression>("data"),
         create<ast::IdentifierExpression>("d")));
 
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
     body->append(create<ast::VariableDeclStatement>(std::move(var)));
     body->append(create<ast::ReturnStatement>());
 
-    auto func = create<ast::Function>("a", std::move(params), &void_type,
-                                      std::move(body));
+    auto* func = create<ast::Function>("a", std::move(params), &void_type,
+                                       std::move(body));
     func->add_decoration(
         create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
@@ -209,17 +209,17 @@
 
   {
     ast::VariableList params;
-    auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+    auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
     var->set_constructor(create<ast::MemberAccessorExpression>(
         create<ast::IdentifierExpression>("data"),
         create<ast::IdentifierExpression>("d")));
 
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
     body->append(create<ast::VariableDeclStatement>(std::move(var)));
     body->append(create<ast::ReturnStatement>());
 
-    auto func = create<ast::Function>("b", std::move(params), &void_type,
-                                      std::move(body));
+    auto* func = create<ast::Function>("b", std::move(params), &void_type,
+                                       std::move(body));
     func->add_decoration(
         create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
diff --git a/src/writer/spirv/builder_function_variable_test.cc b/src/writer/spirv/builder_function_variable_test.cc
index af4f055..4b5beef 100644
--- a/src/writer/spirv/builder_function_variable_test.cc
+++ b/src/writer/spirv/builder_function_variable_test.cc
@@ -77,9 +77,9 @@
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto* init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
-  EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
+  EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
 
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
   v.set_constructor(std::move(init));
@@ -111,7 +111,7 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec(&f32, 2);
 
-  auto rel =
+  auto* rel =
       create<ast::BinaryExpression>(ast::BinaryOp::kAdd,
                                     create<ast::ScalarConstructorExpression>(
                                         create<ast::FloatLiteral>(&f32, 3.0f)),
@@ -123,9 +123,9 @@
       create<ast::FloatLiteral>(&f32, 1.0f)));
   vals.push_back(std::move(rel));
 
-  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto* init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
-  EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
+  EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
 
   ast::Variable v("var", ast::StorageClass::kFunction, &vec);
   v.set_constructor(std::move(init));
@@ -160,10 +160,10 @@
 
   ast::type::F32Type f32;
 
-  auto init = create<ast::ScalarConstructorExpression>(
+  auto* init = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0f));
 
-  ASSERT_TRUE(td.DetermineResultType(init.get())) << td.error();
+  ASSERT_TRUE(td.DetermineResultType(init)) << td.error();
 
   ast::Variable v("v", ast::StorageClass::kFunction, &f32);
   v.set_constructor(std::move(init));
@@ -205,10 +205,10 @@
 
   ast::type::F32Type f32;
 
-  auto init = create<ast::ScalarConstructorExpression>(
+  auto* init = create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 1.0f));
 
-  EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
+  EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
 
   ast::Variable v("v", ast::StorageClass::kFunction, &f32);
   v.set_constructor(std::move(init));
@@ -254,9 +254,9 @@
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto* init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
-  EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
+  EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
 
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
   v.set_constructor(std::move(init));
diff --git a/src/writer/spirv/builder_global_variable_test.cc b/src/writer/spirv/builder_global_variable_test.cc
index ff044d5..332af1d 100644
--- a/src/writer/spirv/builder_global_variable_test.cc
+++ b/src/writer/spirv/builder_global_variable_test.cc
@@ -104,9 +104,9 @@
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto* init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
-  EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
+  EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
 
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
   v.set_constructor(std::move(init));
@@ -139,9 +139,9 @@
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto* init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
-  EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
+  EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
 
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
   v.set_constructor(std::move(init));
@@ -172,9 +172,9 @@
       create<ast::FloatLiteral>(&f32, 2.0f)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
-  auto init = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* init = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
+  EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
 
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
   v.set_constructor(std::move(init));
@@ -203,15 +203,15 @@
       create<ast::FloatLiteral>(&f32, 1.0f)));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 2.0f)));
-  auto first = create<ast::TypeConstructorExpression>(&vec2, std::move(vals));
+  auto* first = create<ast::TypeConstructorExpression>(&vec2, std::move(vals));
 
   vals.push_back(std::move(first));
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto* init = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
+  EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
 
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
   v.set_constructor(std::move(init));
@@ -239,7 +239,7 @@
 
 TEST_F(BuilderTest, GlobalVar_WithLocation) {
   ast::type::F32Type f32;
-  auto v = create<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
+  auto* v = create<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::LocationDecoration>(5, Source{}));
 
@@ -260,7 +260,7 @@
 
 TEST_F(BuilderTest, GlobalVar_WithBindingAndSet) {
   ast::type::F32Type f32;
-  auto v = create<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
+  auto* v = create<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
   ast::VariableDecorationList decos;
   decos.push_back(create<ast::BindingDecoration>(2, Source{}));
   decos.push_back(create<ast::SetDecoration>(3, Source{}));
@@ -283,7 +283,7 @@
 
 TEST_F(BuilderTest, GlobalVar_WithBuiltin) {
   ast::type::F32Type f32;
-  auto v = create<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
+  auto* v = create<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
   ast::VariableDecorationList decos;
   decos.push_back(
       create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
diff --git a/src/writer/spirv/builder_ident_expression_test.cc b/src/writer/spirv/builder_ident_expression_test.cc
index 8014183..056a44e 100644
--- a/src/writer/spirv/builder_ident_expression_test.cc
+++ b/src/writer/spirv/builder_ident_expression_test.cc
@@ -50,9 +50,9 @@
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto* init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
-  EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
+  EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
 
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
   v.set_constructor(std::move(init));
@@ -109,9 +109,9 @@
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto* init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
-  EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
+  EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
 
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
   v.set_constructor(std::move(init));
@@ -165,8 +165,8 @@
 
   td.RegisterVariableForTesting(&var);
 
-  auto lhs = create<ast::IdentifierExpression>("var");
-  auto rhs = create<ast::IdentifierExpression>("var");
+  auto* lhs = create<ast::IdentifierExpression>("var");
+  auto* rhs = create<ast::IdentifierExpression>("var");
 
   ast::BinaryExpression expr(ast::BinaryOp::kAdd, std::move(lhs),
                              std::move(rhs));
@@ -199,8 +199,8 @@
 
   td.RegisterVariableForTesting(&var);
 
-  auto lhs = create<ast::IdentifierExpression>("var");
-  auto rhs = create<ast::IdentifierExpression>("var");
+  auto* lhs = create<ast::IdentifierExpression>("var");
+  auto* rhs = create<ast::IdentifierExpression>("var");
 
   ast::BinaryExpression expr(ast::BinaryOp::kAdd, std::move(lhs),
                              std::move(rhs));
diff --git a/src/writer/spirv/builder_if_test.cc b/src/writer/spirv/builder_if_test.cc
index 0842d76..75f56f0 100644
--- a/src/writer/spirv/builder_if_test.cc
+++ b/src/writer/spirv/builder_if_test.cc
@@ -46,7 +46,7 @@
 
   // if (true) {
   // }
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
 
   ast::IfStatement expr(std::move(cond), create<ast::BlockStatement>());
@@ -75,24 +75,24 @@
   // if (true) {
   //   v = 2;
   // }
-  auto var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 2))));
 
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
 
   ast::IfStatement expr(std::move(cond), std::move(body));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
@@ -122,15 +122,15 @@
   // } else {
   //   v = 3;
   // }
-  auto var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 2))));
 
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
@@ -139,18 +139,18 @@
   ast::ElseStatementList else_stmts;
   else_stmts.push_back(create<ast::ElseStatement>(std::move(else_body)));
 
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
 
   ast::IfStatement expr(std::move(cond), std::move(body));
   expr.set_else_statements(std::move(else_stmts));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
@@ -184,39 +184,39 @@
   // } elseif (true) {
   //   v = 3;
   // }
-  auto var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 2))));
 
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 3))));
 
-  auto else_cond = create<ast::ScalarConstructorExpression>(
+  auto* else_cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
 
   ast::ElseStatementList else_stmts;
   else_stmts.push_back(
       create<ast::ElseStatement>(std::move(else_cond), std::move(else_body)));
 
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
 
   ast::IfStatement expr(std::move(cond), std::move(body));
   expr.set_else_statements(std::move(else_stmts));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
@@ -259,32 +259,32 @@
   // } else {
   //   v = 5;
   // }
-  auto var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 2))));
-  auto elseif_1_body = create<ast::BlockStatement>();
+  auto* elseif_1_body = create<ast::BlockStatement>();
   elseif_1_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 3))));
-  auto elseif_2_body = create<ast::BlockStatement>();
+  auto* elseif_2_body = create<ast::BlockStatement>();
   elseif_2_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 4))));
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 5))));
 
-  auto elseif_1_cond = create<ast::ScalarConstructorExpression>(
+  auto* elseif_1_cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
-  auto elseif_2_cond = create<ast::ScalarConstructorExpression>(
+  auto* elseif_2_cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, false));
 
   ast::ElseStatementList else_stmts;
@@ -294,18 +294,18 @@
                                                   std::move(elseif_2_body)));
   else_stmts.push_back(create<ast::ElseStatement>(std::move(else_body)));
 
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
 
   ast::IfStatement expr(std::move(cond), std::move(body));
   expr.set_else_statements(std::move(else_stmts));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
@@ -356,15 +356,15 @@
   //     break;
   //   }
   // }
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
 
-  auto if_body = create<ast::BlockStatement>();
+  auto* if_body = create<ast::BlockStatement>();
   if_body->append(create<ast::BreakStatement>());
 
-  auto if_stmt = create<ast::IfStatement>(std::move(cond), std::move(if_body));
+  auto* if_stmt = create<ast::IfStatement>(std::move(cond), std::move(if_body));
 
-  auto loop_body = create<ast::BlockStatement>();
+  auto* loop_body = create<ast::BlockStatement>();
   loop_body->append(std::move(if_stmt));
 
   ast::LoopStatement expr(std::move(loop_body), create<ast::BlockStatement>());
@@ -403,20 +403,20 @@
   //     break;
   //   }
   // }
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
 
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(create<ast::BreakStatement>());
 
   ast::ElseStatementList else_stmts;
   else_stmts.push_back(create<ast::ElseStatement>(std::move(else_body)));
 
-  auto if_stmt =
+  auto* if_stmt =
       create<ast::IfStatement>(std::move(cond), create<ast::BlockStatement>());
   if_stmt->set_else_statements(std::move(else_stmts));
 
-  auto loop_body = create<ast::BlockStatement>();
+  auto* loop_body = create<ast::BlockStatement>();
   loop_body->append(std::move(if_stmt));
 
   ast::LoopStatement expr(std::move(loop_body), create<ast::BlockStatement>());
@@ -456,15 +456,15 @@
   //     continue;
   //   }
   // }
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
 
-  auto if_body = create<ast::BlockStatement>();
+  auto* if_body = create<ast::BlockStatement>();
   if_body->append(create<ast::ContinueStatement>());
 
-  auto if_stmt = create<ast::IfStatement>(std::move(cond), std::move(if_body));
+  auto* if_stmt = create<ast::IfStatement>(std::move(cond), std::move(if_body));
 
-  auto loop_body = create<ast::BlockStatement>();
+  auto* loop_body = create<ast::BlockStatement>();
   loop_body->append(std::move(if_stmt));
 
   ast::LoopStatement expr(std::move(loop_body), create<ast::BlockStatement>());
@@ -503,20 +503,20 @@
   //     continue;
   //   }
   // }
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
 
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(create<ast::ContinueStatement>());
 
   ast::ElseStatementList else_stmts;
   else_stmts.push_back(create<ast::ElseStatement>(std::move(else_body)));
 
-  auto if_stmt =
+  auto* if_stmt =
       create<ast::IfStatement>(std::move(cond), create<ast::BlockStatement>());
   if_stmt->set_else_statements(std::move(else_stmts));
 
-  auto loop_body = create<ast::BlockStatement>();
+  auto* loop_body = create<ast::BlockStatement>();
   loop_body->append(std::move(if_stmt));
 
   ast::LoopStatement expr(std::move(loop_body), create<ast::BlockStatement>());
@@ -554,10 +554,10 @@
   // if (true) {
   //   return;
   // }
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
 
-  auto if_body = create<ast::BlockStatement>();
+  auto* if_body = create<ast::BlockStatement>();
   if_body->append(create<ast::ReturnStatement>());
 
   ast::IfStatement expr(std::move(cond), std::move(if_body));
@@ -584,12 +584,12 @@
   // if (true) {
   //   return false;
   // }
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, true));
-  auto cond2 = create<ast::ScalarConstructorExpression>(
+  auto* cond2 = create<ast::ScalarConstructorExpression>(
       create<ast::BoolLiteral>(&bool_type, false));
 
-  auto if_body = create<ast::BlockStatement>();
+  auto* if_body = create<ast::BlockStatement>();
   if_body->append(create<ast::ReturnStatement>(std::move(cond2)));
 
   ast::IfStatement expr(std::move(cond), std::move(if_body));
@@ -618,9 +618,9 @@
   // }
 
   ast::type::BoolType bool_type;
-  auto var =
+  auto* var =
       create<ast::Variable>("a", ast::StorageClass::kFunction, &bool_type);
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
 
   ast::IfStatement expr(create<ast::IdentifierExpression>("a"),
                         create<ast::BlockStatement>());
@@ -628,7 +628,7 @@
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeBool
diff --git a/src/writer/spirv/builder_intrinsic_test.cc b/src/writer/spirv/builder_intrinsic_test.cc
index 88b9b23..c8fff57 100644
--- a/src/writer/spirv/builder_intrinsic_test.cc
+++ b/src/writer/spirv/builder_intrinsic_test.cc
@@ -56,21 +56,14 @@
  public:
   IntrinsicBuilderTest() { set_context(&ctx); }
 
-  std::unique_ptr<ast::Variable> make_var(const std::string& name,
-                                          ast::StorageClass storage,
-                                          ast::type::Type* type) override {
-    auto var = ast::Builder::make_var(name, storage, type);
-    td.RegisterVariableForTesting(var.get());
+  ast::Variable* make_var(const std::string& name,
+                          ast::StorageClass storage,
+                          ast::type::Type* type) override {
+    auto* var = ast::Builder::make_var(name, storage, type);
+    td.RegisterVariableForTesting(var);
     return var;
   }
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
-  template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
-  }
-
   Context ctx;
   ast::Module mod;
   TypeDeterminer td{&ctx, &mod};
@@ -94,13 +87,13 @@
 TEST_P(IntrinsicBoolTest, Call_Bool) {
   auto param = GetParam();
 
-  auto var = make_var("v", ast::StorageClass::kPrivate, vec(bool_type(), 3));
+  auto* var = make_var("v", ast::StorageClass::kPrivate, vec(bool_type(), 3));
   auto expr = call_expr(param.name, "v");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 6u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeBool
@@ -123,13 +116,13 @@
 TEST_P(IntrinsicFloatTest, Call_Float_Scalar) {
   auto param = GetParam();
 
-  auto var = make_var("v", ast::StorageClass::kPrivate, f32());
+  auto* var = make_var("v", ast::StorageClass::kPrivate, f32());
   auto expr = call_expr(param.name, "v");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 5u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
@@ -147,13 +140,13 @@
 TEST_P(IntrinsicFloatTest, Call_Float_Vector) {
   auto param = GetParam();
 
-  auto var = make_var("v", ast::StorageClass::kPrivate, vec(f32(), 3));
+  auto* var = make_var("v", ast::StorageClass::kPrivate, vec(f32(), 3));
   auto expr = call_expr(param.name, "v");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 6u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
@@ -178,13 +171,13 @@
 TEST_P(IntrinsicIntTest, Call_SInt_Scalar) {
   auto param = GetParam();
 
-  auto var = make_var("v", ast::StorageClass::kPrivate, i32());
+  auto* var = make_var("v", ast::StorageClass::kPrivate, i32());
   auto expr = call_expr(param.name, "v");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 5u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
@@ -201,13 +194,13 @@
 TEST_P(IntrinsicIntTest, Call_SInt_Vector) {
   auto param = GetParam();
 
-  auto var = make_var("v", ast::StorageClass::kPrivate, vec(i32(), 3));
+  auto* var = make_var("v", ast::StorageClass::kPrivate, vec(i32(), 3));
   auto expr = call_expr(param.name, "v");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 6u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
@@ -225,13 +218,13 @@
 TEST_P(IntrinsicIntTest, Call_UInt_Scalar) {
   auto param = GetParam();
 
-  auto var = make_var("v", ast::StorageClass::kPrivate, u32());
+  auto* var = make_var("v", ast::StorageClass::kPrivate, u32());
   auto expr = call_expr(param.name, "v");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 5u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 0
@@ -248,13 +241,13 @@
 TEST_P(IntrinsicIntTest, Call_UInt_Vector) {
   auto param = GetParam();
 
-  auto var = make_var("v", ast::StorageClass::kPrivate, vec(u32(), 3));
+  auto* var = make_var("v", ast::StorageClass::kPrivate, vec(u32(), 3));
   auto expr = call_expr(param.name, "v");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 6u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
@@ -275,13 +268,13 @@
                     IntrinsicData{"reverseBits", "OpBitReverse"}));
 
 TEST_F(IntrinsicBuilderTest, Call_Dot) {
-  auto var = make_var("v", ast::StorageClass::kPrivate, vec(f32(), 3));
+  auto* var = make_var("v", ast::StorageClass::kPrivate, vec(f32(), 3));
   auto expr = call_expr("dot", "v", "v");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 6u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
@@ -301,13 +294,13 @@
 TEST_P(IntrinsicDeriveTest, Call_Derivative_Scalar) {
   auto param = GetParam();
 
-  auto var = make_var("v", ast::StorageClass::kPrivate, f32());
+  auto* var = make_var("v", ast::StorageClass::kPrivate, f32());
   auto expr = call_expr(param.name, "v");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 5u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
@@ -324,13 +317,13 @@
 TEST_P(IntrinsicDeriveTest, Call_Derivative_Vector) {
   auto param = GetParam();
 
-  auto var = make_var("v", ast::StorageClass::kPrivate, vec(f32(), 3));
+  auto* var = make_var("v", ast::StorageClass::kPrivate, vec(f32(), 3));
   auto expr = call_expr(param.name, "v");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 6u) << b.error();
 
@@ -365,16 +358,16 @@
                     IntrinsicData{"fwidthCoarse", "OpFwidthCoarse"}));
 
 TEST_F(IntrinsicBuilderTest, Call_OuterProduct) {
-  auto v2 = make_var("v2", ast::StorageClass::kPrivate, vec(f32(), 2));
-  auto v3 = make_var("v3", ast::StorageClass::kPrivate, vec(f32(), 3));
+  auto* v2 = make_var("v2", ast::StorageClass::kPrivate, vec(f32(), 2));
+  auto* v3 = make_var("v3", ast::StorageClass::kPrivate, vec(f32(), 3));
 
   auto expr = call_expr("outerProduct", "v2", "v3");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(v2.get())) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(v3.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(v2)) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(v3)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 10u) << b.error();
 
@@ -397,16 +390,16 @@
 }
 
 TEST_F(IntrinsicBuilderTest, Call_Select) {
-  auto v3 = make_var("v3", ast::StorageClass::kPrivate, vec(f32(), 3));
-  auto bool_v3 =
+  auto* v3 = make_var("v3", ast::StorageClass::kPrivate, vec(f32(), 3));
+  auto* bool_v3 =
       make_var("bool_v3", ast::StorageClass::kPrivate, vec(bool_type(), 3));
   auto expr = call_expr("select", "v3", "v3", "bool_v3");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(v3.get())) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(bool_v3.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(v3)) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(bool_v3)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 11u) << b.error();
 
@@ -438,8 +431,8 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
   auto expr = call_expr("textureLoad", "texture", 1.0f, 2);
 
@@ -472,8 +465,8 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
   auto expr = call_expr("textureLoad", "texture",
                         construct(vec(f32(), 2), 1.0f, 2.0f), 2);
@@ -506,8 +499,8 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
   auto expr = call_expr("textureLoad", "texture", 1.0f, 2);
 
@@ -536,8 +529,8 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
   auto expr = call_expr("textureLoad", "texture",
                         construct(vec(f32(), 2), 1.0f, 2.0f), 2);
@@ -570,8 +563,8 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
   auto expr = call_expr("textureLoad", "texture",
                         construct(vec(f32(), 2), 1.0f, 2.0f), 2);
@@ -605,11 +598,11 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &t);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &t);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
-  auto sampler = make_var("sampler", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(sampler.get())) << b.error();
+  auto* sampler = make_var("sampler", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
 
   auto expr = call_expr("textureSample", "texture", "sampler", 1.0f);
 
@@ -642,11 +635,11 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &t);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &t);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
-  auto sampler = make_var("sampler", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(sampler.get())) << b.error();
+  auto* sampler = make_var("sampler", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
 
   auto expr = call_expr("textureSample", "texture", "sampler",
                         construct(vec(f32(), 2), 1.0f, 2.0f));
@@ -683,11 +676,11 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &t);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &t);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
-  auto sampler = make_var("sampler", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(sampler.get())) << b.error();
+  auto* sampler = make_var("sampler", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
 
   auto expr = call_expr("textureSampleLevel", "texture", "sampler", 1.0f, 2.0f);
 
@@ -722,11 +715,11 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &t);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &t);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
-  auto sampler = make_var("sampler", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(sampler.get())) << b.error();
+  auto* sampler = make_var("sampler", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
 
   auto expr = call_expr("textureSampleLevel", "texture", "sampler",
                         construct(vec(f32(), 2), 1.0f, 2.0f), 2.0f);
@@ -764,11 +757,11 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &t);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &t);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
-  auto sampler = make_var("sampler", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(sampler.get())) << b.error();
+  auto* sampler = make_var("sampler", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
 
   auto expr = call_expr("textureSampleBias", "texture", "sampler", 1.0f, 2.0f);
 
@@ -803,11 +796,11 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &t);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &t);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
-  auto sampler = make_var("sampler", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(sampler.get())) << b.error();
+  auto* sampler = make_var("sampler", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
 
   auto expr = call_expr("textureSampleBias", "texture", "sampler",
                         construct(vec(f32(), 2), 1.0f, 2.0f), 2.0f);
@@ -845,11 +838,11 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &t);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &t);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
-  auto sampler = make_var("sampler", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(sampler.get())) << b.error();
+  auto* sampler = make_var("sampler", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
 
   auto expr = call_expr("textureSampleCompare", "texture", "sampler",
                         construct(vec(f32(), 2), 1.0f, 2.0f), 2.0f);
@@ -889,11 +882,11 @@
 
   b.push_function(Function{});
 
-  auto tex = make_var("texture", ast::StorageClass::kNone, &t);
-  ASSERT_TRUE(b.GenerateGlobalVariable(tex.get())) << b.error();
+  auto* tex = make_var("texture", ast::StorageClass::kNone, &t);
+  ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
 
-  auto sampler = make_var("sampler", ast::StorageClass::kNone, &s);
-  ASSERT_TRUE(b.GenerateGlobalVariable(sampler.get())) << b.error();
+  auto* sampler = make_var("sampler", ast::StorageClass::kNone, &s);
+  ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
 
   auto expr1 = call_expr("textureSampleCompare", "texture", "sampler",
                          construct(vec2, 1.0f, 2.0f), 2.0f);
@@ -935,14 +928,14 @@
 }
 
 TEST_F(IntrinsicBuilderTest, Call_GLSLMethod_WithLoad) {
-  auto var = make_var("ident", ast::StorageClass::kPrivate, f32());
+  auto* var = make_var("ident", ast::StorageClass::kPrivate, f32());
   auto expr = call_expr("round", "ident");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   ast::Function func("a_func", {}, void_type(), create<ast::BlockStatement>());
 
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
 
   EXPECT_EQ(b.GenerateCallExpression(&expr), 9u) << b.error();
@@ -1677,7 +1670,7 @@
                          testing::Values(IntrinsicData{"clamp", "UClamp"}));
 
 TEST_F(IntrinsicBuilderTest, Call_Determinant) {
-  auto var = make_var("var", ast::StorageClass::kPrivate, mat(f32(), 3, 3));
+  auto* var = make_var("var", ast::StorageClass::kPrivate, mat(f32(), 3, 3));
   auto expr = call_expr("determinant", "var");
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -1686,7 +1679,7 @@
 
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
 
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateCallExpression(&expr), 11u) << b.error();
 
   EXPECT_EQ(DumpBuilder(b), R"(%12 = OpExtInstImport "GLSL.std.450"
@@ -1715,10 +1708,10 @@
   ast::StructMemberList members;
   members.push_back(create<ast::StructMember>("a", &ary, std::move(decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
-  auto var = make_var("b", ast::StorageClass::kPrivate, &s_type);
+  auto* var = make_var("b", ast::StorageClass::kPrivate, &s_type);
 
   auto expr = call_expr("arrayLength", create<ast::MemberAccessorExpression>(
                                            make_expr("b"), make_expr("a")));
@@ -1728,7 +1721,7 @@
   ast::Function func("a_func", {}, void_type(), create<ast::BlockStatement>());
 
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(&expr), 11u) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -1756,10 +1749,10 @@
   members.push_back(create<ast::StructMember>("z", f32(), std::move(decos)));
   members.push_back(create<ast::StructMember>("a", &ary, std::move(decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
-  auto var = make_var("b", ast::StorageClass::kPrivate, &s_type);
+  auto* var = make_var("b", ast::StorageClass::kPrivate, &s_type);
   auto expr = call_expr("arrayLength", create<ast::MemberAccessorExpression>(
                                            make_expr("b"), make_expr("a")));
 
@@ -1768,7 +1761,7 @@
   ast::Function func("a_func", {}, void_type(), create<ast::BlockStatement>());
 
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(&expr), 11u) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.types()),
@@ -1798,12 +1791,12 @@
   members.push_back(create<ast::StructMember>("z", f32(), std::move(decos)));
   members.push_back(create<ast::StructMember>("a", &ary, std::move(decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
-  auto var = make_var("b", ast::StorageClass::kPrivate, &s_type);
+  auto* var = make_var("b", ast::StorageClass::kPrivate, &s_type);
 
-  auto ptr_var = make_var("ptr_var", ast::StorageClass::kPrivate, &ptr);
+  auto* ptr_var = make_var("ptr_var", ast::StorageClass::kPrivate, &ptr);
   ptr_var->set_constructor(
       create<ast::MemberAccessorExpression>(make_expr("b"), make_expr("a")));
 
@@ -1813,7 +1806,7 @@
   ast::Function func("a_func", {}, void_type(), create<ast::BlockStatement>());
 
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
   EXPECT_EQ(b.GenerateExpression(&expr), 11u) << b.error();
 
   EXPECT_EQ(DumpInstructions(b.types()), R"( ... )");
diff --git a/src/writer/spirv/builder_loop_test.cc b/src/writer/spirv/builder_loop_test.cc
index a9712a6..319163e 100644
--- a/src/writer/spirv/builder_loop_test.cc
+++ b/src/writer/spirv/builder_loop_test.cc
@@ -66,9 +66,9 @@
   // loop {
   //   v = 2;
   // }
-  auto var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
@@ -76,11 +76,11 @@
 
   ast::LoopStatement expr(std::move(body), create<ast::BlockStatement>());
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_TRUE(b.GenerateLoopStatement(&expr)) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
@@ -112,26 +112,26 @@
   //   }
   // }
 
-  auto var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto* var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 2))));
 
-  auto continuing = create<ast::BlockStatement>();
+  auto* continuing = create<ast::BlockStatement>();
   continuing->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 3))));
   ast::LoopStatement expr(std::move(body), std::move(continuing));
 
-  td.RegisterVariableForTesting(var.get());
+  td.RegisterVariableForTesting(var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   b.push_function(Function{});
-  ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
 
   EXPECT_TRUE(b.GenerateLoopStatement(&expr)) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
@@ -160,7 +160,7 @@
   // loop {
   //   continue;
   // }
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::ContinueStatement>());
 
   ast::LoopStatement expr(std::move(body), create<ast::BlockStatement>());
@@ -187,7 +187,7 @@
   // loop {
   //   break;
   // }
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::BreakStatement>());
 
   ast::LoopStatement expr(std::move(body), create<ast::BlockStatement>());
diff --git a/src/writer/spirv/builder_return_test.cc b/src/writer/spirv/builder_return_test.cc
index 856af32..5c0dbb3 100644
--- a/src/writer/spirv/builder_return_test.cc
+++ b/src/writer/spirv/builder_return_test.cc
@@ -58,7 +58,7 @@
   vals.push_back(create<ast::ScalarConstructorExpression>(
       create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto val = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto* val = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
   ast::ReturnStatement ret(std::move(val));
 
diff --git a/src/writer/spirv/builder_switch_test.cc b/src/writer/spirv/builder_switch_test.cc
index 639af98..1dfb466 100644
--- a/src/writer/spirv/builder_switch_test.cc
+++ b/src/writer/spirv/builder_switch_test.cc
@@ -45,7 +45,7 @@
 
   // switch (1) {
   // }
-  auto cond = create<ast::ScalarConstructorExpression>(
+  auto* cond = create<ast::ScalarConstructorExpression>(
       create<ast::SintLiteral>(&i32, 1));
 
   ast::SwitchStatement expr(std::move(cond), ast::CaseStatementList{});
@@ -77,16 +77,16 @@
   //     v = 2;
   // }
 
-  auto v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
-  auto a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
+  auto* v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto* a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
 
-  auto case_1_body = create<ast::BlockStatement>();
+  auto* case_1_body = create<ast::BlockStatement>();
   case_1_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 1))));
 
-  auto case_2_body = create<ast::BlockStatement>();
+  auto* case_2_body = create<ast::BlockStatement>();
   case_2_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
@@ -107,14 +107,14 @@
   ast::SwitchStatement expr(create<ast::IdentifierExpression>("a"),
                             std::move(cases));
 
-  td.RegisterVariableForTesting(v.get());
-  td.RegisterVariableForTesting(a.get());
+  td.RegisterVariableForTesting(v);
+  td.RegisterVariableForTesting(a);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   ast::Function func("a_func", {}, &i32, create<ast::BlockStatement>());
 
-  ASSERT_TRUE(b.GenerateGlobalVariable(v.get())) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(a.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
 
   EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error();
@@ -156,10 +156,10 @@
   //     v = 1;
   //  }
 
-  auto v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
-  auto a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
+  auto* v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto* a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
 
-  auto default_body = create<ast::BlockStatement>();
+  auto* default_body = create<ast::BlockStatement>();
   default_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
@@ -171,14 +171,14 @@
   ast::SwitchStatement expr(create<ast::IdentifierExpression>("a"),
                             std::move(cases));
 
-  td.RegisterVariableForTesting(v.get());
-  td.RegisterVariableForTesting(a.get());
+  td.RegisterVariableForTesting(v);
+  td.RegisterVariableForTesting(a);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   ast::Function func("a_func", {}, &i32, create<ast::BlockStatement>());
 
-  ASSERT_TRUE(b.GenerateGlobalVariable(v.get())) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(a.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
 
   EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error();
@@ -218,22 +218,22 @@
   //      v = 3;
   //  }
 
-  auto v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
-  auto a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
+  auto* v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto* a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
 
-  auto case_1_body = create<ast::BlockStatement>();
+  auto* case_1_body = create<ast::BlockStatement>();
   case_1_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 1))));
 
-  auto case_2_body = create<ast::BlockStatement>();
+  auto* case_2_body = create<ast::BlockStatement>();
   case_2_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 2))));
 
-  auto default_body = create<ast::BlockStatement>();
+  auto* default_body = create<ast::BlockStatement>();
   default_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
@@ -256,14 +256,14 @@
   ast::SwitchStatement expr(create<ast::IdentifierExpression>("a"),
                             std::move(cases));
 
-  td.RegisterVariableForTesting(v.get());
-  td.RegisterVariableForTesting(a.get());
+  td.RegisterVariableForTesting(v);
+  td.RegisterVariableForTesting(a);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   ast::Function func("a_func", {}, &i32, create<ast::BlockStatement>());
 
-  ASSERT_TRUE(b.GenerateGlobalVariable(v.get())) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(a.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
 
   EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error();
@@ -312,23 +312,23 @@
   //      v = 3;
   //  }
 
-  auto v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
-  auto a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
+  auto* v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto* a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
 
-  auto case_1_body = create<ast::BlockStatement>();
+  auto* case_1_body = create<ast::BlockStatement>();
   case_1_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 1))));
   case_1_body->append(create<ast::FallthroughStatement>());
 
-  auto case_2_body = create<ast::BlockStatement>();
+  auto* case_2_body = create<ast::BlockStatement>();
   case_2_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
                                            create<ast::SintLiteral>(&i32, 2))));
 
-  auto default_body = create<ast::BlockStatement>();
+  auto* default_body = create<ast::BlockStatement>();
   default_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
@@ -350,14 +350,14 @@
   ast::SwitchStatement expr(create<ast::IdentifierExpression>("a"),
                             std::move(cases));
 
-  td.RegisterVariableForTesting(v.get());
-  td.RegisterVariableForTesting(a.get());
+  td.RegisterVariableForTesting(v);
+  td.RegisterVariableForTesting(a);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   ast::Function func("a_func", {}, &i32, create<ast::BlockStatement>());
 
-  ASSERT_TRUE(b.GenerateGlobalVariable(v.get())) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(a.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
 
   EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error();
@@ -402,10 +402,10 @@
   //      fallthrough;
   //  }
 
-  auto v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
-  auto a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
+  auto* v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto* a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
 
-  auto case_1_body = create<ast::BlockStatement>();
+  auto* case_1_body = create<ast::BlockStatement>();
   case_1_body->append(
       create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
                                        create<ast::ScalarConstructorExpression>(
@@ -422,14 +422,14 @@
   ast::SwitchStatement expr(create<ast::IdentifierExpression>("a"),
                             std::move(cases));
 
-  td.RegisterVariableForTesting(v.get());
-  td.RegisterVariableForTesting(a.get());
+  td.RegisterVariableForTesting(v);
+  td.RegisterVariableForTesting(a);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   ast::Function func("a_func", {}, &i32, create<ast::BlockStatement>());
 
-  ASSERT_TRUE(b.GenerateGlobalVariable(v.get())) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(a.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
 
   EXPECT_FALSE(b.GenerateSwitchStatement(&expr)) << b.error();
@@ -448,13 +448,13 @@
   //     v = 1;
   //  }
 
-  auto v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
-  auto a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
+  auto* v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto* a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
 
-  auto if_body = create<ast::BlockStatement>();
+  auto* if_body = create<ast::BlockStatement>();
   if_body->append(create<ast::BreakStatement>());
 
-  auto case_1_body = create<ast::BlockStatement>();
+  auto* case_1_body = create<ast::BlockStatement>();
   case_1_body->append(
       create<ast::IfStatement>(create<ast::ScalarConstructorExpression>(
                                    create<ast::BoolLiteral>(&bool_type, true)),
@@ -475,14 +475,14 @@
   ast::SwitchStatement expr(create<ast::IdentifierExpression>("a"),
                             std::move(cases));
 
-  td.RegisterVariableForTesting(v.get());
-  td.RegisterVariableForTesting(a.get());
+  td.RegisterVariableForTesting(v);
+  td.RegisterVariableForTesting(a);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
   ast::Function func("a_func", {}, &i32, create<ast::BlockStatement>());
 
-  ASSERT_TRUE(b.GenerateGlobalVariable(v.get())) << b.error();
-  ASSERT_TRUE(b.GenerateGlobalVariable(a.get())) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
+  ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
 
   EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error();
diff --git a/src/writer/spirv/builder_type_test.cc b/src/writer/spirv/builder_type_test.cc
index 46aa30d..44ab429 100644
--- a/src/writer/spirv/builder_type_test.cc
+++ b/src/writer/spirv/builder_type_test.cc
@@ -279,7 +279,7 @@
 }
 
 TEST_F(BuilderTest_Type, GenerateStruct_Empty) {
-  auto s = create<ast::Struct>();
+  auto* s = create<ast::Struct>();
   ast::type::StructType s_type("S", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
@@ -300,7 +300,7 @@
   ast::StructMemberList members;
   members.push_back(create<ast::StructMember>("a", &f32, std::move(decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
@@ -325,7 +325,7 @@
   ast::StructDecorationList struct_decos;
   struct_decos.push_back(create<ast::StructBlockDecoration>(Source{}));
 
-  auto s = create<ast::Struct>(std::move(struct_decos), std::move(members));
+  auto* s = create<ast::Struct>(std::move(struct_decos), std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
@@ -354,7 +354,7 @@
   members.push_back(create<ast::StructMember>("a", &f32, std::move(a_decos)));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("S", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
@@ -391,7 +391,7 @@
   members.push_back(
       create<ast::StructMember>("c", &glsl_mat4x4, std::move(empty_c)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("S", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
@@ -437,7 +437,7 @@
   members.push_back(
       create<ast::StructMember>("c", &glsl_mat4x4, std::move(c_decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("S", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
@@ -501,7 +501,7 @@
   members.push_back(
       create<ast::StructMember>("c", &glsl_mat4x4, std::move(c_decos)));
 
-  auto s = create<ast::Struct>(std::move(members));
+  auto* s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("S", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
diff --git a/src/writer/spirv/test_helper.h b/src/writer/spirv/test_helper.h
index 03c8975..241a50f 100644
--- a/src/writer/spirv/test_helper.h
+++ b/src/writer/spirv/test_helper.h
@@ -35,11 +35,13 @@
   TestHelperBase() : td(&ctx, &mod), b(&ctx, &mod) {}
   ~TestHelperBase() = default;
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx.create<T>(std::forward<ARGS>(args)...);
   }
 
   /// The context
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index 9880ee0..d9df273 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -85,8 +85,8 @@
   if (!module.constructed_types().empty())
     out_ << std::endl;
 
-  for (const auto& var : module.global_variables()) {
-    if (!EmitVariable(var.get())) {
+  for (auto* var : module.global_variables()) {
+    if (!EmitVariable(var)) {
       return false;
     }
   }
@@ -94,8 +94,8 @@
     out_ << std::endl;
   }
 
-  for (const auto& func : module.functions()) {
-    if (!EmitFunction(func.get())) {
+  for (auto* func : module.functions()) {
+    if (!EmitFunction(func)) {
       return false;
     }
     out_ << std::endl;
@@ -126,11 +126,11 @@
 
   // TODO(dsinclair): This should be smarter and only emit needed const
   // variables
-  for (const auto& var : module.global_variables()) {
+  for (auto* var : module.global_variables()) {
     if (!var->is_const()) {
       continue;
     }
-    if (!EmitVariable(var.get())) {
+    if (!EmitVariable(var)) {
       return false;
     }
   }
@@ -146,12 +146,12 @@
     out_ << std::endl;
   }
 
-  for (const auto& f : module.functions()) {
+  for (auto* f : module.functions()) {
     if (!f->HasAncestorEntryPoint(name)) {
       continue;
     }
 
-    if (!EmitFunction(f.get())) {
+    if (!EmitFunction(f)) {
       return false;
     }
     out_ << std::endl;
@@ -263,13 +263,13 @@
 
   bool first = true;
   const auto& params = expr->params();
-  for (const auto& param : params) {
+  for (auto* param : params) {
     if (!first) {
       out_ << ", ";
     }
     first = false;
 
-    if (!EmitExpression(param.get())) {
+    if (!EmitExpression(param)) {
       return false;
     }
   }
@@ -294,13 +294,13 @@
   out_ << "(";
 
   bool first = true;
-  for (const auto& e : expr->values()) {
+  for (auto* e : expr->values()) {
     if (!first) {
       out_ << ", ";
     }
     first = false;
 
-    if (!EmitExpression(e.get())) {
+    if (!EmitExpression(e)) {
       return false;
     }
   }
@@ -346,7 +346,7 @@
 }
 
 bool GeneratorImpl::EmitFunction(ast::Function* func) {
-  for (auto& deco : func->decorations()) {
+  for (auto* deco : func->decorations()) {
     make_indent();
     out_ << "[[";
     if (deco->IsWorkgroup()) {
@@ -367,7 +367,7 @@
   out_ << "fn " << func->name() << "(";
 
   bool first = true;
-  for (const auto& v : func->params()) {
+  for (auto* v : func->params()) {
     if (!first) {
       out_ << ", ";
     }
@@ -424,7 +424,7 @@
   } else if (type->IsArray()) {
     auto* ary = type->AsArray();
 
-    for (const auto& deco : ary->decorations()) {
+    for (auto* deco : ary->decorations()) {
       if (deco->IsStride()) {
         out_ << "[[stride(" << deco->AsStride()->stride() << ")]] ";
       }
@@ -571,7 +571,7 @@
 
 bool GeneratorImpl::EmitStructType(const ast::type::StructType* str) {
   auto* impl = str->impl();
-  for (auto& deco : impl->decorations()) {
+  for (auto* deco : impl->decorations()) {
     out_ << "[[";
     deco->to_str(out_, 0);
     out_ << "]]" << std::endl;
@@ -579,8 +579,8 @@
   out_ << "struct " << str->name() << " {" << std::endl;
 
   increment_indent();
-  for (const auto& mem : impl->members()) {
-    for (const auto& deco : mem->decorations()) {
+  for (auto* mem : impl->members()) {
+    for (auto* deco : mem->decorations()) {
       make_indent();
 
       // TODO(dsinclair): Split this out when we have more then one
@@ -639,7 +639,7 @@
 bool GeneratorImpl::EmitVariableDecorations(ast::DecoratedVariable* var) {
   out_ << "[[";
   bool first = true;
-  for (const auto& deco : var->decorations()) {
+  for (auto* deco : var->decorations()) {
     if (!first) {
       out_ << ", ";
     }
@@ -766,8 +766,8 @@
   out_ << "{" << std::endl;
   increment_indent();
 
-  for (const auto& s : *stmt) {
-    if (!EmitStatement(s.get())) {
+  for (auto* s : *stmt) {
+    if (!EmitStatement(s)) {
       return false;
     }
   }
@@ -877,13 +877,13 @@
     out_ << "case ";
 
     bool first = true;
-    for (const auto& selector : stmt->selectors()) {
+    for (auto* selector : stmt->selectors()) {
       if (!first) {
         out_ << ", ";
       }
 
       first = false;
-      if (!EmitLiteral(selector.get())) {
+      if (!EmitLiteral(selector)) {
         return false;
       }
     }
@@ -932,8 +932,8 @@
     return false;
   }
 
-  for (const auto& e : stmt->else_statements()) {
-    if (!EmitElse(e.get())) {
+  for (auto* e : stmt->else_statements()) {
+    if (!EmitElse(e)) {
       return false;
     }
   }
@@ -954,8 +954,8 @@
   out_ << "loop {" << std::endl;
   increment_indent();
 
-  for (const auto& s : *(stmt->body())) {
-    if (!EmitStatement(s.get())) {
+  for (auto* s : *(stmt->body())) {
+    if (!EmitStatement(s)) {
       return false;
     }
   }
@@ -1003,8 +1003,8 @@
 
   increment_indent();
 
-  for (const auto& s : stmt->body()) {
-    if (!EmitCase(s.get())) {
+  for (auto* s : stmt->body()) {
+    if (!EmitCase(s)) {
       return false;
     }
   }
diff --git a/src/writer/wgsl/generator_impl_alias_type_test.cc b/src/writer/wgsl/generator_impl_alias_type_test.cc
index bf47d1f..73f0a72 100644
--- a/src/writer/wgsl/generator_impl_alias_type_test.cc
+++ b/src/writer/wgsl/generator_impl_alias_type_test.cc
@@ -51,7 +51,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &i32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("A", std::move(str));
@@ -80,7 +80,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &i32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("A", std::move(str));
diff --git a/src/writer/wgsl/generator_impl_array_accessor_test.cc b/src/writer/wgsl/generator_impl_array_accessor_test.cc
index 1096b04..3b8fa38 100644
--- a/src/writer/wgsl/generator_impl_array_accessor_test.cc
+++ b/src/writer/wgsl/generator_impl_array_accessor_test.cc
@@ -32,9 +32,9 @@
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_ArrayAccessor) {
   ast::type::I32Type i32;
-  auto lit = create<ast::SintLiteral>(&i32, 5);
-  auto idx = create<ast::ScalarConstructorExpression>(std::move(lit));
-  auto ary = create<ast::IdentifierExpression>("ary");
+  auto* lit = create<ast::SintLiteral>(&i32, 5);
+  auto* idx = create<ast::ScalarConstructorExpression>(std::move(lit));
+  auto* ary = create<ast::IdentifierExpression>("ary");
 
   ast::ArrayAccessorExpression expr(std::move(ary), std::move(idx));
 
@@ -43,8 +43,8 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitArrayAccessor) {
-  auto ary = create<ast::IdentifierExpression>("ary");
-  auto idx = create<ast::IdentifierExpression>("idx");
+  auto* ary = create<ast::IdentifierExpression>("ary");
+  auto* idx = create<ast::IdentifierExpression>("idx");
 
   ast::ArrayAccessorExpression expr(std::move(ary), std::move(idx));
 
diff --git a/src/writer/wgsl/generator_impl_assign_test.cc b/src/writer/wgsl/generator_impl_assign_test.cc
index 4204437..36e8650 100644
--- a/src/writer/wgsl/generator_impl_assign_test.cc
+++ b/src/writer/wgsl/generator_impl_assign_test.cc
@@ -29,8 +29,8 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Assign) {
-  auto lhs = create<ast::IdentifierExpression>("lhs");
-  auto rhs = create<ast::IdentifierExpression>("rhs");
+  auto* lhs = create<ast::IdentifierExpression>("lhs");
+  auto* rhs = create<ast::IdentifierExpression>("rhs");
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
 
   gen.increment_indent();
diff --git a/src/writer/wgsl/generator_impl_binary_test.cc b/src/writer/wgsl/generator_impl_binary_test.cc
index c1a35c7..d210f73 100644
--- a/src/writer/wgsl/generator_impl_binary_test.cc
+++ b/src/writer/wgsl/generator_impl_binary_test.cc
@@ -37,8 +37,8 @@
 TEST_P(WgslBinaryTest, Emit) {
   auto params = GetParam();
 
-  auto left = create<ast::IdentifierExpression>("left");
-  auto right = create<ast::IdentifierExpression>("right");
+  auto* left = create<ast::IdentifierExpression>("left");
+  auto* right = create<ast::IdentifierExpression>("right");
 
   ast::BinaryExpression expr(params.op, std::move(left), std::move(right));
 
diff --git a/src/writer/wgsl/generator_impl_bitcast_test.cc b/src/writer/wgsl/generator_impl_bitcast_test.cc
index 793bd20..c6452ae 100644
--- a/src/writer/wgsl/generator_impl_bitcast_test.cc
+++ b/src/writer/wgsl/generator_impl_bitcast_test.cc
@@ -30,7 +30,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_Bitcast) {
   ast::type::F32Type f32;
-  auto id = create<ast::IdentifierExpression>("id");
+  auto* id = create<ast::IdentifierExpression>("id");
   ast::BitcastExpression bitcast(&f32, std::move(id));
 
   ASSERT_TRUE(gen.EmitExpression(&bitcast)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_call_test.cc b/src/writer/wgsl/generator_impl_call_test.cc
index 3c3f221..aa0c7cb 100644
--- a/src/writer/wgsl/generator_impl_call_test.cc
+++ b/src/writer/wgsl/generator_impl_call_test.cc
@@ -29,7 +29,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_Call_WithoutParams) {
-  auto id = create<ast::IdentifierExpression>("my_func");
+  auto* id = create<ast::IdentifierExpression>("my_func");
   ast::CallExpression call(std::move(id), {});
 
   ASSERT_TRUE(gen.EmitExpression(&call)) << gen.error();
@@ -37,7 +37,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_Call_WithParams) {
-  auto id = create<ast::IdentifierExpression>("my_func");
+  auto* id = create<ast::IdentifierExpression>("my_func");
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("param1"));
   params.push_back(create<ast::IdentifierExpression>("param2"));
@@ -48,7 +48,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitStatement_Call) {
-  auto id = create<ast::IdentifierExpression>("my_func");
+  auto* id = create<ast::IdentifierExpression>("my_func");
   ast::ExpressionList params;
   params.push_back(create<ast::IdentifierExpression>("param1"));
   params.push_back(create<ast::IdentifierExpression>("param2"));
diff --git a/src/writer/wgsl/generator_impl_case_test.cc b/src/writer/wgsl/generator_impl_case_test.cc
index a6705e2..1246465 100644
--- a/src/writer/wgsl/generator_impl_case_test.cc
+++ b/src/writer/wgsl/generator_impl_case_test.cc
@@ -33,7 +33,7 @@
 TEST_F(WgslGeneratorImplTest, Emit_Case) {
   ast::type::I32Type i32;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::BreakStatement>());
 
   ast::CaseSelectorList lit;
@@ -52,7 +52,7 @@
 TEST_F(WgslGeneratorImplTest, Emit_Case_MultipleSelectors) {
   ast::type::I32Type i32;
 
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::BreakStatement>());
 
   ast::CaseSelectorList lit;
@@ -70,7 +70,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Case_Default) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::BreakStatement>());
   ast::CaseStatement c(std::move(body));
 
diff --git a/src/writer/wgsl/generator_impl_constructor_test.cc b/src/writer/wgsl/generator_impl_constructor_test.cc
index 7c3c474..70e78e3 100644
--- a/src/writer/wgsl/generator_impl_constructor_test.cc
+++ b/src/writer/wgsl/generator_impl_constructor_test.cc
@@ -37,7 +37,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Bool) {
   ast::type::BoolType bool_type;
-  auto lit = create<ast::BoolLiteral>(&bool_type, false);
+  auto* lit = create<ast::BoolLiteral>(&bool_type, false);
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(&expr)) << gen.error();
@@ -46,7 +46,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Int) {
   ast::type::I32Type i32;
-  auto lit = create<ast::SintLiteral>(&i32, -12345);
+  auto* lit = create<ast::SintLiteral>(&i32, -12345);
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(&expr)) << gen.error();
@@ -55,7 +55,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_UInt) {
   ast::type::U32Type u32;
-  auto lit = create<ast::UintLiteral>(&u32, 56779);
+  auto* lit = create<ast::UintLiteral>(&u32, 56779);
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(&expr)) << gen.error();
@@ -65,7 +65,8 @@
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Float) {
   ast::type::F32Type f32;
   // Use a number close to 1<<30 but whose decimal representation ends in 0.
-  auto lit = create<ast::FloatLiteral>(&f32, static_cast<float>((1 << 30) - 4));
+  auto* lit =
+      create<ast::FloatLiteral>(&f32, static_cast<float>((1 << 30) - 4));
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(&expr)) << gen.error();
@@ -75,7 +76,7 @@
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Float) {
   ast::type::F32Type f32;
 
-  auto lit = create<ast::FloatLiteral>(&f32, -1.2e-5);
+  auto* lit = create<ast::FloatLiteral>(&f32, -1.2e-5);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
@@ -88,7 +89,7 @@
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Bool) {
   ast::type::BoolType b;
 
-  auto lit = create<ast::BoolLiteral>(&b, true);
+  auto* lit = create<ast::BoolLiteral>(&b, true);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
@@ -101,7 +102,7 @@
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Int) {
   ast::type::I32Type i32;
 
-  auto lit = create<ast::SintLiteral>(&i32, -12345);
+  auto* lit = create<ast::SintLiteral>(&i32, -12345);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
@@ -114,7 +115,7 @@
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Uint) {
   ast::type::U32Type u32;
 
-  auto lit = create<ast::UintLiteral>(&u32, 12345);
+  auto* lit = create<ast::UintLiteral>(&u32, 12345);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
@@ -128,9 +129,9 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec(&f32, 3);
 
-  auto lit1 = create<ast::FloatLiteral>(&f32, 1.f);
-  auto lit2 = create<ast::FloatLiteral>(&f32, 2.f);
-  auto lit3 = create<ast::FloatLiteral>(&f32, 3.f);
+  auto* lit1 = create<ast::FloatLiteral>(&f32, 1.f);
+  auto* lit2 = create<ast::FloatLiteral>(&f32, 2.f);
+  auto* lit3 = create<ast::FloatLiteral>(&f32, 3.f);
   ast::ExpressionList values;
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit1)));
   values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit2)));
@@ -151,9 +152,9 @@
   ast::ExpressionList mat_values;
 
   for (size_t i = 0; i < 3; i++) {
-    auto lit1 =
+    auto* lit1 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(1 + (i * 2)));
-    auto lit2 =
+    auto* lit2 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(2 + (i * 2)));
 
     ast::ExpressionList values;
@@ -181,11 +182,11 @@
   ast::ExpressionList ary_values;
 
   for (size_t i = 0; i < 3; i++) {
-    auto lit1 =
+    auto* lit1 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(1 + (i * 3)));
-    auto lit2 =
+    auto* lit2 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(2 + (i * 3)));
-    auto lit3 =
+    auto* lit3 =
         create<ast::FloatLiteral>(&f32, static_cast<float>(3 + (i * 3)));
 
     ast::ExpressionList values;
diff --git a/src/writer/wgsl/generator_impl_function_test.cc b/src/writer/wgsl/generator_impl_function_test.cc
index c7f0b30..c05e2df 100644
--- a/src/writer/wgsl/generator_impl_function_test.cc
+++ b/src/writer/wgsl/generator_impl_function_test.cc
@@ -43,7 +43,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Function) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
   body->append(create<ast::ReturnStatement>());
 
@@ -61,7 +61,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Function_WithParams) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
   body->append(create<ast::ReturnStatement>());
 
@@ -85,7 +85,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Function_WithDecoration_WorkgroupSize) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
   body->append(create<ast::ReturnStatement>());
 
@@ -105,7 +105,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Function_WithDecoration_Stage) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
   body->append(create<ast::ReturnStatement>());
 
@@ -126,7 +126,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Function_WithDecoration_Multiple) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
   body->append(create<ast::ReturnStatement>());
 
@@ -177,12 +177,12 @@
   ast::StructDecorationList s_decos;
   s_decos.push_back(create<ast::StructBlockDecoration>(Source{}));
 
-  auto str = create<ast::Struct>(std::move(s_decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(s_decos), std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
   ast::type::AccessControlType ac(ast::AccessControl::kReadWrite, &s);
 
-  auto data_var = create<ast::DecoratedVariable>(
+  auto* data_var = create<ast::DecoratedVariable>(
       create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
@@ -192,22 +192,22 @@
 
   mod.AddConstructedType(&s);
 
-  td.RegisterVariableForTesting(data_var.get());
+  td.RegisterVariableForTesting(data_var);
   mod.AddGlobalVariable(std::move(data_var));
 
   {
     ast::VariableList params;
-    auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+    auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
     var->set_constructor(create<ast::MemberAccessorExpression>(
         create<ast::IdentifierExpression>("data"),
         create<ast::IdentifierExpression>("d")));
 
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
     body->append(create<ast::VariableDeclStatement>(std::move(var)));
     body->append(create<ast::ReturnStatement>());
 
-    auto func = create<ast::Function>("a", std::move(params), &void_type,
-                                      std::move(body));
+    auto* func = create<ast::Function>("a", std::move(params), &void_type,
+                                       std::move(body));
     func->add_decoration(
         create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
@@ -216,17 +216,17 @@
 
   {
     ast::VariableList params;
-    auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+    auto* var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
     var->set_constructor(create<ast::MemberAccessorExpression>(
         create<ast::IdentifierExpression>("data"),
         create<ast::IdentifierExpression>("d")));
 
-    auto body = create<ast::BlockStatement>();
+    auto* body = create<ast::BlockStatement>();
     body->append(create<ast::VariableDeclStatement>(std::move(var)));
     body->append(create<ast::ReturnStatement>());
 
-    auto func = create<ast::Function>("b", std::move(params), &void_type,
-                                      std::move(body));
+    auto* func = create<ast::Function>("b", std::move(params), &void_type,
+                                       std::move(body));
     func->add_decoration(
         create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
diff --git a/src/writer/wgsl/generator_impl_if_test.cc b/src/writer/wgsl/generator_impl_if_test.cc
index 465b711..3094210 100644
--- a/src/writer/wgsl/generator_impl_if_test.cc
+++ b/src/writer/wgsl/generator_impl_if_test.cc
@@ -28,8 +28,8 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_If) {
-  auto cond = create<ast::IdentifierExpression>("cond");
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>("cond");
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
@@ -44,16 +44,16 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithElseIf) {
-  auto else_cond = create<ast::IdentifierExpression>("else_cond");
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_cond = create<ast::IdentifierExpression>("else_cond");
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(create<ast::DiscardStatement>());
 
   ast::ElseStatementList elses;
   elses.push_back(
       create<ast::ElseStatement>(std::move(else_cond), std::move(else_body)));
 
-  auto cond = create<ast::IdentifierExpression>("cond");
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>("cond");
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
@@ -71,14 +71,14 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithElse) {
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(create<ast::DiscardStatement>());
 
   ast::ElseStatementList elses;
   elses.push_back(create<ast::ElseStatement>(std::move(else_body)));
 
-  auto cond = create<ast::IdentifierExpression>("cond");
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>("cond");
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
@@ -96,12 +96,12 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithMultiple) {
-  auto else_cond = create<ast::IdentifierExpression>("else_cond");
+  auto* else_cond = create<ast::IdentifierExpression>("else_cond");
 
-  auto else_body = create<ast::BlockStatement>();
+  auto* else_body = create<ast::BlockStatement>();
   else_body->append(create<ast::DiscardStatement>());
 
-  auto else_body_2 = create<ast::BlockStatement>();
+  auto* else_body_2 = create<ast::BlockStatement>();
   else_body_2->append(create<ast::DiscardStatement>());
 
   ast::ElseStatementList elses;
@@ -109,8 +109,8 @@
       create<ast::ElseStatement>(std::move(else_cond), std::move(else_body)));
   elses.push_back(create<ast::ElseStatement>(std::move(else_body_2)));
 
-  auto cond = create<ast::IdentifierExpression>("cond");
-  auto body = create<ast::BlockStatement>();
+  auto* cond = create<ast::IdentifierExpression>("cond");
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
diff --git a/src/writer/wgsl/generator_impl_loop_test.cc b/src/writer/wgsl/generator_impl_loop_test.cc
index f411ad6..2bcc614 100644
--- a/src/writer/wgsl/generator_impl_loop_test.cc
+++ b/src/writer/wgsl/generator_impl_loop_test.cc
@@ -28,7 +28,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Loop) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
   ast::LoopStatement l(std::move(body), {});
 
@@ -42,10 +42,10 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_LoopWithContinuing) {
-  auto body = create<ast::BlockStatement>();
+  auto* body = create<ast::BlockStatement>();
   body->append(create<ast::DiscardStatement>());
 
-  auto continuing = create<ast::BlockStatement>();
+  auto* continuing = create<ast::BlockStatement>();
   continuing->append(create<ast::DiscardStatement>());
 
   ast::LoopStatement l(std::move(body), std::move(continuing));
diff --git a/src/writer/wgsl/generator_impl_member_accessor_test.cc b/src/writer/wgsl/generator_impl_member_accessor_test.cc
index 501f551..c939a02 100644
--- a/src/writer/wgsl/generator_impl_member_accessor_test.cc
+++ b/src/writer/wgsl/generator_impl_member_accessor_test.cc
@@ -28,8 +28,8 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor) {
-  auto str = create<ast::IdentifierExpression>("str");
-  auto mem = create<ast::IdentifierExpression>("mem");
+  auto* str = create<ast::IdentifierExpression>("str");
+  auto* mem = create<ast::IdentifierExpression>("mem");
 
   ast::MemberAccessorExpression expr(std::move(str), std::move(mem));
 
diff --git a/src/writer/wgsl/generator_impl_return_test.cc b/src/writer/wgsl/generator_impl_return_test.cc
index fdf2f63..91f9e8b 100644
--- a/src/writer/wgsl/generator_impl_return_test.cc
+++ b/src/writer/wgsl/generator_impl_return_test.cc
@@ -38,7 +38,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_ReturnWithValue) {
-  auto expr = create<ast::IdentifierExpression>("expr");
+  auto* expr = create<ast::IdentifierExpression>("expr");
   ast::ReturnStatement r(std::move(expr));
 
   gen.increment_indent();
diff --git a/src/writer/wgsl/generator_impl_switch_test.cc b/src/writer/wgsl/generator_impl_switch_test.cc
index 2319a87..1072d67 100644
--- a/src/writer/wgsl/generator_impl_switch_test.cc
+++ b/src/writer/wgsl/generator_impl_switch_test.cc
@@ -32,25 +32,25 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Switch) {
-  auto def_body = create<ast::BlockStatement>();
+  auto* def_body = create<ast::BlockStatement>();
   def_body->append(create<ast::BreakStatement>());
-  auto def = create<ast::CaseStatement>(std::move(def_body));
+  auto* def = create<ast::CaseStatement>(std::move(def_body));
 
   ast::type::I32Type i32;
   ast::CaseSelectorList case_val;
   case_val.push_back(create<ast::SintLiteral>(&i32, 5));
 
-  auto case_body = create<ast::BlockStatement>();
+  auto* case_body = create<ast::BlockStatement>();
   case_body->append(create<ast::BreakStatement>());
 
-  auto case_stmt =
+  auto* case_stmt =
       create<ast::CaseStatement>(std::move(case_val), std::move(case_body));
 
   ast::CaseStatementList body;
   body.push_back(std::move(case_stmt));
   body.push_back(std::move(def));
 
-  auto cond = create<ast::IdentifierExpression>("cond");
+  auto* cond = create<ast::IdentifierExpression>("cond");
   ast::SwitchStatement s(std::move(cond), std::move(body));
 
   gen.increment_indent();
diff --git a/src/writer/wgsl/generator_impl_type_test.cc b/src/writer/wgsl/generator_impl_type_test.cc
index 5d0864b..48fbf4f 100644
--- a/src/writer/wgsl/generator_impl_type_test.cc
+++ b/src/writer/wgsl/generator_impl_type_test.cc
@@ -143,7 +143,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -164,7 +164,7 @@
   b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = create<ast::Struct>();
+  auto* str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -193,7 +193,7 @@
   ast::StructDecorationList decos;
   decos.push_back(create<ast::StructBlockDecoration>(Source{}));
 
-  auto str = create<ast::Struct>(std::move(decos), std::move(members));
+  auto* str = create<ast::Struct>(std::move(decos), std::move(members));
 
   ast::type::StructType s("S", std::move(str));
 
diff --git a/src/writer/wgsl/generator_impl_unary_op_test.cc b/src/writer/wgsl/generator_impl_unary_op_test.cc
index 7c9ec68..bebe74b 100644
--- a/src/writer/wgsl/generator_impl_unary_op_test.cc
+++ b/src/writer/wgsl/generator_impl_unary_op_test.cc
@@ -38,7 +38,7 @@
 TEST_P(WgslUnaryOpTest, Emit) {
   auto params = GetParam();
 
-  auto expr = create<ast::IdentifierExpression>("expr");
+  auto* expr = create<ast::IdentifierExpression>("expr");
   ast::UnaryOpExpression op(params.op, std::move(expr));
 
   ASSERT_TRUE(gen.EmitExpression(&op)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc b/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc
index 93a3ec6..1db4355 100644
--- a/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc
@@ -32,7 +32,7 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement) {
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
 
   ast::VariableDeclStatement stmt(std::move(var));
 
@@ -47,7 +47,7 @@
   // storage class.  Rely on defaulting.
   // https://github.com/gpuweb/gpuweb/issues/654
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kFunction, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kFunction, &f32);
 
   ast::VariableDeclStatement stmt(std::move(var));
 
@@ -59,7 +59,7 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
   ast::type::F32Type f32;
-  auto var = create<ast::Variable>("a", ast::StorageClass::kPrivate, &f32);
+  auto* var = create<ast::Variable>("a", ast::StorageClass::kPrivate, &f32);
 
   ast::VariableDeclStatement stmt(std::move(var));
 
diff --git a/src/writer/wgsl/generator_impl_variable_test.cc b/src/writer/wgsl/generator_impl_variable_test.cc
index 1c980b9..529bf05 100644
--- a/src/writer/wgsl/generator_impl_variable_test.cc
+++ b/src/writer/wgsl/generator_impl_variable_test.cc
@@ -91,7 +91,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitVariable_Constructor) {
-  auto ident = create<ast::IdentifierExpression>("initializer");
+  auto* ident = create<ast::IdentifierExpression>("initializer");
 
   ast::type::F32Type f32;
   ast::Variable v("a", ast::StorageClass::kNone, &f32);
@@ -103,7 +103,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitVariable_Const) {
-  auto ident = create<ast::IdentifierExpression>("initializer");
+  auto* ident = create<ast::IdentifierExpression>("initializer");
 
   ast::type::F32Type f32;
   ast::Variable v("a", ast::StorageClass::kNone, &f32);
diff --git a/src/writer/wgsl/test_helper.h b/src/writer/wgsl/test_helper.h
index 7c3bd9e..76e434f 100644
--- a/src/writer/wgsl/test_helper.h
+++ b/src/writer/wgsl/test_helper.h
@@ -36,11 +36,13 @@
 
   ~TestHelperBase() = default;
 
-  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
-  /// @param args the arguments to forward to the constructor for `T`
+  /// Creates a new `ast::Node` owned by the Context. When the Context is
+  /// destructed, the `ast::Node` will also be destructed.
+  /// @param args the arguments to pass to the type constructor
+  /// @returns the node pointer
   template <typename T, typename... ARGS>
-  std::unique_ptr<T> create(ARGS&&... args) {
-    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  T* create(ARGS&&... args) {
+    return ctx.create<T>(std::forward<ARGS>(args)...);
   }
 
   /// The context