Create explicit class in the IR for initializer expressions. NFC

Rather than treating an init expression as a raw expression list wrap
it into its own class.  While this does nothing now I plan to follow up
by attaching an end_loc (like we do for Block) so that we can have the
validator handle checking the correct placement of the END instruction.

Its also good for readability to have an explict class here I think.
diff --git a/src/apply-names.cc b/src/apply-names.cc
index 49341c5..fbfbe26 100644
--- a/src/apply-names.cc
+++ b/src/apply-names.cc
@@ -439,7 +439,7 @@
 }
 
 Result NameApplier::VisitGlobal(Global* global) {
-  CHECK_RESULT(visitor_.VisitExprList(global->init_expr));
+  CHECK_RESULT(visitor_.VisitExprList(global->init_expr.exprs));
   return Result::Ok;
 }
 
@@ -460,9 +460,9 @@
 Result NameApplier::VisitElemSegment(Index elem_segment_index,
                                      ElemSegment* segment) {
   CHECK_RESULT(UseNameForTableVar(&segment->table_var));
-  CHECK_RESULT(visitor_.VisitExprList(segment->offset));
-  for (ExprList& elem_expr : segment->elem_exprs) {
-    Expr* expr = &elem_expr.front();
+  CHECK_RESULT(visitor_.VisitExprList(segment->offset.exprs));
+  for (InitExpr& init_expr : segment->elem_exprs) {
+    Expr* expr = &init_expr.exprs.front();
     if (expr->type() == ExprType::RefFunc) {
       CHECK_RESULT(UseNameForFuncVar(&cast<RefFuncExpr>(expr)->var));
     }
@@ -473,7 +473,7 @@
 Result NameApplier::VisitDataSegment(Index data_segment_index,
                                      DataSegment* segment) {
   CHECK_RESULT(UseNameForMemoryVar(&segment->memory_var));
-  CHECK_RESULT(visitor_.VisitExprList(segment->offset));
+  CHECK_RESULT(visitor_.VisitExprList(segment->offset.exprs));
   return Result::Ok;
 }
 
diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc
index ef837c0..ab8fe15 100644
--- a/src/binary-reader-ir.cc
+++ b/src/binary-reader-ir.cc
@@ -304,7 +304,7 @@
 
   Func* current_func_ = nullptr;
   std::vector<LabelNode> label_stack_;
-  ExprList* current_init_expr_ = nullptr;
+  InitExpr* current_init_expr_ = nullptr;
   const char* filename_;
 };
 
@@ -368,7 +368,7 @@
 Result BinaryReaderIR::AppendExpr(std::unique_ptr<Expr> expr) {
   expr->loc = GetLocation();
   if (current_init_expr_) {
-    current_init_expr_->push_back(std::move(expr));
+    current_init_expr_->exprs.push_back(std::move(expr));
   } else {
     LabelNode* label;
     CHECK_RESULT(TopLabel(&label));
@@ -1188,8 +1188,8 @@
   assert(segment_index == module_->elem_segments.size() - 1);
   ElemSegment* segment = module_->elem_segments[segment_index];
   Location loc = GetLocation();
-  ExprList init_expr;
-  init_expr.push_back(MakeUnique<RefNullExpr>(type, loc));
+  InitExpr init_expr;
+  init_expr.exprs.push_back(MakeUnique<RefNullExpr>(type, loc));
   segment->elem_exprs.push_back(std::move(init_expr));
   return Result::Ok;
 }
@@ -1199,8 +1199,8 @@
   assert(segment_index == module_->elem_segments.size() - 1);
   ElemSegment* segment = module_->elem_segments[segment_index];
   Location loc = GetLocation();
-  ExprList init_expr;
-  init_expr.push_back(MakeUnique<RefFuncExpr>(Var(func_index, loc), loc));
+  InitExpr init_expr;
+  init_expr.exprs.push_back(MakeUnique<RefFuncExpr>(Var(func_index, loc), loc));
   segment->elem_exprs.push_back(std::move(init_expr));
   return Result::Ok;
 }
diff --git a/src/binary-writer.cc b/src/binary-writer.cc
index c3adfbf..5efc777 100644
--- a/src/binary-writer.cc
+++ b/src/binary-writer.cc
@@ -395,7 +395,7 @@
                                   const char* desc);
   void WriteExpr(const Func* func, const Expr* expr);
   void WriteExprList(const Func* func, const ExprList& exprs);
-  void WriteInitExpr(const ExprList& expr);
+  void WriteInitExpr(const InitExpr& expr);
   void WriteFuncLocals(const Func* func, const LocalTypes& local_types);
   void WriteFunc(const Func* func);
   void WriteTable(const Table* table);
@@ -1112,8 +1112,8 @@
   }
 }
 
