Merge into master from pull request #348:
loci: remove inheritance unions and header classes (https://github.com/floodlight/loxigen/pull/348)
diff --git a/c_gen/build_of_g.py b/c_gen/build_of_g.py
index ff2dfe8..ace386d 100755
--- a/c_gen/build_of_g.py
+++ b/c_gen/build_of_g.py
@@ -202,13 +202,7 @@
if type(m) == OFPadMember:
continue
else:
- # HACK the C backend does not yet support of_oxm_t
- if m.oftype == 'of_oxm_t':
- m_type = 'of_oxm_header_t'
- # HACK the C backend does not yet support of_bsn_vport_t
- elif m.oftype == 'of_bsn_vport_t':
- m_type = 'of_bsn_vport_header_t'
- elif m.oftype.find("list(") == 0:
+ if m.oftype.find("list(") == 0:
(list_name, base_type) = loxi_utils.list_name_extract(m.oftype)
m_type = list_name + "_t"
else:
@@ -248,19 +242,6 @@
Add information computed from the input, including offsets and
lengths of struct members and the set of list and action_id types.
"""
-
- # Generate header classes for inheritance parents
- for wire_version, ordered_classes in of_g.ordered_classes.items():
- classes = versions[of_g.of_version_wire2name[wire_version]]['classes']
- for cls in ordered_classes:
- if type_maps.class_is_inheritance_root(cls):
- new_cls = cls + '_header'
- of_g.ordered_classes[wire_version].append(new_cls)
- classes[new_cls] = classes[cls]
- of_g.base_length[(new_cls, wire_version)] = of_g.base_length[(cls, wire_version)]
- if (cls, wire_version) in of_g.is_fixed_length:
- of_g.is_fixed_length.add((cls, wire_version))
-
# Create lists
for version, protocol in loxi_globals.ir.items():
lists = set()
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index 239034a..968d939 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -753,7 +753,6 @@
* Per-class static delete functions
* Per-class, per-member accessor declarations
* Per-class structure definitions
- * Generic union (inheritance) definitions
* Pointer set function declarations
* Some special case macros
*
@@ -966,38 +965,14 @@
#
################################################################
-def gen_generics(out):
- for (cls, subclasses) in type_maps.inheritance_map.items():
- out.write("""
-/**
- * Inheritance super class for %(cls)s
- *
- * This class is the union of %(cls)s classes. You can refer
- * to it untyped by refering to the member 'header' whose structure
- * is common across all sub-classes.
- */
-
-union %(cls)s_u {
- %(cls)s_header_t header; /* Generic instance */
-""" % dict(cls=cls))
- for subcls in sorted(subclasses):
- instance = loxi_utils.class_to_instance(subcls, cls)
- out.write(" %s_%s_t %s;\n" % (cls, instance, instance))
- out.write("};\n")
-
def gen_struct_typedefs(out):
"""
Generate typedefs for all struct objects
@param out The file for output, already open
"""
- out.write("\n/* LOCI inheritance parent typedefs */\n")
- for cls in type_maps.inheritance_map:
- out.write("typedef union %(cls)s_u %(cls)s_t;\n" % dict(cls=cls))
out.write("\n/* LOCI object typedefs */\n")
for cls in of_g.standard_class_order:
- if type_maps.class_is_inheritance_root(cls):
- continue
template = "typedef of_object_t %(cls)s_t;\n"
out.write(template % dict(cls=cls))
@@ -1036,7 +1011,7 @@
****************************************************************/
""")
for cls in of_g.standard_class_order:
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls) and not loxi_utils.class_is_list(cls):
continue
out.write("\n/* Unified accessor functions for %s */\n" % cls)
for m_name in of_g.ordered_members[cls]:
@@ -1076,13 +1051,13 @@
e_type = loxi_utils.list_to_entry_type(cls)
out.write("""
extern int %(cls)s_first(
- %(cls)s_t *list, of_list_iter_t iter);
+ %(cls)s_t *list, of_object_t *iter);
extern int %(cls)s_next(
- %(cls)s_t *list, of_list_iter_t iter);
+ %(cls)s_t *list, of_object_t *iter);
extern int %(cls)s_append_bind(
- %(cls)s_t *list, of_list_iter_t iter);
+ %(cls)s_t *list, of_object_t *iter);
extern int %(cls)s_append(
- %(cls)s_t *list, of_list_iter_t iter);
+ %(cls)s_t *list, of_object_t *iter);
/**
* Iteration macro for list of type %(cls)s
@@ -1224,7 +1199,7 @@
LOCI_ASSERT(cur_len + abs_offset <= WBUF_CURRENT_BYTES(wbuf));
OF_TRY(of_match_deserialize(ver, %(m_name)s, obj, offset, cur_len));
""" % dict(m_name=m_name))
- elif m_type == "of_oxm_header_t":
+ elif m_type == "of_oxm_t":
out.write("""
/* Initialize child */
%(m_type)s_init(%(m_name)s, obj->version, 0, 1);
@@ -1232,7 +1207,7 @@
of_object_attach(obj, %(m_name)s, offset, cur_len);
of_object_wire_init(%(m_name)s, OF_OXM, 0);
""" % dict(m_type=m_type[:-2], m_name=m_name))
- elif m_type == "of_bsn_vport_header_t":
+ elif m_type == "of_bsn_vport_t":
out.write("""
/* Initialize child */
%(m_type)s_init(%(m_name)s, obj->version, 0, 1);
@@ -1715,8 +1690,6 @@
****************************************************************/
""")
for cls in of_g.standard_class_order:
-# if type_maps.class_is_inheritance_root(cls):
-# continue
out.write("""
/**
* Delete an object of type %(cls)s_t
@@ -1774,8 +1747,8 @@
out.write("/* DOCUMENTATION ONLY */\n")
for cls in of_g.standard_class_order:
- if type_maps.class_is_inheritance_root(cls):
- pass # Check this
+ if type_maps.class_is_virtual(cls):
+ pass
out.write("""
/**
diff --git a/c_gen/c_dump_gen.py b/c_gen/c_dump_gen.py
index a9074af..799dc09 100644
--- a/c_gen/c_dump_gen.py
+++ b/c_gen/c_dump_gen.py
@@ -90,7 +90,7 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
out.write("""\
int %(cls)s_%(ver_name)s_dump(loci_writer_f writer, void* cookie, of_object_t *obj);
@@ -129,7 +129,7 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
out.write("""
int
@@ -184,7 +184,7 @@
sub_cls = m_type[:-2] # Trim _t
out.write("""
%(cls)s_%(m_name)s_bind(obj, &%(v_name)s);
- out += %(sub_cls)s_%(ver_name)s_dump(writer, cookie, &%(v_name)s);
+ out += of_object_dump(writer, cookie, &%(v_name)s);
""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name,
v_name=var_name_map(m_type), ver_name=ver_name))
@@ -234,7 +234,7 @@
comma = ","
if (not loxi_utils.class_in_version(cls, version) or
- type_maps.class_is_inheritance_root(cls)):
+ type_maps.class_is_virtual(cls)):
out.write(" unknown_dump%s\n" % comma);
else:
out.write(" %s_%s_dump%s\n" %
diff --git a/c_gen/c_show_gen.py b/c_gen/c_show_gen.py
index a6ce048..d1cbbdb 100644
--- a/c_gen/c_show_gen.py
+++ b/c_gen/c_show_gen.py
@@ -89,7 +89,6 @@
('uint64_t', 'generation_id'),
('uint16_t', 'value_mask'),
('uint32_t', 'value_mask'),
- ('uint32_t', 'oxm_header'),
('uint8_t', 'value_mask'),
('uint64_t', 'value_mask'),
('uint64_t', 'write_setfields'),
@@ -164,7 +163,7 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
out.write("""\
int %(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, of_object_t *obj);
@@ -203,7 +202,7 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
out.write("""
int
@@ -255,7 +254,7 @@
sub_cls = m_type[:-2] # Trim _t
out.write("""
%(cls)s_%(m_name)s_bind(obj, &%(v_name)s);
- out += %(sub_cls)s_%(ver_name)s_show(writer, cookie, &%(v_name)s);
+ out += of_object_show(writer, cookie, &%(v_name)s);
""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name,
v_name=var_name_map(m_type), ver_name=ver_name))
@@ -303,7 +302,7 @@
comma = ","
if (not loxi_utils.class_in_version(cls, version) or
- type_maps.class_is_inheritance_root(cls)):
+ type_maps.class_is_virtual(cls)):
out.write(" unknown_show%s\n" % comma);
else:
out.write(" %s_%s_show%s\n" %
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 5ddd4e9..109ab9b 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -99,8 +99,8 @@
of_octets_t="octets",
of_meter_features_t="features",
of_match_t="match",
- of_oxm_header_t="oxm",
- of_bsn_vport_header_t="bsn_vport",
+ of_oxm_t="oxm",
+ of_bsn_vport_t="bsn_vport",
of_table_desc_t="table_desc",
# BSN extensions
of_bsn_vport_q_in_q_t="vport",
@@ -128,8 +128,8 @@
# When embedding an object inside of another object we have to pick a single
# subclass to use, unlike lists where we use all subclasses.
embedded_subclasses = {
- 'of_oxm_header_t': 'of_oxm_eth_type',
- 'of_bsn_vport_header_t': 'of_bsn_vport_q_in_q',
+ 'of_oxm_t': 'of_oxm_eth_type',
+ 'of_bsn_vport_t': 'of_bsn_vport_q_in_q',
}
def ignore_member(cls, version, m_name, m_type):
@@ -380,7 +380,7 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls) and not loxi_utils.class_is_list(cls):
continue
out.write("""
extern int %(cls)s_%(v_name)s_populate(
@@ -515,7 +515,7 @@
*/
""" % v_name)
for cls in of_g.standard_class_order:
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
if version in of_g.unified[cls]:
message_scalar_test(out, version, cls)
@@ -528,7 +528,7 @@
for version in of_g.of_version_range:
v_name = loxi_utils.version_to_name(version)
for cls in of_g.standard_class_order:
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
if version in of_g.unified[cls]:
test_name = "%s_%s" % (cls, v_name)
@@ -701,7 +701,7 @@
"""
for version in of_g.of_version_range:
for cls in of_g.standard_class_order:
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
(members, member_types) = scalar_member_types_get(cls, version)
scalar_funs_instance(out, cls, version, members, member_types)
@@ -1588,11 +1588,9 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
- continue
elif loxi_utils.class_is_list(cls):
gen_list_setup_check(out, cls, version)
- else:
+ elif not type_maps.class_is_virtual(cls):
gen_class_setup_check(out, cls, version)
def gen_unified_accessor_tests(out, name):
@@ -1611,7 +1609,7 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
unified_accessor_test_case(out, cls, version)
@@ -1625,7 +1623,7 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
test_name = "%s_%s" % (cls, v_name)
out.write(" RUN_TEST(%s);\n" % test_name)
@@ -1708,6 +1706,8 @@
sub_classes = type_maps.sub_class_map(cls, version)
for (_, sub_cls) in sub_classes:
sub_enum = sub_cls.upper()
+ if type_maps.class_is_virtual(sub_cls):
+ continue
out.write("""
if (src->object_id == %(sub_enum)s) {
return %(sub_cls)s_%(ver_name)s_dup(src);
@@ -1841,7 +1841,7 @@
gen_dup_inheritance(out, cls, version)
elif loxi_utils.class_is_list(cls):
gen_dup_list(out, cls, version)
- else:
+ elif not type_maps.class_is_virtual(cls):
gen_dup_cls(out, cls, version)
def gen_dup(out=sys.stdout):
@@ -1859,7 +1859,12 @@
for version in of_g.of_version_range:
if not loxi_utils.class_in_version(cls, version):
continue
-
+ elif type_maps.class_is_inheritance_root(cls):
+ pass
+ elif loxi_utils.class_is_list(cls):
+ pass
+ elif type_maps.class_is_virtual(cls):
+ continue
ver_name = loxi_utils.version_to_name(version)
out.write("""
if (src->version == %(ver_name)s) {
@@ -1928,6 +1933,12 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
+ elif type_maps.class_is_inheritance_root(cls):
+ pass
+ elif loxi_utils.class_is_list(cls):
+ pass
+ elif type_maps.class_is_virtual(cls):
+ continue
ver_name = loxi_utils.version_to_name(version)
out.write("""
extern of_object_t *
@@ -1962,7 +1973,7 @@
for j, cls in enumerate(of_g.all_class_order):
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
if cls == "of_bsn_virtual_port_create_request": # test q_in_q
out.write("""
diff --git a/c_gen/codegen.py b/c_gen/codegen.py
index f480453..f052950 100644
--- a/c_gen/codegen.py
+++ b/c_gen/codegen.py
@@ -121,26 +121,12 @@
c_code_gen.gen_new_function_definitions(out, uclass.name)
c_code_gen.gen_accessor_definitions(out, uclass.name)
-# TODO remove header classes and use the corresponding class instead
-def generate_header_classes(install_dir):
- for cls in of_g.standard_class_order:
- if not cls.endswith("_header") or cls in ["of_header", "of_bsn_header", "of_nicira_header"]:
- continue
- with template_utils.open_output(install_dir, "loci/src/%s.c" % cls) as out:
- util.render_template(out, "class.c",
- push_wire_types_data=None,
- parse_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)
-
def generate_classes_header(install_dir):
# Collect legacy code
tmp = StringIO()
c_code_gen.gen_struct_typedefs(tmp)
c_code_gen.gen_new_function_declarations(tmp)
c_code_gen.gen_accessor_declarations(tmp)
- c_code_gen.gen_generics(tmp)
with template_utils.open_output(install_dir, "loci/inc/loci/loci_classes.h") as out:
util.render_template(out, "loci_classes.h",
@@ -240,16 +226,6 @@
wire_type_get=wire_type_get,
wire_type_set=wire_type_set))
- # If this is the root of an inheritance hierachy, add metadata
- # for the corresponding header class
- if uclass.name in type_maps.inheritance_map:
- class_metadata.append(ClassMetadata(
- name=uclass.name + '_header',
- wire_length_get=wire_length_get,
- wire_length_set=wire_length_set,
- wire_type_get=wire_type_get,
- wire_type_set=wire_type_set))
-
for metadata in class_metadata:
class_metadata_dict[metadata.name] = metadata
diff --git a/c_gen/match.py b/c_gen/match.py
index d6b43fa..c6459d4 100644
--- a/c_gen/match.py
+++ b/c_gen/match.py
@@ -197,8 +197,7 @@
# Generate list of OXM names from the unified classes
oxm_names = [x[7:] for x in of_g.unified.keys() if
x.startswith('of_oxm_') and
- x.find('masked') < 0 and
- x.find('header') < 0]
+ x.find('masked') < 0]
# Check that all OXMs are in the match members
for key in oxm_names:
diff --git a/c_gen/templates/list.c b/c_gen/templates/list.c
index d39af9a..5eb45c6 100644
--- a/c_gen/templates/list.c
+++ b/c_gen/templates/list.c
@@ -42,10 +42,9 @@
*/
int
-${cls}_first(${cls}_t *list, of_list_iter_t iter)
+${cls}_first(${cls}_t *list, of_object_t *obj)
{
int rv;
- of_object_t *obj = iter.obj;
${e_cls}_init(obj, list->version, -1, 1);
@@ -73,10 +72,9 @@
*/
int
-${cls}_next(${cls}_t *list, of_list_iter_t iter)
+${cls}_next(${cls}_t *list, of_object_t *obj)
{
int rv;
- of_object_t *obj = iter.obj;
if ((rv = of_list_next(list, obj)) < 0) {
return rv;
@@ -105,9 +103,9 @@
*/
int
-${cls}_append_bind(${cls}_t *list, of_list_iter_t iter)
+${cls}_append_bind(${cls}_t *list, of_object_t *obj)
{
- return of_list_append_bind(list, iter.obj);
+ return of_list_append_bind(list, obj);
}
/**
@@ -119,7 +117,7 @@
*/
int
-${cls}_append(${cls}_t *list, of_list_iter_t iter)
+${cls}_append(${cls}_t *list, of_object_t *obj)
{
- return of_list_append(list, iter.obj);
+ return of_list_append(list, obj);
}
diff --git a/c_gen/templates/loci_classes.h b/c_gen/templates/loci_classes.h
index 86fe36b..c5147cb 100644
--- a/c_gen/templates/loci_classes.h
+++ b/c_gen/templates/loci_classes.h
@@ -36,22 +36,6 @@
void ${uclass.name}_push_wire_types(of_object_t *obj);
:: #endfor
-/*
- * Transparent union used for list iteration
- *
- * This will be removed when all callers are converted to of_object_t.
- */
-union of_list_iter_u {
- of_object_t *obj;
-:: for uclass in loxi_globals.unified.classes:
-:: if uclass.virtual and not uclass.superclass:
- union ${uclass.name}_u *${uclass.name};
-:: #endif
-:: #endfor
-} __attribute__ ((__transparent_union__));
-
-typedef union of_list_iter_u of_list_iter_t;
-
${legacy_code}
#endif
diff --git a/c_gen/type_maps.py b/c_gen/type_maps.py
index 3544d80..607814c 100644
--- a/c_gen/type_maps.py
+++ b/c_gen/type_maps.py
@@ -36,8 +36,6 @@
"""
Returns True if cls is a virtual class
"""
- if cls.endswith("header"):
- return True
if loxi_utils.class_is_list(cls):
return True
return loxi_globals.unified.class_by_name(cls).virtual
@@ -46,6 +44,10 @@
return cls in inheritance_map
def generate_maps():
+ for ofclass in loxi_globals.unified.classes:
+ if ofclass.virtual and not ofclass.superclass:
+ inheritance_map[ofclass.name] = set()
+
for version, protocol in loxi_globals.ir.items():
wire_version = version.wire_version
for ofclass in protocol.classes:
@@ -53,8 +55,6 @@
if not root or root == ofclass or root.name == "of_header":
continue
- if root.name not in inheritance_map:
- inheritance_map[root.name] = set()
inheritance_map[root.name].add(ofclass.name)
def sub_class_map(base_type, version):
diff --git a/lang_c.py b/lang_c.py
index c7b68f7..bec4a65 100644
--- a/lang_c.py
+++ b/lang_c.py
@@ -125,7 +125,6 @@
fn(outfile, os.path.basename(name))
c_gen.codegen.build_class_metadata()
c_gen.codegen.generate_classes(install_dir)
- c_gen.codegen.generate_header_classes(install_dir)
c_gen.codegen.generate_classes_header(install_dir)
c_gen.codegen.generate_lists(install_dir)
c_gen.codegen.generate_strings(install_dir)