Remove suppressing [chromium-style] errors

Lots of little style nits needed to be fixed for this work.

BUG=tint:44

Change-Id: Ibb45d9e3f6795ee0c09f5eca994bb28e20979d97
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/19221
Reviewed-by: dan sinclair <dsinclair@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 3bb1cee..b3848d8 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -34,8 +34,8 @@
     "src/ast/binary_expression.h",
     "src/ast/binding_decoration.cc",
     "src/ast/binding_decoration.h",
-    "src/ast/bool_literal.h",
     "src/ast/bool_literal.cc",
+    "src/ast/bool_literal.h",
     "src/ast/break_statement.cc",
     "src/ast/break_statement.h",
     "src/ast/builtin.cc",
@@ -78,8 +78,8 @@
     "src/ast/int_literal.h",
     "src/ast/kill_statement.cc",
     "src/ast/kill_statement.h",
-    "src/ast/literal.h",
     "src/ast/literal.cc",
+    "src/ast/literal.h",
     "src/ast/location_decoration.cc",
     "src/ast/location_decoration.h",
     "src/ast/loop_statement.cc",
@@ -108,10 +108,10 @@
     "src/ast/statement_condition.h",
     "src/ast/storage_class.cc",
     "src/ast/storage_class.h",
-    "src/ast/struct_decoration.cc",
-    "src/ast/struct_decoration.h",
     "src/ast/struct.cc",
     "src/ast/struct.h",
+    "src/ast/struct_decoration.cc",
+    "src/ast/struct_decoration.h",
     "src/ast/struct_member.cc",
     "src/ast/struct_member.h",
     "src/ast/struct_member_decoration.cc",
@@ -120,8 +120,6 @@
     "src/ast/struct_member_offset_decoration.h",
     "src/ast/switch_statement.cc",
     "src/ast/switch_statement.h",
-    "src/ast/type_constructor_expression.h",
-    "src/ast/type_constructor_expression.cc",
     "src/ast/type/alias_type.cc",
     "src/ast/type/alias_type.h",
     "src/ast/type/array_type.cc",
@@ -146,6 +144,8 @@
     "src/ast/type/vector_type.h",
     "src/ast/type/void_type.cc",
     "src/ast/type/void_type.h",
+    "src/ast/type_constructor_expression.cc",
+    "src/ast/type_constructor_expression.h",
     "src/ast/uint_literal.cc",
     "src/ast/uint_literal.h",
     "src/ast/unary_derivative.cc",
@@ -164,12 +164,12 @@
     "src/ast/unless_statement.h",
     "src/ast/variable.cc",
     "src/ast/variable.h",
-    "src/ast/variable_decoration.cc",
-    "src/ast/variable_decoration.h",
     "src/ast/variable_decl_statement.cc",
     "src/ast/variable_decl_statement.h",
-    "src/context.h",
+    "src/ast/variable_decoration.cc",
+    "src/ast/variable_decoration.h",
     "src/context.cc",
+    "src/context.h",
     "src/reader/reader.cc",
     "src/reader/reader.h",
     "src/scope_stack.h",
@@ -186,34 +186,26 @@
     "src/writer/writer.h",
   ]
 
+  configs += [ ":tint_common_config" ]
+
   if (build_with_chromium) {
     configs -= [ "//build/config/compiler:chromium_code" ]
     configs += [ "//build/config/compiler:no_chromium_code" ]
   }
-
-  # Suppress warnings from the Chromium Clang plugin
-  configs -= [ "//build/config/clang:find_bad_constructs" ]
 }
 
 executable("tint") {
-  sources = [
-    "samples/main.cc",
-  ]
-  deps = [
-    ":libtint",
-  ]
+  sources = [ "samples/main.cc" ]
+  deps = [ ":libtint" ]
+
+  configs += [ ":tint_common_config" ]
 
   if (build_with_chromium) {
     configs -= [ "//build/config/compiler:chromium_code" ]
     configs += [ "//build/config/compiler:no_chromium_code" ]
   }
-
-  # Suppress warnings from the Chromium Clang plugin
-  configs -= [ "//build/config/clang:find_bad_constructs" ]
 }
 
 group("tint_all") {
-  deps = [
-      ":tint",
-    ]
+  deps = [ ":tint" ]
 }
diff --git a/src/ast/array_accessor_expression.cc b/src/ast/array_accessor_expression.cc
index 87e0ea2..4fcb5e0 100644
--- a/src/ast/array_accessor_expression.cc
+++ b/src/ast/array_accessor_expression.cc
@@ -32,8 +32,15 @@
       array_(std::move(array)),
       idx_expr_(std::move(idx_expr)) {}
 
+ArrayAccessorExpression::ArrayAccessorExpression(ArrayAccessorExpression&&) =
+    default;
+
 ArrayAccessorExpression::~ArrayAccessorExpression() = default;
 
+bool ArrayAccessorExpression::IsArrayAccessor() const {
+  return true;
+}
+
 bool ArrayAccessorExpression::IsValid() const {
   if (array_ == nullptr || !array_->IsValid())
     return false;
diff --git a/src/ast/array_accessor_expression.h b/src/ast/array_accessor_expression.h
index 73a866e..5f90fb6 100644
--- a/src/ast/array_accessor_expression.h
+++ b/src/ast/array_accessor_expression.h
@@ -42,7 +42,7 @@
                           std::unique_ptr<Expression> array,
                           std::unique_ptr<Expression> idx_expr);
   /// Move constructor
-  ArrayAccessorExpression(ArrayAccessorExpression&&) = default;
+  ArrayAccessorExpression(ArrayAccessorExpression&&);
   ~ArrayAccessorExpression() override;
 
   /// Sets the array
@@ -62,7 +62,7 @@
   Expression* idx_expr() const { return idx_expr_.get(); }
 
   /// @returns true if this is an array accessor expression
-  bool IsArrayAccessor() const override { return true; }
+  bool IsArrayAccessor() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/as_expression.cc b/src/ast/as_expression.cc
index a7b34e4..65705cc 100644
--- a/src/ast/as_expression.cc
+++ b/src/ast/as_expression.cc
@@ -27,8 +27,13 @@
                            std::unique_ptr<Expression> expr)
     : Expression(source), type_(type), expr_(std::move(expr)) {}
 
+AsExpression::AsExpression(AsExpression&&) = default;
 AsExpression::~AsExpression() = default;
 
+bool AsExpression::IsAs() const {
+  return true;
+}
+
 bool AsExpression::IsValid() const {
   if (expr_ == nullptr || !expr_->IsValid())
     return false;
diff --git a/src/ast/as_expression.h b/src/ast/as_expression.h
index 16b4f91..e8feeb6 100644
--- a/src/ast/as_expression.h
+++ b/src/ast/as_expression.h
@@ -42,7 +42,7 @@
                type::Type* type,
                std::unique_ptr<Expression> expr);
   /// Move constructor
-  AsExpression(AsExpression&&) = default;
+  AsExpression(AsExpression&&);
   ~AsExpression() override;
 
   /// Sets the type
@@ -58,7 +58,7 @@
   Expression* expr() const { return expr_.get(); }
 
   /// @returns true if this is an as expression
-  bool IsAs() const override { return true; }
+  bool IsAs() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/assignment_statement.cc b/src/ast/assignment_statement.cc
index 47b5543..d9bc04f 100644
--- a/src/ast/assignment_statement.cc
+++ b/src/ast/assignment_statement.cc
@@ -28,8 +28,14 @@
                                          std::unique_ptr<Expression> rhs)
     : Statement(source), lhs_(std::move(lhs)), rhs_(std::move(rhs)) {}
 
+AssignmentStatement::AssignmentStatement(AssignmentStatement&&) = default;
+
 AssignmentStatement::~AssignmentStatement() = default;
 
+bool AssignmentStatement::IsAssign() const {
+  return true;
+}
+
 bool AssignmentStatement::IsValid() const {
   if (lhs_ == nullptr || !lhs_->IsValid())
     return false;
diff --git a/src/ast/assignment_statement.h b/src/ast/assignment_statement.h
index c49472c..cf105cd 100644
--- a/src/ast/assignment_statement.h
+++ b/src/ast/assignment_statement.h
@@ -43,7 +43,7 @@
                       std::unique_ptr<Expression> lhs,
                       std::unique_ptr<Expression> rhs);
   /// Move constructor
-  AssignmentStatement(AssignmentStatement&&) = default;
+  AssignmentStatement(AssignmentStatement&&);
   ~AssignmentStatement() override;
 
   /// Sets the left side of the statement
@@ -59,7 +59,7 @@
   Expression* rhs() const { return rhs_.get(); }
 
   /// @returns true if this is an assignment statement
-  bool IsAssign() const override { return true; }
+  bool IsAssign() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/binary_expression.cc b/src/ast/binary_expression.cc
index 115b41f..47d600d 100644
--- a/src/ast/binary_expression.cc
+++ b/src/ast/binary_expression.cc
@@ -30,8 +30,14 @@
                                    std::unique_ptr<Expression> rhs)
     : Expression(source), op_(op), lhs_(std::move(lhs)), rhs_(std::move(rhs)) {}
 
+BinaryExpression::BinaryExpression(BinaryExpression&&) = default;
+
 BinaryExpression::~BinaryExpression() = default;
 
+bool BinaryExpression::IsBinary() const {
+  return true;
+}
+
 bool BinaryExpression::IsValid() const {
   if (lhs_ == nullptr || !lhs_->IsValid()) {
     return false;
diff --git a/src/ast/binary_expression.h b/src/ast/binary_expression.h
index 0af2b6e..00fdf66 100644
--- a/src/ast/binary_expression.h
+++ b/src/ast/binary_expression.h
@@ -70,7 +70,7 @@
                    std::unique_ptr<Expression> lhs,
                    std::unique_ptr<Expression> rhs);
   /// Move constructor
-  BinaryExpression(BinaryExpression&&) = default;
+  BinaryExpression(BinaryExpression&&);
   ~BinaryExpression() override;
 
   /// Sets the binary op type
@@ -131,7 +131,7 @@
   Expression* rhs() const { return rhs_.get(); }
 
   /// @returns true if this is a op expression
-  bool IsBinary() const override { return true; }
+  bool IsBinary() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/binding_decoration.cc b/src/ast/binding_decoration.cc
index a2fbc0c..bcfdf1b 100644
--- a/src/ast/binding_decoration.cc
+++ b/src/ast/binding_decoration.cc
@@ -21,6 +21,10 @@
 
 BindingDecoration::~BindingDecoration() = default;
 
+bool BindingDecoration::IsBinding() const {
+  return true;
+}
+
 void BindingDecoration::to_str(std::ostream& out) const {
   out << "BindingDecoration{" << value_ << "}" << std::endl;
 }
diff --git a/src/ast/binding_decoration.h b/src/ast/binding_decoration.h
index b9484a5..a554aac 100644
--- a/src/ast/binding_decoration.h
+++ b/src/ast/binding_decoration.h
@@ -31,7 +31,7 @@
   ~BindingDecoration() override;
 
   /// @returns true if this is a binding decoration
-  bool IsBinding() const override { return true; }
+  bool IsBinding() const override;
 
   /// @returns the binding value
   uint32_t value() const { return value_; }
diff --git a/src/ast/bool_literal.cc b/src/ast/bool_literal.cc
index 2ab78b9..7e11015 100644
--- a/src/ast/bool_literal.cc
+++ b/src/ast/bool_literal.cc
@@ -22,6 +22,10 @@
 
 BoolLiteral::~BoolLiteral() = default;
 
+bool BoolLiteral::IsBool() const {
+  return true;
+}
+
 std::string BoolLiteral::to_str() const {
   return value_ ? "true" : "false";
 }
diff --git a/src/ast/bool_literal.h b/src/ast/bool_literal.h
index d1749b1..fbb1868 100644
--- a/src/ast/bool_literal.h
+++ b/src/ast/bool_literal.h
@@ -32,7 +32,7 @@
   ~BoolLiteral() override;
 
   /// @returns true if this is a bool literal
-  bool IsBool() const override { return true; }
+  bool IsBool() const override;
 
   /// @returns true if the bool literal is true
   bool IsTrue() const { return value_; }
diff --git a/src/ast/break_statement.cc b/src/ast/break_statement.cc
index c3bcbe6..a1dda43 100644
--- a/src/ast/break_statement.cc
+++ b/src/ast/break_statement.cc
@@ -34,8 +34,14 @@
       condition_(condition),
       conditional_(std::move(conditional)) {}
 
+BreakStatement::BreakStatement(BreakStatement&&) = default;
+
 BreakStatement::~BreakStatement() = default;
 
+bool BreakStatement::IsBreak() const {
+  return true;
+}
+
 bool BreakStatement::IsValid() const {
   if (condition_ == StatementCondition::kNone)
     return conditional_ == nullptr;
diff --git a/src/ast/break_statement.h b/src/ast/break_statement.h
index 298933c..4a720de 100644
--- a/src/ast/break_statement.h
+++ b/src/ast/break_statement.h
@@ -46,7 +46,7 @@
                  StatementCondition condition,
                  std::unique_ptr<Expression> conditional);
   /// Move constructor
-  BreakStatement(BreakStatement&&) = default;
+  BreakStatement(BreakStatement&&);
   ~BreakStatement() override;
 
   /// Sets the condition type
@@ -64,7 +64,7 @@
   Expression* conditional() const { return conditional_.get(); }
 
   /// @returns true if this is an break statement
-  bool IsBreak() const override { return true; }
+  bool IsBreak() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/builtin_decoration.cc b/src/ast/builtin_decoration.cc
index 89d116e..50cea89 100644
--- a/src/ast/builtin_decoration.cc
+++ b/src/ast/builtin_decoration.cc
@@ -21,6 +21,10 @@
 
 BuiltinDecoration::~BuiltinDecoration() = default;
 
+bool BuiltinDecoration::IsBuiltin() const {
+  return true;
+}
+
 void BuiltinDecoration::to_str(std::ostream& out) const {
   out << "BuiltinDecoration{" << builtin_ << "}" << std::endl;
 }
diff --git a/src/ast/builtin_decoration.h b/src/ast/builtin_decoration.h
index 5027e12..072f196 100644
--- a/src/ast/builtin_decoration.h
+++ b/src/ast/builtin_decoration.h
@@ -30,7 +30,7 @@
   ~BuiltinDecoration() override;
 
   /// @returns true if this is a builtin decoration
-  bool IsBuiltin() const override { return true; }
+  bool IsBuiltin() const override;
 
   /// @returns the builtin value
   Builtin value() const { return builtin_; }
diff --git a/src/ast/call_expression.cc b/src/ast/call_expression.cc
index 5cc9e73..f7d71c7 100644
--- a/src/ast/call_expression.cc
+++ b/src/ast/call_expression.cc
@@ -28,8 +28,14 @@
                                ExpressionList params)
     : Expression(source), func_(std::move(func)), params_(std::move(params)) {}
 