-void BinaryWriter::WriteInitExpr(const ExprList& expr) {
-  WriteExprList(nullptr, expr);
+void BinaryWriter::WriteInitExpr(const InitExpr& expr) {
+  WriteExprList(nullptr, expr.exprs);
   WriteOpcode(stream_, Opcode::End);
 }
 
@@ -1539,13 +1539,13 @@
       // preceeded by length
       WriteU32Leb128(stream_, segment->elem_exprs.size(), "num elems");
       if (flags & SegUseElemExprs) {
-        for (const ExprList& elem_expr : segment->elem_exprs) {
+        for (const InitExpr& elem_expr : segment->elem_exprs) {
           WriteInitExpr(elem_expr);
         }
       } else {
-        for (const ExprList& elem_expr : segment->elem_exprs) {
-          assert(elem_expr.size() == 1);
-          const Expr* expr = &elem_expr.front();
+        for (const InitExpr& elem_expr : segment->elem_exprs) {
+          assert(elem_expr.exprs.size() == 1);
+          const Expr* expr = &elem_expr.exprs.front();
           assert(expr->type() == ExprType::RefFunc);
           WriteU32Leb128(stream_,
                          module_->GetFuncIndex(cast<RefFuncExpr>(expr)->var),
diff --git a/src/c-writer.cc b/src/c-writer.cc
index d4381a6..9a3e8b8 100644
--- a/src/c-writer.cc
+++ b/src/c-writer.cc
@@ -220,7 +220,7 @@
   void Write(const StackVar&);
   void Write(const ResultType&);
   void Write(const Const&);
-  void WriteInitExpr(const ExprList&);
+  void WriteInitExpr(const InitExpr&);
   std::string GenerateHeaderGuard() const;
   void WriteSourceTop();
   void WriteMultivalueTypes();
@@ -782,7 +782,9 @@
   }
 }
 
-void CWriter::WriteInitExpr(const ExprList& expr_list) {
+void CWriter::WriteInitExpr(const InitExpr& init_expr) {
+  const ExprList& expr_list = init_expr.exprs;
+
   if (expr_list.empty())
     return;
 
@@ -981,7 +983,7 @@
   for (const Global* global : module_->globals) {
     bool is_import = global_index < module_->num_global_imports;
     if (!is_import) {
-      assert(!global->init_expr.empty());
+      assert(!global->init_expr.exprs.empty());
       Write(GlobalName(global->name), " = ");
       WriteInitExpr(global->init_expr);
       Write(";", Newline());
@@ -1111,11 +1113,11 @@
     Write(";", Newline());
 
     size_t i = 0;
-    for (const ExprList& elem_expr : elem_segment->elem_exprs) {
+    for (const InitExpr& elem_expr : elem_segment->elem_exprs) {
       // We don't support the bulk-memory proposal here, so we know that we
       // don't have any passive segments (where ref.null can be used).
-      assert(elem_expr.size() == 1);
-      const Expr* expr = &elem_expr.front();
+      assert(elem_expr.exprs.size() == 1);
+      const Expr* expr = &elem_expr.exprs.front();
       assert(expr->type() == ExprType::RefFunc);
       const Func* func = module_->GetFunc(cast<RefFuncExpr>(expr)->var);
       Index func_type_index = module_->GetFuncTypeIndex(func->decl.type_var);
diff --git a/src/decompiler.cc b/src/decompiler.cc
index 25fd75a..84942f1 100644
--- a/src/decompiler.cc
+++ b/src/decompiler.cc
@@ -266,8 +266,8 @@
       // FIXME: make this less expensive with a binary search or whatever.
       for (auto dat : mc.module.data_segments) {
         uint64_t dat_base;
-        if (dat->offset.size() == 1 &&
-            ConstIntVal(&dat->offset.front(), dat_base) &&
+        if (dat->offset.exprs.size() == 1 &&
+            ConstIntVal(&dat->offset.exprs.front(), dat_base) &&
             abs_base >= dat_base &&
             abs_base < dat_base + dat->data.size()) {
           // We are inside the range of this data segment!
@@ -719,7 +719,7 @@
           CheckImportExport(s, ExternalKind::Global, global_index, g->name);
       s += cat("global ", g->name, ":", GetDecompTypeName(g->type));
       if (!is_import) {
-        s += cat(" = ", InitExp(g->init_expr));
+        s += cat(" = ", InitExp(g->init_expr.exprs));
       }
       s += ";\n";
       global_index++;
@@ -745,7 +745,7 @@
 
     // Data.
     for (auto dat : mc.module.data_segments) {
-      s += cat("data ", dat->name, "(offset: ", InitExp(dat->offset), ") =");
+      s += cat("data ", dat->name, "(offset: ", InitExp(dat->offset.exprs), ") =");
       auto ds = BinaryToString(dat->data);
       if (ds.size() > target_exp_width / 2) {
         s += "\n";
diff --git a/src/ir.cc b/src/ir.cc
index bace825..3f63274 100644
--- a/src/ir.cc
+++ b/src/ir.cc
@@ -667,8 +667,8 @@
   all_ref_func =
       all_ref_func &&
       std::all_of(elem_exprs.begin(), elem_exprs.end(),
-                  [](const ExprList& elem_expr) {
-                    return elem_expr.front().type() == ExprType::RefFunc;
+                  [](const InitExpr& elem_expr) {
+                    return elem_expr.exprs.front().type() == ExprType::RefFunc;
                   });
   if (!all_ref_func) {
     flags |= SegUseElemExprs;
diff --git a/src/ir.h b/src/ir.h
index 52baab3..4c82faf 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -372,6 +372,13 @@
   Location end_loc;
 };
 
+struct InitExpr {
+  InitExpr() = default;
+  explicit InitExpr(ExprList exprs) : exprs(std::move(exprs)) {}
+
+  ExprList exprs;
+};
+
 struct Catch {
   explicit Catch(const Location& loc = Location()) : loc(loc) {}
   explicit Catch(const Var& var, const Location& loc = Location())
@@ -835,7 +842,7 @@
   std::string name;
   Type type = Type::Void;
   bool mutable_ = false;
-  ExprList init_expr;
+  InitExpr init_expr;
 };
 
 struct Table {
@@ -847,7 +854,7 @@
   Type elem_type;
 };
 
-typedef std::vector<ExprList> ExprListVector;
+typedef std::vector<InitExpr> InitExprVector;
 
 struct ElemSegment {
   explicit ElemSegment(string_view name) : name(name.to_string()) {}
@@ -857,8 +864,8 @@
   std::string name;
   Var table_var;
   Type elem_type;
-  ExprList offset;
-  ExprListVector elem_exprs;
+  InitExpr offset;
+  InitExprVector elem_exprs;
 };
 
 struct Memory {
@@ -875,7 +882,7 @@
   SegmentKind kind = SegmentKind::Active;
   std::string name;
   Var memory_var;
-  ExprList offset;
+  InitExpr offset;
   std::vector<uint8_t> data;
 };
 
diff --git a/src/resolve-names.cc b/src/resolve-names.cc
index 6b67a90..b324853 100644
--- a/src/resolve-names.cc
+++ b/src/resolve-names.cc
@@ -514,7 +514,7 @@
 }
 
 void NameResolver::VisitGlobal(Global* global) {
-  visitor_.VisitExprList(global->init_expr);
+  visitor_.VisitExprList(global->init_expr.exprs);
 }
 
 void NameResolver::VisitTag(Tag* tag) {
@@ -525,18 +525,18 @@
 
 void NameResolver::VisitElemSegment(ElemSegment* segment) {
   ResolveTableVar(&segment->table_var);
-  visitor_.VisitExprList(segment->offset);
-  for (ExprList& elem_expr : segment->elem_exprs) {
-    if (elem_expr.size() == 1 &&
-        elem_expr.front().type() == ExprType::RefFunc) {
-      ResolveFuncVar(&cast<RefFuncExpr>(&elem_expr.front())->var);
+  visitor_.VisitExprList(segment->offset.exprs);
+  for (InitExpr& elem_expr : segment->elem_exprs) {
+    if (elem_expr.exprs.size() == 1 &&
+        elem_expr.exprs.front().type() == ExprType::RefFunc) {
+      ResolveFuncVar(&cast<RefFuncExpr>(&elem_expr.exprs.front())->var);
     }
   }
 }
 
 void NameResolver::VisitDataSegment(DataSegment* segment) {
   ResolveMemoryVar(&segment->memory_var);
-  visitor_.VisitExprList(segment->offset);
+  visitor_.VisitExprList(segment->offset.exprs);
 }
 
 Result NameResolver::VisitModule(Module* module) {
diff --git a/src/validator.cc b/src/validator.cc
index 6fa2d80..f4351f6 100644
--- a/src/validator.cc
+++ b/src/validator.cc
@@ -731,8 +731,8 @@
       result_ |=
           validator_.OnGlobal(field.loc, f->global.type, f->global.mutable_);
 
-      if (f->global.init_expr.size() == 1) {
-        const Expr* expr = &f->global.init_expr.front();
+      if (f->global.init_expr.exprs.size() == 1) {
+        const Expr* expr = &f->global.init_expr.exprs.front();
 
         switch (expr->type()) {
           case ExprType::Const:
@@ -798,8 +798,8 @@
       validator_.OnElemSegmentElemType(f->elem_segment.elem_type);
 
       // Init expr.
-      if (f->elem_segment.offset.size() == 1) {
-        const Expr* expr = &f->elem_segment.offset.front();
+      if (f->elem_segment.offset.exprs.size() == 1) {
+        const Expr* expr = &f->elem_segment.offset.exprs.front();
 
         switch (expr->type()) {
           case ExprType::Const:
@@ -818,14 +818,14 @@
             result_ |= validator_.OnElemSegmentInitExpr_Other(expr->loc);
             break;
         }
-      } else if (f->elem_segment.offset.size() > 1) {
+      } else if (f->elem_segment.offset.exprs.size() > 1) {
         result_ |= validator_.OnElemSegmentInitExpr_Other(field.loc);
       }
 
       // Element expr.
       for (auto&& elem_expr : f->elem_segment.elem_exprs) {
-        if (elem_expr.size() == 1) {
-          const Expr* expr = &elem_expr.front();
+        if (elem_expr.exprs.size() == 1) {
+          const Expr* expr = &elem_expr.exprs.front();
           switch (expr->type()) {
             case ExprType::RefNull:
               result_ |= validator_.OnElemSegmentElemExpr_RefNull(
@@ -839,7 +839,7 @@
               result_ |= validator_.OnElemSegmentElemExpr_Other(expr->loc);
               break;
           }
-        } else if (elem_expr.size() > 1) {
+        } else if (elem_expr.exprs.size() > 1) {
           result_ |= validator_.OnElemSegmentElemExpr_Other(field.loc);
         }
       }
@@ -873,8 +873,8 @@
           field.loc, f->data_segment.memory_var, f->data_segment.kind);
 
       // Init expr.
-      if (f->data_segment.offset.size() == 1) {
-        const Expr* expr = &f->data_segment.offset.front();
+      if (f->data_segment.offset.exprs.size() == 1) {
+        const Expr* expr = &f->data_segment.offset.exprs.front();
 
         switch (expr->type()) {
           case ExprType::Const:
@@ -893,7 +893,7 @@
             result_ |= validator_.OnDataSegmentInitExpr_Other(expr->loc);
             break;
         }
-      } else if (f->data_segment.offset.size() > 1) {
+      } else if (f->data_segment.offset.exprs.size() > 1) {
         result_ |= validator_.OnDataSegmentInitExpr_Other(field.loc);
       }
     }
diff --git a/src/wast-parser.cc b/src/wast-parser.cc
index 7c3c66a..10ba73e 100644
--- a/src/wast-parser.cc
+++ b/src/wast-parser.cc
@@ -823,20 +823,20 @@
   return true;
 }
 
-bool WastParser::ParseElemExprListOpt(ExprListVector* out_list) {
-  ExprList elem_expr;
-  while (ParseElemExprOpt(&elem_expr)) {
-    out_list->push_back(std::move(elem_expr));
+bool WastParser::ParseElemExprListOpt(InitExprVector* out_list) {
+  InitExpr init_expr;
+  while (ParseElemExprOpt(&init_expr.exprs)) {
+    out_list->push_back(std::move(init_expr));
   }
   return !out_list->empty();
 }
 
-bool WastParser::ParseElemExprVarListOpt(ExprListVector* out_list) {
+bool WastParser::ParseElemExprVarListOpt(InitExprVector* out_list) {
   WABT_TRACE(ParseElemExprVarListOpt);
   Var var;
-  ExprList init_expr;
+  InitExpr init_expr;
   while (ParseVarOpt(&var)) {
-    init_expr.push_back(MakeUnique<RefFuncExpr>(var));
+    init_expr.exprs.push_back(MakeUnique<RefFuncExpr>(var));
     out_list->push_back(std::move(init_expr));
   }
   return !out_list->empty();
@@ -1201,10 +1201,10 @@
     EXPECT(Memory);
     CHECK_RESULT(ParseVar(&field->data_segment.memory_var));
     EXPECT(Rpar);
-    CHECK_RESULT(ParseOffsetExpr(&field->data_segment.offset));
+    CHECK_RESULT(ParseOffsetExpr(&field->data_segment.offset.exprs));
   } else if (ParseVarOpt(&field->data_segment.memory_var, Var(0, loc))) {
-    CHECK_RESULT(ParseOffsetExpr(&field->data_segment.offset));
-  } else if (!ParseOffsetExprOpt(&field->data_segment.offset)) {
+    CHECK_RESULT(ParseOffsetExpr(&field->data_segment.offset.exprs));
+  } else if (!ParseOffsetExprOpt(&field->data_segment.offset.exprs)) {
     if (!options_->features.bulk_memory_enabled()) {
       Error(loc, "passive data segments are not allowed");
       return Result::Error;
@@ -1264,11 +1264,11 @@
   // Parse offset expression, if not declared/passive segment.
   if (options_->features.bulk_memory_enabled()) {
     if (field->elem_segment.kind != SegmentKind::Declared &&
-        !ParseOffsetExprOpt(&field->elem_segment.offset)) {
+        !ParseOffsetExprOpt(&field->elem_segment.offset.exprs)) {
       field->elem_segment.kind = SegmentKind::Passive;
     }
   } else {
-    CHECK_RESULT(ParseOffsetExpr(&field->elem_segment.offset));
+    CHECK_RESULT(ParseOffsetExpr(&field->elem_segment.offset.exprs));
   }
 
   if (ParseRefTypeOpt(&field->elem_segment.elem_type)) {
@@ -1474,7 +1474,7 @@
   } else {
     auto field = MakeUnique<GlobalModuleField>(loc, name);
     CHECK_RESULT(ParseGlobalType(&field->global));
-    CHECK_RESULT(ParseTerminatingInstrList(&field->global.init_expr));
+    CHECK_RESULT(ParseTerminatingInstrList(&field->global.init_expr.exprs));
     module->AppendField(std::move(field));
   }
 
@@ -1600,9 +1600,9 @@
       auto data_segment_field = MakeUnique<DataSegmentModuleField>(loc);
       DataSegment& data_segment = data_segment_field->data_segment;
       data_segment.memory_var = Var(module->memories.size());
-      data_segment.offset.push_back(MakeUnique<ConstExpr>(
+      data_segment.offset.exprs.push_back(MakeUnique<ConstExpr>(
           field->memory.page_limits.is_64 ? Const::I64(0) : Const::I32(0)));
-      data_segment.offset.back().loc = loc;
+      data_segment.offset.exprs.back().loc = loc;
       ParseTextListOpt(&data_segment.data);
       EXPECT(Rpar);
 
@@ -1672,13 +1672,13 @@
     auto elem_segment_field = MakeUnique<ElemSegmentModuleField>(loc);
     ElemSegment& elem_segment = elem_segment_field->elem_segment;
     elem_segment.table_var = Var(module->tables.size());
-    elem_segment.offset.push_back(MakeUnique<ConstExpr>(Const::I32(0)));
-    elem_segment.offset.back().loc = loc;
+    elem_segment.offset.exprs.push_back(MakeUnique<ConstExpr>(Const::I32(0)));
+    elem_segment.offset.exprs.back().loc = loc;
     elem_segment.elem_type = elem_type;
     // Syntax is either an optional list of var (legacy), or a non-empty list
     // of elem expr.
-    ExprList elem_expr;
-    if (ParseElemExprOpt(&elem_expr)) {
+    InitExpr elem_expr;
+    if (ParseElemExprOpt(&elem_expr.exprs)) {
       elem_segment.elem_exprs.push_back(std::move(elem_expr));
       // Parse the rest.
       ParseElemExprListOpt(&elem_segment.elem_exprs);
diff --git a/src/wast-parser.h b/src/wast-parser.h
index 9072e41..94dcc77 100644
--- a/src/wast-parser.h
+++ b/src/wast-parser.h
@@ -131,8 +131,8 @@
   bool ParseTextListOpt(std::vector<uint8_t>* out_data);
   Result ParseVarList(VarVector* out_var_list);
   bool ParseElemExprOpt(ExprList* out_elem_expr);
-  bool ParseElemExprListOpt(ExprListVector* out_list);
-  bool ParseElemExprVarListOpt(ExprListVector* out_list);
+  bool ParseElemExprListOpt(InitExprVector* out_list);
+  bool ParseElemExprVarListOpt(InitExprVector* out_list);
   Result ParseValueType(Var* out_type);
   Result ParseValueTypeList(
       TypeVector* out_type_list,
diff --git a/src/wat-writer.cc b/src/wat-writer.cc
index 531cb5b..1e8d502 100644
--- a/src/wat-writer.cc
+++ b/src/wat-writer.cc
@@ -142,7 +142,7 @@
   template <typename T>
   void WriteMemoryLoadStoreExpr(const Expr* expr);
   void WriteExprList(const ExprList& exprs);
-  void WriteInitExpr(const ExprList& expr);
+  void WriteInitExpr(const InitExpr& expr);
   template <typename T>
   void WriteTypeBindings(const char* prefix,
                          const T& types,
@@ -1263,10 +1263,10 @@
   FlushExprTreeVector(stack_copy);
 }
 
-void WatWriter::WriteInitExpr(const ExprList& expr) {
-  if (!expr.empty()) {
+void WatWriter::WriteInitExpr(const InitExpr& expr) {
+  if (!expr.exprs.empty()) {
     WritePuts("(", NextChar::None);
-    WriteExprList(expr);
+    WriteExprList(expr.exprs);
     /* clear the next char, so we don't write a newline after the expr */
     next_char_ = NextChar::None;
     WritePuts(")", NextChar::Space);
@@ -1448,13 +1448,13 @@
     WritePuts("func", NextChar::Space);
   }
 
-  for (const ExprList& expr : segment.elem_exprs) {
+  for (const InitExpr& init_expr : segment.elem_exprs) {
     if (flags & SegUseElemExprs) {
-      WriteInitExpr(expr);
+      WriteInitExpr(init_expr);
     } else {
-      assert(expr.size() == 1);
-      assert(expr.front().type() == ExprType::RefFunc);
-      WriteVar(cast<const RefFuncExpr>(&expr.front())->var, NextChar::Space);
+      assert(init_expr.exprs.size() == 1);
+      assert(init_expr.exprs.front().type() == ExprType::RefFunc);
+      WriteVar(cast<const RefFuncExpr>(&init_expr.exprs.front())->var, NextChar::Space);
     }
   }
   WriteCloseNewline();