loci: use IR to push wire types

The old code is disabled but not yet deleted.

The generated code looks like:

```
void
of_bsn_lacp_stats_reply_push_wire_types(of_object_t *obj)
{
    unsigned char *buf = loci_object_to_buffer(obj);
    switch (obj->version) {
    case OF_VERSION_1_3:
        *(uint8_t *)(buf + 0) = obj->version; /* version */
        *(uint8_t *)(buf + 1) = 19; /* type */
        *(uint16_t *)(buf + 8) = htobe16(65535); /* stats_type */
        *(uint32_t *)(buf + 16) = htobe32(6035143); /* experimenter */
        *(uint32_t *)(buf + 20) = htobe32(1); /* subtype */
        break;
    default:
        UNREACHABLE();
    }
}
```
diff --git a/c_gen/codegen.py b/c_gen/codegen.py
new file mode 100644
index 0000000..0d7832a
--- /dev/null
+++ b/c_gen/codegen.py
@@ -0,0 +1,79 @@
+# 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.
+
+"""
+Code generation
+
+These functions extract data from the IR and render templates with it.
+"""
+
+from collections import namedtuple
+from itertools import groupby
+import template_utils
+import loxi_globals
+import loxi_ir.ir as ir
+import util
+
+PushWireTypesFn = namedtuple('PushWireTypesFn',
+    ['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
+
+        # 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)))
+
+        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)