diff options
| author | Paul Stansifer <paul.stansifer@gmail.com> | 2012-07-26 16:16:28 -0700 |
|---|---|---|
| committer | Paul Stansifer <paul.stansifer@gmail.com> | 2012-07-26 16:16:28 -0700 |
| commit | 97422f0f0fdcbdd17a769fa9588e76b8bf8a5bdf (patch) | |
| tree | a91f89c585b54fccf34cd873d2488d2cb3c09909 /src/rustc | |
| parent | 8209b2e9b383b9e38a09b1ec79c7b5691aeb5d22 (diff) | |
| parent | 44631722ff234241cb7100103320a402fe4fdfa9 (diff) | |
Merge branch 'incoming' of github.com:mozilla/rust
Diffstat (limited to 'src/rustc')
| -rw-r--r-- | src/rustc/driver/driver.rs | 7 | ||||
| -rw-r--r-- | src/rustc/driver/session.rs | 4 | ||||
| -rw-r--r-- | src/rustc/lib/llvm.rs | 3 | ||||
| -rw-r--r-- | src/rustc/metadata/csearch.rs | 9 | ||||
| -rw-r--r-- | src/rustc/metadata/decoder.rs | 19 | ||||
| -rw-r--r-- | src/rustc/metadata/encoder.rs | 12 | ||||
| -rw-r--r-- | src/rustc/middle/astencode.rs | 4 | ||||
| -rw-r--r-- | src/rustc/middle/borrowck/categorization.rs | 2 | ||||
| -rw-r--r-- | src/rustc/middle/lang_items.rs | 209 | ||||
| -rw-r--r-- | src/rustc/middle/region.rs | 2 | ||||
| -rw-r--r-- | src/rustc/middle/resolve3.rs | 23 | ||||
| -rw-r--r-- | src/rustc/middle/ty.rs | 2 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/astconv.rs | 2 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/check.rs | 4 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/check/regionmanip.rs | 2 | ||||
| -rw-r--r-- | src/rustc/rustc.rc | 1 |
16 files changed, 284 insertions, 21 deletions
diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs index 52aa88e6cb6..a6734b285a1 100644 --- a/src/rustc/driver/driver.rs +++ b/src/rustc/driver/driver.rs @@ -14,6 +14,7 @@ import io::{reader_util, writer_util}; import getopts::{optopt, optmulti, optflag, optflagopt, opt_present}; import back::{x86, x86_64}; import std::map::hashmap; +import lib::llvm::llvm; enum pp_mode {ppm_normal, ppm_expanded, ppm_typed, ppm_identified, ppm_expanded_identified } @@ -169,6 +170,9 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg, session::sess_os_to_meta_os(sess.targ_cfg.os), sess.opts.static)); + time(time_passes, ~"language item collection", || + middle::lang_items::collect_language_items(crate, sess)); + let { def_map: def_map, exp_map: exp_map, impl_map: impl_map, @@ -440,6 +444,9 @@ fn build_session_options(match: getopts::match, } debugging_opts |= this_bit; } + if debugging_opts & session::debug_llvm != 0 { + llvm::LLVMSetDebug(1); + } let output_type = if parse_only || no_trans { diff --git a/src/rustc/driver/session.rs b/src/rustc/driver/session.rs index 64ae30895c4..61ef9f73c3f 100644 --- a/src/rustc/driver/session.rs +++ b/src/rustc/driver/session.rs @@ -40,6 +40,7 @@ const borrowck_stats: uint = 1024u; const borrowck_note_pure: uint = 2048; const borrowck_note_loan: uint = 4096; const no_landing_pads: uint = 8192; +const debug_llvm: uint = 16384; fn debugging_opts_map() -> ~[(~str, ~str, uint)] { ~[(~"ppregions", ~"prettyprint regions with \ @@ -61,7 +62,8 @@ fn debugging_opts_map() -> ~[(~str, ~str, uint)] { (~"borrowck-note-loan", ~"note where loans are req'd", borrowck_note_loan), (~"no-landing-pads", ~"omit landing pads for unwinding", - no_landing_pads) + no_landing_pads), + (~"debug-llvm", ~"enable debug output from LLVM", debug_llvm) ] } diff --git a/src/rustc/lib/llvm.rs b/src/rustc/lib/llvm.rs index 376012dcf4e..7dbefa8e498 100644 --- a/src/rustc/lib/llvm.rs +++ b/src/rustc/lib/llvm.rs @@ -969,6 +969,9 @@ extern mod llvm { fn LLVMConstNamedStruct(S: TypeRef, ConstantVals: *ValueRef, Count: c_uint) -> ValueRef; + + /** Enables LLVM debug output. */ + fn LLVMSetDebug(Enabled: c_int); } fn SetInstructionCallConv(Instr: ValueRef, CC: CallConv) { diff --git a/src/rustc/metadata/csearch.rs b/src/rustc/metadata/csearch.rs index 7f97583fe3d..0ba76c49246 100644 --- a/src/rustc/metadata/csearch.rs +++ b/src/rustc/metadata/csearch.rs @@ -25,6 +25,7 @@ export get_enum_variants; export get_impls_for_mod; export get_trait_methods; export get_method_names_if_trait; +export get_item_attrs; export each_path; export get_type; export get_impl_traits; @@ -149,6 +150,14 @@ fn get_method_names_if_trait(cstore: cstore::cstore, def: ast::def_id) ret decoder::get_method_names_if_trait(cdata, def.node); } +fn get_item_attrs(cstore: cstore::cstore, + def_id: ast::def_id, + f: fn(~[@ast::meta_item])) { + + let cdata = cstore::get_crate_data(cstore, def_id.crate); + decoder::get_item_attrs(cdata, def_id.node, f) +} + fn get_class_fields(tcx: ty::ctxt, def: ast::def_id) -> ~[ty::field_ty] { let cstore = tcx.cstore; let cdata = cstore::get_crate_data(cstore, def.crate); diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs index 3ff9ded3f1e..83684413641 100644 --- a/src/rustc/metadata/decoder.rs +++ b/src/rustc/metadata/decoder.rs @@ -39,6 +39,7 @@ export get_crate_vers; export get_impls_for_mod; export get_trait_methods; export get_method_names_if_trait; +export get_item_attrs; export get_crate_module_paths; export def_like; export dl_def; @@ -282,7 +283,8 @@ fn item_to_def_like(item: ebml::doc, did: ast::def_id, cnum: ast::crate_num) let fam_ch = item_family(item); alt fam_ch { 'c' { dl_def(ast::def_const(did)) } - 'C' { dl_def(ast::def_class(did)) } + 'C' { dl_def(ast::def_class(did, true)) } + 'S' { dl_def(ast::def_class(did, false)) } 'u' { dl_def(ast::def_fn(did, ast::unsafe_fn)) } 'f' { dl_def(ast::def_fn(did, ast::impure_fn)) } 'p' { dl_def(ast::def_fn(did, ast::pure_fn)) } @@ -659,6 +661,18 @@ fn get_method_names_if_trait(cdata: cmd, node_id: ast::node_id) ret some(resulting_method_names); } +fn get_item_attrs(cdata: cmd, + node_id: ast::node_id, + f: fn(~[@ast::meta_item])) { + + let item = lookup_item(node_id, cdata.data); + do ebml::tagged_docs(item, tag_attributes) |attributes| { + do ebml::tagged_docs(attributes, tag_attribute) |attribute| { + f(get_meta_items(attribute)); + } + } +} + // Helper function that gets either fields or methods fn get_class_members(cdata: cmd, id: ast::node_id, p: fn(char) -> bool) -> ~[ty::field_ty] { @@ -694,7 +708,7 @@ fn family_has_type_params(fam_ch: char) -> bool { alt check fam_ch { 'c' | 'T' | 'm' | 'n' | 'g' | 'h' | 'j' { false } 'f' | 'u' | 'p' | 'F' | 'U' | 'P' | 'y' | 't' | 'v' | 'i' | 'I' | 'C' - | 'a' + | 'a' | 'S' { true } } } @@ -738,6 +752,7 @@ fn item_family_to_str(fam: char) -> ~str { 'i' { ret ~"impl"; } 'I' { ret ~"trait"; } 'C' { ret ~"class"; } + 'S' { ret ~"struct"; } 'g' { ret ~"public field"; } 'j' { ret ~"private field"; } } diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index b2847b3acc5..e1ed9fe396a 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -663,7 +663,16 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, /* Now, make an item for the class itself */ ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); - encode_family(ebml_w, 'C'); + + alt ctor { + none { + encode_family(ebml_w, 'S'); + } + some(_) { + encode_family(ebml_w, 'C'); + } + } + encode_type_param_bounds(ebml_w, ecx, tps); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_name(ebml_w, item.ident); @@ -759,6 +768,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_type_param_bounds(ebml_w, ecx, tps); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_name(ebml_w, item.ident); + encode_attributes(ebml_w, item.attrs); let mut i = 0u; for vec::each(*ty::trait_methods(tcx, local_def(item.id))) |mty| { alt ms[i] { diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index 002b4d97e23..1f5f7c4518d 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -369,8 +369,8 @@ impl of tr for ast::def { ast::def_upvar(nid1, def, nid2) { ast::def_upvar(xcx.tr_id(nid1), @(*def).tr(xcx), xcx.tr_id(nid2)) } - ast::def_class(did) { - ast::def_class(did.tr(xcx)) + ast::def_class(did, has_constructor) { + ast::def_class(did.tr(xcx), has_constructor) } ast::def_region(nid) { ast::def_region(xcx.tr_id(nid)) } } diff --git a/src/rustc/middle/borrowck/categorization.rs b/src/rustc/middle/borrowck/categorization.rs index f5879145a9d..4088945e550 100644 --- a/src/rustc/middle/borrowck/categorization.rs +++ b/src/rustc/middle/borrowck/categorization.rs @@ -196,7 +196,7 @@ impl public_methods for borrowck_ctxt { ast::def_foreign_mod(_) | ast::def_const(_) | ast::def_use(_) | ast::def_variant(_, _) | ast::def_ty(_) | ast::def_prim_ty(_) | - ast::def_ty_param(_, _) | ast::def_class(_) | + ast::def_ty_param(_, _) | ast::def_class(_, _) | ast::def_region(_) { @{id:id, span:span, cat:cat_special(sk_static_item), lp:none, diff --git a/src/rustc/middle/lang_items.rs b/src/rustc/middle/lang_items.rs new file mode 100644 index 00000000000..2353da51f98 --- /dev/null +++ b/src/rustc/middle/lang_items.rs @@ -0,0 +1,209 @@ +// Detecting language items. +// +// Language items are items that represent concepts intrinsic to the language +// itself. Examples are: +// +// * Traits that specify "kinds"; e.g. "const", "copy", "send". +// +// * Traits that represent operators; e.g. "add", "sub", "index". +// +// * Functions called by the compiler itself. + +import driver::session::session; +import metadata::csearch::{each_path, get_item_attrs}; +import metadata::cstore::{iter_crate_data}; +import metadata::decoder::{dl_def, dl_field, dl_impl}; +import syntax::ast::{crate, def_id, def_ty, lit_str, meta_item, meta_list}; +import syntax::ast::{meta_name_value, meta_word}; +import syntax::ast_util::{local_def}; +import syntax::visit::{default_simple_visitor, mk_simple_visitor}; +import syntax::visit::{visit_crate, visit_item}; + +import std::map::{hashmap, str_hash}; +import str_eq = str::eq; + +class LanguageItems { + let mut const_trait: option<def_id>; + let mut copy_trait: option<def_id>; + let mut send_trait: option<def_id>; + let mut owned_trait: option<def_id>; + + let mut add_trait: option<def_id>; + let mut sub_trait: option<def_id>; + let mut mul_trait: option<def_id>; + let mut div_trait: option<def_id>; + let mut modulo_trait: option<def_id>; + let mut neg_trait: option<def_id>; + let mut bitops_trait: option<def_id>; + let mut index_trait: option<def_id>; + + new() { + self.const_trait = none; + self.copy_trait = none; + self.send_trait = none; + self.owned_trait = none; + + self.add_trait = none; + self.sub_trait = none; + self.mul_trait = none; + self.div_trait = none; + self.modulo_trait = none; + self.neg_trait = none; + self.bitops_trait = none; + self.index_trait = none; + } +} + +class LanguageItemCollector { + let items: LanguageItems; + + let crate: @crate; + let session: session; + + let item_refs: hashmap<~str,&mut option<def_id>>; + + new(crate: @crate, session: session) { + self.crate = crate; + self.session = session; + + self.items = LanguageItems(); + + self.item_refs = str_hash(); + } + + // XXX: Needed to work around an issue with constructors. + fn init() { + self.item_refs.insert(~"const", &mut self.items.const_trait); + self.item_refs.insert(~"copy", &mut self.items.copy_trait); + self.item_refs.insert(~"send", &mut self.items.send_trait); + self.item_refs.insert(~"owned", &mut self.items.owned_trait); + + self.item_refs.insert(~"add", &mut self.items.add_trait); + self.item_refs.insert(~"sub", &mut self.items.sub_trait); + self.item_refs.insert(~"mul", &mut self.items.mul_trait); + self.item_refs.insert(~"div", &mut self.items.div_trait); + self.item_refs.insert(~"modulo", &mut self.items.modulo_trait); + self.item_refs.insert(~"neg", &mut self.items.neg_trait); + self.item_refs.insert(~"bitops", &mut self.items.bitops_trait); + self.item_refs.insert(~"index", &mut self.items.index_trait); + } + + fn match_and_collect_meta_item(item_def_id: def_id, + meta_item: meta_item) { + + alt meta_item.node { + meta_name_value(key, literal) => { + alt literal.node { + lit_str(value) => { + self.match_and_collect_item(item_def_id, + *key, + *value); + } + _ => { + // Skip. + } + } + } + meta_word(*) | meta_list(*) { + // Skip. + } + } + } + + fn match_and_collect_item(item_def_id: def_id, key: ~str, value: ~str) { + if !str_eq(key, ~"lang") { + ret; // Didn't match. + } + + alt self.item_refs.find(value) { + none => { + // Didn't match. + } + some(item_ref) => { + // Check for duplicates. + alt copy *item_ref { + some(original_def_id) + if original_def_id != item_def_id => { + + self.session.warn(#fmt("duplicate entry for `%s`", + value)); + } + some(_) | none => { + // OK. + } + } + + // Matched. + *item_ref = some(item_def_id); + } + } + } + + fn collect_local_language_items() { + let this = unsafe { ptr::addr_of(self) }; + visit_crate(*self.crate, (), mk_simple_visitor(@{ + visit_item: |item| { + for item.attrs.each |attribute| { + unsafe { + (*this).match_and_collect_meta_item(local_def(item + .id), + attribute.node + .value); + } + } + } + with *default_simple_visitor() + })); + } + + fn collect_external_language_items() { + let crate_store = self.session.cstore; + do iter_crate_data(crate_store) |crate_number, _crate_metadata| { + for each_path(crate_store, crate_number) |path_entry| { + let def_id; + alt path_entry.def_like { + dl_def(def_ty(did)) => { + def_id = did; + } + dl_def(_) | dl_impl(_) | dl_field { + // Skip this. + again; + } + } + + do get_item_attrs(crate_store, def_id) |meta_items| { + for meta_items.each |meta_item| { + self.match_and_collect_meta_item(def_id, *meta_item); + } + } + } + } + } + + fn check_completeness() { + for self.item_refs.each |key, item_ref| { + alt copy *item_ref { + none => { + self.session.warn(#fmt("no item found for `%s`", key)); + } + some(did) => { + // OK. + } + } + } + } + + fn collect() { + self.init(); + self.collect_local_language_items(); + self.collect_external_language_items(); + self.check_completeness(); + } +} + +fn collect_language_items(crate: @crate, session: session) -> LanguageItems { + let collector = LanguageItemCollector(crate, session); + collector.collect(); + copy collector.items +} + diff --git a/src/rustc/middle/region.rs b/src/rustc/middle/region.rs index ca00aeaa0f4..cc6874bc967 100644 --- a/src/rustc/middle/region.rs +++ b/src/rustc/middle/region.rs @@ -467,7 +467,7 @@ fn determine_rp_in_ty(ty: @ast::ty, alt ty.node { ast::ty_path(_, id) { alt cx.def_map.get(id) { - ast::def_ty(did) | ast::def_class(did) { + ast::def_ty(did) | ast::def_class(did, _) { if did.crate == ast::local_crate { cx.add_dep(did.node, cx.item_id); } else { diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs index bddf83c429e..e75268cde7f 100644 --- a/src/rustc/middle/resolve3.rs +++ b/src/rustc/middle/resolve3.rs @@ -41,7 +41,7 @@ import syntax::visit::{visit_mod, visit_ty, vt}; import box::ptr_eq; import dvec::{dvec, extensions}; -import option::get; +import option::{get, is_some}; import str::{connect, split_str}; import vec::pop; @@ -604,7 +604,7 @@ class Resolver { let unused_import_lint_level: level; let trait_info: hashmap<def_id,@hashmap<Atom,()>>; - let structs: hashmap<def_id,()>; + let structs: hashmap<def_id,bool>; // The number of imports that are currently unresolved. let mut unresolved_imports: uint; @@ -926,7 +926,8 @@ class Resolver { (*name_bindings).define_impl(impl_info); // Record the def ID of this struct. - self.structs.insert(local_def(item.id), ()); + self.structs.insert(local_def(item.id), + is_some(optional_ctor)); visit_item(item, new_parent, visitor); } @@ -1378,12 +1379,16 @@ class Resolver { (*child_name_bindings).define_type(def); } - def_class(def_id) { + def_class(def_id, has_constructor) { #debug("(building reduced graph for external \ - crate) building value and type %s", - final_ident); - (*child_name_bindings).define_value(def); + crate) building type %s (value? %d)", + final_ident, + if has_constructor { 1 } else { 0 }); (*child_name_bindings).define_type(def); + + if has_constructor { + (*child_name_bindings).define_value(def); + } } def_self(*) | def_arg(*) | def_local(*) | def_prim_ty(*) | def_ty_param(*) | def_binding(*) | @@ -4201,7 +4206,9 @@ class Resolver { some(definition @ def_ty(class_id)) if self.structs.contains_key(class_id) { - self.record_def(expr.id, def_class(class_id)); + let has_constructor = self.structs.get(class_id); + let class_def = def_class(class_id, has_constructor); + self.record_def(expr.id, class_def); } _ { self.session.span_err(path.span, diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index b6b1873b1dc..465aeebe3af 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -2587,7 +2587,7 @@ fn type_err_to_str(cx: ctxt, err: type_err) -> ~str { fn def_has_ty_params(def: ast::def) -> bool { alt def { - ast::def_fn(_, _) | ast::def_variant(_, _) | ast::def_class(_) + ast::def_fn(_, _) | ast::def_variant(_, _) | ast::def_class(_, _) { true } _ { false } } diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs index ebd189a15b7..3baea12ab48 100644 --- a/src/rustc/middle/typeck/astconv.rs +++ b/src/rustc/middle/typeck/astconv.rs @@ -270,7 +270,7 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy owned>( path_to_str(path))); } some(d) { d }}; alt a_def { - ast::def_ty(did) | ast::def_class(did) { + ast::def_ty(did) | ast::def_class(did, _) { ast_path_to_ty(self, rscope, did, path, id).ty } ast::def_prim_ty(nty) { diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index 0b78fd1a505..eaf0e90b26d 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -1649,7 +1649,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, // Resolve the path. let class_id; alt tcx.def_map.find(id) { - some(ast::def_class(type_def_id)) => { + some(ast::def_class(type_def_id, _)) => { class_id = type_def_id; } _ => { @@ -2160,7 +2160,7 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) -> } ast::def_fn(id, _) | ast::def_const(id) | - ast::def_variant(_, id) | ast::def_class(id) { + ast::def_variant(_, id) | ast::def_class(id, _) { ret ty::lookup_item_type(fcx.ccx.tcx, id); } ast::def_binding(nid) { diff --git a/src/rustc/middle/typeck/check/regionmanip.rs b/src/rustc/middle/typeck/check/regionmanip.rs index 2231d9b320a..d1052fd6a2a 100644 --- a/src/rustc/middle/typeck/check/regionmanip.rs +++ b/src/rustc/middle/typeck/check/regionmanip.rs @@ -200,7 +200,7 @@ fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region { ast::def_foreign_mod(_) | ast::def_const(_) | ast::def_use(_) | ast::def_variant(_, _) | ast::def_ty(_) | ast::def_prim_ty(_) | - ast::def_ty_param(_, _) | ast::def_class(_) | + ast::def_ty_param(_, _) | ast::def_class(_, _) | ast::def_region(_) { ty::re_static } diff --git a/src/rustc/rustc.rc b/src/rustc/rustc.rc index 406c46cc6c6..b2cce508e57 100644 --- a/src/rustc/rustc.rc +++ b/src/rustc/rustc.rc @@ -88,6 +88,7 @@ mod middle { mod region; mod const_eval; mod astencode; + mod lang_items; } mod front { |
