+
+ end
+
+ protected fun build_class_compilation_info(mclass: MClass): ClassCompilationInfo
+ do
+ var mtype = mclass.intro.bound_mtype
+ var rta = runtime_type_analysis
+ var is_dead = rta != null and not rta.live_classes.has(mclass)
+
+ # While the class may be dead, some part of separately compiled code may use symbols associated to the class, so
+ # in order to compile and link correctly the C code, these symbols should be declared and defined.
+ var need_corpse = is_dead and mtype.is_c_primitive or mclass.kind == extern_kind or mclass.kind == enum_kind
+
+ var compilation_info = new ClassCompilationInfo(mclass, is_dead, need_corpse)
+ return compilation_info
+ end
+
+ # Globally compile the table of the class mclass
+ # In a link-time optimisation compiler, tables are globally computed
+ # In a true separate compiler (a with dynamic loading) you cannot do this unfortnally
+ fun compile_class_to_c(mclass: MClass)
+ do
+ var v = new_visitor
+ var class_info = build_class_compilation_info(mclass)
+ compile_class_vft(class_info, v)
+ var is_already_managed = compile_class_if_universal(class_info, v)
+ if not is_already_managed then
+ compile_default_new(class_info, v)
+ end
+ end
+
+ # Compile structures used to map tagged primitive values to their classes and types.
+ # This method also determines which class will be tagged.
+ fun compile_class_infos
+ do
+ if modelbuilder.toolcontext.opt_no_tag_primitives.value then return
+
+ # Note: if you change the tagging scheme, do not forget to update
+ # `autobox` and `extract_tag`
+ var class_info = new Array[nullable MClass].filled_with(null, 4)
+ for t in box_kinds.keys do
+ # Note: a same class can be associated to multiple slots if one want to
+ # use some Huffman coding.
+ if t.name == "Int" then
+ class_info[1] = t
+ t.mclass_type.tag_value = 1
+ else if t.name == "Char" then
+ class_info[2] = t
+ t.mclass_type.tag_value = 2
+ else if t.name == "Bool" then
+ class_info[3] = t
+ t.mclass_type.tag_value = 3
+ else
+ continue
+ end
+ t.mclass_type.is_tagged = true
+ end
+
+ # Compile the table for classes. The tag is used as an index
+ var v = self.new_visitor
+ v.add_decl "const struct class *class_info[4] = \{"
+ for t in class_info do
+ if t == null then
+ v.add_decl("NULL,")
+ else
+ var s = "class_{t.c_name}"
+ v.require_declaration(s)
+ v.add_decl("&{s},")
+ end
+ end
+ v.add_decl("\};")
+
+ # Compile the table for types. The tag is used as an index
+ v.add_decl "const struct type *type_info[4] = \{"
+ for t in class_info do
+ if t == null then
+ v.add_decl("NULL,")
+ else
+ var s = "type_{t.c_name}"
+ undead_types.add(t.mclass_type)
+ v.require_declaration(s)
+ v.add_decl("&{s},")
+ end
+ end
+ v.add_decl("\};")