trans: &CrateTranslation,
outputs: &OutputFilenames) {
- // NB: Android hack
- if sess.targ_cfg.os == session::os_android &&
+ // On Windows, LLVM integrated assembler emits bad stack unwind tables when
+ // segmented stacks are enabled. However, unwind info directives in assembly
+ // output are OK, so we generate assembly first and then run it through
+ // an external assembler.
+ // Same for Android.
+ if (sess.targ_cfg.os == session::os_android ||
+ sess.targ_cfg.os == session::os_win32) &&
(sess.opts.output_type == link::output_type_object ||
sess.opts.output_type == link::output_type_exe) {
let output_type = link::output_type_assembly;
- let obj_filename = outputs.obj_filename.with_filetype("s");
+ let asm_filename = outputs.obj_filename.with_filetype("s");
time(sess.time_passes(), ~"LLVM passes", ||
link::write::run_passes(sess,
trans.context,
trans.module,
output_type,
- &obj_filename));
+ &asm_filename));
- link::write::run_ndk(sess, &obj_filename, &outputs.obj_filename);
+ link::write::run_assembler(sess, &asm_filename, &outputs.obj_filename);
+
+ // Remove assembly source unless --save-temps was specified
+ if !sess.opts.save_temps {
+ os::remove_file(&asm_filename);
+ }
} else {
time(sess.time_passes(), ~"LLVM passes", ||
link::write::run_passes(sess,
abi::Arm => (ast::ty_i32, ast::ty_u32, ast::ty_f64),
abi::Mips => (ast::ty_i32, ast::ty_u32, ast::ty_f64)
};
+ let target_triple = sopts.target_triple.clone();
let target_strs = match arch {
- abi::X86 => x86::get_target_strs(os),
- abi::X86_64 => x86_64::get_target_strs(os),
- abi::Arm => arm::get_target_strs(os),
- abi::Mips => mips::get_target_strs(os)
+ abi::X86 => x86::get_target_strs(target_triple, os),
+ abi::X86_64 => x86_64::get_target_strs(target_triple, os),
+ abi::Arm => arm::get_target_strs(target_triple, os),
+ abi::Mips => mips::get_target_strs(target_triple, os)
};
let target_cfg = @session::config {
os: os,
parse_only: parse_only,
no_trans: no_trans,
debugging_opts: debugging_opts,
- android_cross_path: android_cross_path
+ android_cross_path: android_cross_path,
};
return sopts;
}
use metadata::tydecode::{parse_ty_data, parse_def_id,
parse_type_param_def_data,
parse_bare_fn_ty_data, parse_trait_ref_data};
+ use metadata::loader::{MetadataSection, UnsafeSection};
use middle::ty;
use middle::typeck;
use middle::astencode::vtable_decoder_helpers;
let index = reader::get_doc(d, tag_index);
let table = reader::get_doc(index, tag_index_table);
let hash_pos = table.start + (hash % 256 * 4) as uint;
- let pos = io::u64_from_be_bytes(*d.data, hash_pos, 4) as uint;
- let tagged_doc = reader::doc_at(d.data, pos);
+ let pos = io::u64_from_be_bytes(d.data.as_slice(), hash_pos, 4) as uint;
+ let tagged_doc = reader::doc_at(&d.data, pos);
let belt = tag_index_buckets_bucket_elt;
let mut ret = None;
do reader::tagged_docs(tagged_doc.doc, belt) |elt| {
- let pos = io::u64_from_be_bytes(*elt.data, elt.start, 4) as uint;
+ let pos = io::u64_from_be_bytes(elt.data.as_slice(), elt.start, 4) as uint;
if eq_fn(elt.data.slice(elt.start + 4, elt.end)) {
- ret = Some(reader::doc_at(d.data, pos).doc);
+ ret = Some(reader::doc_at(&d.data, pos).doc);
false
} else {
true
// Looks up an item in the given metadata and returns an ebml doc pointing
// to the item data.
- fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc {
- let items = reader::get_doc(reader::Doc(data), tag_items);
+ fn lookup_item(item_id: int, data: MetadataSection) -> ebml::Doc {
+ let items = reader::get_doc(section_to_ebml_doc(data), tag_items);
find_item(item_id, items)
}
fn doc_type(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::t {
let tp = reader::get_doc(doc, tag_items_data_item_type);
- parse_ty_data(*tp.data, cdata.cnum, tp.start, tcx,
+ parse_ty_data(tp.data.as_slice(), cdata.cnum, tp.start, tcx,
|_, did| translate_def_id(cdata, did))
}
fn doc_method_fty(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::BareFnTy {
let tp = reader::get_doc(doc, tag_item_method_fty);
- parse_bare_fn_ty_data(*tp.data, cdata.cnum, tp.start, tcx,
+ parse_bare_fn_ty_data(tp.data.as_slice(), cdata.cnum, tp.start, tcx,
|_, did| translate_def_id(cdata, did))
}
cdata: cmd) -> Option<ty::t>
{
do reader::maybe_get_doc(doc, tag_item_method_transformed_self_ty).map |tp| {
- parse_ty_data(*tp.data, cdata.cnum, tp.start, tcx,
+ parse_ty_data(tp.data.as_slice(), cdata.cnum, tp.start, tcx,
|_, did| translate_def_id(cdata, did))
}
}
}
fn doc_trait_ref(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::TraitRef {
- parse_trait_ref_data(*doc.data, cdata.cnum, doc.start, tcx,
+ parse_trait_ref_data(doc.data.as_slice(), cdata.cnum, doc.start, tcx,
|_, did| translate_def_id(cdata, did))
}
let mut bounds = ~[];
do reader::tagged_docs(item, tag) |p| {
let bd = parse_type_param_def_data(
- *p.data, p.start, cdata.cnum, tcx,
+ p.data.as_slice(), p.start, cdata.cnum, tcx,
|_, did| translate_def_id(cdata, did));
bounds.push(bd);
true
}
}
- pub fn lookup_def(cnum: ast::CrateNum, data: @~[u8], did_: ast::def_id) ->
+ pub fn lookup_def(cnum: ast::CrateNum, data: MetadataSection, did_: ast::def_id) ->
ast::def {
let item = lookup_item(did_.node, data);
let did = ast::def_id { crate: cnum, node: did_.node };
let tp_defs = item_ty_param_defs(item_doc, tcx, cdata,
tag_items_data_item_ty_param_bounds);
let rp = item_ty_region_param(item_doc);
+ let mut bounds = ty::EmptyBuiltinBounds();
+ // Collect the builtin bounds from the encoded supertraits.
+ // FIXME(#8559): They should be encoded directly.
+ do reader::tagged_docs(item_doc, tag_item_super_trait_ref) |trait_doc| {
+ // NB. Bypasses real supertraits. See get_supertraits() if you wanted them.
+ let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
+ do tcx.lang_items.to_builtin_kind(trait_ref.def_id).map_move |bound| {
+ bounds.add(bound);
+ };
+ true
+ };
ty::TraitDef {
generics: ty::Generics {type_param_defs: tp_defs,
region_param: rp},
+ bounds: bounds,
trait_ref: @item_trait_ref(item_doc, tcx, cdata)
}
}
return item_ty_region_param(item);
}
- pub fn get_type_param_count(data: @~[u8], id: ast::NodeId) -> uint {
+ pub fn get_type_param_count(data: MetadataSection, id: ast::NodeId) -> uint {
item_ty_param_count(lookup_item(id, data))
}
pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::NodeId,
name: ast::ident) -> Option<ast::def_id> {
- let items = reader::get_doc(reader::Doc(cdata.data), tag_items);
+ let items = reader::get_doc(section_to_ebml_doc(cdata.data), tag_items);
let mut found = None;
do reader::tagged_docs(find_item(id, items), tag_item_impl_method) |mid| {
let m_did = reader::with_doc_data(mid, parse_def_id);
found
}
- pub fn get_symbol(data: @~[u8], id: ast::NodeId) -> ~str {
+ pub fn get_symbol(data: MetadataSection, id: ast::NodeId) -> ~str {
return item_symbol(lookup_item(id, data));
}
/// Iterates over the language items in the given crate.
pub fn each_lang_item(cdata: cmd, f: &fn(ast::NodeId, uint) -> bool) -> bool {
- let root = reader::Doc(cdata.data);
+ let root = section_to_ebml_doc(cdata.data);
let lang_items = reader::get_doc(root, tag_lang_items);
do reader::tagged_docs(lang_items, tag_lang_items_item) |item_doc| {
let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
fn each_item_of_module(&mut self, def_id: ast::def_id) -> bool {
// This item might not be in this crate. If it's not, look it up.
let items = if def_id.crate == self.cdata.cnum {
- reader::get_doc(reader::Doc(self.cdata.data), tag_items)
+ reader::get_doc(section_to_ebml_doc(self.cdata.data), tag_items)
} else {
let crate_data = (self.get_crate_data)(def_id.crate);
- let root = reader::Doc(crate_data.data);
+ let root = section_to_ebml_doc(crate_data.data);
reader::get_doc(root, tag_items)
};
// a reexport.
let other_crates_items = if child_def_id.crate ==
self.cdata.cnum {
- reader::get_doc(reader::Doc(self.cdata.data), tag_items)
+ reader::get_doc(section_to_ebml_doc(self.cdata.data), tag_items)
} else {
let crate_data = (self.get_crate_data)(child_def_id.crate);
- let root = reader::Doc(crate_data.data);
+ let root = section_to_ebml_doc(crate_data.data);
reader::get_doc(root, tag_items)
};
// This reexport may be in yet another crate.
let other_crates_items = if def_id.crate == self.cdata.cnum {
- reader::get_doc(reader::Doc(self.cdata.data), tag_items)
+ reader::get_doc(section_to_ebml_doc(self.cdata.data), tag_items)
} else {
let crate_data = (self.get_crate_data)(def_id.crate);
- let root = reader::Doc(crate_data.data);
+ let root = section_to_ebml_doc(crate_data.data);
reader::get_doc(root, tag_items)
};
// make fast. It's the source of most of the performance problems when
// compiling small crates.
- let root_doc = reader::Doc(cdata.data);
+ let root_doc = section_to_ebml_doc(cdata.data);
let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
let crate_items_doc = reader::get_doc(misc_info_doc,
tag_misc_info_crate_items);
pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::NodeId,
tcx: ty::ctxt) -> ~[@ty::VariantInfo] {
let data = cdata.data;
- let items = reader::get_doc(reader::Doc(data), tag_items);
+ let items = reader::get_doc(section_to_ebml_doc(data), tag_items);
let item = find_item(id, items);
let mut infos: ~[@ty::VariantInfo] = ~[];
let variant_ids = enum_variant_ids(item, cdata);
let mut results = ~[];
let item_doc = lookup_item(id, cdata.data);
do reader::tagged_docs(item_doc, tag_item_super_trait_ref) |trait_doc| {
- results.push(@doc_trait_ref(trait_doc, tcx, cdata));
+ // NB. Only reads the ones that *aren't* builtin-bounds. See also
+ // get_trait_def() for collecting the builtin bounds.
+ // FIXME(#8559): The builtin bounds shouldn't be encoded in the first place.
+ let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
+ if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_none() {
+ results.push(@trait_ref);
+ }
true
};
return results;
out.write_str("\n\n");
}
- pub fn get_crate_attributes(data: @~[u8]) -> ~[ast::Attribute] {
- return get_attributes(reader::Doc(data));
+ pub fn get_crate_attributes(data: MetadataSection) -> ~[ast::Attribute] {
+ return get_attributes(section_to_ebml_doc(data));
+ }
+
+ pub fn section_to_ebml_doc(data: MetadataSection) -> ebml::Doc {
+ match data {
+ UnsafeSection(_, buf, len) => reader::unsafe_Doc(buf, len)
+ }
}
#[deriving(Clone)]
hash: @str
}
- pub fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] {
+ pub fn get_crate_deps(data: MetadataSection) -> ~[crate_dep] {
let mut deps: ~[crate_dep] = ~[];
- let cratedoc = reader::Doc(data);
+ let cratedoc = section_to_ebml_doc(data);
let depsdoc = reader::get_doc(cratedoc, tag_crate_deps);
let mut crate_num = 1;
fn docstr(doc: ebml::Doc, tag_: uint) -> @str {
return deps;
}
- fn list_crate_deps(data: @~[u8], out: @io::Writer) {
+ fn list_crate_deps(data: MetadataSection, out: @io::Writer) {
out.write_str("=External Dependencies=\n");
let r = get_crate_deps(data);
out.write_str("\n");
}
- pub fn get_crate_hash(data: @~[u8]) -> @str {
- let cratedoc = reader::Doc(data);
+ pub fn get_crate_hash(data: MetadataSection) -> @str {
+ let cratedoc = section_to_ebml_doc(data);
let hashdoc = reader::get_doc(cratedoc, tag_crate_hash);
hashdoc.as_str_slice().to_managed()
}
- pub fn get_crate_vers(data: @~[u8]) -> @str {
+ pub fn get_crate_vers(data: MetadataSection) -> @str {
let attrs = decoder::get_crate_attributes(data);
let linkage_attrs = attr::find_linkage_metas(attrs);
};
}
- pub fn list_crate_metadata(intr: @ident_interner, bytes: @~[u8],
+ pub fn list_crate_metadata(intr: @ident_interner, bytes: MetadataSection,
out: @io::Writer) {
let hash = get_crate_hash(bytes);
- let md = reader::Doc(bytes);
+ let md = section_to_ebml_doc(bytes);
list_crate_attributes(intr, md, hash, out);
list_crate_deps(bytes, out);
}
}
pub fn get_link_args_for_crate(cdata: cmd) -> ~[~str] {
- let link_args = reader::get_doc(reader::Doc(cdata.data), tag_link_args);
+ let link_args = reader::get_doc(section_to_ebml_doc(cdata.data), tag_link_args);
let mut result = ~[];
do reader::tagged_docs(link_args, tag_link_args_arg) |arg_doc| {
result.push(arg_doc.as_str());