+CallExpression::CallExpression(CallExpression&&) = default;
+
 CallExpression::~CallExpression() = default;
 
+bool CallExpression::IsCall() const {
+  return true;
+}
+
 bool CallExpression::IsValid() const {
   if (func_ == nullptr || !func_->IsValid())
     return false;
diff --git a/src/ast/call_expression.h b/src/ast/call_expression.h
index 597cf43..4edeb84 100644
--- a/src/ast/call_expression.h
+++ b/src/ast/call_expression.h
@@ -41,7 +41,7 @@
                  std::unique_ptr<Expression> func,
                  ExpressionList params);
   /// Move constructor
-  CallExpression(CallExpression&&) = default;
+  CallExpression(CallExpression&&);
   ~CallExpression() override;
 
   /// Sets the func
@@ -57,7 +57,7 @@
   const ExpressionList& params() const { return params_; }
 
   /// @returns true if this is a call expression
-  bool IsCall() const override { return true; }
+  bool IsCall() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/case_statement.cc b/src/ast/case_statement.cc
index 51412a1..8aca58c 100644
--- a/src/ast/case_statement.cc
+++ b/src/ast/case_statement.cc
@@ -30,8 +30,14 @@
       condition_(std::move(condition)),
       body_(std::move(body)) {}
 
+CaseStatement::CaseStatement(CaseStatement&&) = default;
+
 CaseStatement::~CaseStatement() = default;
 
+bool CaseStatement::IsCase() const {
+  return true;
+}
+
 bool CaseStatement::IsValid() const {
   for (const auto& stmt : body_) {
     if (stmt == nullptr || !stmt->IsValid())
diff --git a/src/ast/case_statement.h b/src/ast/case_statement.h
index b8db599..5d2c24e 100644
--- a/src/ast/case_statement.h
+++ b/src/ast/case_statement.h
@@ -44,7 +44,7 @@
                 std::unique_ptr<Literal> condition,
                 StatementList body);
   /// Move constructor
-  CaseStatement(CaseStatement&&) = default;
+  CaseStatement(CaseStatement&&);
   ~CaseStatement() override;
 
   /// Sets the condition for the case statement
@@ -64,7 +64,7 @@
   const StatementList& body() const { return body_; }
 
   /// @returns true if this is a case statement
-  bool IsCase() const override { return true; }
+  bool IsCase() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/cast_expression.cc b/src/ast/cast_expression.cc
index a0d836f..327c37d 100644
--- a/src/ast/cast_expression.cc
+++ b/src/ast/cast_expression.cc
@@ -28,8 +28,14 @@
                                std::unique_ptr<Expression> expr)
     : Expression(source), type_(type), expr_(std::move(expr)) {}
 
+CastExpression::CastExpression(CastExpression&&) = default;
+
 CastExpression::~CastExpression() = default;
 
+bool CastExpression::IsCast() const {
+  return true;
+}
+
 bool CastExpression::IsValid() const {
   if (expr_ == nullptr || !expr_->IsValid())
     return false;
diff --git a/src/ast/cast_expression.h b/src/ast/cast_expression.h
index 69bfbf5..b1db7fe 100644
--- a/src/ast/cast_expression.h
+++ b/src/ast/cast_expression.h
@@ -42,7 +42,7 @@
                  type::Type* type,
                  std::unique_ptr<Expression> expr);
   /// Move constructor
-  CastExpression(CastExpression&&) = default;
+  CastExpression(CastExpression&&);
   ~CastExpression() override;
 
   /// Sets the type
@@ -58,7 +58,7 @@
   Expression* expr() const { return expr_.get(); }
 
   /// @returns true if this is a cast expression
-  bool IsCast() const override { return true; }
+  bool IsCast() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/constructor_expression.cc b/src/ast/constructor_expression.cc
index 9ff88b4..5202bdf 100644
--- a/src/ast/constructor_expression.cc
+++ b/src/ast/constructor_expression.cc
@@ -29,6 +29,18 @@
 ConstructorExpression::ConstructorExpression(const Source& source)
     : Expression(source) {}
 
