From 87c14f1e3d85751bffffda0b1920be5e726172c4 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Wed, 29 Feb 2012 11:46:23 -0800 Subject: Move src/comp to src/rustc --- src/comp/driver/diagnostic.rs | 256 ---------------- src/comp/driver/driver.rs | 667 ------------------------------------------ src/comp/driver/rustc.rs | 197 ------------- src/comp/driver/session.rs | 210 ------------- 4 files changed, 1330 deletions(-) delete mode 100644 src/comp/driver/diagnostic.rs delete mode 100644 src/comp/driver/driver.rs delete mode 100644 src/comp/driver/rustc.rs delete mode 100644 src/comp/driver/session.rs (limited to 'src/comp/driver') diff --git a/src/comp/driver/diagnostic.rs b/src/comp/driver/diagnostic.rs deleted file mode 100644 index 8f0570a4349..00000000000 --- a/src/comp/driver/diagnostic.rs +++ /dev/null @@ -1,256 +0,0 @@ -import std::{io, term}; -import io::writer_util; -import syntax::codemap; -import codemap::span; - -export emitter, emit; -export level, fatal, error, warning, note; -export span_handler, handler, mk_span_handler, mk_handler; -export codemap_span_handler, codemap_handler; -export ice_msg; - -type emitter = fn@(cmsp: option<(codemap::codemap, span)>, - msg: str, lvl: level); - - -iface span_handler { - fn span_fatal(sp: span, msg: str) -> !; - fn span_err(sp: span, msg: str); - fn span_warn(sp: span, msg: str); - fn span_note(sp: span, msg: str); - fn span_bug(sp: span, msg: str) -> !; - fn span_unimpl(sp: span, msg: str) -> !; - fn handler() -> handler; -} - -iface handler { - fn fatal(msg: str) -> !; - fn err(msg: str); - fn bump_err_count(); - fn has_errors() -> bool; - fn abort_if_errors(); - fn warn(msg: str); - fn note(msg: str); - fn bug(msg: str) -> !; - fn unimpl(msg: str) -> !; - fn emit(cmsp: option<(codemap::codemap, span)>, msg: str, lvl: level); -} - -type handler_t = @{ - mutable err_count: uint, - _emit: emitter -}; - -type codemap_t = @{ - handler: handler, - cm: codemap::codemap -}; - -impl codemap_span_handler of span_handler for codemap_t { - fn span_fatal(sp: span, msg: str) -> ! { - self.handler.emit(some((self.cm, sp)), msg, fatal); - fail; - } - fn span_err(sp: span, msg: str) { - self.handler.emit(some((self.cm, sp)), msg, error); - self.handler.bump_err_count(); - } - fn span_warn(sp: span, msg: str) { - self.handler.emit(some((self.cm, sp)), msg, warning); - } - fn span_note(sp: span, msg: str) { - self.handler.emit(some((self.cm, sp)), msg, note); - } - fn span_bug(sp: span, msg: str) -> ! { - self.span_fatal(sp, ice_msg(msg)); - } - fn span_unimpl(sp: span, msg: str) -> ! { - self.span_bug(sp, "unimplemented " + msg); - } - fn handler() -> handler { - self.handler - } -} - -impl codemap_handler of handler for handler_t { - fn fatal(msg: str) -> ! { - self._emit(none, msg, fatal); - fail; - } - fn err(msg: str) { - self._emit(none, msg, error); - self.bump_err_count(); - } - fn bump_err_count() { - self.err_count += 1u; - } - fn has_errors() -> bool { self.err_count > 0u } - fn abort_if_errors() { - if self.err_count > 0u { - self.fatal("aborting due to previous errors"); - } - } - fn warn(msg: str) { - self._emit(none, msg, warning); - } - fn note(msg: str) { - self._emit(none, msg, note); - } - fn bug(msg: str) -> ! { - self.fatal(ice_msg(msg)); - } - fn unimpl(msg: str) -> ! { self.bug("unimplemented " + msg); } - fn emit(cmsp: option<(codemap::codemap, span)>, msg: str, lvl: level) { - self._emit(cmsp, msg, lvl); - } -} - -fn ice_msg(msg: str) -> str { - #fmt["internal compiler error %s", msg] -} - -fn mk_span_handler(handler: handler, cm: codemap::codemap) -> span_handler { - @{ handler: handler, cm: cm } as span_handler -} - -fn mk_handler(emitter: option) -> handler { - - let emit = alt emitter { - some(e) { e } - none { - let f = fn@(cmsp: option<(codemap::codemap, span)>, - msg: str, t: level) { - emit(cmsp, msg, t); - }; - f - } - }; - - @{ - mutable err_count: 0u, - _emit: emit - } as handler -} - -enum level { - fatal, - error, - warning, - note, -} - -fn diagnosticstr(lvl: level) -> str { - alt lvl { - fatal { "error" } - error { "error" } - warning { "warning" } - note { "note" } - } -} - -fn diagnosticcolor(lvl: level) -> u8 { - alt lvl { - fatal { term::color_bright_red } - error { term::color_bright_red } - warning { term::color_bright_yellow } - note { term::color_bright_green } - } -} - -fn print_diagnostic(topic: str, lvl: level, msg: str) { - if str::is_not_empty(topic) { - io::stderr().write_str(#fmt["%s ", topic]); - } - if term::color_supported() { - term::fg(io::stderr(), diagnosticcolor(lvl)); - } - io::stderr().write_str(#fmt["%s:", diagnosticstr(lvl)]); - if term::color_supported() { - term::reset(io::stderr()); - } - io::stderr().write_str(#fmt[" %s\n", msg]); -} - -fn emit(cmsp: option<(codemap::codemap, span)>, - msg: str, lvl: level) { - alt cmsp { - some((cm, sp)) { - let sp = codemap::adjust_span(cm,sp); - let ss = codemap::span_to_str(sp, cm); - let lines = codemap::span_to_lines(sp, cm); - print_diagnostic(ss, lvl, msg); - highlight_lines(cm, sp, lines); - print_macro_backtrace(cm, sp); - } - none { - print_diagnostic("", lvl, msg); - } - } -} - -fn highlight_lines(cm: codemap::codemap, sp: span, - lines: @codemap::file_lines) { - - let fm = lines.file; - - // arbitrarily only print up to six lines of the error - let max_lines = 6u; - let elided = false; - let display_lines = lines.lines; - if vec::len(display_lines) > max_lines { - display_lines = vec::slice(display_lines, 0u, max_lines); - elided = true; - } - // Print the offending lines - for line: uint in display_lines { - io::stderr().write_str(#fmt["%s:%u ", fm.name, line + 1u]); - let s = codemap::get_line(fm, line as int) + "\n"; - io::stderr().write_str(s); - } - if elided { - let last_line = display_lines[vec::len(display_lines) - 1u]; - let s = #fmt["%s:%u ", fm.name, last_line + 1u]; - let indent = str::len(s); - let out = ""; - while indent > 0u { out += " "; indent -= 1u; } - out += "...\n"; - io::stderr().write_str(out); - } - - - // If there's one line at fault we can easily point to the problem - if vec::len(lines.lines) == 1u { - let lo = codemap::lookup_char_pos(cm, sp.lo); - let digits = 0u; - let num = (lines.lines[0] + 1u) / 10u; - - // how many digits must be indent past? - while num > 0u { num /= 10u; digits += 1u; } - - // indent past |name:## | and the 0-offset column location - let left = str::len(fm.name) + digits + lo.col + 3u; - let s = ""; - while left > 0u { str::push_char(s, ' '); left -= 1u; } - - s += "^"; - let hi = codemap::lookup_char_pos(cm, sp.hi); - if hi.col != lo.col { - // the ^ already takes up one space - let width = hi.col - lo.col - 1u; - while width > 0u { str::push_char(s, '~'); width -= 1u; } - } - io::stderr().write_str(s + "\n"); - } -} - -fn print_macro_backtrace(cm: codemap::codemap, sp: span) { - option::may (sp.expn_info) {|ei| - let ss = option::maybe("", ei.callie.span, - bind codemap::span_to_str(_, cm)); - print_diagnostic(ss, note, - #fmt("in expansion of #%s", ei.callie.name)); - let ss = codemap::span_to_str(ei.call_site, cm); - print_diagnostic(ss, note, "expansion site"); - print_macro_backtrace(cm, ei.call_site); - } -} diff --git a/src/comp/driver/driver.rs b/src/comp/driver/driver.rs deleted file mode 100644 index 4aaabc667ba..00000000000 --- a/src/comp/driver/driver.rs +++ /dev/null @@ -1,667 +0,0 @@ - -// -*- rust -*- -import metadata::{creader, cstore}; -import session::session; -import syntax::parse::{parser}; -import syntax::{ast, codemap}; -import front::attr; -import middle::{trans, resolve, freevars, kind, ty, typeck, fn_usage, - last_use, lint, inline}; -import syntax::print::{pp, pprust}; -import util::{ppaux, filesearch}; -import back::link; -import result::{ok, err}; -import std::{fs, io, getopts}; -import io::{reader_util, writer_util}; -import getopts::{optopt, optmulti, optflag, optflagopt, opt_present}; -import back::{x86, x86_64}; - -enum pp_mode { ppm_normal, ppm_expanded, ppm_typed, ppm_identified, } - -fn default_configuration(sess: session, argv0: str, input: str) -> - ast::crate_cfg { - let libc = alt sess.targ_cfg.os { - session::os_win32 { "msvcrt.dll" } - session::os_macos { "libc.dylib" } - session::os_linux { "libc.so.6" } - session::os_freebsd { "libc.so.7" } - _ { "libc.so" } - }; - - let mk = attr::mk_name_value_item_str; - - let arch = alt sess.targ_cfg.arch { - session::arch_x86 { "x86" } - session::arch_x86_64 { "x86_64" } - session::arch_arm { "arm" } - }; - - ret [ // Target bindings. - mk("target_os", std::os::target_os()), - mk("target_arch", arch), - mk("target_libc", libc), - // Build bindings. - mk("build_compiler", argv0), - mk("build_input", input)]; -} - -fn build_configuration(sess: session, argv0: str, input: str) -> - ast::crate_cfg { - // Combine the configuration requested by the session (command line) with - // some default and generated configuration items - let default_cfg = default_configuration(sess, argv0, input); - let user_cfg = sess.opts.cfg; - // If the user wants a test runner, then add the test cfg - let gen_cfg = - { - if sess.opts.test && !attr::contains_name(user_cfg, "test") - { - [attr::mk_word_item("test")] - } else { [] } - }; - ret user_cfg + gen_cfg + default_cfg; -} - -// Convert strings provided as --cfg [cfgspec] into a crate_cfg -fn parse_cfgspecs(cfgspecs: [str]) -> ast::crate_cfg { - // FIXME: It would be nice to use the parser to parse all varieties of - // meta_item here. At the moment we just support the meta_word variant. - let words = []; - for s: str in cfgspecs { words += [attr::mk_word_item(s)]; } - ret words; -} - -fn input_is_stdin(filename: str) -> bool { filename == "-" } - -fn parse_input(sess: session, cfg: ast::crate_cfg, input: str) - -> @ast::crate { - if !input_is_stdin(input) { - parser::parse_crate_from_file(input, cfg, sess.parse_sess) - } else { - let src = @str::from_bytes(io::stdin().read_whole_stream()); - parser::parse_crate_from_source_str(input, src, cfg, sess.parse_sess) - } -} - -fn time(do_it: bool, what: str, thunk: fn@() -> T) -> T { - if !do_it { ret thunk(); } - let start = std::time::precise_time_s(); - let rv = thunk(); - let end = std::time::precise_time_s(); - io::stdout().write_str(#fmt("time: %3.3f s\t%s\n", - end - start, what)); - ret rv; -} - -enum compile_upto { - cu_parse, - cu_expand, - cu_typeck, - cu_no_trans, - cu_everything, -} - -fn compile_upto(sess: session, cfg: ast::crate_cfg, - input: str, upto: compile_upto, - outputs: option) - -> {crate: @ast::crate, tcx: option} { - let time_passes = sess.opts.time_passes; - let crate = time(time_passes, "parsing", - bind parse_input(sess, cfg, input)); - if upto == cu_parse { ret {crate: crate, tcx: none}; } - - sess.building_library = session::building_library( - sess.opts.crate_type, crate, sess.opts.test); - - crate = - time(time_passes, "configuration", - bind front::config::strip_unconfigured_items(crate)); - crate = - time(time_passes, "maybe building test harness", - bind front::test::modify_for_testing(sess, crate)); - crate = - time(time_passes, "expansion", - bind syntax::ext::expand::expand_crate(sess, crate)); - - if upto == cu_expand { ret {crate: crate, tcx: none}; } - - crate = - time(time_passes, "core injection", - bind front::core_inject::maybe_inject_libcore_ref(sess, crate)); - - let ast_map = - time(time_passes, "ast indexing", - bind middle::ast_map::map_crate(*crate)); - time(time_passes, "external crate/lib resolution", - bind creader::read_crates(sess, *crate)); - let {def_map, exp_map, impl_map} = - time(time_passes, "resolution", - bind resolve::resolve_crate(sess, ast_map, crate)); - let freevars = - time(time_passes, "freevar finding", - bind freevars::annotate_freevars(def_map, crate)); - let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars); - let (method_map, dict_map) = - time(time_passes, "typechecking", - bind typeck::check_crate(ty_cx, impl_map, crate)); - time(time_passes, "const checking", - bind middle::check_const::check_crate(sess, crate, method_map)); - - if upto == cu_typeck { ret {crate: crate, tcx: some(ty_cx)}; } - - time(time_passes, "block-use checking", - bind middle::block_use::check_crate(ty_cx, crate)); - time(time_passes, "function usage", - bind fn_usage::check_crate_fn_usage(ty_cx, crate)); - time(time_passes, "alt checking", - bind middle::check_alt::check_crate(ty_cx, crate)); - time(time_passes, "typestate checking", - bind middle::tstate::ck::check_crate(ty_cx, crate)); - let mutbl_map = - time(time_passes, "mutability checking", - bind middle::mutbl::check_crate(ty_cx, crate)); - let (copy_map, ref_map) = - time(time_passes, "alias checking", - bind middle::alias::check_crate(ty_cx, crate)); - let last_uses = time(time_passes, "last use finding", - bind last_use::find_last_uses(crate, def_map, ref_map, ty_cx)); - time(time_passes, "kind checking", - bind kind::check_crate(ty_cx, method_map, last_uses, crate)); - - lint::check_crate(ty_cx, crate, sess.opts.lint_opts, time_passes); - - if upto == cu_no_trans { ret {crate: crate, tcx: some(ty_cx)}; } - let outputs = option::get(outputs); - - let maps = {mutbl_map: mutbl_map, copy_map: copy_map, - last_uses: last_uses, impl_map: impl_map, - method_map: method_map, dict_map: dict_map}; - - let ienbld = sess.opts.inline; - let inline_map = - time(time_passes, "inline", - bind inline::instantiate_inlines(ienbld, ty_cx, maps, crate)); - - let (llmod, link_meta) = - time(time_passes, "translation", - bind trans::base::trans_crate( - sess, crate, ty_cx, outputs.obj_filename, - exp_map, maps, inline_map)); - time(time_passes, "LLVM passes", - bind link::write::run_passes(sess, llmod, outputs.obj_filename)); - - let stop_after_codegen = - sess.opts.output_type != link::output_type_exe || - sess.opts.static && sess.building_library; - - if stop_after_codegen { ret {crate: crate, tcx: some(ty_cx)}; } - - time(time_passes, "Linking", - bind link::link_binary(sess, outputs.obj_filename, - outputs.out_filename, link_meta)); - ret {crate: crate, tcx: some(ty_cx)}; -} - -fn compile_input(sess: session, cfg: ast::crate_cfg, input: str, - outdir: option, output: option) { - - let upto = if sess.opts.parse_only { cu_parse } - else if sess.opts.no_trans { cu_no_trans } - else { cu_everything }; - let outputs = build_output_filenames(input, outdir, output, sess); - compile_upto(sess, cfg, input, upto, some(outputs)); -} - -fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: str, - ppm: pp_mode) { - fn ann_paren_for_expr(node: pprust::ann_node) { - alt node { pprust::node_expr(s, expr) { pprust::popen(s); } _ { } } - } - fn ann_typed_post(tcx: ty::ctxt, node: pprust::ann_node) { - alt node { - pprust::node_expr(s, expr) { - pp::space(s.s); - pp::word(s.s, "as"); - pp::space(s.s); - pp::word(s.s, ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr))); - pprust::pclose(s); - } - _ { } - } - } - fn ann_identified_post(node: pprust::ann_node) { - alt node { - pprust::node_item(s, item) { - pp::space(s.s); - pprust::synth_comment(s, int::to_str(item.id, 10u)); - } - pprust::node_block(s, blk) { - pp::space(s.s); - pprust::synth_comment(s, - "block " + int::to_str(blk.node.id, 10u)); - } - pprust::node_expr(s, expr) { - pp::space(s.s); - pprust::synth_comment(s, int::to_str(expr.id, 10u)); - pprust::pclose(s); - } - _ { } - } - } - - // Because the pretty printer needs to make a pass over the source - // to collect comments and literals, and we need to support reading - // from stdin, we're going to just suck the source into a string - // so both the parser and pretty-printer can use it. - let upto = alt ppm { - ppm_expanded { cu_expand } - ppm_typed { cu_typeck } - _ { cu_parse } - }; - let {crate, tcx} = compile_upto(sess, cfg, input, upto, none); - - let ann: pprust::pp_ann = pprust::no_ann(); - alt ppm { - ppm_typed { - ann = {pre: ann_paren_for_expr, - post: bind ann_typed_post(option::get(tcx), _)}; - } - ppm_identified { - ann = {pre: ann_paren_for_expr, post: ann_identified_post}; - } - ppm_expanded | ppm_normal {} - } - let src = codemap::get_filemap(sess.codemap, input).src; - pprust::print_crate(sess.codemap, sess.span_diagnostic, crate, input, - io::string_reader(*src), io::stdout(), ann); -} - -fn get_os(triple: str) -> option { - ret if str::contains(triple, "win32") || - str::contains(triple, "mingw32") { - some(session::os_win32) - } else if str::contains(triple, "darwin") { - some(session::os_macos) - } else if str::contains(triple, "linux") { - some(session::os_linux) - } else if str::contains(triple, "freebsd") { - some(session::os_freebsd) - } else { none }; -} - -fn get_arch(triple: str) -> option { - ret if str::contains(triple, "i386") || str::contains(triple, "i486") || - str::contains(triple, "i586") || - str::contains(triple, "i686") || - str::contains(triple, "i786") { - some(session::arch_x86) - } else if str::contains(triple, "x86_64") { - some(session::arch_x86_64) - } else if str::contains(triple, "arm") || - str::contains(triple, "xscale") { - some(session::arch_arm) - } else { none }; -} - -fn build_target_config(sopts: @session::options, - demitter: diagnostic::emitter) -> @session::config { - let os = alt get_os(sopts.target_triple) { - some(os) { os } - none { early_error(demitter, "Unknown operating system!") } - }; - let arch = alt get_arch(sopts.target_triple) { - some(arch) { arch } - none { early_error(demitter, - "Unknown architecture! " + sopts.target_triple) } - }; - let (int_type, uint_type, float_type) = alt arch { - session::arch_x86 {(ast::ty_i32, ast::ty_u32, ast::ty_f64)} - session::arch_x86_64 {(ast::ty_i64, ast::ty_u64, ast::ty_f64)} - session::arch_arm {(ast::ty_i32, ast::ty_u32, ast::ty_f64)} - }; - let target_strs = alt arch { - session::arch_x86 {x86::get_target_strs(os)} - session::arch_x86_64 {x86_64::get_target_strs(os)} - session::arch_arm {x86::get_target_strs(os)} - }; - let target_cfg: @session::config = - @{os: os, arch: arch, target_strs: target_strs, int_type: int_type, - uint_type: uint_type, float_type: float_type}; - ret target_cfg; -} - -fn host_triple() -> str { - // Get the host triple out of the build environment. This ensures that our - // idea of the host triple is the same as for the set of libraries we've - // actually built. We can't just take LLVM's host triple because they - // normalize all ix86 architectures to i386. - // FIXME: Instead of grabbing the host triple we really should be - // grabbing (at compile time) the target triple that this rustc is - // built with and calling that (at runtime) the host triple. - let ht = #env("CFG_HOST_TRIPLE"); - ret if ht != "" { - ht - } else { - fail "rustc built without CFG_HOST_TRIPLE" - }; -} - -fn build_session_options(match: getopts::match, - demitter: diagnostic::emitter) -> @session::options { - let crate_type = if opt_present(match, "lib") { - session::lib_crate - } else if opt_present(match, "bin") { - session::bin_crate - } else { - session::unknown_crate - }; - let static = opt_present(match, "static"); - - let parse_only = opt_present(match, "parse-only"); - let no_trans = opt_present(match, "no-trans"); - let lint_opts = []; - if opt_present(match, "no-lint-ctypes") { - lint_opts += [(lint::ctypes, false)]; - } - let monomorphize = opt_present(match, "monomorphize"); - let inline = opt_present(match, "inline"); - - let output_type = - if parse_only || no_trans { - link::output_type_none - } else if opt_present(match, "S") && opt_present(match, "emit-llvm") { - link::output_type_llvm_assembly - } else if opt_present(match, "S") { - link::output_type_assembly - } else if opt_present(match, "c") { - link::output_type_object - } else if opt_present(match, "emit-llvm") { - link::output_type_bitcode - } else { link::output_type_exe }; - let verify = !opt_present(match, "no-verify"); - let save_temps = opt_present(match, "save-temps"); - let extra_debuginfo = opt_present(match, "xg"); - let debuginfo = opt_present(match, "g") || extra_debuginfo; - let stats = opt_present(match, "stats"); - let time_passes = opt_present(match, "time-passes"); - let time_llvm_passes = opt_present(match, "time-llvm-passes"); - let sysroot_opt = getopts::opt_maybe_str(match, "sysroot"); - let target_opt = getopts::opt_maybe_str(match, "target"); - let no_asm_comments = getopts::opt_present(match, "no-asm-comments"); - alt output_type { - // unless we're emitting huamn-readable assembly, omit comments. - link::output_type_llvm_assembly | link::output_type_assembly {} - _ { no_asm_comments = true; } - } - let opt_level: uint = - if opt_present(match, "O") { - if opt_present(match, "opt-level") { - early_error(demitter, "-O and --opt-level both provided"); - } - 2u - } else if opt_present(match, "opt-level") { - alt getopts::opt_str(match, "opt-level") { - "0" { 0u } - "1" { 1u } - "2" { 2u } - "3" { 3u } - _ { - early_error(demitter, "optimization level needs " + - "to be between 0-3") - } - } - } else { 0u }; - let target = - alt target_opt { - none { host_triple() } - some(s) { s } - }; - - let addl_lib_search_paths = getopts::opt_strs(match, "L"); - let cfg = parse_cfgspecs(getopts::opt_strs(match, "cfg")); - let test = opt_present(match, "test"); - let warn_unused_imports = opt_present(match, "warn-unused-imports"); - let enforce_mut_vars = opt_present(match, "enforce-mut-vars"); - let sopts: @session::options = - @{crate_type: crate_type, - static: static, - optimize: opt_level, - debuginfo: debuginfo, - extra_debuginfo: extra_debuginfo, - verify: verify, - lint_opts: lint_opts, - save_temps: save_temps, - stats: stats, - time_passes: time_passes, - time_llvm_passes: time_llvm_passes, - output_type: output_type, - addl_lib_search_paths: addl_lib_search_paths, - maybe_sysroot: sysroot_opt, - target_triple: target, - cfg: cfg, - test: test, - parse_only: parse_only, - no_trans: no_trans, - no_asm_comments: no_asm_comments, - monomorphize: monomorphize, - inline: inline, - warn_unused_imports: warn_unused_imports, - enforce_mut_vars: enforce_mut_vars}; - ret sopts; -} - -fn build_session(sopts: @session::options, input: str, - demitter: diagnostic::emitter) -> session { - let codemap = codemap::new_codemap(); - let diagnostic_handler = - diagnostic::mk_handler(some(demitter)); - let span_diagnostic_handler = - diagnostic::mk_span_handler(diagnostic_handler, codemap); - build_session_(sopts, input, codemap, demitter, - span_diagnostic_handler) -} - -fn build_session_( - sopts: @session::options, input: str, - codemap: codemap::codemap, - demitter: diagnostic::emitter, - span_diagnostic_handler: diagnostic::span_handler -) -> session { - let target_cfg = build_target_config(sopts, demitter); - let cstore = cstore::mk_cstore(); - let filesearch = filesearch::mk_filesearch( - sopts.maybe_sysroot, - sopts.target_triple, - sopts.addl_lib_search_paths); - @{targ_cfg: target_cfg, - opts: sopts, - cstore: cstore, - parse_sess: @{ - cm: codemap, - mutable next_id: 1, - span_diagnostic: span_diagnostic_handler, - mutable chpos: 0u, - mutable byte_pos: 0u - }, - codemap: codemap, - // For a library crate, this is always none - mutable main_fn: none, - span_diagnostic: span_diagnostic_handler, - filesearch: filesearch, - mutable building_library: false, - working_dir: fs::dirname(input)} -} - -fn parse_pretty(sess: session, &&name: str) -> pp_mode { - if str::eq(name, "normal") { - ret ppm_normal; - } else if str::eq(name, "expanded") { - ret ppm_expanded; - } else if str::eq(name, "typed") { - ret ppm_typed; - } else if str::eq(name, "identified") { ret ppm_identified; } - sess.fatal("argument to `pretty` must be one of `normal`, `typed`, or " + - "`identified`"); -} - -fn opts() -> [getopts::opt] { - ret [optflag("h"), optflag("help"), optflag("v"), optflag("version"), - optflag("emit-llvm"), optflagopt("pretty"), - optflag("ls"), optflag("parse-only"), optflag("no-trans"), - optflag("O"), optopt("opt-level"), optmulti("L"), optflag("S"), - optopt("o"), optopt("out-dir"), optflag("xg"), - optflag("c"), optflag("g"), optflag("save-temps"), - optopt("sysroot"), optopt("target"), optflag("stats"), - optflag("time-passes"), optflag("time-llvm-passes"), - optflag("no-verify"), - optflag("no-lint-ctypes"), - optflag("monomorphize"), - optflag("inline"), - optmulti("cfg"), optflag("test"), - optflag("lib"), optflag("bin"), optflag("static"), optflag("gc"), - optflag("no-asm-comments"), - optflag("warn-unused-imports"), - optflag("enforce-mut-vars")]; -} - -type output_filenames = @{out_filename: str, obj_filename:str}; - -fn build_output_filenames(ifile: str, - odir: option, - ofile: option, - sess: session) - -> output_filenames { - let obj_path = ""; - let out_path: str = ""; - let sopts = sess.opts; - let stop_after_codegen = - sopts.output_type != link::output_type_exe || - sopts.static && sess.building_library; - - - let obj_suffix = - alt sopts.output_type { - link::output_type_none { "none" } - link::output_type_bitcode { "bc" } - link::output_type_assembly { "s" } - link::output_type_llvm_assembly { "ll" } - // Object and exe output both use the '.o' extension here - link::output_type_object | link::output_type_exe { - "o" - } - }; - - alt ofile { - none { - // "-" as input file will cause the parser to read from stdin so we - // have to make up a name - // We want to toss everything after the final '.' - let dirname = alt odir { - some(d) { d } - none { - if input_is_stdin(ifile) { - std::os::getcwd() - } else { - fs::dirname(ifile) - } - } - }; - - let base_filename = if !input_is_stdin(ifile) { - let (path, _) = fs::splitext(ifile); - fs::basename(path) - } else { - "rust_out" - }; - let base_path = fs::connect(dirname, base_filename); - - - if sess.building_library { - let basename = fs::basename(base_path); - let dylibname = std::os::dylib_filename(basename); - out_path = fs::connect(dirname, dylibname); - obj_path = fs::connect(dirname, basename + "." + obj_suffix); - } else { - out_path = base_path; - obj_path = base_path + "." + obj_suffix; - } - } - - some(out_file) { - out_path = out_file; - obj_path = if stop_after_codegen { - out_file - } else { - let (base, _) = fs::splitext(out_file); - let modified = base + "." + obj_suffix; - modified - }; - - if sess.building_library { - // FIXME: We might want to warn here; we're actually not going to - // respect the user's choice of library name when it comes time to - // link, we'll be linking to lib--.so no - // matter what. - } - - if odir != none { - sess.warn("Ignoring --out-dir flag due to -o flag."); - } - } - } - ret @{out_filename: out_path, - obj_filename: obj_path}; -} - -fn early_error(emitter: diagnostic::emitter, msg: str) -> ! { - emitter(none, msg, diagnostic::fatal); - fail; -} - -fn list_metadata(sess: session, path: str, out: io::writer) { - metadata::creader::list_file_metadata(sess, path, out); -} - -#[cfg(test)] -mod test { - - // When the user supplies --test we should implicitly supply --cfg test - #[test] - fn test_switch_implies_cfg_test() { - let match = - alt getopts::getopts(["--test"], opts()) { - ok(m) { m } - err(f) { fail "test_switch_implies_cfg_test: " + - getopts::fail_str(f); } - }; - let sessopts = build_session_options(match, diagnostic::emit); - let sess = build_session(sessopts, "", diagnostic::emit); - let cfg = build_configuration(sess, "whatever", "whatever"); - assert (attr::contains_name(cfg, "test")); - } - - // When the user supplies --test and --cfg test, don't implicitly add - // another --cfg test - #[test] - fn test_switch_implies_cfg_test_unless_cfg_test() { - let match = - alt getopts::getopts(["--test", "--cfg=test"], opts()) { - ok(m) { m } - err(f) { fail "test_switch_implies_cfg_test_unless_cfg_test: " + - getopts::fail_str(f); } - }; - let sessopts = build_session_options(match, diagnostic::emit); - let sess = build_session(sessopts, "", diagnostic::emit); - let cfg = build_configuration(sess, "whatever", "whatever"); - let test_items = attr::find_meta_items_by_name(cfg, "test"); - assert (vec::len(test_items) == 1u); - } -} - -// Local Variables: -// mode: rust -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// End: diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs deleted file mode 100644 index 8d0b8549062..00000000000 --- a/src/comp/driver/rustc.rs +++ /dev/null @@ -1,197 +0,0 @@ -use std; -use rustc; - -// -*- rust -*- -import result::{ok, err}; -import std::{io, getopts}; -import io::writer_util; -import getopts::{opt_present}; -import rustc::driver::driver::*; -import rustc::syntax::codemap; -import rustc::driver::diagnostic; - -fn version(argv0: str) { - let vers = "unknown version"; - let env_vers = #env["CFG_VERSION"]; - if str::len(env_vers) != 0u { vers = env_vers; } - io::stdout().write_str(#fmt["%s %s\n", argv0, vers]); - io::stdout().write_str(#fmt["host: %s\n", host_triple()]); -} - -fn usage(argv0: str) { - io::stdout().write_str(#fmt["Usage: %s [options] \n", argv0] + - " -Options: - - --bin Compile an executable crate (default) - -c Compile and assemble, but do not link - --cfg Configure the compilation environment - --emit-llvm Produce an LLVM bitcode file - -g Produce debug info - --gc Garbage collect shared data (experimental/temporary) - -h --help Display this message - -L Add a directory to the library search path - --lib Compile a library crate - --ls List the symbols defined by a compiled library crate - --no-asm-comments Do not add comments into the assembly source - --no-lint-ctypes Suppress warnings for possibly incorrect ctype usage - --no-trans Run all passes except translation; no output - --no-verify Suppress LLVM verification step (slight speedup) - (see http://llvm.org/docs/Passes.html for detail) - -O Equivalent to --opt-level=2 - -o Write output to - --opt-level Optimize with possible levels 0-3 - --out-dir Write output to compiler-chosen filename in - --parse-only Parse only; do not compile, assemble, or link - --pretty [type] Pretty-print the input instead of compiling; - valid types are: normal (un-annotated source), - expanded (crates expanded), typed (crates expanded, - with type annotations), or identified (fully - parenthesized, AST nodes and blocks with IDs) - -S Compile only; do not assemble or link - --save-temps Write intermediate files (.bc, .opt.bc, .o) - in addition to normal output - --static Use or produce static libraries or binaries - --stats Print compilation statistics - --sysroot Override the system root - --test Build a test harness - --target Target cpu-manufacturer-kernel[-os] to compile for - (default: host triple) - (see http://sources.redhat.com/autobook/autobook/ - autobook_17.html for detail) - - --time-passes Time the individual phases of the compiler - --time-llvm-passes Time the individual phases of the LLVM backend - -v --version Print version info and exit - --warn-unused-imports - Warn about unnecessary imports - -"); -} - -fn run_compiler(args: [str], demitter: diagnostic::emitter) { - // Don't display log spew by default. Can override with RUST_LOG. - logging::console_off(); - - let args = args, binary = vec::shift(args); - - if vec::len(args) == 0u { usage(binary); ret; } - - let match = - alt getopts::getopts(args, opts()) { - ok(m) { m } - err(f) { - early_error(demitter, getopts::fail_str(f)) - } - }; - if opt_present(match, "h") || opt_present(match, "help") { - usage(binary); - ret; - } - if opt_present(match, "v") || opt_present(match, "version") { - version(binary); - ret; - } - let ifile = alt vec::len(match.free) { - 0u { early_error(demitter, "No input filename given.") } - 1u { match.free[0] } - _ { early_error(demitter, "Multiple input filenames provided.") } - }; - - let sopts = build_session_options(match, demitter); - let sess = build_session(sopts, ifile, demitter); - let odir = getopts::opt_maybe_str(match, "out-dir"); - let ofile = getopts::opt_maybe_str(match, "o"); - let cfg = build_configuration(sess, binary, ifile); - let pretty = - option::map(getopts::opt_default(match, "pretty", - "normal"), - bind parse_pretty(sess, _)); - alt pretty { - some::(ppm) { pretty_print_input(sess, cfg, ifile, ppm); ret; } - none:: {/* continue */ } - } - let ls = opt_present(match, "ls"); - if ls { - list_metadata(sess, ifile, io::stdout()); - ret; - } - - compile_input(sess, cfg, ifile, odir, ofile); -} - -/* -This is a sanity check that any failure of the compiler is performed -through the diagnostic module and reported properly - we shouldn't be calling -plain-old-fail on any execution path that might be taken. Since we have -console logging off by default, hitting a plain fail statement would make the -compiler silently exit, which would be terrible. - -This method wraps the compiler in a subtask and injects a function into the -diagnostic emitter which records when we hit a fatal error. If the task -fails without recording a fatal error then we've encountered a compiler -bug and need to present an error. -*/ -fn monitor(f: fn~(diagnostic::emitter)) { - enum monitor_msg { - fatal, - done, - }; - - let p = comm::port(); - let ch = comm::chan(p); - - alt task::try {|| - - // The 'diagnostics emitter'. Every error, warning, etc. should - // go through this function. - let demitter = fn@(cmsp: option<(codemap::codemap, codemap::span)>, - msg: str, lvl: diagnostic::level) { - if lvl == diagnostic::fatal { - comm::send(ch, fatal); - } - diagnostic::emit(cmsp, msg, lvl); - }; - - resource finally(ch: comm::chan) { - comm::send(ch, done); - } - - let _finally = finally(ch); - - f(demitter) - } { - result::ok(_) { /* fallthrough */ } - result::err(_) { - // Task failed without emitting a fatal diagnostic - if comm::recv(p) == done { - diagnostic::emit( - none, - diagnostic::ice_msg("unexpected failure"), - diagnostic::error); - let note = "The compiler hit an unexpected failure path. \ - This is a bug. Try running with \ - RUST_LOG=rustc=0,::rt::backtrace \ - to get further details and report the results \ - to github.com/mozilla/rust/issues"; - diagnostic::emit(none, note, diagnostic::note); - } - // Fail so the process returns a failure code - fail; - } - } -} - -fn main(args: [str]) { - monitor {|demitter| - run_compiler(args, demitter); - } -} - -// Local Variables: -// mode: rust -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// End: diff --git a/src/comp/driver/session.rs b/src/comp/driver/session.rs deleted file mode 100644 index ec2182d2929..00000000000 --- a/src/comp/driver/session.rs +++ /dev/null @@ -1,210 +0,0 @@ - -import syntax::{ast, codemap}; -import syntax::ast::node_id; -import codemap::span; -import syntax::ast::{int_ty, uint_ty, float_ty}; -import syntax::parse::parser::parse_sess; -import util::filesearch; -import back::target_strs; -import middle::lint; - -enum os { os_win32, os_macos, os_linux, os_freebsd, } - -enum arch { arch_x86, arch_x86_64, arch_arm, } - -enum crate_type { bin_crate, lib_crate, unknown_crate, } - -type config = - {os: os, - arch: arch, - target_strs: target_strs::t, - int_type: int_ty, - uint_type: uint_ty, - float_type: float_ty}; - -type options = - // The crate config requested for the session, which may be combined - // with additional crate configurations during the compile process - {crate_type: crate_type, - static: bool, - optimize: uint, - debuginfo: bool, - extra_debuginfo: bool, - verify: bool, - lint_opts: [(lint::option, bool)], - save_temps: bool, - stats: bool, - time_passes: bool, - time_llvm_passes: bool, - output_type: back::link::output_type, - addl_lib_search_paths: [str], - maybe_sysroot: option, - target_triple: str, - cfg: ast::crate_cfg, - test: bool, - parse_only: bool, - no_trans: bool, - no_asm_comments: bool, - monomorphize: bool, - inline: bool, - warn_unused_imports: bool, - enforce_mut_vars: bool}; - -type crate_metadata = {name: str, data: [u8]}; - -type session = @{targ_cfg: @config, - opts: @options, - cstore: metadata::cstore::cstore, - parse_sess: parse_sess, - codemap: codemap::codemap, - // For a library crate, this is always none - mutable main_fn: option<(node_id, codemap::span)>, - span_diagnostic: diagnostic::span_handler, - filesearch: filesearch::filesearch, - mutable building_library: bool, - working_dir: str}; - -impl session for session { - fn span_fatal(sp: span, msg: str) -> ! { - self.span_diagnostic.span_fatal(sp, msg) - } - fn fatal(msg: str) -> ! { - self.span_diagnostic.handler().fatal(msg) - } - fn span_err(sp: span, msg: str) { - self.span_diagnostic.span_err(sp, msg) - } - fn err(msg: str) { - self.span_diagnostic.handler().err(msg) - } - fn has_errors() -> bool { - self.span_diagnostic.handler().has_errors() - } - fn abort_if_errors() { - self.span_diagnostic.handler().abort_if_errors() - } - fn span_warn(sp: span, msg: str) { - self.span_diagnostic.span_warn(sp, msg) - } - fn warn(msg: str) { - self.span_diagnostic.handler().warn(msg) - } - fn span_note(sp: span, msg: str) { - self.span_diagnostic.span_note(sp, msg) - } - fn note(msg: str) { - self.span_diagnostic.handler().note(msg) - } - fn span_bug(sp: span, msg: str) -> ! { - self.span_diagnostic.span_bug(sp, msg) - } - fn bug(msg: str) -> ! { - self.span_diagnostic.handler().bug(msg) - } - fn span_unimpl(sp: span, msg: str) -> ! { - self.span_diagnostic.span_unimpl(sp, msg) - } - fn unimpl(msg: str) -> ! { - self.span_diagnostic.handler().unimpl(msg) - } - fn next_node_id() -> ast::node_id { - ret syntax::parse::parser::next_node_id(self.parse_sess); - } -} - -fn building_library(req_crate_type: crate_type, crate: @ast::crate, - testing: bool) -> bool { - alt req_crate_type { - bin_crate { false } - lib_crate { true } - unknown_crate { - if testing { - false - } else { - alt front::attr::get_meta_item_value_str_by_name( - crate.node.attrs, - "crate_type") { - option::some("lib") { true } - _ { false } - } - } - } - } -} - -#[cfg(test)] -mod test { - import syntax::ast_util; - - fn make_crate_type_attr(t: str) -> ast::attribute { - ast_util::respan(ast_util::dummy_sp(), { - style: ast::attr_outer, - value: ast_util::respan(ast_util::dummy_sp(), - ast::meta_name_value( - "crate_type", - ast_util::respan(ast_util::dummy_sp(), - ast::lit_str(t)))) - }) - } - - fn make_crate(with_bin: bool, with_lib: bool) -> @ast::crate { - let attrs = []; - if with_bin { attrs += [make_crate_type_attr("bin")]; } - if with_lib { attrs += [make_crate_type_attr("lib")]; } - @ast_util::respan(ast_util::dummy_sp(), { - directives: [], - module: {view_items: [], items: []}, - attrs: attrs, - config: [] - }) - } - - #[test] - fn bin_crate_type_attr_results_in_bin_output() { - let crate = make_crate(true, false); - assert !building_library(unknown_crate, crate, false); - } - - #[test] - fn lib_crate_type_attr_results_in_lib_output() { - let crate = make_crate(false, true); - assert building_library(unknown_crate, crate, false); - } - - #[test] - fn bin_option_overrides_lib_crate_type() { - let crate = make_crate(false, true); - assert !building_library(bin_crate, crate, false); - } - - #[test] - fn lib_option_overrides_bin_crate_type() { - let crate = make_crate(true, false); - assert building_library(lib_crate, crate, false); - } - - #[test] - fn bin_crate_type_is_default() { - let crate = make_crate(false, false); - assert !building_library(unknown_crate, crate, false); - } - - #[test] - fn test_option_overrides_lib_crate_type() { - let crate = make_crate(false, true); - assert !building_library(unknown_crate, crate, true); - } - - #[test] - fn test_option_does_not_override_requested_lib_type() { - let crate = make_crate(false, false); - assert building_library(lib_crate, crate, true); - } -} - -// Local Variables: -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// End: -- cgit 1.4.1-3-g733a5