@@ -118,6 +118,7 @@ state type crate_ctxt = rec(session::session sess,
118
118
hashmap[ ast:: def_id,
119
119
@ast:: native_item] native_items ,
120
120
hashmap[ ast:: def_id, str] item_symbols ,
121
+ mutable option:: t[ ValueRef ] main_fn ,
121
122
// TODO: hashmap[tup(tag_id,subtys), @tag_info]
122
123
hashmap[ ty:: t, uint] tag_sizes ,
123
124
hashmap[ ast:: def_id, ValueRef ] discrims ,
@@ -308,19 +309,10 @@ tag block_parent {
308
309
state type result = rec ( @block_ctxt bcx,
309
310
ValueRef val) ;
310
311
311
- fn sep ( ) -> str {
312
- ret "_" ;
313
- }
314
-
315
312
fn extend_path ( @local_ctxt cx , & str name ) -> @local_ctxt {
316
313
ret @rec( path = cx. path + [ name] with * cx) ;
317
314
}
318
315
319
- fn path_name ( & vec[ str] path ) -> str {
320
- ret str:: connect ( path, sep ( ) ) ;
321
- }
322
-
323
-
324
316
fn get_type_sha1 ( & @crate_ctxt ccx , & ty:: t t) -> str {
325
317
auto hash = "" ;
326
318
alt ( ccx. type_sha1s . find ( t) ) {
@@ -336,15 +328,31 @@ fn get_type_sha1(&@crate_ctxt ccx, &ty::t t) -> str {
336
328
337
329
ccx. sha . input_str ( metadata:: Encode :: ty_str ( cx, t) ) ;
338
330
hash = str:: substr ( ccx. sha . result_str ( ) , 0 u, 16 u) ;
331
+ // Prefix with _ so that it never blends into adjacent digits
332
+ hash = "_" + hash;
339
333
ccx. type_sha1s . insert ( t, hash) ;
340
334
}
341
335
}
342
336
ret hash;
343
337
}
344
338
339
+ fn mangle ( & vec[ str] ss ) -> str {
340
+
341
+ // Follow C++ namespace-mangling style
342
+
343
+ auto n = "_ZN" ; // Begin name-sequence.
344
+
345
+ for ( str s in ss) {
346
+ n += #fmt ( "%u%s" , str:: byte_len ( s) , s) ;
347
+ }
348
+
349
+ n += "E" ; // End name-sequence.
350
+ ret n;
351
+ }
352
+
345
353
fn mangle_name_by_type ( & @crate_ctxt ccx , & vec[ str] path , & ty:: t t) -> str {
346
354
auto hash = get_type_sha1 ( ccx, t) ;
347
- ret sep ( ) + "rust" + sep ( ) + hash + sep ( ) + path_name ( path ) ;
355
+ ret mangle ( path + [ hash] ) ;
348
356
}
349
357
350
358
fn mangle_name_by_type_only ( & @crate_ctxt ccx , & ty:: t t, & str name ) -> str {
@@ -353,14 +361,20 @@ fn mangle_name_by_type_only(&@crate_ctxt ccx, &ty::t t, &str name) -> str {
353
361
auto s = ty:: ty_to_short_str ( ccx. tcx , t) ;
354
362
355
363
auto hash = get_type_sha1 ( ccx, t) ;
356
- ret sep( ) + "rust" + sep ( ) + hash + sep ( ) + name + "_" + s;
364
+ ret mangle( [ name, s, hash] ) ;
365
+ }
366
+
367
+ fn mangle_name_by_path_and_seq ( & @crate_ctxt ccx , & vec[ str] path ,
368
+ & str flav ) -> str {
369
+ ret mangle ( path + [ ccx. names . next ( flav) ] ) ;
370
+ }
371
+
372
+ fn mangle_name_by_path ( & @crate_ctxt ccx , & vec[ str] path ) -> str {
373
+ ret mangle ( path) ;
357
374
}
358
375
359
- fn mangle_name_by_seq ( & @crate_ctxt ccx , & vec[ str] path ,
360
- & str flav ) -> str {
361
- ret sep ( ) + "rust" + sep ( )
362
- + ccx. names . next ( flav) + sep ( )
363
- + path_name ( path) ;
376
+ fn mangle_name_by_seq ( & @crate_ctxt ccx , & str flav ) -> str {
377
+ ret ccx. names . next ( flav) ;
364
378
}
365
379
366
380
fn res ( @block_ctxt bcx , ValueRef val) -> result {
@@ -1903,7 +1917,7 @@ fn declare_tydesc(&@local_ctxt cx, &span sp, &ty::t t,
1903
1917
name = mangle_name_by_type_only( cx. ccx, t, "tydesc" ) ;
1904
1918
name = sanitize( name) ;
1905
1919
} else {
1906
- name = mangle_name_by_seq( cx. ccx, cx . path , "tydesc" ) ;
1920
+ name = mangle_name_by_seq( cx. ccx, "tydesc" ) ;
1907
1921
}
1908
1922
1909
1923
auto gvar = llvm:: LLVMAddGlobal ( ccx. llmod, T_tydesc ( ccx. tn) ,
@@ -1937,7 +1951,7 @@ fn declare_generic_glue(&@local_ctxt cx,
1937
1951
fn_nm = mangle_name_by_type_only( cx. ccx, t, "glue_" + name) ;
1938
1952
fn_nm = sanitize( fn_nm) ;
1939
1953
} else {
1940
- fn_nm = mangle_name_by_seq( cx. ccx, cx . path , "glue_" + name) ;
1954
+ fn_nm = mangle_name_by_seq( cx. ccx, "glue_" + name) ;
1941
1955
}
1942
1956
auto llfn = decl_fastcall_fn( cx. ccx. llmod, fn_nm, llfnty) ;
1943
1957
set_glue_inlining( cx, llfn, t) ;
@@ -4093,7 +4107,7 @@ fn trans_for_each(&@block_ctxt cx,
4093
4107
4094
4108
// Step 2: Declare foreach body function.
4095
4109
4096
- let str s = mangle_name_by_seq ( lcx. ccx, lcx. path, "foreach" ) ;
4110
+ let str s = mangle_name_by_path_and_seq ( lcx. ccx, lcx. path, "foreach" ) ;
4097
4111
4098
4112
// The 'env' arg entering the body function is a fake env member (as in
4099
4113
// the env-part of the normal rust calling convention) that actually
@@ -4792,7 +4806,7 @@ fn trans_bind_thunk(&@local_ctxt cx,
4792
4806
// Construct a thunk-call with signature incoming_fty, and that copies
4793
4807
// args forward into a call to outgoing_fty:
4794
4808
4795
- let str s = mangle_name_by_seq ( cx. ccx , cx. path , "thunk" ) ;
4809
+ let str s = mangle_name_by_path_and_seq ( cx. ccx , cx. path , "thunk" ) ;
4796
4810
let TypeRef llthunk_ty = get_pair_fn_ty ( type_of ( cx. ccx , sp,
4797
4811
incoming_fty) ) ;
4798
4812
let ValueRef llthunk = decl_internal_fastcall_fn ( cx. ccx . llmod ,
@@ -6225,9 +6239,10 @@ fn mk_spawn_wrapper(&@block_ctxt cx,
6225
6239
0 u) ;
6226
6240
6227
6241
// TODO: construct a name based on tname
6228
- let str wrap_name = mangle_name_by_seq ( cx. fcx . lcx . ccx ,
6229
- [ "" ] ,
6230
- "spawn_wrapper" ) ;
6242
+ let str wrap_name =
6243
+ mangle_name_by_path_and_seq ( cx. fcx . lcx . ccx ,
6244
+ cx. fcx . lcx . path ,
6245
+ "spawn_wrapper" ) ;
6231
6246
auto llfndecl = decl_fastcall_fn ( llmod, wrap_name,
6232
6247
wrapper_fn_type) ;
6233
6248
@@ -7078,8 +7093,9 @@ fn create_vtbl(@local_ctxt cx,
7078
7093
}
7079
7094
}
7080
7095
7081
- let @local_ctxt mcx = extend_path( cx, m. node. ident) ;
7082
- let str s = mangle_name_by_seq( mcx. ccx, mcx. path, "method" ) ;
7096
+ let @local_ctxt mcx = @rec( path = cx. path + [ "method" ,
7097
+ m. node. ident] with * cx) ;
7098
+ let str s = mangle_name_by_path( mcx. ccx, mcx. path) ;
7083
7099
let ValueRef llfn = decl_internal_fastcall_fn( cx. ccx. llmod, s,
7084
7100
llfnty) ;
7085
7101
cx. ccx. item_ids. insert( m. node. id, llfn) ;
@@ -7091,7 +7107,7 @@ fn create_vtbl(@local_ctxt cx,
7091
7107
methods += [ llfn] ;
7092
7108
}
7093
7109
auto vtbl = C_struct ( methods) ;
7094
- auto vtbl_name = mangle_name_by_seq ( cx. ccx, cx. path, "vtbl" ) ;
7110
+ auto vtbl_name = mangle_name_by_path ( cx. ccx, cx. path + [ "vtbl" ] ) ;
7095
7111
auto gvar = llvm:: LLVMAddGlobal ( cx. ccx. llmod, val_ty( vtbl) ,
7096
7112
str:: buf( vtbl_name) ) ;
7097
7113
llvm:: LLVMSetInitializer ( gvar, vtbl) ;
@@ -7108,13 +7124,12 @@ fn trans_dtor(@local_ctxt cx,
7108
7124
& @ast:: method dtor) -> ValueRef {
7109
7125
7110
7126
auto llfnty = T_dtor ( cx. ccx, dtor. span, llself_ty) ;
7111
- let @local_ctxt dcx = extend_path( cx, "drop") ;
7112
- let str s = mangle_name_by_seq( dcx. ccx, dcx. path, "drop") ;
7127
+ let str s = mangle_name_by_path( cx. ccx, cx. path + [ "drop"] ) ;
7113
7128
let ValueRef llfn = decl_internal_fastcall_fn( cx. ccx. llmod, s, llfnty) ;
7114
7129
cx. ccx. item_ids. insert( dtor. node. id, llfn) ;
7115
7130
cx. ccx. item_symbols. insert( dtor. node. id, s) ;
7116
7131
7117
- trans_fn( dcx , dtor. span, dtor. node. meth, dtor. node. id,
7132
+ trans_fn( cx , dtor. span, dtor. node. meth, dtor. node. id,
7118
7133
some[ ty_self_pair] ( tup( llself_ty, self_ty) ) ,
7119
7134
ty_params, dtor. node. ann) ;
7120
7135
@@ -7503,13 +7518,22 @@ fn decl_fn_and_pair(&@crate_ctxt ccx, &span sp,
7503
7518
}
7504
7519
7505
7520
// Declare the function itself.
7506
- let str s = mangle_name_by_seq ( ccx, path, flav ) ;
7521
+ let str s = mangle_name_by_path ( ccx, path) ;
7507
7522
let ValueRef llfn = decl_internal_fastcall_fn( ccx. llmod, s, llfty) ;
7508
7523
7509
7524
// Declare the global constant pair that points to it.
7510
7525
let str ps = mangle_name_by_type( ccx, path, node_ann_type( ccx, ann) ) ;
7511
7526
7512
7527
register_fn_pair( ccx, ps, llpairty, llfn, id) ;
7528
+
7529
+ if ( str:: eq( vec:: top( path) , "main" ) &&
7530
+ !ccx. sess. get_opts( ) . shared) {
7531
+ if ( ccx. main_fn != none[ ValueRef ] ) {
7532
+ ccx. sess. span_err( sp, "multiple 'main' functions" ) ;
7533
+ }
7534
+ log #fmt( "registering %s as main function for crate" , ps) ;
7535
+ ccx. main_fn = some( llfn) ;
7536
+ }
7513
7537
}
7514
7538
7515
7539
fn register_fn_pair( & @crate_ctxt cx, str ps, TypeRef llpairty, ValueRef llfn,
@@ -7569,7 +7593,7 @@ fn decl_native_fn_and_pair(&@crate_ctxt ccx,
7569
7593
// Declare the wrapper.
7570
7594
auto t = node_ann_type( ccx, ann) ;
7571
7595
auto wrapper_type = native_fn_wrapper_type( ccx, sp, num_ty_param, t) ;
7572
- let str s = mangle_name_by_seq ( ccx, path, "wrapper" ) ;
7596
+ let str s = mangle_name_by_path ( ccx, path) ;
7573
7597
let ValueRef wrapper_fn = decl_internal_fastcall_fn( ccx. llmod, s,
7574
7598
wrapper_type) ;
7575
7599
@@ -7912,9 +7936,8 @@ fn trans_constant(&@crate_ctxt ccx, @walk_ctxt wcx, &@ast::item it) {
7912
7936
7913
7937
auto discrim_val = C_int ( i as int ) ;
7914
7938
7915
- auto s = mangle_name_by_seq ( ccx, wcx. path ,
7916
- #fmt ( "_rust_tag_discrim_%s_%u" ,
7917
- ident, i) ) ;
7939
+ auto p = wcx. path + [ ident, variant. node . name , "discrim" ] ;
7940
+ auto s = mangle_name_by_type ( ccx, p, ty:: mk_int ( ccx. tcx ) ) ;
7918
7941
auto discrim_gvar = llvm:: LLVMAddGlobal ( ccx. llmod , T_int ( ) ,
7919
7942
str:: buf ( s) ) ;
7920
7943
@@ -7973,29 +7996,6 @@ fn create_typedefs(&@crate_ctxt cx) {
7973
7996
llvm:: LLVMAddTypeName ( cx. llmod , str:: buf ( "tydesc" ) , T_tydesc ( cx. tn ) ) ;
7974
7997
}
7975
7998
7976
- fn find_main_fn ( & @crate_ctxt cx ) -> ValueRef {
7977
- auto e = sep ( ) + "main" ;
7978
- let ValueRef v = C_nil ( ) ;
7979
- let uint n = 0 u;
7980
- for each ( @tup( ast:: def_id, str) i in cx. item_symbols . items ( ) ) {
7981
- if ( str:: ends_with ( i. _1 , e) ) {
7982
- n += 1 u;
7983
- v = cx. item_ids . get ( i. _0 ) ;
7984
- }
7985
- }
7986
- alt ( n) {
7987
- case ( 0 u) {
7988
- cx. sess . err ( "main fn not found" ) ;
7989
- }
7990
- case ( 1 u) {
7991
- ret v;
7992
- }
7993
- case ( _) {
7994
- cx. sess . err ( "multiple main fns found" ) ;
7995
- }
7996
- }
7997
- }
7998
-
7999
7999
fn trans_main_fn ( @local_ctxt cx , ValueRef crate_map ) {
8000
8000
auto T_main_args = [ T_int ( ) , T_int ( ) ] ;
8001
8001
auto T_rust_start_args = [ T_int ( ) , T_int ( ) , T_int ( ) , T_int ( ) ] ;
@@ -8015,7 +8015,14 @@ fn trans_main_fn(@local_ctxt cx, ValueRef crate_map) {
8015
8015
8016
8016
auto llargc = llvm:: LLVMGetParam ( llmain, 0 u) ;
8017
8017
auto llargv = llvm:: LLVMGetParam ( llmain, 1 u) ;
8018
- auto llrust_main = find_main_fn ( cx. ccx ) ;
8018
+ auto llrust_main = alt ( cx. ccx . main_fn ) {
8019
+ case ( none) {
8020
+ cx. ccx . sess . err ( "missing 'main' function" ) ;
8021
+ // FIXME: shouldn't sess.err's ! result unify with f?
8022
+ C_nil ( )
8023
+ }
8024
+ case ( some ( ?f) ) { f }
8025
+ } ;
8019
8026
8020
8027
//
8021
8028
// Emit the moral equivalent of:
@@ -8283,6 +8290,7 @@ fn trans_crate(&session::session sess, &@ast::crate crate,
8283
8290
items = new_def_hash[ @ast:: item] ( ) ,
8284
8291
native_items = new_def_hash[ @ast:: native_item] ( ) ,
8285
8292
item_symbols = new_def_hash[ str] ( ) ,
8293
+ mutable main_fn = none[ ValueRef ] ,
8286
8294
tag_sizes = tag_sizes,
8287
8295
discrims = new_def_hash[ ValueRef ] ( ) ,
8288
8296
discrim_symbols = new_def_hash[ str] ( ) ,
0 commit comments