+ # Force the creation of a new file
+ # The point is to avoid contamination between must-be-compiled-separately files
+ fun new_file
+ do
+ var v = self.new_visitor
+ v.file_break = true
+ end
+
+ fun compile_header do
+ var v = self.header
+ self.header.add_decl("#include <stdlib.h>")
+ self.header.add_decl("#include <stdio.h>")
+ self.header.add_decl("#include <string.h>")
+ self.header.add_decl("#ifndef NOBOEHM")
+ self.header.add_decl("#include <gc/gc.h>")
+ self.header.add_decl("#ifdef NOBOEHM_ATOMIC")
+ self.header.add_decl("#undef GC_MALLOC_ATOMIC")
+ self.header.add_decl("#define GC_MALLOC_ATOMIC(x) GC_MALLOC(x)")
+ self.header.add_decl("#endif /*NOBOEHM_ATOMIC*/")
+ self.header.add_decl("#else /*NOBOEHM*/")
+ self.header.add_decl("#define GC_MALLOC(x) calloc(1, (x))")
+ self.header.add_decl("#define GC_MALLOC_ATOMIC(x) calloc(1, (x))")
+ self.header.add_decl("#endif /*NOBOEHM*/")
+
+ compile_header_structs
+
+ # Global variable used by the legacy native interface
+ self.header.add_decl("extern int glob_argc;")
+ self.header.add_decl("extern char **glob_argv;")
+ self.header.add_decl("extern val *glob_sys;")
+ end
+
+ # Class names (for the class_name and output_class_name methods)
+ protected fun compile_class_names do
+ self.header.add_decl("extern const char const * class_names[];")
+ self.header.add("const char const * class_names[] = \{")
+ for t in self.runtime_type_analysis.live_types do
+ self.header.add("\"{t}\", /* {self.classid(t)} */")
+ end
+ self.header.add("\};")
+ end
+
+ # Declaration of structures the live Nit types
+ # Each live type is generated as an independent C `struct' type.
+ # They only share a common first field `classid` used to implement the polymorphism.
+ # Usualy, all C variables that refers to a Nit object are typed on the abstract struct `val' that contains only the `classid` field.
+ protected fun compile_header_structs do
+ self.header.add_decl("typedef struct \{int classid;\} val; /* general C type representing a Nit instance. */")
+ end
+