Declare C structures and identifiers for a runtime class

Property definitions

nitc $ GlobalCompiler :: declare_runtimeclass
	# Declare C structures and identifiers for a runtime class
	fun declare_runtimeclass(mtype: MClassType)
	do
		var v = self.header
		assert self.runtime_type_analysis.live_types.has(mtype)
		v.add_decl("/* runtime class {mtype} */")
		var idnum = classids.length
		var idname = "ID_" + mtype.c_name
		self.classids[mtype] = idname
		v.add_decl("#define {idname} {idnum} /* {mtype} */")

		v.add_decl("struct {mtype.c_name} \{")
		v.add_decl("int classid; /* must be {idname} */")

		if mtype.mclass.name == "NativeArray" then
			# NativeArrays are just a instance header followed by an array of values
			v.add_decl("int length;")
			v.add_decl("{mtype.arguments.first.ctype} values[1];")
		end

                if all_routine_types_name.has(mtype.mclass.name) then
                        v.add_decl("val* recv;")
                        var c_args = ["val* self"]
                        var c_ret = "void"
                        var k = mtype.arguments.length
                        if mtype.mclass.name.has("Fun") then
                                c_ret = mtype.arguments.last.ctype
                                k -= 1
                        end
                        for i in [0..k[ do
                                var t = mtype.arguments[i]
                                c_args.push("{t.ctype} p{i}")
                        end
                        var c_sig = c_args.join(", ")
                        v.add_decl("{c_ret} (*method)({c_sig});")
                end

		if mtype.ctype_extern != "val*" then
			# Is the Nit type is native then the struct is a box with two fields:
			# * the `classid` to be polymorph
			# * the `value` that contains the native value.
			v.add_decl("{mtype.ctype_extern} value;")
		end

		# Collect all attributes and associate them a field in the structure.
		# Note: we do not try to optimize the order and helps CC to optimize the client code.
		for cd in mtype.collect_mclassdefs(self.mainmodule) do
			for p in cd.intro_mproperties do
				if not p isa MAttribute then continue
				var t = p.intro.static_mtype.as(not null)
				t = t.anchor_to(self.mainmodule, mtype)
				v.add_decl("{t.ctype} {p.intro.c_name}; /* {p}: {t} */")
			end
		end
		v.add_decl("\};")
	end
src/compiler/global_compiler.nit:187,2--242,4