+bool ConstructorExpression::IsConstructor() const {
+  return true;
+}
+
+bool ConstructorExpression::IsScalarConstructor() const {
+  return false;
+}
+
+bool ConstructorExpression::IsTypeConstructor() const {
+  return false;
+}
+
 ScalarConstructorExpression* ConstructorExpression::AsScalarConstructor() {
   assert(IsScalarConstructor());
   return static_cast<ScalarConstructorExpression*>(this);
diff --git a/src/ast/constructor_expression.h b/src/ast/constructor_expression.h
index 6846768..5aaa5c3 100644
--- a/src/ast/constructor_expression.h
+++ b/src/ast/constructor_expression.h
@@ -29,12 +29,12 @@
   ~ConstructorExpression() override;
 
   /// @returns true if this is an constructor expression
-  bool IsConstructor() const override { return true; }
+  bool IsConstructor() const override;
 
   /// @returns true if this is a scalar constructor
-  virtual bool IsScalarConstructor() const { return false; }
+  virtual bool IsScalarConstructor() const;
   /// @returns true if this is a type constructor
-  virtual bool IsTypeConstructor() const { return false; }
+  virtual bool IsTypeConstructor() const;
 
   /// @returns this as a scalar constructor expression
   ScalarConstructorExpression* AsScalarConstructor();
diff --git a/src/ast/continue_statement.cc b/src/ast/continue_statement.cc
index 0485020..6ef2f81 100644
--- a/src/ast/continue_statement.cc
+++ b/src/ast/continue_statement.cc
@@ -35,8 +35,14 @@
       condition_(condition),
       conditional_(std::move(conditional)) {}
 
+ContinueStatement::ContinueStatement(ContinueStatement&&) = default;
+
 ContinueStatement::~ContinueStatement() = default;
 
+bool ContinueStatement::IsContinue() const {
+  return true;
+}
+
 bool ContinueStatement::IsValid() const {
   if (condition_ == StatementCondition::kNone)
     return conditional_ == nullptr;
diff --git a/src/ast/continue_statement.h b/src/ast/continue_statement.h
index 69aaaa6..f06df2f 100644
--- a/src/ast/continue_statement.h
+++ b/src/ast/continue_statement.h
@@ -46,7 +46,7 @@
                     StatementCondition condition,
                     std::unique_ptr<Expression> conditional);
   /// Move constructor
-  ContinueStatement(ContinueStatement&&) = default;
+  ContinueStatement(ContinueStatement&&);
   ~ContinueStatement() override;
 
   /// Sets the condition type
@@ -64,7 +64,7 @@
   Expression* conditional() const { return conditional_.get(); }
 
   /// @returns true if this is an continue statement
-  bool IsContinue() const override { return true; }
+  bool IsContinue() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/decorated_variable.cc b/src/ast/decorated_variable.cc
index d5fc6cc..340075e 100644
--- a/src/ast/decorated_variable.cc
+++ b/src/ast/decorated_variable.cc
@@ -26,6 +26,10 @@
 
 DecoratedVariable::~DecoratedVariable() = default;
 
+bool DecoratedVariable::IsDecorated() const {
+  return true;
+}
+
 bool DecoratedVariable::IsValid() const {
   return Variable::IsValid();
 }
diff --git a/src/ast/decorated_variable.h b/src/ast/decorated_variable.h
index 5f05416..992e641 100644
--- a/src/ast/decorated_variable.h
+++ b/src/ast/decorated_variable.h
@@ -46,7 +46,7 @@
   const VariableDecorationList& decorations() const { return decorations_; }
 
   /// @returns true if this is a decorated variable
-  bool IsDecorated() const override { return true; }
+  bool IsDecorated() const override;
 
   /// @returns true if the name and path are both present
   bool IsValid() const override;
diff --git a/src/ast/else_statement.cc b/src/ast/else_statement.cc
index b879a4f..e430571 100644
--- a/src/ast/else_statement.cc
+++ b/src/ast/else_statement.cc
@@ -36,8 +36,14 @@
       condition_(std::move(condition)),
       body_(std::move(body)) {}
 
+ElseStatement::ElseStatement(ElseStatement&&) = default;
+
 ElseStatement::~ElseStatement() = default;
 
+bool ElseStatement::IsElse() const {
+  return true;
+}
+
 bool ElseStatement::IsValid() const {
   for (const auto& stmt : body_) {
     if (stmt == nullptr || !stmt->IsValid())
diff --git a/src/ast/else_statement.h b/src/ast/else_statement.h
index a935bb4..b627769 100644
--- a/src/ast/else_statement.h
+++ b/src/ast/else_statement.h
@@ -49,7 +49,7 @@
                 std::unique_ptr<Expression> condition,
                 StatementList body);
   /// Move constructor
-  ElseStatement(ElseStatement&&) = default;
+  ElseStatement(ElseStatement&&);
   ~ElseStatement() override;
 
   /// Sets the condition for the else statement
@@ -69,7 +69,7 @@
   const StatementList& body() const { return body_; }
 
   /// @returns true if this is a else statement
-  bool IsElse() const override { return true; }
+  bool IsElse() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/expression.cc b/src/ast/expression.cc
index 6e34ef9..e12dc27 100644
--- a/src/ast/expression.cc
+++ b/src/ast/expression.cc
@@ -37,6 +37,50 @@
 
 Expression::~Expression() = default;
 
+bool Expression::IsArrayAccessor() const {
+  return false;
+}
+
+bool Expression::IsAs() const {
+  return false;
+}
+
+bool Expression::IsCall() const {
+  return false;
+}
+
+bool Expression::IsCast() const {
+  return false;
+}
+
+bool Expression::IsIdentifier() const {
+  return false;
+}
+
+bool Expression::IsConstructor() const {
+  return false;
+}
+
+bool Expression::IsMemberAccessor() const {
+  return false;
+}
+
+bool Expression::IsBinary() const {
+  return false;
+}
+
+bool Expression::IsUnaryDerivative() const {
+  return false;
+}
+
+bool Expression::IsUnaryMethod() const {
+  return false;
+}
+
+bool Expression::IsUnaryOp() const {
+  return false;
+}
+
 ArrayAccessorExpression* Expression::AsArrayAccessor() {
   assert(IsArrayAccessor());
   return static_cast<ArrayAccessorExpression*>(this);
diff --git a/src/ast/expression.h b/src/ast/expression.h
index abd7661..da20aa8 100644
--- a/src/ast/expression.h
+++ b/src/ast/expression.h
@@ -48,27 +48,27 @@
   type::Type* result_type() const { return result_type_; }
 
   /// @returns true if this is an array accessor expression
-  virtual bool IsArrayAccessor() const { return false; }
+  virtual bool IsArrayAccessor() const;
   /// @returns true if this is an as expression
-  virtual bool IsAs() const { return false; }
+  virtual bool IsAs() const;
   /// @returns true if this is a call expression
-  virtual bool IsCall() const { return false; }
+  virtual bool IsCall() const;
   /// @returns true if this is a cast expression
-  virtual bool IsCast() const { return false; }
+  virtual bool IsCast() const;
   /// @returns true if this is an identifier expression
-  virtual bool IsIdentifier() const { return false; }
+  virtual bool IsIdentifier() const;
   /// @returns true if this is an constructor expression
-  virtual bool IsConstructor() const { return false; }
+  virtual bool IsConstructor() const;
   /// @returns true if this is a member accessor expression
-  virtual bool IsMemberAccessor() const { return false; }
+  virtual bool IsMemberAccessor() const;
   /// @returns true if this is a binary expression
-  virtual bool IsBinary() const { return false; }
+  virtual bool IsBinary() const;
   /// @returns true if this is a unary derivative expression
-  virtual bool IsUnaryDerivative() const { return false; }
+  virtual bool IsUnaryDerivative() const;
   /// @returns true if this is a unary method expression
-  virtual bool IsUnaryMethod() const { return false; }
+  virtual bool IsUnaryMethod() const;
   /// @returns true if this is a unary op expression
-  virtual bool IsUnaryOp() const { return false; }
+  virtual bool IsUnaryOp() const;
 
   /// @returns the expression as an array accessor
   ArrayAccessorExpression* AsArrayAccessor();
diff --git a/src/ast/fallthrough_statement.cc b/src/ast/fallthrough_statement.cc
index b5b7cf2..9abb2d2 100644
--- a/src/ast/fallthrough_statement.cc
+++ b/src/ast/fallthrough_statement.cc
@@ -24,6 +24,10 @@
 
 FallthroughStatement::~FallthroughStatement() = default;
 
+bool FallthroughStatement::IsFallthrough() const {
+  return true;
+}
+
 bool FallthroughStatement::IsValid() const {
   return true;
 }
diff --git a/src/ast/fallthrough_statement.h b/src/ast/fallthrough_statement.h
index d9a8675..a165b3a 100644
--- a/src/ast/fallthrough_statement.h
+++ b/src/ast/fallthrough_statement.h
@@ -35,7 +35,7 @@
   ~FallthroughStatement() override;
 
   /// @returns true if this is an fallthrough statement
-  bool IsFallthrough() const override { return true; }
+  bool IsFallthrough() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/float_literal.cc b/src/ast/float_literal.cc
index 4c67719..3d6d1f8 100644
--- a/src/ast/float_literal.cc
+++ b/src/ast/float_literal.cc
@@ -25,6 +25,10 @@
 
 FloatLiteral::~FloatLiteral() = default;
 
+bool FloatLiteral::IsFloat() const {
+  return true;
+}
+
 std::string FloatLiteral::to_str() const {
   return std::to_string(value_);
 }
diff --git a/src/ast/float_literal.h b/src/ast/float_literal.h
index 370a553..44977c2 100644
--- a/src/ast/float_literal.h
+++ b/src/ast/float_literal.h
@@ -32,7 +32,7 @@
   ~FloatLiteral() override;
 
   /// @returns true if this is a float literal
-  bool IsFloat() const override { return true; }
+  bool IsFloat() const override;
 
   /// @returns the float literal value
   float value() const { return value_; }
diff --git a/src/ast/function.cc b/src/ast/function.cc
index abe5809..3b1e839 100644
--- a/src/ast/function.cc
+++ b/src/ast/function.cc
@@ -19,6 +19,8 @@
 namespace tint {
 namespace ast {
 
+Function::Function() = default;
+
 Function::Function(const std::string& name,
                    VariableList params,
                    type::Type* return_type)
@@ -36,6 +38,8 @@
       params_(std::move(params)),
       return_type_(return_type) {}
 
+Function::Function(Function&&) = default;
+
 Function::~Function() = default;
 
 bool Function::IsValid() const {
diff --git a/src/ast/function.h b/src/ast/function.h
index 06ea194..c6ee88c 100644
--- a/src/ast/function.h
+++ b/src/ast/function.h
@@ -34,7 +34,7 @@
 class Function : public Node {
  public:
   /// Create a new empty function statement
-  Function() = default;
+  Function();
   /// Create a function
   /// @param name the function name
   /// @param params the function parameters
@@ -52,7 +52,7 @@
            VariableList params,
            type::Type* return_type);
   /// Move constructor
-  Function(Function&&) = default;
+  Function(Function&&);
 
   ~Function() override;
 
diff --git a/src/ast/identifier_expression.cc b/src/ast/identifier_expression.cc
index b4d9eb7..25b0602 100644
--- a/src/ast/identifier_expression.cc
+++ b/src/ast/identifier_expression.cc
@@ -31,8 +31,14 @@
                                            std::vector<std::string> name)
     : Expression(source), name_(std::move(name)) {}
 
+IdentifierExpression::IdentifierExpression(IdentifierExpression&&) = default;
+
 IdentifierExpression::~IdentifierExpression() = default;
 
+bool IdentifierExpression::IsIdentifier() const {
+  return true;
+}
+
 bool IdentifierExpression::IsValid() const {
   if (name_.size() == 0)
     return false;
diff --git a/src/ast/identifier_expression.h b/src/ast/identifier_expression.h
index 3e46129..e6eee06 100644
--- a/src/ast/identifier_expression.h
+++ b/src/ast/identifier_expression.h
@@ -42,7 +42,7 @@
   /// @param name the name
   IdentifierExpression(const Source& source, std::vector<std::string> name);
   /// Move constructor
-  IdentifierExpression(IdentifierExpression&&) = default;
+  IdentifierExpression(IdentifierExpression&&);
   ~IdentifierExpression() override;
 
   /// Sets the name
@@ -52,7 +52,7 @@
   std::vector<std::string> name() const { return name_; }
 
   /// @returns true if this is an identifier expression
-  bool IsIdentifier() const override { return true; }
+  bool IsIdentifier() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/if_statement.cc b/src/ast/if_statement.cc
index 671cac3..9447c6c 100644
--- a/src/ast/if_statement.cc
+++ b/src/ast/if_statement.cc
@@ -32,8 +32,14 @@
       condition_(std::move(condition)),
       body_(std::move(body)) {}
 
+IfStatement::IfStatement(IfStatement&&) = default;
+
 IfStatement::~IfStatement() = default;
 
+bool IfStatement::IsIf() const {
+  return true;
+}
+
 bool IfStatement::IsValid() const {
   if (condition_ == nullptr || !condition_->IsValid())
     return false;
diff --git a/src/ast/if_statement.h b/src/ast/if_statement.h
index 30f2e66..7acb72b 100644
--- a/src/ast/if_statement.h
+++ b/src/ast/if_statement.h
@@ -1,4 +1,4 @@
-// Copyright 2020 The Tint Authors.
+// Copyright 2020 The Tint Authors.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@
               std::unique_ptr<Expression> condition,
               StatementList body);
   /// Move constructor
-  IfStatement(IfStatement&&) = default;
+  IfStatement(IfStatement&&);
   ~IfStatement() override;
 
   /// Sets the condition for the if statement
@@ -74,7 +74,7 @@
   const StatementList& premerge() const { return premerge_; }
 
   /// @returns true if this is a if statement
-  bool IsIf() const override { return true; }
+  bool IsIf() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/int_literal.cc b/src/ast/int_literal.cc
index 1fdf84f..54f13d2 100644
--- a/src/ast/int_literal.cc
+++ b/src/ast/int_literal.cc
@@ -22,6 +22,10 @@
 
 IntLiteral::~IntLiteral() = default;
 
+bool IntLiteral::IsInt() const {
+  return true;
+}
+
 std::string IntLiteral::to_str() const {
   return std::to_string(value_);
 }
diff --git a/src/ast/int_literal.h b/src/ast/int_literal.h
index ccbd89c..1a72749 100644
--- a/src/ast/int_literal.h
+++ b/src/ast/int_literal.h
@@ -32,7 +32,7 @@
   ~IntLiteral() override;
 
   /// @returns true if this is a int literal
-  bool IsInt() const override { return true; }
+  bool IsInt() const override;
 
   /// @returns the int literal value
   int32_t value() const { return value_; }
diff --git a/src/ast/kill_statement.cc b/src/ast/kill_statement.cc
index 70581a7..23612fc 100644
--- a/src/ast/kill_statement.cc
+++ b/src/ast/kill_statement.cc
@@ -23,6 +23,10 @@
 
 KillStatement::~KillStatement() = default;
 
+bool KillStatement::IsKill() const {
+  return true;
+}
+
 bool KillStatement::IsValid() const {
   return true;
 }
diff --git a/src/ast/kill_statement.h b/src/ast/kill_statement.h
index bbb1040..78d13e4 100644
--- a/src/ast/kill_statement.h
+++ b/src/ast/kill_statement.h
@@ -33,7 +33,7 @@
   ~KillStatement() override;
 
   /// @returns true if this is a kill statement
-  bool IsKill() const override { return true; }
+  bool IsKill() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/literal.cc b/src/ast/literal.cc
index 3759274..d8d64c0 100644
--- a/src/ast/literal.cc
+++ b/src/ast/literal.cc
@@ -28,6 +28,22 @@
 
 Literal::~Literal() = default;
 
+bool Literal::IsBool() const {
+  return false;
+}
+
+bool Literal::IsFloat() const {
+  return false;
+}
+
+bool Literal::IsInt() const {
+  return false;
+}
+
+bool Literal::IsUint() const {
+  return false;
+}
+
 BoolLiteral* Literal::AsBool() {
   assert(IsBool());
   return static_cast<BoolLiteral*>(this);
diff --git a/src/ast/literal.h b/src/ast/literal.h
index 7ae091c..f7ae470 100644
--- a/src/ast/literal.h
+++ b/src/ast/literal.h
@@ -33,13 +33,13 @@
   virtual ~Literal();
 
   /// @returns true if this is a bool literal
-  virtual bool IsBool() const { return false; }
+  virtual bool IsBool() const;
   /// @returns true if this is a float literal
-  virtual bool IsFloat() const { return false; }
+  virtual bool IsFloat() const;
   /// @returns true if this is a signed int literal
-  virtual bool IsInt() const { return false; }
+  virtual bool IsInt() const;
   /// @returns true if this is a unsigned int literal
-  virtual bool IsUint() const { return false; }
+  virtual bool IsUint() const;
 
   /// @returns the literal as a boolean literal
   BoolLiteral* AsBool();
diff --git a/src/ast/location_decoration.cc b/src/ast/location_decoration.cc
index f261b3a..1330b77 100644
--- a/src/ast/location_decoration.cc
+++ b/src/ast/location_decoration.cc
@@ -21,6 +21,10 @@
 
 LocationDecoration::~LocationDecoration() = default;
 
+bool LocationDecoration::IsLocation() const {
+  return true;
+}
+
 void LocationDecoration::to_str(std::ostream& out) const {
   out << "LocationDecoration{" << value_ << "}" << std::endl;
 }
diff --git a/src/ast/location_decoration.h b/src/ast/location_decoration.h
index 287e891..8eca37f 100644
--- a/src/ast/location_decoration.h
+++ b/src/ast/location_decoration.h
@@ -31,7 +31,7 @@
   ~LocationDecoration() override;
 
   /// @returns true if this is a location decoration
-  bool IsLocation() const override { return true; }
+  bool IsLocation() const override;
 
   /// @returns the location value
   uint32_t value() const { return value_; }
diff --git a/src/ast/loop_statement.cc b/src/ast/loop_statement.cc
index 3a853c6..69d0a28 100644
--- a/src/ast/loop_statement.cc
+++ b/src/ast/loop_statement.cc
@@ -29,8 +29,14 @@
       body_(std::move(body)),
       continuing_(std::move(continuing)) {}
 
+LoopStatement::LoopStatement(LoopStatement&&) = default;
+
 LoopStatement::~LoopStatement() = default;
 
+bool LoopStatement::IsLoop() const {
+  return true;
+}
+
 bool LoopStatement::IsValid() const {
   for (const auto& stmt : body_) {
     if (stmt == nullptr || !stmt->IsValid())
diff --git a/src/ast/loop_statement.h b/src/ast/loop_statement.h
index c70a0cf..26365da 100644
--- a/src/ast/loop_statement.h
+++ b/src/ast/loop_statement.h
@@ -39,7 +39,7 @@
                 StatementList body,
                 StatementList continuing);
   /// Move constructor
-  LoopStatement(LoopStatement&&) = default;
+  LoopStatement(LoopStatement&&);
   ~LoopStatement() override;
 
   /// Sets the body statements
@@ -59,7 +59,7 @@
   bool has_continuing() const { return !continuing_.empty(); }
 
   /// @returns true if this is a loop statement
-  bool IsLoop() const override { return true; }
+  bool IsLoop() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/member_accessor_expression.cc b/src/ast/member_accessor_expression.cc
index 180b06b..c88b604 100644
--- a/src/ast/member_accessor_expression.cc
+++ b/src/ast/member_accessor_expression.cc
@@ -32,8 +32,15 @@
       struct_(std::move(structure)),
       member_(std::move(member)) {}
 
+MemberAccessorExpression::MemberAccessorExpression(MemberAccessorExpression&&) =
+    default;
+
 MemberAccessorExpression::~MemberAccessorExpression() = default;
 
+bool MemberAccessorExpression::IsMemberAccessor() const {
+  return true;
+}
+
 bool MemberAccessorExpression::IsValid() const {
   if (struct_ == nullptr || !struct_->IsValid()) {
     return false;
diff --git a/src/ast/member_accessor_expression.h b/src/ast/member_accessor_expression.h
index b8e0dce..ee56fc6 100644
--- a/src/ast/member_accessor_expression.h
+++ b/src/ast/member_accessor_expression.h
@@ -44,7 +44,7 @@
                            std::unique_ptr<Expression> structure,
                            std::unique_ptr<IdentifierExpression> member);
   /// Move constructor
-  MemberAccessorExpression(MemberAccessorExpression&&) = default;
+  MemberAccessorExpression(MemberAccessorExpression&&);
   ~MemberAccessorExpression() override;
 
   /// Sets the structure
@@ -64,7 +64,7 @@
   IdentifierExpression* member() const { return member_.get(); }
 
   /// @returns true if this is a member accessor expression
-  bool IsMemberAccessor() const override { return true; }
+  bool IsMemberAccessor() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/module.cc b/src/ast/module.cc
index 8b69af0..79e566b 100644
--- a/src/ast/module.cc
+++ b/src/ast/module.cc
@@ -19,6 +19,12 @@
 namespace tint {
 namespace ast {
 
+Module::Module() = default;
+
+Module::Module(Module&&) = default;
+
+Module::~Module() = default;
+
 const Import* Module::FindImportByName(const std::string& name) {
   for (const auto& import : imports_) {
     if (import->name() == name)
@@ -43,7 +49,7 @@
       return false;
     }
   }
-  for (const auto& alias : alias_types_) {
+  for (auto* const alias : alias_types_) {
     if (alias == nullptr) {
       return false;
     }
@@ -70,7 +76,7 @@
   for (const auto& ep : entry_points_) {
     ep->to_str(out, indent);
   }
-  for (const auto& alias : alias_types_) {
+  for (auto* const alias : alias_types_) {
     out << alias->name() << " -> " << alias->type()->type_name() << std::endl;
   }
   for (const auto& func : functions_) {
diff --git a/src/ast/module.h b/src/ast/module.h
index 8bada47..5484a81 100644
--- a/src/ast/module.h
+++ b/src/ast/module.h
@@ -32,10 +32,10 @@
 /// Represents all the source in a given program.
 class Module {
  public:
-  Module() = default;
+  Module();
   /// Move constructor
-  Module(Module&&) = default;
-  ~Module() = default;
+  Module(Module&&);
+  ~Module();
 
   /// Add the given import to the module
   /// @param import The import to add.
diff --git a/src/ast/nop_statement.cc b/src/ast/nop_statement.cc
index b325bb3..86699cb 100644
--- a/src/ast/nop_statement.cc
+++ b/src/ast/nop_statement.cc
@@ -23,6 +23,10 @@
 
 NopStatement::~NopStatement() = default;
 
+bool NopStatement::IsNop() const {
+  return true;
+}
+
 bool NopStatement::IsValid() const {
   return true;
 }
diff --git a/src/ast/nop_statement.h b/src/ast/nop_statement.h
index 551ba29..eae7c60 100644
--- a/src/ast/nop_statement.h
+++ b/src/ast/nop_statement.h
@@ -33,7 +33,7 @@
   ~NopStatement() override;
 
   /// @returns true if this is a nop statement
-  bool IsNop() const override { return true; }
+  bool IsNop() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/regardless_statement.cc b/src/ast/regardless_statement.cc
index 3e1c52a..d01bc81 100644
--- a/src/ast/regardless_statement.cc
+++ b/src/ast/regardless_statement.cc
@@ -30,8 +30,13 @@
       condition_(std::move(condition)),
       body_(std::move(body)) {}
 
+RegardlessStatement::RegardlessStatement(RegardlessStatement&&) = default;
 RegardlessStatement::~RegardlessStatement() = default;
 
+bool RegardlessStatement::IsRegardless() const {
+  return true;
+}
+
 bool RegardlessStatement::IsValid() const {
   if (condition_ == nullptr || !condition_->IsValid()) {
     return false;
diff --git a/src/ast/regardless_statement.h b/src/ast/regardless_statement.h
index aad9fc7..22cbd64 100644
--- a/src/ast/regardless_statement.h
+++ b/src/ast/regardless_statement.h
@@ -42,7 +42,7 @@
                       std::unique_ptr<Expression> condition,
                       StatementList body);
   /// Move constructor
-  RegardlessStatement(RegardlessStatement&&) = default;
+  RegardlessStatement(RegardlessStatement&&);
   ~RegardlessStatement() override;
 
   /// Sets the condition expression
@@ -60,7 +60,7 @@
   const StatementList& body() const { return body_; }
 
   /// @returns true if this is an regardless statement
-  bool IsRegardless() const override { return true; }
+  bool IsRegardless() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/return_statement.cc b/src/ast/return_statement.cc
index dec5f8c..9071d62 100644
--- a/src/ast/return_statement.cc
+++ b/src/ast/return_statement.cc
@@ -28,8 +28,14 @@
                                  std::unique_ptr<Expression> value)
     : Statement(source), value_(std::move(value)) {}
 
+ReturnStatement::ReturnStatement(ReturnStatement&&) = default;
+
 ReturnStatement::~ReturnStatement() = default;
 
+bool ReturnStatement::IsReturn() const {
+  return true;
+}
+
 bool ReturnStatement::IsValid() const {
   if (value_ != nullptr) {
     return value_->IsValid();
diff --git a/src/ast/return_statement.h b/src/ast/return_statement.h
index 216e964..164a602 100644
--- a/src/ast/return_statement.h
+++ b/src/ast/return_statement.h
@@ -40,7 +40,7 @@
   /// @param value the return value
   ReturnStatement(const Source& source, std::unique_ptr<Expression> value);
   /// Move constructor
-  ReturnStatement(ReturnStatement&&) = default;
+  ReturnStatement(ReturnStatement&&);
   ~ReturnStatement() override;
 
   /// Sets the value
@@ -54,7 +54,7 @@
   bool has_value() const { return value_ != nullptr; }
 
   /// @returns true if this is a return statement
-  bool IsReturn() const override { return true; }
+  bool IsReturn() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/scalar_constructor_expression.cc b/src/ast/scalar_constructor_expression.cc
index 7c8cd82..287cb36 100644
--- a/src/ast/scalar_constructor_expression.cc
+++ b/src/ast/scalar_constructor_expression.cc
@@ -29,8 +29,15 @@
     std::unique_ptr<Literal> litearl)
     : ConstructorExpression(source), literal_(std::move(litearl)) {}
 
+ScalarConstructorExpression::ScalarConstructorExpression(
+    ScalarConstructorExpression&&) = default;
+
 ScalarConstructorExpression::~ScalarConstructorExpression() = default;
 
+bool ScalarConstructorExpression::IsScalarConstructor() const {
+  return true;
+}
+
 bool ScalarConstructorExpression::IsValid() const {
   return literal_ != nullptr;
 }
diff --git a/src/ast/scalar_constructor_expression.h b/src/ast/scalar_constructor_expression.h
index 2f977ab..0061bf7 100644
--- a/src/ast/scalar_constructor_expression.h
+++ b/src/ast/scalar_constructor_expression.h
@@ -38,11 +38,11 @@
   ScalarConstructorExpression(const Source& source,
                               std::unique_ptr<Literal> literal);
   /// Move constructor
-  ScalarConstructorExpression(ScalarConstructorExpression&&) = default;
+  ScalarConstructorExpression(ScalarConstructorExpression&&);
   ~ScalarConstructorExpression() override;
 
   /// @returns true if this is a scalar constructor
-  bool IsScalarConstructor() const override { return true; }
+  bool IsScalarConstructor() const override;
 
   /// Set the literal value
   /// @param literal the literal
diff --git a/src/ast/set_decoration.cc b/src/ast/set_decoration.cc
index 6d965a2..5924a00 100644
--- a/src/ast/set_decoration.cc
+++ b/src/ast/set_decoration.cc
@@ -21,6 +21,10 @@
 
 SetDecoration::~SetDecoration() = default;
 
+bool SetDecoration::IsSet() const {
+  return true;
+}
+
 void SetDecoration::to_str(std::ostream& out) const {
   out << "SetDecoration{" << value_ << "}" << std::endl;
 }
diff --git a/src/ast/set_decoration.h b/src/ast/set_decoration.h
index dd0e2d9..41f4d13 100644
--- a/src/ast/set_decoration.h
+++ b/src/ast/set_decoration.h
@@ -31,7 +31,7 @@
   ~SetDecoration() override;
 
   /// @returns true if this is a set decoration
-  bool IsSet() const override { return true; }
+  bool IsSet() const override;
 
   /// @returns the set value
   uint32_t value() const { return value_; }
diff --git a/src/ast/statement.cc b/src/ast/statement.cc
index 1e2fa73..f34be37 100644
--- a/src/ast/statement.cc
+++ b/src/ast/statement.cc
@@ -39,8 +39,70 @@
 
 Statement::Statement(const Source& source) : Node(source) {}
 
+Statement::Statement(Statement&&) = default;
+
 Statement::~Statement() = default;
 
+bool Statement::IsAssign() const {
+  return false;
+}
+
+bool Statement::IsBreak() const {
+  return false;
+}
+
+bool Statement::IsCase() const {
+  return false;
+}
+
+bool Statement::IsContinue() const {
+  return false;
+}
+
+bool Statement::IsElse() const {
+  return false;
+}
+
+bool Statement::IsFallthrough() const {
+  return false;
+}
+
+bool Statement::IsIf() const {
+  return false;
+}
+
+bool Statement::IsKill() const {
+  return false;
+}
+
+bool Statement::IsLoop() const {
+  return false;
+}
+
+bool Statement::IsNop() const {
+  return false;
+}
+
+bool Statement::IsRegardless() const {
+  return false;
+}
+
+bool Statement::IsReturn() const {
+  return false;
+}
+
+bool Statement::IsSwitch() const {
+  return false;
+}
+
+bool Statement::IsUnless() const {
+  return false;
+}
+
+bool Statement::IsVariableDecl() const {
+  return false;
+}
+
 AssignmentStatement* Statement::AsAssign() {
   assert(IsAssign());
   return static_cast<AssignmentStatement*>(this);
diff --git a/src/ast/statement.h b/src/ast/statement.h
index ee9b13b..dcd4c36 100644
--- a/src/ast/statement.h
+++ b/src/ast/statement.h
@@ -45,35 +45,35 @@
   ~Statement() override;
 
   /// @returns true if this is an assign statement
-  virtual bool IsAssign() const { return false; }
+  virtual bool IsAssign() const;
   /// @returns true if this is a break statement
-  virtual bool IsBreak() const { return false; }
+  virtual bool IsBreak() const;
   /// @returns true if this is a case statement
-  virtual bool IsCase() const { return false; }
+  virtual bool IsCase() const;
   /// @returns true if this is a continue statement
-  virtual bool IsContinue() const { return false; }
+  virtual bool IsContinue() const;
   /// @returns true if this is an else statement
-  virtual bool IsElse() const { return false; }
+  virtual bool IsElse() const;
   /// @returns true if this is a fallthrough statement
-  virtual bool IsFallthrough() const { return false; }
+  virtual bool IsFallthrough() const;
   /// @returns true if this is an if statement
-  virtual bool IsIf() const { return false; }
+  virtual bool IsIf() const;
   /// @returns true if this is a kill statement
-  virtual bool IsKill() const { return false; }
+  virtual bool IsKill() const;
   /// @returns true if this is a loop statement
-  virtual bool IsLoop() const { return false; }
+  virtual bool IsLoop() const;
   /// @returns true if this is a nop statement
-  virtual bool IsNop() const { return false; }
+  virtual bool IsNop() const;
   /// @returns true if this is an regardless statement
-  virtual bool IsRegardless() const { return false; }
+  virtual bool IsRegardless() const;
   /// @returns true if this is a return statement
-  virtual bool IsReturn() const { return false; }
+  virtual bool IsReturn() const;
   /// @returns true if this is a switch statement
-  virtual bool IsSwitch() const { return false; }
+  virtual bool IsSwitch() const;
   /// @returns true if this is an unless statement
-  virtual bool IsUnless() const { return false; }
+  virtual bool IsUnless() const;
   /// @returns true if this is an variable statement
-  virtual bool IsVariableDecl() const { return false; }
+  virtual bool IsVariableDecl() const;
 
   /// @returns the statement as an assign statement
   AssignmentStatement* AsAssign();
@@ -113,7 +113,7 @@
   /// @param source the source of the expression
   explicit Statement(const Source& source);
   /// Move constructor
-  Statement(Statement&&) = default;
+  Statement(Statement&&);
 
  private:
   Statement(const Statement&) = delete;
diff --git a/src/ast/struct.cc b/src/ast/struct.cc
index 73df8f8..f0b2a9c 100644
--- a/src/ast/struct.cc
+++ b/src/ast/struct.cc
@@ -27,6 +27,8 @@
                StructMemberList members)
     : Node(source), decoration_(decoration), members_(std::move(members)) {}
 
+Struct::Struct(Struct&&) = default;
+
 Struct::~Struct() = default;
 
 bool Struct::IsValid() const {
diff --git a/src/ast/struct.h b/src/ast/struct.h
index 76dcd2e..9705d0f 100644
--- a/src/ast/struct.h
+++ b/src/ast/struct.h
@@ -43,7 +43,7 @@
          StructDecoration decoration,
          StructMemberList members);
   /// Move constructor
-  Struct(Struct&&) = default;
+  Struct(Struct&&);
 
   ~Struct() override;
 
diff --git a/src/ast/struct_member.cc b/src/ast/struct_member.cc
index a002c6e..f0ce746 100644
--- a/src/ast/struct_member.cc
+++ b/src/ast/struct_member.cc
@@ -17,6 +17,8 @@
 namespace tint {
 namespace ast {
 
+StructMember::StructMember() = default;
+
 StructMember::StructMember(const std::string& name,
                            type::Type* type,
                            StructMemberDecorationList decorations)
@@ -31,6 +33,8 @@
       type_(type),
       decorations_(std::move(decorations)) {}
 
+StructMember::StructMember(StructMember&&) = default;
+
 StructMember::~StructMember() = default;
 
 bool StructMember::IsValid() const {
diff --git a/src/ast/struct_member.h b/src/ast/struct_member.h
index 07af25d..fb21ea8 100644
--- a/src/ast/struct_member.h
+++ b/src/ast/struct_member.h
@@ -32,7 +32,7 @@
 class StructMember : public Node {
  public:
   /// Create a new empty struct member statement
-  StructMember() = default;
+  StructMember();
   /// Create a new struct member statement
   /// @param name The struct member name
   /// @param type The struct member type
@@ -50,7 +50,7 @@
                type::Type* type,
                StructMemberDecorationList decorations);
   /// Move constructor
-  StructMember(StructMember&&) = default;
+  StructMember(StructMember&&);
 
   ~StructMember() override;
 
diff --git a/src/ast/struct_member_decoration.cc b/src/ast/struct_member_decoration.cc
index bcb091a..1c4d154 100644
--- a/src/ast/struct_member_decoration.cc
+++ b/src/ast/struct_member_decoration.cc
@@ -25,6 +25,10 @@
 
 StructMemberDecoration::~StructMemberDecoration() = default;
 
+bool StructMemberDecoration::IsOffset() const {
+  return false;
+}
+
 StructMemberOffsetDecoration* StructMemberDecoration::AsOffset() {
   assert(IsOffset());
   return static_cast<StructMemberOffsetDecoration*>(this);
diff --git a/src/ast/struct_member_decoration.h b/src/ast/struct_member_decoration.h
index e7a49ba..b54f3eb 100644
--- a/src/ast/struct_member_decoration.h
+++ b/src/ast/struct_member_decoration.h
@@ -30,7 +30,7 @@
   virtual ~StructMemberDecoration();
 
   /// @returns true if this is an offset decoration
-  virtual bool IsOffset() const { return false; }
+  virtual bool IsOffset() const;
 
   /// @returns the decoration as an offset decoration
   StructMemberOffsetDecoration* AsOffset();
diff --git a/src/ast/struct_member_offset_decoration.cc b/src/ast/struct_member_offset_decoration.cc
index ec49b19..79168c6 100644
--- a/src/ast/struct_member_offset_decoration.cc
+++ b/src/ast/struct_member_offset_decoration.cc
@@ -20,6 +20,10 @@
 StructMemberOffsetDecoration::StructMemberOffsetDecoration(uint32_t offset)
     : offset_(offset) {}
 
+bool StructMemberOffsetDecoration::IsOffset() const {
+  return true;
+}
+
 StructMemberOffsetDecoration::~StructMemberOffsetDecoration() = default;
 
 std::string StructMemberOffsetDecoration::to_str() const {
diff --git a/src/ast/struct_member_offset_decoration.h b/src/ast/struct_member_offset_decoration.h
index 4e59b2a..e8140af 100644
--- a/src/ast/struct_member_offset_decoration.h
+++ b/src/ast/struct_member_offset_decoration.h
@@ -33,7 +33,7 @@
   ~StructMemberOffsetDecoration() override;
 
   /// @returns true if this is an offset decoration
-  bool IsOffset() const override { return true; }
+  bool IsOffset() const override;
 
   /// @returns the offset value
   uint32_t offset() const { return offset_; }
diff --git a/src/ast/switch_statement.cc b/src/ast/switch_statement.cc
index 483f3d9..4a38869 100644
--- a/src/ast/switch_statement.cc
+++ b/src/ast/switch_statement.cc
@@ -32,6 +32,12 @@
       condition_(std::move(condition)),
       body_(std::move(body)) {}
 
+bool SwitchStatement::IsSwitch() const {
+  return true;
+}
+
+SwitchStatement::SwitchStatement(SwitchStatement&&) = default;
+
 SwitchStatement::~SwitchStatement() = default;
 
 bool SwitchStatement::IsValid() const {
diff --git a/src/ast/switch_statement.h b/src/ast/switch_statement.h
index dceaef7..29078cc 100644
--- a/src/ast/switch_statement.h
+++ b/src/ast/switch_statement.h
@@ -45,7 +45,7 @@
                   std::unique_ptr<Expression> condition,
                   CaseStatementList body);
   /// Move constructor
-  SwitchStatement(SwitchStatement&&) = default;
+  SwitchStatement(SwitchStatement&&);
   ~SwitchStatement() override;
 
   /// Sets the condition for the switch statement
@@ -65,7 +65,7 @@
   const CaseStatementList& body() const { return body_; }
 
   /// @returns true if this is a switch statement
-  bool IsSwitch() const override { return true; }
+  bool IsSwitch() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/type/alias_type.cc b/src/ast/type/alias_type.cc
index 199557e..cce05e3 100644
--- a/src/ast/type/alias_type.cc
+++ b/src/ast/type/alias_type.cc
@@ -27,6 +27,14 @@
 
 AliasType::~AliasType() = default;
 
+bool AliasType::IsAlias() const {
+  return true;
+}
+
+std::string AliasType::type_name() const {
+  return "__alias_" + name_ + subtype_->type_name();
+}
+
 }  // namespace type
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/type/alias_type.h b/src/ast/type/alias_type.h
index a555951..d407306 100644
--- a/src/ast/type/alias_type.h
+++ b/src/ast/type/alias_type.h
@@ -35,7 +35,7 @@
   ~AliasType() override;
 
   /// @returns true if the type is an alias type
-  bool IsAlias() const override { return true; }
+  bool IsAlias() const override;
 
   /// @returns the alias name
   const std::string& name() const { return name_; }
@@ -43,9 +43,7 @@
   Type* type() const { return subtype_; }
 
   /// @returns the name for this type
-  std::string type_name() const override {
-    return "__alias_" + name_ + subtype_->type_name();
-  }
+  std::string type_name() const override;
 
  private:
   std::string name_;
diff --git a/src/ast/type/array_type.cc b/src/ast/type/array_type.cc
index 15ad533..2c840d3 100644
--- a/src/ast/type/array_type.cc
+++ b/src/ast/type/array_type.cc
@@ -23,8 +23,24 @@
 ArrayType::ArrayType(Type* subtype, uint32_t size)
     : subtype_(subtype), size_(size) {}
 
+ArrayType::ArrayType(ArrayType&&) = default;
+
 ArrayType::~ArrayType() = default;
 
+bool ArrayType::IsArray() const {
+  return true;
+}
+
+std::string ArrayType::type_name() const {
+  assert(subtype_);
+
+  std::string type_name = "__array" + subtype_->type_name();
+  if (!IsRuntimeArray())
+    type_name += "_" + std::to_string(size_);
+
+  return type_name;
+}
+
 }  // namespace type
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/type/array_type.h b/src/ast/type/array_type.h
index 22962dd..7bc8023 100644
--- a/src/ast/type/array_type.h
+++ b/src/ast/type/array_type.h
@@ -36,11 +36,11 @@
   /// @param size the number of elements in the array
   ArrayType(Type* subtype, uint32_t size);
   /// Move constructor
-  ArrayType(ArrayType&&) = default;
+  ArrayType(ArrayType&&);
   ~ArrayType() override;
 
   /// @returns true if the type is an array type
-  bool IsArray() const override { return true; }
+  bool IsArray() const override;
   /// @returns true if this is a runtime array.
   /// i.e. the size is determined at runtime
   bool IsRuntimeArray() const { return size_ == 0; }
@@ -51,15 +51,7 @@
   uint32_t size() const { return size_; }
 
   /// @returns the name for the type
-  std::string type_name() const override {
-    assert(subtype_);
-
-    std::string type_name = "__array" + subtype_->type_name();
-    if (!IsRuntimeArray())
-      type_name += "_" + std::to_string(size_);
-
-    return type_name;
-  }
+  std::string type_name() const override;
 
  private:
   Type* subtype_ = nullptr;
diff --git a/src/ast/type/bool_type.cc b/src/ast/type/bool_type.cc
index d584181..e3c7971 100644
--- a/src/ast/type/bool_type.cc
+++ b/src/ast/type/bool_type.cc
@@ -22,6 +22,14 @@
 
 BoolType::~BoolType() = default;
 
+bool BoolType::IsBool() const {
+  return true;
+}
+
+std::string BoolType::type_name() const {
+  return "__bool";
+}
+
 }  // namespace type
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/type/bool_type.h b/src/ast/type/bool_type.h
index 79c4d63..828e2c1 100644
--- a/src/ast/type/bool_type.h
+++ b/src/ast/type/bool_type.h
@@ -33,10 +33,10 @@
   ~BoolType() override;
 
   /// @returns true if the type is a bool type
-  bool IsBool() const override { return true; }
+  bool IsBool() const override;
 
   /// @returns the name for this type
-  std::string type_name() const override { return "__bool"; }
+  std::string type_name() const override;
 };
 
 }  // namespace type
diff --git a/src/ast/type/f32_type.cc b/src/ast/type/f32_type.cc
index 065c22e..bac892b 100644
--- a/src/ast/type/f32_type.cc
+++ b/src/ast/type/f32_type.cc
@@ -22,6 +22,14 @@
 
 F32Type::~F32Type() = default;
 
+bool F32Type::IsF32() const {
+  return true;
+}
+
+std::string F32Type::type_name() const {
+  return "__f32";
+}
+
 }  // namespace type
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/type/f32_type.h b/src/ast/type/f32_type.h
index 881ec4a..a975837 100644
--- a/src/ast/type/f32_type.h
+++ b/src/ast/type/f32_type.h
@@ -33,10 +33,10 @@
   ~F32Type() override;
 
   /// @returns true if the type is an f32 type
-  bool IsF32() const override { return true; }
+  bool IsF32() const override;
 
   /// @returns the name for this type
-  std::string type_name() const override { return "__f32"; }
+  std::string type_name() const override;
 };
 
 }  // namespace type
diff --git a/src/ast/type/i32_type.cc b/src/ast/type/i32_type.cc
index 0a7194d..fd5ab0c 100644
--- a/src/ast/type/i32_type.cc
+++ b/src/ast/type/i32_type.cc
@@ -22,6 +22,14 @@
 
 I32Type::~I32Type() = default;
 
+bool I32Type::IsI32() const {
+  return true;
+}
+
+std::string I32Type::type_name() const {
+  return "__i32";
+}
+
 }  // namespace type
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/type/i32_type.h b/src/ast/type/i32_type.h
index ea60c13..3f8a213 100644
--- a/src/ast/type/i32_type.h
+++ b/src/ast/type/i32_type.h
@@ -33,10 +33,10 @@
   ~I32Type() override;
 
   /// @returns true if the type is an i32 type
-  bool IsI32() const override { return true; }
+  bool IsI32() const override;
 
   /// @returns the name for this type
-  std::string type_name() const override { return "__i32"; }
+  std::string type_name() const override;
 };
 
 }  // namespace type
diff --git a/src/ast/type/matrix_type.cc b/src/ast/type/matrix_type.cc
index 08937d9..d34208c 100644
--- a/src/ast/type/matrix_type.cc
+++ b/src/ast/type/matrix_type.cc
@@ -28,6 +28,15 @@
   assert(columns < 5);
 }
 
+bool MatrixType::IsMatrix() const {
+  return true;
+}
+
+std::string MatrixType::type_name() const {
+  return "__mat_" + std::to_string(rows_) + "_" + std::to_string(columns_) +
+         subtype_->type_name();
+}
+
 MatrixType::~MatrixType() = default;
 
 }  // namespace type
diff --git a/src/ast/type/matrix_type.h b/src/ast/type/matrix_type.h
index a3f95d3..35cd932 100644
--- a/src/ast/type/matrix_type.h
+++ b/src/ast/type/matrix_type.h
@@ -36,7 +36,7 @@
   ~MatrixType() override;
 
   /// @returns true if the type is a matrix type
-  bool IsMatrix() const override { return true; }
+  bool IsMatrix() const override;
 
   /// @returns the type of the matrix
   Type* type() const { return subtype_; }
@@ -46,10 +46,7 @@
   uint32_t columns() const { return columns_; }
 
   /// @returns the name for this type
-  std::string type_name() const override {
-    return "__mat_" + std::to_string(rows_) + "_" + std::to_string(columns_) +
-           subtype_->type_name();
-  }
+  std::string type_name() const override;
 
  private:
   Type* subtype_ = nullptr;
diff --git a/src/ast/type/pointer_type.cc b/src/ast/type/pointer_type.cc
index 2b8e9ce..e6083c8 100644
--- a/src/ast/type/pointer_type.cc
+++ b/src/ast/type/pointer_type.cc
@@ -21,6 +21,16 @@
 PointerType::PointerType(Type* subtype, StorageClass storage_class)
     : subtype_(subtype), storage_class_(storage_class) {}
 
+bool PointerType::IsPointer() const {
+  return true;
+}
+
+std::string PointerType::type_name() const {
+  std::ostringstream out;
+  out << "__ptr_" << storage_class_ << subtype_->type_name();
+  return out.str();
+}
+
 PointerType::~PointerType() = default;
 
 }  // namespace type
diff --git a/src/ast/type/pointer_type.h b/src/ast/type/pointer_type.h
index 40ea116..fa97975 100644
--- a/src/ast/type/pointer_type.h
+++ b/src/ast/type/pointer_type.h
@@ -37,7 +37,7 @@
   ~PointerType() override;
 
   /// @returns true if the type is a pointer type
-  bool IsPointer() const override { return true; }
+  bool IsPointer() const override;
 
   /// @returns the pointee type
   Type* type() const { return subtype_; }
@@ -45,11 +45,7 @@
   StorageClass storage_class() const { return storage_class_; }
 
   /// @returns the name for this type
-  std::string type_name() const override {
-    std::ostringstream out;
-    out << "__ptr_" << storage_class_ << subtype_->type_name();
-    return out.str();
-  }
+  std::string type_name() const override;
 
  private:
   Type* subtype_;
diff --git a/src/ast/type/struct_type.cc b/src/ast/type/struct_type.cc
index d2fcfdc..414dc17 100644
--- a/src/ast/type/struct_type.cc
+++ b/src/ast/type/struct_type.cc
@@ -23,6 +23,16 @@
 StructType::StructType(std::unique_ptr<Struct> impl)
     : struct_(std::move(impl)) {}
 
+StructType::StructType(StructType&&) = default;
+
+bool StructType::IsStruct() const {
+  return true;
+}
+
+std::string StructType::type_name() const {
+  return "__struct_" + name_;
+}
+
 StructType::~StructType() = default;
 
 }  // namespace type
diff --git a/src/ast/type/struct_type.h b/src/ast/type/struct_type.h
index c33cd27..18ce296 100644
--- a/src/ast/type/struct_type.h
+++ b/src/ast/type/struct_type.h
@@ -32,7 +32,7 @@
   /// @param impl the struct data
   explicit StructType(std::unique_ptr<Struct> impl);
   /// Move constructor
-  StructType(StructType&&) = default;
+  StructType(StructType&&);
   ~StructType() override;
 
   /// Sets the name of the struct
@@ -42,13 +42,13 @@
   const std::string& name() const { return name_; }
 
   /// @returns true if the type is a struct type
-  bool IsStruct() const override { return true; }
+  bool IsStruct() const override;
 
   /// @returns the struct name
   Struct* impl() const { return struct_.get(); }
 
   /// @returns the name for th type
-  std::string type_name() const override { return "__struct_" + name_; }
+  std::string type_name() const override;
 
  private:
   std::string name_;
diff --git a/src/ast/type/type.cc b/src/ast/type/type.cc
index 00fe94d..fc5ce2d 100644
--- a/src/ast/type/type.cc
+++ b/src/ast/type/type.cc
@@ -36,6 +36,50 @@
 
 Type::~Type() = default;
 
+bool Type::IsAlias() const {
+  return false;
+}
+
+bool Type::IsArray() const {
+  return false;
+}
+
+bool Type::IsBool() const {
+  return false;
+}
+
+bool Type::IsF32() const {
+  return false;
+}
+
+bool Type::IsI32() const {
+  return false;
+}
+
+bool Type::IsMatrix() const {
+  return false;
+}
+
+bool Type::IsPointer() const {
+  return false;
+}
+
+bool Type::IsStruct() const {
+  return false;
+}
+
+bool Type::IsU32() const {
+  return false;
+}
+
+bool Type::IsVector() const {
+  return false;
+}
+
+bool Type::IsVoid() const {
+  return false;
+}
+
 AliasType* Type::AsAlias() {
   assert(IsAlias());
   return static_cast<AliasType*>(this);
diff --git a/src/ast/type/type.h b/src/ast/type/type.h
index d2e171d..05e29dd 100644
--- a/src/ast/type/type.h
+++ b/src/ast/type/type.h
@@ -41,27 +41,27 @@
   virtual ~Type();
 
   /// @returns true if the type is an alias type
-  virtual bool IsAlias() const { return false; }
+  virtual bool IsAlias() const;
   /// @returns true if the type is an array type
-  virtual bool IsArray() const { return false; }
+  virtual bool IsArray() const;
   /// @returns true if the type is a bool type
-  virtual bool IsBool() const { return false; }
+  virtual bool IsBool() const;
   /// @returns true if the type is an f32 type
-  virtual bool IsF32() const { return false; }
+  virtual bool IsF32() const;
   /// @returns true if the type is an i32 type
-  virtual bool IsI32() const { return false; }
+  virtual bool IsI32() const;
   /// @returns true if the type is a matrix type
-  virtual bool IsMatrix() const { return false; }
+  virtual bool IsMatrix() const;
   /// @returns true if the type is a ptr type
-  virtual bool IsPointer() const { return false; }
+  virtual bool IsPointer() const;
   /// @returns true if the type is a struct type
-  virtual bool IsStruct() const { return false; }
+  virtual bool IsStruct() const;
   /// @returns true if the type is a u32 type
-  virtual bool IsU32() const { return false; }
+  virtual bool IsU32() const;
   /// @returns true if the type is a vec type
-  virtual bool IsVector() const { return false; }
+  virtual bool IsVector() const;
   /// @returns true if the type is a void type
-  virtual bool IsVoid() const { return false; }
+  virtual bool IsVoid() const;
 
   /// @returns the name for this type. The |type_name| is unique over all types.
   virtual std::string type_name() const = 0;
diff --git a/src/ast/type/u32_type.cc b/src/ast/type/u32_type.cc
index b155b1d..2bb7a3f 100644
--- a/src/ast/type/u32_type.cc
+++ b/src/ast/type/u32_type.cc
@@ -22,6 +22,16 @@
 
 U32Type::~U32Type() = default;
 
+U32Type::U32Type(U32Type&&) = default;
+
+bool U32Type::IsU32() const {
+  return true;
+}
+
+std::string U32Type::type_name() const {
+  return "__u32";
+}
+
 }  // namespace type
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/type/u32_type.h b/src/ast/type/u32_type.h
index b0d9440..21dd9ea 100644
--- a/src/ast/type/u32_type.h
+++ b/src/ast/type/u32_type.h
@@ -29,14 +29,14 @@
   /// Constructor
   U32Type();
   /// Move constructor
-  U32Type(U32Type&&) = default;
+  U32Type(U32Type&&);
   ~U32Type() override;
 
   /// @returns true if the type is a u32 type
-  bool IsU32() const override { return true; }
+  bool IsU32() const override;
 
   /// @returns the name for th type
-  std::string type_name() const override { return "__u32"; }
+  std::string type_name() const override;
 };
 
 }  // namespace type
diff --git a/src/ast/type/vector_type.cc b/src/ast/type/vector_type.cc
index de97e04..2335b94 100644
--- a/src/ast/type/vector_type.cc
+++ b/src/ast/type/vector_type.cc
@@ -26,8 +26,18 @@
   assert(size_ < 5);
 }
 
+VectorType::VectorType(VectorType&&) = default;
+
 VectorType::~VectorType() = default;
 
+bool VectorType::IsVector() const {
+  return true;
+}
+
+std::string VectorType::type_name() const {
+  return "__vec_" + std::to_string(size_) + subtype_->type_name();
+}
+
 }  // namespace type
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/type/vector_type.h b/src/ast/type/vector_type.h
index d2704c3..6ea2c8f 100644
--- a/src/ast/type/vector_type.h
+++ b/src/ast/type/vector_type.h
@@ -31,11 +31,11 @@
   /// @param size the number of elements in the vector
   VectorType(Type* subtype, uint32_t size);
   /// Move constructor
-  VectorType(VectorType&&) = default;
+  VectorType(VectorType&&);
   ~VectorType() override;
 
   /// @returns true if the type is a vector type
-  bool IsVector() const override { return true; }
+  bool IsVector() const override;
 
   /// @returns the type of the vector elements
   Type* type() const { return subtype_; }
@@ -43,9 +43,7 @@
   uint32_t size() const { return size_; }
 
   /// @returns the name for th type
-  std::string type_name() const override {
-    return "__vec_" + std::to_string(size_) + subtype_->type_name();
-  }
+  std::string type_name() const override;
 
  private:
   Type* subtype_ = nullptr;
diff --git a/src/ast/type/void_type.cc b/src/ast/type/void_type.cc
index f41a9ba..5cec1f0 100644
--- a/src/ast/type/void_type.cc
+++ b/src/ast/type/void_type.cc
@@ -20,8 +20,18 @@
 
 VoidType::VoidType() = default;
 
+VoidType::VoidType(VoidType&&) = default;
+
 VoidType::~VoidType() = default;
 
+bool VoidType::IsVoid() const {
+  return true;
+}
+
+std::string VoidType::type_name() const {
+  return "__void";
+}
+
 }  // namespace type
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/type/void_type.h b/src/ast/type/void_type.h
index 702a9b5..2a02f46 100644
--- a/src/ast/type/void_type.h
+++ b/src/ast/type/void_type.h
@@ -29,14 +29,14 @@
   /// Constructor
   VoidType();
   /// Move constructor
-  VoidType(VoidType&&) = default;
+  VoidType(VoidType&&);
   ~VoidType() override;
 
   /// @returns true if the type is a void type
-  bool IsVoid() const override { return true; }
+  bool IsVoid() const override;
 
   /// @returns the name for this type
-  std::string type_name() const override { return "__void"; }
+  std::string type_name() const override;
 };
 
 }  // namespace type
