+ fun as_line_pragma: String do return "#line {line_start-1} \"{file.filename}\"\n"
+end
+
+redef class MModule
+ var c_compiler_options = "" is writable
+ var c_linker_options = "" is writable
+
+ # Additional libraries needed for the compilation
+ # Will be used with pkg-config
+ var pkgconfigs = new Array[String]
+end
+
+class ForeignCType
+ super ForeignType
+
+ redef var ctype: String
+end
+
+redef class NitniCallback
+ fun compile_callback_to_c(mmodule: MModule, ffi_ccu: CCompilationUnit) do end
+end
+
+redef class Object
+ # Context when calling user C code from generated code
+ fun to_c_call_context: ToCCallContext do return once new ToCCallContext
+
+ # Context when calling generated code from user C code
+ fun from_c_call_context: FromCCallContext do return once new FromCCallContext
+end
+
+redef class MExplicitCall
+ redef fun compile_callback_to_c(mmodule, ffi_ccu)
+ do
+ var mproperty = mproperty.as(MMethod)
+
+ var full_cname = mproperty.build_cname(recv_mtype, mmodule, null, long_signature)
+ var friendly_cname = mproperty.build_cname(recv_mtype, mmodule, null, short_signature)
+ ffi_ccu.body_decl.add("#define {friendly_cname} {full_cname}\n")
+ end
+end
+
+# Context when calling user C code from generated code
+class ToCCallContext
+ super CallContext
+
+ # TODO: private init because singleton instance (see `to_c_call_context`)
+
+ redef fun name_mtype(mtype)
+ do
+ if mtype isa MClassType and mtype.mclass.kind == extern_kind then return "void *"
+ return mtype.cname
+ end
+end
+
+# Context when calling generated code from user C code
+class FromCCallContext
+ super CallContext
+
+ # TODO: private init because singleton instance (see `from_c_call_context`)
+
+ redef fun name_mtype(mtype) do return mtype.cname
+end
+
+class ExternCFunction
+ super CFunction
+
+ var method: AMethPropdef
+
+ init (method: AMethPropdef, mmodule: MModule)