Add a structure for passing option flags around the compiler, put it in session, and use it.

This commit is contained in:
Graydon Hoare 2011-05-04 16:53:42 -07:00
parent 619b4743e3
commit cdb6822405
5 changed files with 106 additions and 87 deletions

View file

@ -78,50 +78,39 @@ fn time[T](bool do_it, str what, fn()->T thunk) -> T {
}
fn compile_input(session.session sess,
eval.env env,
str input, str output,
bool shared,
bool optimize,
bool debuginfo,
bool verify,
bool save_temps,
trans.output_type ot,
bool time_passes,
bool run_typestate,
vec[str] library_search_paths) {
eval.env env,
str input, str output) {
auto time_passes = sess.get_opts().time_passes;
auto def = tup(0, 0);
auto p = parser.new_parser(sess, env, def, input, 0u);
auto crate = time[@ast.crate](time_passes, "parsing",
bind parse_input(sess, p, input));
if (ot == trans.output_type_none) {ret;}
bind parse_input(sess, p, input));
if (sess.get_opts().output_type == trans.output_type_none) {ret;}
crate = time[@ast.crate](time_passes, "external crate reading",
bind creader.read_crates(sess, crate, library_search_paths));
bind creader.read_crates(sess, crate));
crate = time[@ast.crate](time_passes, "resolution",
bind resolve.resolve_crate(sess, crate));
bind resolve.resolve_crate(sess, crate));
time[()](time_passes, "capture checking",
bind capture.check_for_captures(sess, crate));
bind capture.check_for_captures(sess, crate));
auto ty_cx = ty.mk_ctxt(sess);
auto typeck_result =
time[typeck.typecheck_result](time_passes, "typechecking",
bind typeck.check_crate(ty_cx, crate));
bind typeck.check_crate(ty_cx, crate));
crate = typeck_result._0;
auto type_cache = typeck_result._1;
if (run_typestate) {
if (sess.get_opts().run_typestate) {
crate = time[@ast.crate](time_passes, "typestate checking",
bind typestate_check.check_crate(crate));
}
auto llmod = time[llvm.ModuleRef](time_passes, "translation",
bind trans.trans_crate(sess, crate, ty_cx, type_cache, output,
debuginfo, shared));
bind trans.trans_crate(sess, crate, ty_cx, type_cache, output));
time[()](time_passes, "LLVM passes",
bind trans.run_passes(llmod, optimize, debuginfo,
verify, save_temps, output,
ot));
bind trans.run_passes(sess, llmod, output));
}
fn pretty_print_input(session.session sess,
@ -133,7 +122,7 @@ fn pretty_print_input(session.session sess,
pretty.pprust.print_file(crate.node.module, input, std.io.stdout());
}
fn usage(session.session sess, str argv0) {
fn usage(str argv0) {
io.stdout().write_str(#fmt("usage: %s [options] <input>\n", argv0) + "
options:
@ -166,17 +155,12 @@ fn get_os() -> session.os {
fn main(vec[str] args) {
// FIXME: don't hard-wire this.
auto target_cfg = rec(os = get_os(),
arch = session.arch_x86,
int_type = common.ty_i32,
uint_type = common.ty_u32,
float_type = common.ty_f64 );
auto crate_cache = common.new_int_hash[session.crate_metadata]();
auto target_crate_num = 0;
let vec[@ast.meta_item] md = vec();
auto sess = session.session(target_crate_num, target_cfg, crate_cache,
md, front.codemap.new_codemap());
let @session.config target_cfg =
@rec(os = get_os(),
arch = session.arch_x86,
int_type = common.ty_i32,
uint_type = common.ty_u32,
float_type = common.ty_f64);
auto opts = vec(optflag("h"), optflag("glue"),
optflag("pretty"), optflag("ls"), optflag("parse-only"),
@ -187,11 +171,14 @@ fn main(vec[str] args) {
auto binary = _vec.shift[str](args);
auto match;
alt (GetOpts.getopts(args, opts)) {
case (GetOpts.failure(?f)) { sess.err(GetOpts.fail_str(f)); fail; }
case (GetOpts.failure(?f)) {
log_err #fmt("error: %s", GetOpts.fail_str(f));
fail;
}
case (GetOpts.success(?m)) { match = m; }
}
if (opt_present(match, "h")) {
usage(sess, binary);
usage(binary);
ret;
}
@ -201,13 +188,13 @@ fn main(vec[str] args) {
auto shared = opt_present(match, "shared");
auto output_file = GetOpts.opt_maybe_str(match, "o");
auto library_search_paths = GetOpts.opt_strs(match, "L");
auto ot = trans.output_type_bitcode;
auto output_type = trans.output_type_bitcode;
if (opt_present(match, "parse-only")) {
ot = trans.output_type_none;
output_type = trans.output_type_none;
} else if (opt_present(match, "S")) {
ot = trans.output_type_assembly;
output_type = trans.output_type_assembly;
} else if (opt_present(match, "c")) {
ot = trans.output_type_object;
output_type = trans.output_type_object;
}
auto verify = !opt_present(match, "noverify");
auto save_temps = opt_present(match, "save-temps");
@ -216,6 +203,25 @@ fn main(vec[str] args) {
auto debuginfo = opt_present(match, "g");
auto time_passes = opt_present(match, "time-passes");
auto run_typestate = !opt_present(match, "no-typestate");
let @session.options sopts =
@rec(shared = shared,
optimize = optimize,
debuginfo = debuginfo,
verify = verify,
run_typestate = run_typestate,
save_temps = save_temps,
time_passes = time_passes,
output_type = output_type,
library_search_paths = library_search_paths);
auto crate_cache = common.new_int_hash[session.crate_metadata]();
auto target_crate_num = 0;
let vec[@ast.meta_item] md = vec();
auto sess =
session.session(target_crate_num, target_cfg, sopts,
crate_cache, md, front.codemap.new_codemap());
auto n_inputs = _vec.len[str](match.free);
if (glue) {
@ -223,7 +229,7 @@ fn main(vec[str] args) {
sess.err("No input files allowed with --glue.");
}
auto out = option.from_maybe[str]("glue.bc", output_file);
middle.trans.make_common_glue(out, optimize, verify, save_temps, ot);
middle.trans.make_common_glue(sess, out);
ret;
}
@ -244,18 +250,21 @@ fn main(vec[str] args) {
case (none[str]) {
let vec[str] parts = _str.split(ifile, '.' as u8);
_vec.pop[str](parts);
parts += vec("bc");
alt (output_type) {
case (trans.output_type_none)
{ parts += vec("pp"); }
case (trans.output_type_bitcode)
{ parts += vec("bc"); }
case (trans.output_type_assembly)
{ parts += vec("s"); }
case (trans.output_type_object)
{ parts += vec("o"); }
}
auto ofile = _str.connect(parts, ".");
compile_input(sess, env, ifile, ofile, shared,
optimize, debuginfo, verify,
save_temps, ot, time_passes,
run_typestate, library_search_paths);
compile_input(sess, env, ifile, ofile);
}
case (some[str](?ofile)) {
compile_input(sess, env, ifile, ofile, shared,
optimize, debuginfo, verify,
save_temps, ot, time_passes,
run_typestate, library_search_paths);
compile_input(sess, env, ifile, ofile);
}
}
}

View file

@ -19,11 +19,21 @@
arch_arm;
}
type cfg = rec(os os,
arch arch,
ty_mach int_type,
ty_mach uint_type,
ty_mach float_type);
type config = rec(os os,
arch arch,
ty_mach int_type,
ty_mach uint_type,
ty_mach float_type);
type options = rec(bool shared,
bool optimize,
bool debuginfo,
bool verify,
bool run_typestate,
bool save_temps,
bool time_passes,
middle.trans.output_type output_type,
vec[str] library_search_paths);
type crate_metadata = rec(str name,
vec[u8] data);
@ -47,13 +57,18 @@ fn emit_diagnostic(span sp, str msg, str kind, u8 color, codemap.codemap cm) {
io.stdout().write_str(#fmt(" %s\n", msg));
}
state obj session(ast.crate_num cnum, cfg targ,
state obj session(ast.crate_num cnum,
@config targ_cfg, @options opts,
map.hashmap[int, crate_metadata] crates,
mutable vec[@ast.meta_item] metadata,
codemap.codemap cm) {
fn get_targ_cfg() -> cfg {
ret targ;
fn get_targ_cfg() -> @config {
ret targ_cfg;
}
fn get_opts() -> @options {
ret opts;
}
fn get_targ_crate_num() -> ast.crate_num {

View file

@ -459,12 +459,11 @@ fn fold_view_item_use(&env e, &span sp, ast.ident ident,
// Reads external crates referenced by "use" directives.
fn read_crates(session.session sess,
@ast.crate crate,
vec[str] library_search_paths) -> @ast.crate {
@ast.crate crate) -> @ast.crate {
auto e = @rec(
sess=sess,
crate_cache=@common.new_str_hash[int](),
library_search_paths=library_search_paths,
library_search_paths=sess.get_opts().library_search_paths,
mutable next_crate_num=1
);

View file

@ -687,9 +687,9 @@ fn encode_metadata(@trans.crate_ctxt cx, @ast.crate crate)
ret C_postr(string_w.get_str());
}
fn write_metadata(@trans.crate_ctxt cx, bool shared, @ast.crate crate) {
fn write_metadata(@trans.crate_ctxt cx, @ast.crate crate) {
auto llmeta = C_postr("");
if (shared) {
if (cx.sess.get_opts().shared) {
llmeta = encode_metadata(cx, crate);
}

View file

@ -116,8 +116,7 @@ fn next(str prefix) -> str {
std.sha1.sha1 sha,
hashmap[ty.t, str] type_sha1s,
hashmap[ty.t, metadata.ty_abbrev] type_abbrevs,
ty.ctxt tcx,
bool debuginfo);
ty.ctxt tcx);
type local_ctxt = rec(vec[str] path,
vec[str] module_path,
@ -1787,7 +1786,7 @@ fn declare_generic_glue(@local_ctxt cx,
TypeRef llfnty,
str name) -> ValueRef {
auto fn_nm;
if (cx.ccx.debuginfo) {
if (cx.ccx.sess.get_opts().debuginfo) {
fn_nm = mangle_name_by_type_only(cx.ccx, t, "glue_" + name);
fn_nm = sanitize(fn_nm);
} else {
@ -7247,18 +7246,18 @@ fn is_object_or_assembly(output_type ot) -> bool {
ret false;
}
fn run_passes(ModuleRef llmod, bool opt, bool dbg, bool verify,
bool save_temps, str output, output_type ot) {
fn run_passes(session.session sess, ModuleRef llmod, str output) {
auto pm = mk_pass_manager();
auto opts = sess.get_opts();
// TODO: run the linter here also, once there are llvm-c bindings for it.
// Generate a pre-optimization intermediate file if -save-temps was
// specified.
if (save_temps) {
alt (ot) {
if (opts.save_temps) {
alt (opts.output_type) {
case (output_type_bitcode) {
if (opt) {
if (opts.optimize) {
auto filename = mk_intermediate_name(output, "no-opt.bc");
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(filename));
}
@ -7274,7 +7273,7 @@ fn run_passes(ModuleRef llmod, bool opt, bool dbg, bool verify,
// available in the C api.
// FIXME2: We might want to add optmization levels like -O1, -O2, -Os, etc
// FIXME3: Should we expose and use the pass lists used by the opt tool?
if (opt) {
if (opts.optimize) {
auto fpm = mk_pass_manager();
// createStandardFunctionPasses
@ -7330,25 +7329,25 @@ fn run_passes(ModuleRef llmod, bool opt, bool dbg, bool verify,
llvm.LLVMAddConstantMergePass(pm.llpm);
}
if (verify) {
if (opts.verify) {
llvm.LLVMAddVerifierPass(pm.llpm);
}
// TODO: Write .s if -c was specified and -save-temps was on.
if (is_object_or_assembly(ot)) {
if (is_object_or_assembly(opts.output_type)) {
let int LLVMAssemblyFile = 0;
let int LLVMObjectFile = 1;
let int LLVMNullFile = 2;
auto FileType;
if (ot == output_type_object) {
if (opts.output_type == output_type_object) {
FileType = LLVMObjectFile;
} else {
FileType = LLVMAssemblyFile;
}
// Write optimized bitcode if --save-temps was on.
if (save_temps) {
alt (ot) {
if (opts.save_temps) {
alt (opts.output_type) {
case (output_type_bitcode) { /* nothing to do */ }
case (_) {
auto filename = mk_intermediate_name(output, "opt.bc");
@ -7712,8 +7711,7 @@ fn make_glues(ModuleRef llmod, type_names tn) -> @glue_fns {
vec_append_glue = make_vec_append_glue(llmod, tn));
}
fn make_common_glue(str output, bool optimize, bool verify, bool save_temps,
output_type ot) {
fn make_common_glue(session.session sess, str output) {
// FIXME: part of this is repetitive and is probably a good idea
// to autogen it, but things like the memcpy implementation are not
// and it might be better to just check in a .ll file.
@ -7739,7 +7737,7 @@ fn make_common_glue(str output, bool optimize, bool verify, bool save_temps,
trans_exit_task_glue(glues, new_str_hash[ValueRef](), tn, llmod);
run_passes(llmod, optimize, false, verify, save_temps, output, ot);
run_passes(sess, llmod, output);
}
fn create_module_map(@crate_ctxt ccx) -> ValueRef {
@ -7791,8 +7789,7 @@ fn create_crate_map(@crate_ctxt ccx) -> ValueRef {
}
fn trans_crate(session.session sess, @ast.crate crate, ty.ctxt tcx,
ty.type_cache type_cache, str output,
bool debuginfo, bool shared)
ty.type_cache type_cache, str output)
-> ModuleRef {
auto llmod =
llvm.LLVMModuleCreateWithNameInContext(_str.buf("rust_out"),
@ -7842,8 +7839,7 @@ fn trans_crate(session.session sess, @ast.crate crate, ty.ctxt tcx,
sha = std.sha1.mk_sha1(),
type_sha1s = sha1s,
type_abbrevs = abbrevs,
tcx = tcx,
debuginfo = debuginfo);
tcx = tcx);
auto cx = new_local_ctxt(ccx);
create_typedefs(ccx);
@ -7854,12 +7850,12 @@ fn trans_crate(session.session sess, @ast.crate crate, ty.ctxt tcx,
trans_mod(cx, crate.node.module);
trans_vec_append_glue(cx);
auto crate_map = create_crate_map(ccx);
if (!shared) {
if (!sess.get_opts().shared) {
trans_main_fn(cx, crate_ptr, crate_map);
}
// Translate the metadata.
middle.metadata.write_metadata(cx.ccx, shared, crate);
middle.metadata.write_metadata(cx.ccx, crate);
ret llmod;
}