diff --git a/src/ast/type_constructor_expression.cc b/src/ast/type_constructor_expression.cc
index f555902..e53b87d 100644
--- a/src/ast/type_constructor_expression.cc
+++ b/src/ast/type_constructor_expression.cc
@@ -29,8 +29,15 @@
                                                      ExpressionList values)
     : ConstructorExpression(source), type_(type), values_(std::move(values)) {}
 
+TypeConstructorExpression::TypeConstructorExpression(
+    TypeConstructorExpression&&) = default;
+
 TypeConstructorExpression::~TypeConstructorExpression() = default;
 
+bool TypeConstructorExpression::IsTypeConstructor() const {
+  return true;
+}
+
 bool TypeConstructorExpression::IsValid() const {
   if (values_.empty()) {
     return false;
diff --git a/src/ast/type_constructor_expression.h b/src/ast/type_constructor_expression.h
index a6e6aba..68ad2d1 100644
--- a/src/ast/type_constructor_expression.h
+++ b/src/ast/type_constructor_expression.h
@@ -40,11 +40,11 @@
                             type::Type* type,
                             ExpressionList values);
   /// Move constructor
-  TypeConstructorExpression(TypeConstructorExpression&&) = default;
+  TypeConstructorExpression(TypeConstructorExpression&&);
   ~TypeConstructorExpression() override;
 
   /// @returns true if this is a type constructor
-  bool IsTypeConstructor() const override { return true; }
+  bool IsTypeConstructor() const override;
 
   /// Set the type
   /// @param type the type
diff --git a/src/ast/uint_literal.cc b/src/ast/uint_literal.cc
index 562d47a..5f8fc93 100644
--- a/src/ast/uint_literal.cc
+++ b/src/ast/uint_literal.cc
@@ -22,6 +22,10 @@
 
 UintLiteral::~UintLiteral() = default;
 
+bool UintLiteral::IsUint() const {
+  return true;
+}
+
 std::string UintLiteral::to_str() const {
   return std::to_string(value_);
 }
diff --git a/src/ast/uint_literal.h b/src/ast/uint_literal.h
index c9e7731..eafbab5 100644
--- a/src/ast/uint_literal.h
+++ b/src/ast/uint_literal.h
@@ -32,7 +32,7 @@
   ~UintLiteral() override;
 
   /// @returns true if this is a uint literal
-  bool IsUint() const override { return true; }
+  bool IsUint() const override;
 
   /// @returns the uint literal value
   uint32_t value() const { return value_; }
diff --git a/src/ast/unary_derivative_expression.cc b/src/ast/unary_derivative_expression.cc
index b2416f3..23c13d5 100644
--- a/src/ast/unary_derivative_expression.cc
+++ b/src/ast/unary_derivative_expression.cc
@@ -32,8 +32,15 @@
     std::unique_ptr<Expression> param)
     : Expression(source), op_(op), modifier_(mod), param_(std::move(param)) {}
 
