Skip to content

Commit be8dc61

Browse files
committed
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 3290110 commit be8dc61

File tree

4 files changed

+122
-79
lines changed

4 files changed

+122
-79
lines changed

src/librustc/driver/driver.rs

+2
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

+119
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

-79
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
@@ -3545,40 +3529,6 @@ pub impl Resolver {
35453529
}
35463530

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

5112-
//
5113-
// main function checking
5114-
//
5115-
// be sure that there is only one main function
5116-
//
5117-
fn check_duplicate_main(@mut self) {
5118-
let this = &mut *self;
5119-
if this.attr_main_fn.is_none() && this.start_fn.is_none() {
5120-
if this.main_fns.len() >= 1u {
5121-
let mut i = 1u;
5122-
while i < this.main_fns.len() {
5123-
let (_, dup_main_span) = this.main_fns[i].unwrap();
5124-
this.session.span_err(
5125-
dup_main_span,
5126-
~"multiple 'main' functions");
5127-
i += 1;
5128-
}
5129-
*this.session.entry_fn = this.main_fns[0];
5130-
*this.session.entry_type = Some(session::EntryMain);
5131-
}
5132-
} else if !this.start_fn.is_none() {
5133-
*this.session.entry_fn = this.start_fn;
5134-
*this.session.entry_type = Some(session::EntryStart);
5135-
} else {
5136-
*this.session.entry_fn = this.attr_main_fn;
5137-
*this.session.entry_type = Some(session::EntryMain);
5138-
}
5139-
}
5140-
51415062
//
51425063
// Unused import checking
51435064
//

src/librustc/rustc.rc

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ pub mod middle {
9696
pub mod lang_items;
9797
pub mod privacy;
9898
pub mod moves;
99+
pub mod entry;
99100
}
100101

101102
pub mod front {

0 commit comments

Comments
 (0)