loci: move push_wire_types functions to their class's C file
diff --git a/c_gen/codegen.py b/c_gen/codegen.py
index 67c0904..158d9ce 100644
--- a/c_gen/codegen.py
+++ b/c_gen/codegen.py
@@ -41,50 +41,43 @@
 import c_gen.of_g_legacy as of_g
 import c_gen.type_maps as type_maps
 
-PushWireTypesFn = namedtuple('PushWireTypesFn',
+PushWireTypesData = namedtuple('PushWireTypesData',
     ['class_name', 'versioned_type_members'])
 PushWireTypesMember = namedtuple('PushWireTypesMember',
     ['name', 'offset', 'length', 'value'])
 
-def gen_push_wire_types(install_dir):
-    fns = []
-    for uclass in loxi_globals.unified.classes:
-        if uclass.virtual or not uclass.has_type_members:
-            continue
+def push_wire_types_data(uclass):
+    if uclass.virtual or not uclass.has_type_members:
+        return None
 
-        # Generate a dict of version -> list of PushWireTypesMember
-        type_members_by_version = {}
-        for version, ofclass in sorted(uclass.version_classes.items()):
-            pwtms = []
-            for m in ofclass.members:
-                if isinstance(m, ir.OFTypeMember):
-                    if m.name == "version" and m.value == version.wire_version:
-                        # Special case for version
-                        pwtms.append(PushWireTypesMember(m.name, m.offset, m.length, "obj->version"))
-                    else:
-                        pwtms.append(PushWireTypesMember(m.name, m.offset, m.length, m.value))
-            type_members_by_version[version] = pwtms
+    # Generate a dict of version -> list of PushWireTypesMember
+    type_members_by_version = {}
+    for version, ofclass in sorted(uclass.version_classes.items()):
+        pwtms = []
+        for m in ofclass.members:
+            if isinstance(m, ir.OFTypeMember):
+                if m.name == "version" and m.value == version.wire_version:
+                    # Special case for version
+                    pwtms.append(PushWireTypesMember(m.name, m.offset, m.length, "obj->version"))
+                else:
+                    pwtms.append(PushWireTypesMember(m.name, m.offset, m.length, m.value))
+        type_members_by_version[version] = pwtms
 
-        # Merge versions with identical type members
-        all_versions = sorted(type_members_by_version.keys())
-        versioned_type_members = []
-        for pwtms, versions in groupby(all_versions, type_members_by_version.get):
-            versioned_type_members.append((pwtms, list(versions)))
+    # Merge versions with identical type members
+    all_versions = sorted(type_members_by_version.keys())
+    versioned_type_members = []
+    for pwtms, versions in groupby(all_versions, type_members_by_version.get):
+        versioned_type_members.append((pwtms, list(versions)))
 
-        fns.append(PushWireTypesFn(
-            class_name=uclass.name,
-            versioned_type_members=versioned_type_members))
-
-    with template_utils.open_output(install_dir, "loci/src/loci_push_wire_types.c") as out:
-        util.render_template(out, "loci_push_wire_types.c", fns=fns)
-
-    with template_utils.open_output(install_dir, "loci/src/loci_push_wire_types.h") as out:
-        util.render_template(out, "loci_push_wire_types.h", fns=fns)
+    return PushWireTypesData(
+        class_name=uclass.name,
+        versioned_type_members=versioned_type_members)
 
 def generate_classes(install_dir):
     for uclass in loxi_globals.unified.classes:
         with template_utils.open_output(install_dir, "loci/src/%s.c" % uclass.name) as out:
-            util.render_template(out, "class.c")
+            util.render_template(out, "class.c",
+                push_wire_types_data=push_wire_types_data(uclass))
             # Append legacy generated code
             c_code_gen.gen_new_function_definitions(out, uclass.name)
             c_code_gen.gen_accessor_definitions(out, uclass.name)
@@ -95,7 +88,8 @@
         if cls.find("_header") < 0:
             continue
         with template_utils.open_output(install_dir, "loci/src/%s.c" % cls) as out:
-            util.render_template(out, "class.c")
+            util.render_template(out, "class.c",
+                push_wire_types_data=None)
             # Append legacy generated code
             c_code_gen.gen_new_function_definitions(out, cls)
             c_code_gen.gen_accessor_definitions(out, cls)
@@ -103,7 +97,8 @@
 def generate_lists(install_dir):
     for cls in of_g.ordered_list_objects:
         with template_utils.open_output(install_dir, "loci/src/%s.c" % cls) as out:
-            util.render_template(out, "class.c")
+            util.render_template(out, "class.c",
+                push_wire_types_data=None)
             # Append legacy generated code
             c_code_gen.gen_new_function_definitions(out, cls)
             c_code_gen.gen_list_accessors(out, cls)
diff --git a/c_gen/templates/loci_push_wire_types.c b/c_gen/templates/_push_wire_types.c
similarity index 71%
rename from c_gen/templates/loci_push_wire_types.c
rename to c_gen/templates/_push_wire_types.c
index 2103aad..b7b6288 100644
--- a/c_gen/templates/loci_push_wire_types.c
+++ b/c_gen/templates/_push_wire_types.c
@@ -25,41 +25,12 @@
 :: # EPL for the specific language governing permissions and limitations
 :: # under the EPL.
 ::
-:: include('_copyright.c')
-
-/****************************************************************
- *
- * Functions for each concrete class that set the type fields
- *
- ****************************************************************/
-
-#include <loci/loci.h>
-#include <loci/of_message.h>
-#include <endian.h>
-
-#ifdef __GNUC__
-#define UNREACHABLE() __builtin_unreachable()
-#else
-#define UNREACHABLE()
-#endif
-
-/*
- * In a separate function to give the compiler the choice of whether to inline.
- */
-static unsigned char *
-loci_object_to_buffer(of_object_t *obj)
+static void
+${data.class_name}_push_wire_types(of_object_t *obj)
 {
-    return OF_OBJECT_BUFFER_INDEX(obj, 0);
-}
-
-:: for fn in fns:
-
-void
-${fn.class_name}_push_wire_types(of_object_t *obj)
-{
-    unsigned char *buf = loci_object_to_buffer(obj);
+    unsigned char *buf = OF_OBJECT_BUFFER_INDEX(obj, 0);
     switch (obj->version) {
-:: for ms, versions in fn.versioned_type_members:
+:: for ms, versions in data.versioned_type_members:
 :: for version in versions:
     case ${version.constant_version(prefix='OF_VERSION_')}:
 :: #endfor
@@ -80,4 +51,3 @@
         UNREACHABLE();
     }
 }
-:: #endfor
diff --git a/c_gen/templates/class.c b/c_gen/templates/class.c
index 170cf54..044e03e 100644
--- a/c_gen/templates/class.c
+++ b/c_gen/templates/class.c
@@ -29,5 +29,9 @@
 :: include('_pragmas.c')
 
 #include "loci_log.h"
-#include "loci_push_wire_types.h"
 #include "loci_int.h"
+
+:: if push_wire_types_data:
+:: include("_push_wire_types.c", data=push_wire_types_data)
+
+:: #endif
diff --git a/c_gen/templates/loci_int.h b/c_gen/templates/loci_int.h
index b4df78c..241cf7b 100644
--- a/c_gen/templates/loci_int.h
+++ b/c_gen/templates/loci_int.h
@@ -46,6 +46,12 @@
 
 #include <loci/loci.h>
 
+#ifdef __GNUC__
+#define UNREACHABLE() __builtin_unreachable()
+#else
+#define UNREACHABLE()
+#endif
+
 /****************************************************************
  * Special case macros for calculating variable lengths and offsets
  ****************************************************************/
diff --git a/c_gen/templates/loci_push_wire_types.h b/c_gen/templates/loci_push_wire_types.h
deleted file mode 100644
index 5b2c1e8..0000000
--- a/c_gen/templates/loci_push_wire_types.h
+++ /dev/null
@@ -1,40 +0,0 @@
-:: # Copyright 2013, Big Switch Networks, Inc.
-:: #
-:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
-:: # the following special exception:
-:: #
-:: # LOXI Exception
-:: #
-:: # As a special exception to the terms of the EPL, you may distribute libraries
-:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
-:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
-:: # from the LoxiGen Libraries and the notice provided below is (i) included in
-:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
-:: # documentation for the LoxiGen Libraries, if distributed in binary form.
-:: #
-:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
-:: #
-:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
-:: # a copy of the EPL at:
-:: #
-:: # http://www.eclipse.org/legal/epl-v10.html
-:: #
-:: # Unless required by applicable law or agreed to in writing, software
-:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-:: # EPL for the specific language governing permissions and limitations
-:: # under the EPL.
-::
-:: include('_copyright.c')
-#ifndef LOCI_PUSH_WIRE_TYPES_H
-#define LOCI_PUSH_WIRE_TYPES_H
-
-#include <loci/loci.h>
-
-/* Declarations of public functions from loci_push_wire_types.c */
-
-:: for fn in fns:
-void ${fn.class_name}_push_wire_types(of_object_t *obj);
-:: #endfor
-
-#endif
diff --git a/lang_c.py b/lang_c.py
index d550b84..fbb3b9b 100644
--- a/lang_c.py
+++ b/lang_c.py
@@ -174,7 +174,6 @@
     for (name, fn) in targets.items():
         with template_utils.open_output(install_dir, name) as outfile:
             fn(outfile, os.path.basename(name))
-    c_gen.codegen.gen_push_wire_types(install_dir)
     c_gen.codegen.generate_classes(install_dir)
     c_gen.codegen.generate_header_classes(install_dir)
     c_gen.codegen.generate_lists(install_dir)