+UnaryDerivativeExpression::UnaryDerivativeExpression(
+    UnaryDerivativeExpression&&) = default;
+
 UnaryDerivativeExpression::~UnaryDerivativeExpression() = default;
 
+bool UnaryDerivativeExpression::IsUnaryDerivative() const {
+  return true;
+}
+
 bool UnaryDerivativeExpression::IsValid() const {
   if (param_ == nullptr || !param_->IsValid()) {
     return false;
diff --git a/src/ast/unary_derivative_expression.h b/src/ast/unary_derivative_expression.h
index 48d592a..2076eaf 100644
--- a/src/ast/unary_derivative_expression.h
+++ b/src/ast/unary_derivative_expression.h
@@ -48,7 +48,7 @@
                             DerivativeModifier mod,
                             std::unique_ptr<Expression> param);
   /// Move constructor
-  UnaryDerivativeExpression(UnaryDerivativeExpression&&) = default;
+  UnaryDerivativeExpression(UnaryDerivativeExpression&&);
   ~UnaryDerivativeExpression() override;
 
   /// Sets the op
@@ -72,7 +72,7 @@
   Expression* param() const { return param_.get(); }
 
   /// @returns true if this is an as expression
-  bool IsUnaryDerivative() const override { return true; }
+  bool IsUnaryDerivative() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/unary_method_expression.cc b/src/ast/unary_method_expression.cc
index 9c8a77c..034a8e4 100644
--- a/src/ast/unary_method_expression.cc
+++ b/src/ast/unary_method_expression.cc
@@ -28,8 +28,14 @@
                                              ExpressionList params)
     : Expression(source), op_(op), params_(std::move(params)) {}
 
