allowing the entry point name to be something other than main
add build tests
This commit is contained in:
parent
0e8490757f
commit
b7cefd0c96
@ -25,6 +25,7 @@ use syntax::codemap::span;
|
||||
use syntax::fold;
|
||||
use syntax::print::pprust;
|
||||
use syntax::{ast, ast_util};
|
||||
use syntax::attr::attrs_contains_name;
|
||||
|
||||
export modify_for_testing;
|
||||
|
||||
@ -88,13 +89,11 @@ fn fold_mod(cx: test_ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod {
|
||||
// Remove any defined main function from the AST so it doesn't clash with
|
||||
// the one we're going to add. Only if compiling an executable.
|
||||
|
||||
// FIXME (#2403): This is sloppy. Instead we should have some mechanism to
|
||||
// indicate to the translation pass which function we want to be main.
|
||||
fn nomain(cx: test_ctxt, item: @ast::item) -> Option<@ast::item> {
|
||||
match item.node {
|
||||
ast::item_fn(*) => {
|
||||
if item.ident == cx.sess.ident_of(~"main")
|
||||
&& !cx.sess.building_library {
|
||||
if attrs_contains_name(item.attrs, ~"main")
|
||||
&& !cx.sess.building_library {
|
||||
option::None
|
||||
} else { option::Some(item) }
|
||||
}
|
||||
@ -498,7 +497,7 @@ fn mk_main(cx: test_ctxt) -> @ast::item {
|
||||
let item_ = ast::item_fn(decl, ast::impure_fn, ~[], body);
|
||||
let item: ast::item =
|
||||
{ident: cx.sess.ident_of(~"main"),
|
||||
attrs: ~[],
|
||||
attrs: ~[attr::mk_attr(attr::mk_word_item(~"main"))],
|
||||
id: cx.sess.next_node_id(),
|
||||
node: item_,
|
||||
vis: ast::public,
|
||||
|
@ -59,7 +59,7 @@ use syntax::ast_util::{def_id_of_def, dummy_sp, local_def};
|
||||
use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
|
||||
use syntax::ast_util::{Privacy, Public, Private, visibility_to_privacy};
|
||||
use syntax::ast_util::has_legacy_export_attr;
|
||||
use syntax::attr::{attr_metas, contains_name};
|
||||
use syntax::attr::{attr_metas, contains_name, attrs_contains_name};
|
||||
use syntax::parse::token::ident_interner;
|
||||
use syntax::parse::token::special_idents;
|
||||
use syntax::print::pprust::{pat_to_str, path_to_str};
|
||||
@ -857,6 +857,9 @@ fn Resolver(session: Session, lang_items: LanguageItems,
|
||||
|
||||
namespaces: ~[ TypeNS, ValueNS ],
|
||||
|
||||
attr_main_fn: None,
|
||||
main_fns: ~[],
|
||||
|
||||
def_map: HashMap(),
|
||||
export_map2: HashMap(),
|
||||
trait_map: @HashMap(),
|
||||
@ -916,6 +919,11 @@ struct Resolver {
|
||||
// The four namespaces.
|
||||
namespaces: ~[Namespace],
|
||||
|
||||
// The function that has attribute named 'main'
|
||||
mut attr_main_fn: Option<(node_id, span)>,
|
||||
// The functions named 'main'
|
||||
mut main_fns: ~[Option<(node_id, span)>],
|
||||
|
||||
def_map: DefMap,
|
||||
export_map2: ExportMap2,
|
||||
trait_map: TraitMap,
|
||||
@ -937,6 +945,7 @@ impl Resolver {
|
||||
self.resolve_crate();
|
||||
self.session.abort_if_errors();
|
||||
|
||||
self.check_duplicate_main();
|
||||
self.check_for_unused_imports_if_necessary();
|
||||
}
|
||||
|
||||
@ -3923,15 +3932,22 @@ impl Resolver {
|
||||
item_fn(ref fn_decl, _, ref ty_params, ref block) => {
|
||||
// If this is the main function, we must record it in the
|
||||
// session.
|
||||
//
|
||||
// For speed, we put the string comparison last in this chain
|
||||
// of conditionals.
|
||||
if !self.session.building_library {
|
||||
if self.attr_main_fn.is_none() &&
|
||||
item.ident == special_idents::main {
|
||||
|
||||
if !self.session.building_library &&
|
||||
is_none(&self.session.main_fn) &&
|
||||
item.ident == special_idents::main {
|
||||
self.main_fns.push(Some((item.id, item.span)));
|
||||
}
|
||||
|
||||
self.session.main_fn = 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.resolve_function(OpaqueFunctionRibKind,
|
||||
@ -5353,6 +5369,30 @@ impl Resolver {
|
||||
self.def_map.insert(node_id, def);
|
||||
}
|
||||
|
||||
//
|
||||
// main function checking
|
||||
//
|
||||
// be sure that there is only one main function
|
||||
//
|
||||
fn check_duplicate_main() {
|
||||
if self.attr_main_fn.is_none() {
|
||||
if self.main_fns.len() >= 1u {
|
||||
let mut i = 1u;
|
||||
while i < self.main_fns.len() {
|
||||
let (_, dup_main_span) =
|
||||
option::unwrap(self.main_fns[i]);
|
||||
self.session.span_err(
|
||||
dup_main_span,
|
||||
~"multiple 'main' functions");
|
||||
i += 1;
|
||||
}
|
||||
self.session.main_fn = self.main_fns[0];
|
||||
}
|
||||
} else {
|
||||
self.session.main_fn = self.attr_main_fn;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Unused import checking
|
||||
//
|
||||
|
@ -2153,13 +2153,21 @@ fn register_fn_fuller(ccx: @crate_ctxt,
|
||||
ccx.item_symbols.insert(node_id, ps);
|
||||
|
||||
// FIXME #4404 android JNI hacks
|
||||
let is_main = is_main_name(path) && (!ccx.sess.building_library ||
|
||||
let is_main = is_main_fn(&ccx.sess, node_id) &&
|
||||
(!ccx.sess.building_library ||
|
||||
(ccx.sess.building_library &&
|
||||
ccx.sess.targ_cfg.os == session::os_android));
|
||||
if is_main { create_main_wrapper(ccx, sp, llfn); }
|
||||
llfn
|
||||
}
|
||||
|
||||
fn is_main_fn(sess: &Session, node_id: ast::node_id) -> bool {
|
||||
match sess.main_fn {
|
||||
Some((main_id, _)) => node_id == main_id,
|
||||
None => false
|
||||
}
|
||||
}
|
||||
|
||||
// Create a _rust_main(args: ~[str]) function which will be called from the
|
||||
// runtime rust_start function
|
||||
fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef) {
|
||||
|
17
src/test/compile-fail/multiple-main-2.rs
Normal file
17
src/test/compile-fail/multiple-main-2.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// 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.
|
||||
|
||||
#[main]
|
||||
fn bar() {
|
||||
}
|
||||
|
||||
#[main]
|
||||
fn foo() { //~ ERROR multiple 'main' functions
|
||||
}
|
19
src/test/compile-fail/multiple-main-3.rs
Normal file
19
src/test/compile-fail/multiple-main-3.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// 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.
|
||||
|
||||
#[main]
|
||||
fn main1() {
|
||||
}
|
||||
|
||||
mod foo {
|
||||
#[main]
|
||||
fn main2() { //~ ERROR multiple 'main' functions
|
||||
}
|
||||
}
|
17
src/test/run-pass/attr-main-2.rs
Normal file
17
src/test/run-pass/attr-main-2.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// 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.
|
||||
|
||||
fn main() {
|
||||
fail
|
||||
}
|
||||
|
||||
#[main]
|
||||
fn foo() {
|
||||
}
|
13
src/test/run-pass/attr-main.rs
Normal file
13
src/test/run-pass/attr-main.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// 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.
|
||||
|
||||
#[main]
|
||||
fn foo() {
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user