import auto_super_init
import frontend
import common_ffi
+import platform
# Add compiling options
redef class ToolContext
# Simple indirection to `Toolchain::write_and_make`
protected fun write_and_make(compiler: AbstractCompiler)
do
- var toolchain = new MakefileToolchain(toolcontext)
+ var platform = compiler.mainmodule.target_platform
+ var toolchain
+ if platform == null then
+ toolchain = new MakefileToolchain(toolcontext)
+ else
+ toolchain = platform.toolchain(toolcontext)
+ end
compile_dir = toolchain.compile_dir
toolchain.write_and_make compiler
end
end
-class MakefileToolchain
- # The list of directories to search for included C headers (-I for C compilers)
- # The list is initially set with :
- # * the toolcontext --cc-path option
- # * the NIT_CC_PATH environment variable
- # * some heuristics including the NIT_DIR environment variable and the progname of the process
- # Path can be added (or removed) by the client
- var cc_paths = new Array[String]
+redef class Platform
+ fun toolchain(toolcontext: ToolContext): Toolchain is abstract
+end
+
+class Toolchain
var toolcontext: ToolContext
fun compile_dir: String
return compile_dir
end
+ fun write_and_make(compiler: AbstractCompiler) is abstract
+end
+
+class MakefileToolchain
+ super Toolchain
+ # The list of directories to search for included C headers (-I for C compilers)
+ # The list is initially set with :
+ # * the toolcontext --cc-path option
+ # * the NIT_CC_PATH environment variable
+ # * some heuristics including the NIT_DIR environment variable and the progname of the process
+ # Path can be added (or removed) by the client
+ var cc_paths = new Array[String]
+
protected fun gather_cc_paths
do
# Look for the the Nit clib path
end
end
- fun write_and_make(compiler: AbstractCompiler)
+ redef fun write_and_make(compiler)
do
gather_cc_paths
hfile.write "#include \"{hfilename}\"\n"
for key in f.required_declarations do
if not compiler.provided_declarations.has_key(key) then
- print "No provided declaration for {key}"
+ var node = compiler.requirers_of_declarations.get_or_null(key)
+ if node != null then
+ node.debug "No provided declaration for {key}"
+ else
+ print "No provided declaration for {key}"
+ end
abort
end
hfile.write compiler.provided_declarations[key]
var o = f.makefile_rule_name
var ff = f.filename.basename("")
makefile.write("{o}: {ff}\n")
- makefile.write("\t{f.makefile_rule_content}\n")
+ makefile.write("\t{f.makefile_rule_content}\n\n")
dep_rules.add(f.makefile_rule_name)
if f isa ExternCppFile then ofiles.add(o)
end
# Link edition
- makefile.write("{outpath}: {ofiles.join(" ")}\n\t$(CC) $(LDFLAGS) -o {outpath} {ofiles.join(" ")} $(LDLIBS)\n\n")
+ makefile.write("{outpath}: {dep_rules.join(" ")}\n\t$(CC) $(LDFLAGS) -o {outpath} {ofiles.join(" ")} $(LDLIBS)\n\n")
# Clean
makefile.write("clean:\n\trm {ofiles.join(" ")} 2>/dev/null\n\n")
makefile.close
private var provided_declarations = new HashMap[String, String]
+ private var requirers_of_declarations = new HashMap[String, ANode]
+
# Builds the .c and .h files to be used when generating a Stack Trace
# Binds the generated C function names to Nit function names
fun build_c_to_nit_bindings
v.add("signal(SIGINT, sig_handler);")
v.add("signal(SIGTERM, sig_handler);")
v.add("signal(SIGSEGV, sig_handler);")
+ v.add("signal(SIGPIPE, sig_handler);")
v.add("glob_argc = argc; glob_argv = argv;")
v.add("initialize_gc_option();")
nmodule.finalize_ffi(visitor, modelbuilder)
nmodule.finalize_nitni(visitor)
end
-
- # Does this compiler support the FFI?
- fun supports_ffi: Bool do return false
end
# A file unit (may be more than one file if
# Request the presence of a global declaration
fun require_declaration(key: String)
do
- self.writer.file.required_declarations.add(key)
+ var reqs = self.writer.file.required_declarations
+ if reqs.has(key) then return
+ reqs.add(key)
+ var node = current_node
+ if node != null then compiler.requirers_of_declarations[key] = node
end
# Add a declaration in the local-header
var args = [arguments.first]
for auto_super_init in auto_super_inits do
args.clear
- for i in [0..auto_super_init.intro.msignature.arity+1[ do
+ for i in [0..auto_super_init.msignature.arity+1[ do
args.add(arguments[i])
end
- v.send(auto_super_init, args)
+ v.compile_callsite(auto_super_init, args)
end
end
v.stmt(self.n_block)
var cl = v.expr(self.n_expr, null)
var it_meth = self.method_iterator
assert it_meth != null
- var it = v.send(it_meth, [cl])
+ var it = v.compile_callsite(it_meth, [cl])
assert it != null
v.add("for(;;) \{")
var isok_meth = self.method_is_ok
assert isok_meth != null
- var ok = v.send(isok_meth, [it])
+ var ok = v.compile_callsite(isok_meth, [it])
assert ok != null
v.add("if(!{ok}) break;")
if self.variables.length == 1 then
var item_meth = self.method_item
assert item_meth != null
- var i = v.send(item_meth, [it])
+ var i = v.compile_callsite(item_meth, [it])
assert i != null
v.assign(v.variable(variables.first), i)
else if self.variables.length == 2 then
var key_meth = self.method_key
assert key_meth != null
- var i = v.send(key_meth, [it])
+ var i = v.compile_callsite(key_meth, [it])
assert i != null
v.assign(v.variable(variables[0]), i)
var item_meth = self.method_item
assert item_meth != null
- i = v.send(item_meth, [it])
+ i = v.compile_callsite(item_meth, [it])
assert i != null
v.assign(v.variable(variables[1]), i)
else
v.add("CONTINUE_{v.escapemark_name(escapemark)}: (void)0;")
var next_meth = self.method_next
assert next_meth != null
- v.send(next_meth, [it])
+ v.compile_callsite(next_meth, [it])
v.add("\}")
v.add("BREAK_{v.escapemark_name(escapemark)}: (void)0;")
end
var i2 = v.expr(self.n_expr2, null)
var mtype = self.mtype.as(MClassType)
var res = v.init_instance(mtype)
- var it = v.send(v.get_property("init", res.mtype), [res, i1, i2])
+ var it = v.compile_callsite(init_callsite.as(not null), [res, i1, i2])
return res
end
end
var i2 = v.expr(self.n_expr2, null)
var mtype = self.mtype.as(MClassType)
var res = v.init_instance(mtype)
- var it = v.send(v.get_property("without_last", res.mtype), [res, i1, i2])
+ var it = v.compile_callsite(init_callsite.as(not null), [res, i1, i2])
return res
end
end
end
# stantard call-next-method
- return v.supercall(v.frame.mpropdef.as(MMethodDef), recv.mtype.as(MClassType), args)
+ return v.supercall(mpropdef.as(not null), recv.mtype.as(MClassType), args)
end
end