@@ -37,8 +37,9 @@ use middle::subst::Substs;
3737use middle:: ty:: { self , Ty } ;
3838use util:: nodemap:: NodeMap ;
3939
40+ use std:: ffi:: { CStr , CString } ;
4041use libc:: c_uint;
41- use syntax:: { ast, ast_util} ;
42+ use syntax:: { ast, ast_util, attr } ;
4243use syntax:: parse:: token;
4344use syntax:: ptr:: P ;
4445
@@ -898,37 +899,70 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
898899 "bad constant expression type in consts::const_expr" ) ,
899900 }
900901}
901-
902- pub fn trans_static ( ccx : & CrateContext , m : ast:: Mutability , id : ast:: NodeId ) -> ValueRef {
902+ pub fn trans_static ( ccx : & CrateContext ,
903+ m : ast:: Mutability ,
904+ expr : & ast:: Expr ,
905+ id : ast:: NodeId ,
906+ attrs : & Vec < ast:: Attribute > )
907+ -> ValueRef {
903908 unsafe {
904909 let _icx = push_ctxt ( "trans_static" ) ;
905910 let g = base:: get_item_val ( ccx, id) ;
906- // At this point, get_item_val has already translated the
907- // constant's initializer to determine its LLVM type.
908- let v = ccx. static_values ( ) . borrow ( ) . get ( & id) . unwrap ( ) . clone ( ) ;
911+
912+ let empty_substs = ccx. tcx ( ) . mk_substs ( Substs :: trans_empty ( ) ) ;
913+ let ( v, _) = const_expr ( ccx, expr, empty_substs, None ) ;
914+
909915 // boolean SSA values are i1, but they have to be stored in i8 slots,
910916 // otherwise some LLVM optimization passes don't work as expected
911- let v = if llvm:: LLVMTypeOf ( v) == Type :: i1 ( ccx) . to_ref ( ) {
912- llvm:: LLVMConstZExt ( v, Type :: i8 ( ccx) . to_ref ( ) )
917+ let mut val_llty = llvm:: LLVMTypeOf ( v) ;
918+ let v = if val_llty == Type :: i1 ( ccx) . to_ref ( ) {
919+ val_llty = Type :: i8 ( ccx) . to_ref ( ) ;
920+ llvm:: LLVMConstZExt ( v, val_llty)
913921 } else {
914922 v
915923 } ;
924+
925+ let ty = ccx. tcx ( ) . node_id_to_type ( id) ;
926+ let llty = type_of:: type_of ( ccx, ty) ;
927+ let g = if val_llty == llty. to_ref ( ) {
928+ g
929+ } else {
930+ // If we created the global with the wrong type,
931+ // correct the type.
932+ let empty_string = CString :: new ( "" ) . unwrap ( ) ;
933+ let name_str_ref = CStr :: from_ptr ( llvm:: LLVMGetValueName ( g) ) ;
934+ let name_string = CString :: new ( name_str_ref. to_bytes ( ) ) . unwrap ( ) ;
935+ llvm:: LLVMSetValueName ( g, empty_string. as_ptr ( ) ) ;
936+ let new_g = llvm:: LLVMGetOrInsertGlobal (
937+ ccx. llmod ( ) , name_string. as_ptr ( ) , val_llty) ;
938+ // To avoid breaking any invariants, we leave around the old
939+ // global for the moment; we'll replace all references to it
940+ // with the new global later. (See base::trans_crate.)
941+ ccx. statics_to_rauw ( ) . borrow_mut ( ) . push ( ( g, new_g) ) ;
942+ new_g
943+ } ;
916944 llvm:: LLVMSetInitializer ( g, v) ;
917945
918946 // As an optimization, all shared statics which do not have interior
919947 // mutability are placed into read-only memory.
920948 if m != ast:: MutMutable {
921- let node_ty = ccx. tcx ( ) . node_id_to_type ( id) ;
922- let tcontents = node_ty. type_contents ( ccx. tcx ( ) ) ;
949+ let tcontents = ty. type_contents ( ccx. tcx ( ) ) ;
923950 if !tcontents. interior_unsafe ( ) {
924- llvm:: LLVMSetGlobalConstant ( g, True ) ;
951+ llvm:: LLVMSetGlobalConstant ( g, llvm :: True ) ;
925952 }
926953 }
954+
927955 debuginfo:: create_global_var_metadata ( ccx, id, g) ;
956+
957+ if attr:: contains_name ( attrs,
958+ "thread_local" ) {
959+ llvm:: set_thread_local ( g, true ) ;
960+ }
928961 g
929962 }
930963}
931964
965+
932966fn get_static_val < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > , did : ast:: DefId ,
933967 ty : Ty < ' tcx > ) -> ValueRef {
934968 if ast_util:: is_local ( did) { return base:: get_item_val ( ccx, did. node ) }
0 commit comments