private import annotation
import mixin
import counter
+import pkgconfig
+private import explain_assert_api
# Add compiling options
redef class ToolContext
var opt_release = new OptionBool("Compile in release mode and finalize application", "--release")
# -g
var opt_debug = new OptionBool("Compile in debug mode (no C-side optimization)", "-g", "--debug")
+ # --trace
+ var opt_trace = new OptionBool("Compile with lttng's instrumentation", "--trace")
redef init
do
self.option_context.add_option(self.opt_release)
self.option_context.add_option(self.opt_max_c_lines, self.opt_group_c_files)
self.option_context.add_option(self.opt_debug)
+ self.option_context.add_option(self.opt_trace)
opt_no_main.hidden = true
end
var time1 = get_time
self.toolcontext.info("*** END WRITING C: {time1-time0} ***", 2)
+ if not toolcontext.check_errors then return
+
# Execute the Makefile
if self.toolcontext.opt_no_cc.value then return
compiler.files_to_copy.add "{clib}/gc_chooser.c"
compiler.files_to_copy.add "{clib}/gc_chooser.h"
+ # Add lttng traces provider to external bodies
+ if toolcontext.opt_trace.value then
+ #-I. is there in order to make the TRACEPOINT_INCLUDE directive in clib/traces.h refer to the directory in which gcc was invoked.
+ var traces = new ExternCFile("traces.c", "-I.")
+ traces.pkgconfigs.add "lttng-ust"
+ compiler.extern_bodies.add(traces)
+ compiler.files_to_copy.add "{clib}/traces.c"
+ compiler.files_to_copy.add "{clib}/traces.h"
+ end
+
# FFI
for m in compiler.mainmodule.in_importation.greaters do
compiler.finalize_ffi_for_module(m)
LDLIBS ?= -lm {{{linker_options.join(" ")}}}
\n"""
+ if self.toolcontext.opt_trace.value then makefile.write "LDLIBS += -llttng-ust -ldl\n"
+
makefile.write "\n# SPECIAL CONFIGURATION FLAGS\n"
if platform.supports_libunwind then
if toolcontext.opt_no_stacktrace.value then
f.close
end
- var java_files = new Array[ExternFile]
-
+ # pkg-config annotation support
var pkgconfigs = new Array[String]
for f in compiler.extern_bodies do
pkgconfigs.add_all f.pkgconfigs
end
- # Protect pkg-config
+
+ # Only test if pkg-config is used
if not pkgconfigs.is_empty then
+
+ # Check availability of pkg-config, silence the proc output
+ toolcontext.check_pkgconfig_packages pkgconfigs
+
+ # Double the check in the Makefile in case it's distributed
makefile.write """
# does pkg-config exists?
ifneq ($(shell which pkg-config >/dev/null; echo $$?), 0)
end
# Compile each required extern body into a specific .o
+ var java_files = new Array[ExternFile]
for f in compiler.extern_bodies do
var o = f.makefile_rule_name
var ff = f.filename.basename
self.header.add_decl("#endif")
self.header.add_decl("#include <inttypes.h>\n")
self.header.add_decl("#include \"gc_chooser.h\"")
+ if modelbuilder.toolcontext.opt_trace.value then self.header.add_decl("#include \"traces.h\"")
self.header.add_decl("#ifdef __APPLE__")
self.header.add_decl(" #include <TargetConditionals.h>")
self.header.add_decl(" #include <syslog.h>")
self.header.add_decl("#ifdef _WIN32")
self.header.add_decl(" #define be32toh(val) _byteswap_ulong(val)")
self.header.add_decl("#endif")
- self.header.add_decl("#ifdef __pnacl__")
- self.header.add_decl(" #define be16toh(val) (((val) >> 8) | ((val) << 8))")
- self.header.add_decl(" #define be32toh(val) ((be16toh((val) << 16) | (be16toh((val) >> 16))))")
- self.header.add_decl("#endif")
self.header.add_decl("#ifdef ANDROID")
self.header.add_decl(" #ifndef be32toh")
self.header.add_decl(" #define be32toh(val) betoh32(val)")
mtype = self.anchor(mtype)
var valmtype = value.mcasttype
+ # CPrimitive is the best you can do
+ if valmtype.is_c_primitive then
+ return value
+ end
+
# Do nothing if useless autocast
if valmtype.is_subtype(self.compiler.mainmodule, null, mtype) then
return value
var cond = v.expr_bool(self.n_expr)
v.add("if (unlikely(!{cond})) \{")
v.stmt(self.n_else)
+
+ explain_assert v
+
var nid = self.n_id
if nid != null then
v.add_abort("Assert '{nid.text}' failed")
end
v.add("\}")
end
+
+ # Explain assert if it fails
+ private fun explain_assert(v: AbstractCompilerVisitor)
+ do
+ var explain_assert_str = explain_assert_str
+ if explain_assert_str == null then return
+
+ var nas = v.compiler.modelbuilder.model.get_mclasses_by_name("NativeArray")
+ if nas == null then return
+
+ nas = v.compiler.modelbuilder.model.get_mclasses_by_name("Array")
+ if nas == null or nas.is_empty then return
+
+ var expr = explain_assert_str.expr(v)
+ if expr == null then return
+
+ var cstr = v.send(v.get_property("to_cstring", expr.mtype), [expr])
+ if cstr == null then return
+
+ v.add "PRINT_ERROR(\"Runtime assert: %s\\n\", {cstr});"
+ end
end
redef class AOrExpr