Skip to content

Commit 111c1d4

Browse files
brsonJames Miller
authored andcommitted
rustc: Move code for discovering the crate entry point into its own pass
It doesn't have anything to do with resolve and the logic will likely get more involved in the future, after rust-lang#4433
1 parent c4e4e57 commit 111c1d4

File tree

4 files changed

+122
-79
lines changed

4 files changed

+122
-79
lines changed

src/librustc/driver/driver.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ pub fn compile_rest(sess: Session,
225225
time(time_passes, ~"resolution", ||
226226
middle::resolve::resolve_crate(sess, lang_items, crate));
227227

228+
time(time_passes, ~"looking for entry point", || middle::entry::find_entry_point(sess, crate));
229+
228230
let freevars = time(time_passes, ~"freevar finding", ||
229231
freevars::annotate_freevars(def_map, crate));
230232

src/librustc/middle/entry.rs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use driver::session;
12+
use driver::session::Session;
13+
use syntax::parse::token::special_idents;
14+
use syntax::ast::{crate, node_id, item, item_fn};
15+
use syntax::codemap::span;
16+
use syntax::visit::{default_visitor, mk_vt, vt, Visitor, visit_crate, visit_item};
17+
use syntax::attr::{attrs_contains_name};
18+
19+
struct EntryContext {
20+
session: Session,
21+
22+
// The function that has attribute named 'main'
23+
attr_main_fn: Option<(node_id, span)>,
24+
25+
// The functions that could be main functions
26+
main_fns: ~[Option<(node_id, span)>],
27+
28+
// The function that has the attribute 'start' on it
29+
start_fn: Option<(node_id, span)>,
30+
}
31+
32+
type EntryVisitor = vt<@mut EntryContext>;
33+
34+
pub fn find_entry_point(session: Session, crate: @crate) {
35+
36+
let ctxt = @mut EntryContext {
37+
session: session,
38+
attr_main_fn: None,
39+
main_fns: ~[],
40+
start_fn: None,
41+
};
42+
43+
visit_crate(crate, ctxt, mk_vt(@Visitor {
44+
visit_item: |item, ctxt, visitor| find_item(item, ctxt, visitor),
45+
.. *default_visitor()
46+
}));
47+
48+
check_duplicate_main(ctxt);
49+
}
50+
51+
fn find_item(item: @item, ctxt: @mut EntryContext, visitor: EntryVisitor) {
52+
match item.node {
53+
item_fn(*) => {
54+
// If this is the main function, we must record it in the
55+
// session.
56+
57+
// FIXME #4404 android JNI hacks
58+
if !*ctxt.session.building_library ||
59+
ctxt.session.targ_cfg.os == session::os_android {
60+
61+
if ctxt.attr_main_fn.is_none() &&
62+
item.ident == special_idents::main {
63+
64+
ctxt.main_fns.push(Some((item.id, item.span)));
65+
}
66+
67+
if attrs_contains_name(item.attrs, ~"main") {
68+
if ctxt.attr_main_fn.is_none() {
69+
ctxt.attr_main_fn = Some((item.id, item.span));
70+
} else {
71+
ctxt.session.span_err(
72+
item.span,
73+
~"multiple 'main' functions");
74+
}
75+
}
76+
77+
if attrs_contains_name(item.attrs, ~"start") {
78+
if ctxt.start_fn.is_none() {
79+
ctxt.start_fn = Some((item.id, item.span));
80+
} else {
81+
ctxt.session.span_err(
82+
item.span,
83+
~"multiple 'start' functions");
84+
}
85+
}
86+
}
87+
}
88+
_ => ()
89+
}
90+
91+
visit_item(item, ctxt, visitor);
92+
}
93+
94+
// main function checking
95+
//
96+
// be sure that there is only one main function
97+
fn check_duplicate_main(ctxt: @mut EntryContext) {
98+
let this = &mut *ctxt;
99+
if this.attr_main_fn.is_none() && this.start_fn.is_none() {
100+
if this.main_fns.len() >= 1u {
101+
let mut i = 1u;
102+
while i < this.main_fns.len() {
103+
let (_, dup_main_span) = this.main_fns[i].unwrap();
104+
this.session.span_err(
105+
dup_main_span,
106+
~"multiple 'main' functions");
107+
i += 1;
108+
}
109+
*this.session.entry_fn = this.main_fns[0];
110+
*this.session.entry_type = Some(session::EntryMain);
111+
}
112+
} else if !this.start_fn.is_none() {
113+
*this.session.entry_fn = this.start_fn;
114+
*this.session.entry_type = Some(session::EntryStart);
115+
} else {
116+
*this.session.entry_fn = this.attr_main_fn;
117+
*this.session.entry_type = Some(session::EntryMain);
118+
}
119+
}

src/librustc/middle/resolve.rs

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use driver::session;
1211
use driver::session::Session;
1312
use metadata::csearch::{each_path, get_trait_method_def_ids};
1413
use metadata::csearch::get_method_name_and_self_ty;
@@ -794,11 +793,6 @@ pub fn Resolver(session: Session,
794793
795794
namespaces: ~[ TypeNS, ValueNS ],
796795
797-
attr_main_fn: None,
798-
main_fns: ~[],
799-
800-
start_fn: None,
801-
802796
def_map: @mut HashMap::new(),
803797
export_map2: @mut HashMap::new(),
804798
trait_map: HashMap::new(),
@@ -856,15 +850,6 @@ pub struct Resolver {
856850
// The four namespaces.
857851
namespaces: ~[Namespace],
858852
859-
// The function that has attribute named 'main'
860-
attr_main_fn: Option<(node_id, span)>,
861-
862-
// The functions that could be main functions
863-
main_fns: ~[Option<(node_id, span)>],
864-
865-
// The function that has the attribute 'start' on it
866-
start_fn: Option<(node_id, span)>,
867-
868853
def_map: DefMap,
869854
export_map2: ExportMap2,
870855
trait_map: TraitMap,
@@ -885,7 +870,6 @@ pub impl Resolver {
885870
self.resolve_crate();
886871
self.session.abort_if_errors();
887872
888-
self.check_duplicate_main();
889873
self.check_for_unused_imports_if_necessary();
890874
}
891875
@@ -3544,40 +3528,6 @@ pub impl Resolver {
35443528
}
35453529

35463530
item_fn(ref fn_decl, _, _, ref generics, ref block) => {
3547-
// If this is the main function, we must record it in the
3548-
// session.
3549-
3550-
// FIXME #4404 android JNI hacks
3551-
if !*self.session.building_library ||
3552-
self.session.targ_cfg.os == session::os_android {
3553-
3554-
if self.attr_main_fn.is_none() &&
3555-
item.ident == special_idents::main {
3556-
3557-
self.main_fns.push(Some((item.id, item.span)));
3558-
}
3559-
3560-
if attrs_contains_name(item.attrs, ~"main") {
3561-
if self.attr_main_fn.is_none() {
3562-
self.attr_main_fn = Some((item.id, item.span));
3563-
} else {
3564-
self.session.span_err(
3565-
item.span,
3566-
~"multiple 'main' functions");
3567-
}
3568-
}
3569-
3570-
if attrs_contains_name(item.attrs, ~"start") {
3571-
if self.start_fn.is_none() {
3572-
self.start_fn = Some((item.id, item.span));
3573-
} else {
3574-
self.session.span_err(
3575-
item.span,
3576-
~"multiple 'start' functions");
3577-
}
3578-
}
3579-
}
3580-
35813531
self.resolve_function(OpaqueFunctionRibKind,
35823532
Some(fn_decl),
35833533
HasTypeParameters
@@ -5089,35 +5039,6 @@ pub impl Resolver {
50895039
}
50905040
}
50915041

5092-
//
5093-
// main function checking
5094-
//
5095-
// be sure that there is only one main function
5096-
//
5097-
fn check_duplicate_main(@mut self) {
5098-
let this = &mut *self;
5099-
if this.attr_main_fn.is_none() && this.start_fn.is_none() {
5100-
if this.main_fns.len() >= 1u {
5101-
let mut i = 1u;
5102-
while i < this.main_fns.len() {
5103-
let (_, dup_main_span) = this.main_fns[i].unwrap();
5104-
this.session.span_err(
5105-
dup_main_span,
5106-
~"multiple 'main' functions");
5107-
i += 1;
5108-
}
5109-
*this.session.entry_fn = this.main_fns[0];
5110-
*this.session.entry_type = Some(session::EntryMain);
5111-
}
5112-
} else if !this.start_fn.is_none() {
5113-
*this.session.entry_fn = this.start_fn;
5114-
*this.session.entry_type = Some(session::EntryStart);
5115-
} else {
5116-
*this.session.entry_fn = this.attr_main_fn;
5117-
*this.session.entry_type = Some(session::EntryMain);
5118-
}
5119-
}
5120-
51215042
//
51225043
// Unused import checking
51235044
//

src/librustc/rustc.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ pub mod middle {
100100
pub mod lang_items;
101101
pub mod privacy;
102102
pub mod moves;
103+
pub mod entry;
103104
}
104105

105106
pub mod front {

0 commit comments

Comments
 (0)