about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-04-29 14:56:05 -0700
committerBrian Anderson <banderson@mozilla.com>2013-04-29 14:56:05 -0700
commitbe8dc615c566104c528ca8389fa0807c8453c8a8 (patch)
treed632faeeae489a72b8b93608851dea0f357a165f /src
parent32901104cb54a37211ac1c05f377f69ee702485c (diff)
downloadrust-be8dc615c566104c528ca8389fa0807c8453c8a8.tar.gz
rust-be8dc615c566104c528ca8389fa0807c8453c8a8.zip
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 #4433
Diffstat (limited to 'src')
-rw-r--r--src/librustc/driver/driver.rs2
-rw-r--r--src/librustc/middle/entry.rs119
-rw-r--r--src/librustc/middle/resolve.rs79
-rw-r--r--src/librustc/rustc.rc1
4 files changed, 122 insertions, 79 deletions
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index 2e64c0c45bf..e421246da8d 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -225,6 +225,8 @@ pub fn compile_rest(sess: Session,
         time(time_passes, ~"resolution", ||
              middle::resolve::resolve_crate(sess, lang_items, crate));
 
+    time(time_passes, ~"looking for entry point", || middle::entry::find_entry_point(sess, crate));
+
     let freevars = time(time_passes, ~"freevar finding", ||
         freevars::annotate_freevars(def_map, crate));
 
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
new file mode 100644
index 00000000000..18f4a5a3072
--- /dev/null
+++ b/src/librustc/middle/entry.rs
@@ -0,0 +1,119 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use driver::session;
+use driver::session::Session;
+use syntax::parse::token::special_idents;
+use syntax::ast::{crate, node_id, item, item_fn};
+use syntax::codemap::span;
+use syntax::visit::{default_visitor, mk_vt, vt, Visitor, visit_crate, visit_item};
+use syntax::attr::{attrs_contains_name};
+
+struct EntryContext {
+    session: Session,
+
+    // The function that has attribute named 'main'
+    attr_main_fn: Option<(node_id, span)>,
+
+    // The functions that could be main functions
+    main_fns: ~[Option<(node_id, span)>],
+
+    // The function that has the attribute 'start' on it
+    start_fn: Option<(node_id, span)>,
+}
+
+type EntryVisitor = vt<@mut EntryContext>;
+
+pub fn find_entry_point(session: Session, crate: @crate) {
+
+    let ctxt = @mut EntryContext {
+        session: session,
+        attr_main_fn: None,
+        main_fns: ~[],
+        start_fn: None,
+    };
+
+    visit_crate(crate, ctxt, mk_vt(@Visitor {
+        visit_item: |item, ctxt, visitor| find_item(item, ctxt, visitor),
+        .. *default_visitor()
+    }));
+
+    check_duplicate_main(ctxt);
+}
+
+fn find_item(item: @item, ctxt: @mut EntryContext, visitor: EntryVisitor) {
+    match item.node {
+        item_fn(*) => {
+            // If this is the main function, we must record it in the
+            // session.
+
+            // FIXME #4404 android JNI hacks
+            if !*ctxt.session.building_library ||
+                ctxt.session.targ_cfg.os == session::os_android {
+
+                if ctxt.attr_main_fn.is_none() &&
+                    item.ident == special_idents::main {
+
+                    ctxt.main_fns.push(Some((item.id, item.span)));
+                }
+
+                if attrs_contains_name(item.attrs, ~"main") {
+                    if ctxt.attr_main_fn.is_none() {
+                        ctxt.attr_main_fn = Some((item.id, item.span));
+                    } else {
+                        ctxt.session.span_err(
+                            item.span,
+                            ~"multiple 'main' functions");
+                    }
+                }
+
+                if attrs_contains_name(item.attrs, ~"start") {
+                    if ctxt.start_fn.is_none() {
+                        ctxt.start_fn = Some((item.id, item.span));
+                    } else {
+                        ctxt.session.span_err(
+                            item.span,
+                            ~"multiple 'start' functions");
+                    }
+                }
+            }
+        }
+        _ => ()
+    }
+
+    visit_item(item, ctxt, visitor);
+}
+
+// main function checking
+//
+// be sure that there is only one main function
+fn check_duplicate_main(ctxt: @mut EntryContext) {
+    let this = &mut *ctxt;
+    if this.attr_main_fn.is_none() && this.start_fn.is_none() {
+        if this.main_fns.len() >= 1u {
+            let mut i = 1u;
+            while i < this.main_fns.len() {
+                let (_, dup_main_span) = this.main_fns[i].unwrap();
+                this.session.span_err(
+                    dup_main_span,
+                    ~"multiple 'main' functions");
+                i += 1;
+            }
+            *this.session.entry_fn = this.main_fns[0];
+            *this.session.entry_type = Some(session::EntryMain);
+        }
+    } else if !this.start_fn.is_none() {
+        *this.session.entry_fn = this.start_fn;
+        *this.session.entry_type = Some(session::EntryStart);
+    } else {
+        *this.session.entry_fn = this.attr_main_fn;
+        *this.session.entry_type = Some(session::EntryMain);
+    }
+}
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 5354ffc5d3c..b0dd627c59f 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use driver::session;
 use driver::session::Session;
 use metadata::csearch::{each_path, get_trait_method_def_ids};
 use metadata::csearch::get_method_name_and_self_ty;
@@ -794,11 +793,6 @@ pub fn Resolver(session: Session,
 
         namespaces: ~[ TypeNS, ValueNS ],
 
-        attr_main_fn: None,
-        main_fns: ~[],
-
-        start_fn: None,
-
         def_map: @mut HashMap::new(),
         export_map2: @mut HashMap::new(),
         trait_map: HashMap::new(),
@@ -856,15 +850,6 @@ pub struct Resolver {
     // The four namespaces.
     namespaces: ~[Namespace],
 
-    // The function that has attribute named 'main'
-    attr_main_fn: Option<(node_id, span)>,
-
-    // The functions that could be main functions
-    main_fns: ~[Option<(node_id, span)>],
-
-    // The function that has the attribute 'start' on it
-    start_fn: Option<(node_id, span)>,
-
     def_map: DefMap,
     export_map2: ExportMap2,
     trait_map: TraitMap,
@@ -885,7 +870,6 @@ pub impl Resolver {
         self.resolve_crate();
         self.session.abort_if_errors();
 
-        self.check_duplicate_main();
         self.check_for_unused_imports_if_necessary();
     }
 
@@ -3545,40 +3529,6 @@ pub impl Resolver {
             }
 
             item_fn(ref fn_decl, _, _, ref generics, ref block) => {
-                // If this is the main function, we must record it in the
-                // session.
-
-                // FIXME #4404 android JNI hacks
-                if !*self.session.building_library ||
-                    self.session.targ_cfg.os == session::os_android {
-
-                    if self.attr_main_fn.is_none() &&
-                           item.ident == special_idents::main {
-
-                        self.main_fns.push(Some((item.id, item.span)));
-                    }
-
-                    if attrs_contains_name(item.attrs, ~"main") {
-                        if self.attr_main_fn.is_none() {
-                            self.attr_main_fn = Some((item.id, item.span));
-                        } else {
-                            self.session.span_err(
-                                    item.span,
-                                    ~"multiple 'main' functions");
-                        }
-                    }
-
-                    if attrs_contains_name(item.attrs, ~"start") {
-                        if self.start_fn.is_none() {
-                            self.start_fn = Some((item.id, item.span));
-                        } else {
-                            self.session.span_err(
-                                    item.span,
-                                    ~"multiple 'start' functions");
-                        }
-                    }
-                }
-
                 self.resolve_function(OpaqueFunctionRibKind,
                                       Some(fn_decl),
                                       HasTypeParameters
@@ -5110,35 +5060,6 @@ pub impl Resolver {
     }
 
     //
-    // main function checking
-    //
-    // be sure that there is only one main function
-    //
-    fn check_duplicate_main(@mut self) {
-        let this = &mut *self;
-        if this.attr_main_fn.is_none() && this.start_fn.is_none() {
-            if this.main_fns.len() >= 1u {
-                let mut i = 1u;
-                while i < this.main_fns.len() {
-                    let (_, dup_main_span) = this.main_fns[i].unwrap();
-                    this.session.span_err(
-                        dup_main_span,
-                        ~"multiple 'main' functions");
-                    i += 1;
-                }
-                *this.session.entry_fn = this.main_fns[0];
-                *this.session.entry_type = Some(session::EntryMain);
-            }
-        } else if !this.start_fn.is_none() {
-            *this.session.entry_fn = this.start_fn;
-            *this.session.entry_type = Some(session::EntryStart);
-        } else {
-            *this.session.entry_fn = this.attr_main_fn;
-            *this.session.entry_type = Some(session::EntryMain);
-        }
-    }
-
-    //
     // Unused import checking
     //
     // Although this is a lint pass, it lives in here because it depends on
diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc
index 54c51cf2e48..82cf4cbaf54 100644
--- a/src/librustc/rustc.rc
+++ b/src/librustc/rustc.rc
@@ -96,6 +96,7 @@ pub mod middle {
     pub mod lang_items;
     pub mod privacy;
     pub mod moves;
+    pub mod entry;
 }
 
 pub mod front {