+UnaryMethodExpression::UnaryMethodExpression(UnaryMethodExpression&&) = default;
+
 UnaryMethodExpression::~UnaryMethodExpression() = default;
 
+bool UnaryMethodExpression::IsUnaryMethod() const {
+  return true;
+}
+
 bool UnaryMethodExpression::IsValid() const {
   if (params_.empty()) {
     return false;
diff --git a/src/ast/unary_method_expression.h b/src/ast/unary_method_expression.h
index 58c86c5..4c63325 100644
--- a/src/ast/unary_method_expression.h
+++ b/src/ast/unary_method_expression.h
@@ -41,7 +41,7 @@
                         UnaryMethod op,
                         ExpressionList params);
   /// Move constructor
-  UnaryMethodExpression(UnaryMethodExpression&&) = default;
+  UnaryMethodExpression(UnaryMethodExpression&&);
   ~UnaryMethodExpression() override;
 
   /// Sets the op
@@ -57,7 +57,7 @@
   const ExpressionList& params() const { return params_; }
 
   /// @returns true if this is an as expression
-  bool IsUnaryMethod() const override { return true; }
+  bool IsUnaryMethod() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/unary_op_expression.cc b/src/ast/unary_op_expression.cc
index 33db0c0..2439601 100644
--- a/src/ast/unary_op_expression.cc
+++ b/src/ast/unary_op_expression.cc
@@ -28,8 +28,14 @@
                                      std::unique_ptr<Expression> expr)
     : Expression(source), op_(op), expr_(std::move(expr)) {}
 
+UnaryOpExpression::UnaryOpExpression(UnaryOpExpression&&) = default;
+
 UnaryOpExpression::~UnaryOpExpression() = default;
 
+bool UnaryOpExpression::IsUnaryOp() const {
+  return true;
+}
+
 bool UnaryOpExpression::IsValid() const {
   return expr_ != nullptr && expr_->IsValid();
 }
diff --git a/src/ast/unary_op_expression.h b/src/ast/unary_op_expression.h
index 4b4ba3d..fb38ba7 100644
--- a/src/ast/unary_op_expression.h
+++ b/src/ast/unary_op_expression.h
@@ -42,7 +42,7 @@
                     UnaryOp op,
                     std::unique_ptr<Expression> expr);
   /// Move constructor
-  UnaryOpExpression(UnaryOpExpression&&) = default;
+  UnaryOpExpression(UnaryOpExpression&&);
   ~UnaryOpExpression() override;
 
   /// Sets the op
@@ -58,7 +58,7 @@
   Expression* expr() const { return expr_.get(); }
 
   /// @returns true if this is an as expression
-  bool IsUnaryOp() const override { return true; }
+  bool IsUnaryOp() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/unless_statement.cc b/src/ast/unless_statement.cc
index 051d205..0cfc8d5 100644
--- a/src/ast/unless_statement.cc
+++ b/src/ast/unless_statement.cc
@@ -30,8 +30,14 @@
       condition_(std::move(condition)),
       body_(std::move(body)) {}
 
+UnlessStatement::UnlessStatement(UnlessStatement&&) = default;
+
 UnlessStatement::~UnlessStatement() = default;
 
+bool UnlessStatement::IsUnless() const {
+  return true;
+}
+
 bool UnlessStatement::IsValid() const {
   if (condition_ == nullptr || !condition_->IsValid()) {
     return false;
diff --git a/src/ast/unless_statement.h b/src/ast/unless_statement.h
index d3a4451..1113686 100644
--- a/src/ast/unless_statement.h
+++ b/src/ast/unless_statement.h
@@ -41,7 +41,7 @@
                   std::unique_ptr<Expression> condition,
                   StatementList body);
   /// Move constructor
-  UnlessStatement(UnlessStatement&&) = default;
+  UnlessStatement(UnlessStatement&&);
   ~UnlessStatement() override;
 
   /// Sets the condition expression
@@ -59,7 +59,7 @@
   const StatementList& body() const { return body_; }
 
   /// @returns true if this is an unless statement
-  bool IsUnless() const override { return true; }
+  bool IsUnless() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/variable.cc b/src/ast/variable.cc
index 33e6b79..54d15d7 100644
--- a/src/ast/variable.cc
+++ b/src/ast/variable.cc
@@ -21,6 +21,8 @@
 namespace tint {
 namespace ast {
 
+Variable::Variable() = default;
+
 Variable::Variable(const std::string& name, StorageClass sc, type::Type* type)
     : Node(), name_(name), storage_class_(sc), type_(type) {}
 
@@ -30,6 +32,8 @@
                    type::Type* type)
     : Node(source), name_(name), storage_class_(sc), type_(type) {}
 
+Variable::Variable(Variable&&) = default;
+
 Variable::~Variable() = default;
 
 DecoratedVariable* Variable::AsDecorated() {
@@ -37,6 +41,10 @@
   return static_cast<DecoratedVariable*>(this);
 }
 
+bool Variable::IsDecorated() const {
+  return false;
+}
+
 bool Variable::IsValid() const {
   if (name_.length() == 0) {
     return false;
diff --git a/src/ast/variable.h b/src/ast/variable.h
index 196b3f8..6db32e4 100644
--- a/src/ast/variable.h
+++ b/src/ast/variable.h
@@ -1,4 +1,4 @@
-// Copyright 2020 The Tint Authors.
+// Copyright 2020 The Tint Authors.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -81,7 +81,7 @@
 class Variable : public Node {
  public:
   /// Create a new empty variable statement
-  Variable() = default;
+  Variable();
   /// Create a variable
   /// @param name the variables name
   /// @param sc the variable storage class
@@ -97,7 +97,7 @@
            StorageClass sc,
            type::Type* type);
   /// Move constructor
-  Variable(Variable&&) = default;
+  Variable(Variable&&);
 
   ~Variable() override;
 
@@ -137,7 +137,7 @@
   bool is_const() const { return is_const_; }
 
   /// @returns true if this is a decorated variable
-  virtual bool IsDecorated() const { return false; }
+  virtual bool IsDecorated() const;
 
   /// @returns the expression as a decorated variable
   DecoratedVariable* AsDecorated();
diff --git a/src/ast/variable_decl_statement.cc b/src/ast/variable_decl_statement.cc
index d8f8a84..b19d750 100644
--- a/src/ast/variable_decl_statement.cc
+++ b/src/ast/variable_decl_statement.cc
@@ -26,8 +26,14 @@
                                              std::unique_ptr<Variable> variable)
     : Statement(source), variable_(std::move(variable)) {}
 
+VariableDeclStatement::VariableDeclStatement(VariableDeclStatement&&) = default;
+
 VariableDeclStatement::~VariableDeclStatement() = default;
 
+bool VariableDeclStatement::IsVariableDecl() const {
+  return true;
+}
+
 bool VariableDeclStatement::IsValid() const {
   return variable_ != nullptr && variable_->IsValid();
 }
diff --git a/src/ast/variable_decl_statement.h b/src/ast/variable_decl_statement.h
index cb66061..4873de0 100644
--- a/src/ast/variable_decl_statement.h
+++ b/src/ast/variable_decl_statement.h
@@ -39,7 +39,7 @@
   VariableDeclStatement(const Source& source,
                         std::unique_ptr<Variable> variable);
   /// Move constructor
-  VariableDeclStatement(VariableDeclStatement&&) = default;
+  VariableDeclStatement(VariableDeclStatement&&);
   ~VariableDeclStatement() override;
 
   /// Sets the variable
@@ -51,7 +51,7 @@
   Variable* variable() const { return variable_.get(); }
 
   /// @returns true if this is an variable statement
-  bool IsVariableDecl() const override { return true; }
+  bool IsVariableDecl() const override;
 
   /// @returns true if the node is valid
   bool IsValid() const override;
diff --git a/src/ast/variable_decoration.cc b/src/ast/variable_decoration.cc
index 2f70268..bdfa81a 100644
--- a/src/ast/variable_decoration.cc
+++ b/src/ast/variable_decoration.cc
@@ -28,6 +28,22 @@
 
 VariableDecoration::~VariableDecoration() = default;
 
+bool VariableDecoration::IsBinding() const {
+  return false;
+}
+
+bool VariableDecoration::IsBuiltin() const {
+  return false;
+}
+
+bool VariableDecoration::IsLocation() const {
+  return false;
+}
+
+bool VariableDecoration::IsSet() const {
+  return false;
+}
+
 BindingDecoration* VariableDecoration::AsBinding() {
   assert(IsBinding());
   return static_cast<BindingDecoration*>(this);
diff --git a/src/ast/variable_decoration.h b/src/ast/variable_decoration.h
index a468533..95d9148 100644
--- a/src/ast/variable_decoration.h
+++ b/src/ast/variable_decoration.h
@@ -34,13 +34,13 @@
   virtual ~VariableDecoration();
 
   /// @returns true if this is a binding decoration
-  virtual bool IsBinding() const { return false; }
+  virtual bool IsBinding() const;
   /// @returns true if this is a builtin decoration
-  virtual bool IsBuiltin() const { return false; }
+  virtual bool IsBuiltin() const;
   /// @returns true if this is a location decoration
-  virtual bool IsLocation() const { return false; }
+  virtual bool IsLocation() const;
   /// @returns true if this is a set decoration
-  virtual bool IsSet() const { return false; }
+  virtual bool IsSet() const;
 
   /// @returns the decoration as a binding decoration
   BindingDecoration* AsBinding();
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index 4ccdbb4..357d3e9 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -114,7 +114,7 @@
     return true;
   }
 
-  auto var = stmt->AsVariableDecl()->variable();
+  auto* var = stmt->AsVariableDecl()->variable();
   // Nothing to do for const
   if (var->is_const()) {
     return true;
@@ -135,23 +135,23 @@
 
 bool TypeDeterminer::DetermineResultType(ast::Statement* stmt) {
   if (stmt->IsAssign()) {
-    auto a = stmt->AsAssign();
+    auto* a = stmt->AsAssign();
     return DetermineResultType(a->lhs()) && DetermineResultType(a->rhs());
   }
   if (stmt->IsBreak()) {
-    auto b = stmt->AsBreak();
+    auto* b = stmt->AsBreak();
     return DetermineResultType(b->conditional());
   }
   if (stmt->IsCase()) {
-    auto c = stmt->AsCase();
+    auto* c = stmt->AsCase();
     return DetermineStatements(c->body());
   }
   if (stmt->IsContinue()) {
-    auto c = stmt->AsContinue();
+    auto* c = stmt->AsContinue();
     return DetermineResultType(c->conditional());
   }
   if (stmt->IsElse()) {
-    auto e = stmt->AsElse();
+    auto* e = stmt->AsElse();
     return DetermineResultType(e->condition()) &&
            DetermineStatements(e->body());
   }
@@ -159,7 +159,7 @@
     return true;
   }
   if (stmt->IsIf()) {
-    auto i = stmt->AsIf();
+    auto* i = stmt->AsIf();
     if (!DetermineResultType(i->condition()) ||
         !DetermineStatements(i->body())) {
       return false;
@@ -176,7 +176,7 @@
     return true;
   }
   if (stmt->IsLoop()) {
-    auto l = stmt->AsLoop();
+    auto* l = stmt->AsLoop();
     return DetermineStatements(l->body()) &&
            DetermineStatements(l->continuing());
   }
@@ -184,16 +184,16 @@
     return true;
   }
   if (stmt->IsRegardless()) {
-    auto r = stmt->AsRegardless();
+    auto* r = stmt->AsRegardless();
     return DetermineResultType(r->condition()) &&
            DetermineStatements(r->body());
   }
   if (stmt->IsReturn()) {
-    auto r = stmt->AsReturn();
+    auto* r = stmt->AsReturn();
     return DetermineResultType(r->value());
   }
   if (stmt->IsSwitch()) {
-    auto s = stmt->AsSwitch();
+    auto* s = stmt->AsSwitch();
     if (!DetermineResultType(s->condition())) {
       return false;
     }
@@ -205,12 +205,12 @@
     return true;
   }
   if (stmt->IsUnless()) {
-    auto u = stmt->AsUnless();
+    auto* u = stmt->AsUnless();
     return DetermineResultType(u->condition()) &&
            DetermineStatements(u->body());
   }
   if (stmt->IsVariableDecl()) {
-    auto v = stmt->AsVariableDecl();
+    auto* v = stmt->AsVariableDecl();
     variable_stack_.set(v->variable()->name(), v->variable());
     return DetermineResultType(v->variable()->constructor());
   }
@@ -268,13 +268,13 @@
   if (!DetermineResultType(expr->array())) {
     return false;
   }
-  auto parent_type = expr->array()->result_type();
+  auto* parent_type = expr->array()->result_type();
   if (parent_type->IsArray()) {
     expr->set_result_type(parent_type->AsArray()->type());
   } else if (parent_type->IsVector()) {
     expr->set_result_type(parent_type->AsVector()->type());
   } else if (parent_type->IsMatrix()) {
-    auto m = parent_type->AsMatrix();
+    auto* m = parent_type->AsMatrix();
     expr->set_result_type(ctx_.type_mgr().Get(
         std::make_unique<ast::type::VectorType>(m->type(), m->rows())));
   } else {
@@ -340,9 +340,9 @@
     return false;
   }
 
-  auto data_type = expr->structure()->result_type();
+  auto* data_type = expr->structure()->result_type();
   if (data_type->IsStruct()) {
-    auto strct = data_type->AsStruct()->impl();
+    auto* strct = data_type->AsStruct()->impl();
     auto name = expr->member()->name()[0];
 
     for (const auto& member : strct->members()) {
@@ -358,7 +358,7 @@
     return false;
   }
   if (data_type->IsVector()) {
-    auto vec = data_type->AsVector();
+    auto* vec = data_type->AsVector();
 
     // The vector will have a number of components equal to the length of the
     // swizzle. This assumes the validator will check that the swizzle
@@ -389,9 +389,9 @@
   if (expr->IsLogicalAnd() || expr->IsLogicalOr() || expr->IsEqual() ||
       expr->IsNotEqual() || expr->IsLessThan() || expr->IsGreaterThan() ||
       expr->IsLessThanEqual() || expr->IsGreaterThanEqual()) {
-    auto bool_type =
+    auto* bool_type =
         ctx_.type_mgr().Get(std::make_unique<ast::type::BoolType>());
-    auto param_type = expr->lhs()->result_type();
+    auto* param_type = expr->lhs()->result_type();
     if (param_type->IsVector()) {
       expr->set_result_type(
           ctx_.type_mgr().Get(std::make_unique<ast::type::VectorType>(
@@ -402,8 +402,8 @@
     return true;
   }
   if (expr->IsMultiply()) {
-    auto lhs_type = expr->lhs()->result_type();
-    auto rhs_type = expr->rhs()->result_type();
+    auto* lhs_type = expr->lhs()->result_type();
+    auto* rhs_type = expr->rhs()->result_type();
 
     // Note, the ordering here matters. The later checks depend on the prior
     // checks having been done.
@@ -414,11 +414,11 @@
               rhs_type->AsMatrix()->columns())));
 
     } else if (lhs_type->IsMatrix() && rhs_type->IsVector()) {
-      auto mat = lhs_type->AsMatrix();
+      auto* mat = lhs_type->AsMatrix();
       expr->set_result_type(ctx_.type_mgr().Get(
           std::make_unique<ast::type::VectorType>(mat->type(), mat->rows())));
     } else if (lhs_type->IsVector() && rhs_type->IsMatrix()) {
-      auto mat = rhs_type->AsMatrix();
+      auto* mat = rhs_type->AsMatrix();
       expr->set_result_type(
           ctx_.type_mgr().Get(std::make_unique<ast::type::VectorType>(
               mat->type(), mat->columns())));
@@ -480,9 +480,9 @@
         return false;
       }
 
-      auto bool_type =
+      auto* bool_type =
           ctx_.type_mgr().Get(std::make_unique<ast::type::BoolType>());
-      auto param_type = expr->params()[0]->result_type();
+      auto* param_type = expr->params()[0]->result_type();
       if (param_type->IsVector()) {
         expr->set_result_type(
             ctx_.type_mgr().Get(std::make_unique<ast::type::VectorType>(
@@ -503,8 +503,8 @@
                   "incorrect number of parameters for outer product");
         return false;
       }
-      auto param0_type = expr->params()[0]->result_type();
-      auto param1_type = expr->params()[1]->result_type();
+      auto* param0_type = expr->params()[0]->result_type();
+      auto* param1_type = expr->params()[1]->result_type();
       if (!param0_type->IsVector() || !param1_type->IsVector()) {
         set_error(expr->source(), "invalid parameter type for outer product");
         return false;