Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 25281b1

Browse files
committedJul 22, 2015
Auto merge of #27176 - alexcrichton:fix-stock-llvm, r=brson
This commit moves the IR files in the distribution, rust_try.ll, rust_try_msvc_64.ll, and rust_try_msvc_32.ll into the compiler from the main distribution. There's a few reasons for this change: * LLVM changes its IR syntax from time to time, so it's very difficult to have these files build across many LLVM versions simultaneously. We'll likely want to retain this ability for quite some time into the future. * The implementation of these files is closely tied to the compiler and runtime itself, so it makes sense to fold it into a location which can do more platform-specific checks for various implementation details (such as MSVC 32 vs 64-bit). * This removes LLVM as a build-time dependency of the standard library. This may end up becoming very useful if we move towards building the standard library with Cargo. In the immediate future, however, this commit should restore compatibility with LLVM 3.5 and 3.6.
2 parents 9090420 + c35b2bd commit 25281b1

File tree

25 files changed

+519
-328
lines changed

25 files changed

+519
-328
lines changed
 

‎mk/rt.mk

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,6 @@ NATIVE_DEPS_miniz_$(1) = miniz.c
5454
NATIVE_DEPS_rust_builtin_$(1) := rust_builtin.c \
5555
rust_android_dummy.c
5656
NATIVE_DEPS_rustrt_native_$(1) := arch/$$(HOST_$(1))/record_sp.S
57-
ifeq ($$(findstring msvc,$(1)),msvc)
58-
ifeq ($$(findstring i686,$(1)),i686)
59-
NATIVE_DEPS_rustrt_native_$(1) += rust_try_msvc_32.ll
60-
else
61-
NATIVE_DEPS_rustrt_native_$(1) += rust_try_msvc_64.ll
62-
endif
63-
else
64-
NATIVE_DEPS_rustrt_native_$(1) += rust_try.ll
65-
endif
6657
NATIVE_DEPS_rust_test_helpers_$(1) := rust_test_helpers.c
6758
NATIVE_DEPS_morestack_$(1) := arch/$$(HOST_$(1))/morestack.S
6859

@@ -76,14 +67,6 @@ NATIVE_DEPS_morestack_$(1) := arch/$$(HOST_$(1))/morestack.S
7667

7768
RT_OUTPUT_DIR_$(1) := $(1)/rt
7869

79-
$$(RT_OUTPUT_DIR_$(1))/%.o: $(S)src/rt/%.ll $$(MKFILE_DEPS) \
80-
$$(LLVM_CONFIG_$$(CFG_BUILD))
81-
@mkdir -p $$(@D)
82-
@$$(call E, compile: $$@)
83-
$$(Q)$$(LLC_$$(CFG_BUILD)) $$(CFG_LLC_FLAGS_$(1)) \
84-
-filetype=obj -mtriple=$$(CFG_LLVM_TARGET_$(1)) \
85-
-relocation-model=pic -o $$@ $$<
86-
8770
$$(RT_OUTPUT_DIR_$(1))/%.o: $(S)src/rt/%.c $$(MKFILE_DEPS)
8871
@mkdir -p $$(@D)
8972
@$$(call E, compile: $$@)
@@ -122,7 +105,6 @@ define THIRD_PARTY_LIB
122105
OBJS_$(2)_$(1) := $$(NATIVE_DEPS_$(2)_$(1):%=$$(RT_OUTPUT_DIR_$(1))/%)
123106
OBJS_$(2)_$(1) := $$(OBJS_$(2)_$(1):.c=.o)
124107
OBJS_$(2)_$(1) := $$(OBJS_$(2)_$(1):.cpp=.o)
125-
OBJS_$(2)_$(1) := $$(OBJS_$(2)_$(1):.ll=.o)
126108
OBJS_$(2)_$(1) := $$(OBJS_$(2)_$(1):.S=.o)
127109
NATIVE_$(2)_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$(2))
128110
$$(RT_OUTPUT_DIR_$(1))/$$(NATIVE_$(2)_$(1)): $$(OBJS_$(2)_$(1))

‎src/libcore/intrinsics.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,4 +602,10 @@ extern "rust-intrinsic" {
602602
/// Returns the value of the discriminant for the variant in 'v',
603603
/// cast to a `u64`; if `T` has no discriminant, returns 0.
604604
pub fn discriminant_value<T>(v: &T) -> u64;
605+
606+
/// Rust's "try catch" construct which invokes the function pointer `f` with
607+
/// the data pointer `data`, returning the exception payload if an exception
608+
/// is thrown (aka the thread panics).
609+
#[cfg(not(stage0))]
610+
pub fn try(f: fn(*mut u8), data: *mut u8) -> *mut u8;
605611
}

‎src/librustc/middle/lang_items.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ lets_do_this! {
326326
StartFnLangItem, "start", start_fn;
327327

328328
EhPersonalityLangItem, "eh_personality", eh_personality;
329+
EhPersonalityCatchLangItem, "eh_personality_catch", eh_personality_catch;
330+
MSVCTryFilterLangItem, "msvc_try_filter", msvc_try_filter;
329331

330332
ExchangeHeapLangItem, "exchange_heap", exchange_heap;
331333
OwnedBoxLangItem, "owned_box", owned_box;

‎src/librustc/middle/weak_lang_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
119119
) }
120120

121121
weak_lang_items! {
122-
panic_fmt, PanicFmtLangItem, rust_begin_unwind;
122+
panic_fmt, PanicFmtLangItem, rust_begin_unwind;
123123
stack_exhausted, StackExhaustedLangItem, rust_stack_exhausted;
124124
eh_personality, EhPersonalityLangItem, rust_eh_personality;
125125
}

‎src/librustc_llvm/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ pub enum DLLStorageClassTypes {
134134
}
135135

136136
bitflags! {
137-
flags Attribute : u32 {
137+
flags Attribute : u64 {
138138
const ZExt = 1 << 0,
139139
const SExt = 1 << 1,
140140
const NoReturn = 1 << 2,
@@ -161,6 +161,7 @@ bitflags! {
161161
const ReturnsTwice = 1 << 29,
162162
const UWTable = 1 << 30,
163163
const NonLazyBind = 1 << 31,
164+
const OptimizeNone = 1 << 42,
164165
}
165166
}
166167

@@ -2193,7 +2194,8 @@ pub fn ConstFCmp(pred: RealPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
21932194

21942195
pub fn SetFunctionAttribute(fn_: ValueRef, attr: Attribute) {
21952196
unsafe {
2196-
LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint, attr.bits() as uint64_t)
2197+
LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint,
2198+
attr.bits() as uint64_t)
21972199
}
21982200
}
21992201

‎src/librustc_trans/trans/build.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,10 @@ pub fn LandingPad(cx: Block, ty: Type, pers_fn: ValueRef,
10421042
B(cx).landing_pad(ty, pers_fn, num_clauses, cx.fcx.llfn)
10431043
}
10441044

1045+
pub fn AddClause(cx: Block, landing_pad: ValueRef, clause: ValueRef) {
1046+
B(cx).add_clause(landing_pad, clause)
1047+
}
1048+
10451049
pub fn SetCleanup(cx: Block, landing_pad: ValueRef) {
10461050
B(cx).set_cleanup(landing_pad)
10471051
}

‎src/librustc_trans/trans/builder.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
937937
}
938938
}
939939

940+
pub fn add_clause(&self, landing_pad: ValueRef, clause: ValueRef) {
941+
unsafe {
942+
llvm::LLVMAddClause(landing_pad, clause);
943+
}
944+
}
945+
940946
pub fn set_cleanup(&self, landing_pad: ValueRef) {
941947
self.count_insn("setcleanup");
942948
unsafe {

‎src/librustc_trans/trans/callee.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -620,16 +620,17 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
620620
}, ArgVals(args), dest)
621621
}
622622

623-
/// This behemoth of a function translates function calls. Unfortunately, in order to generate more
624-
/// efficient LLVM output at -O0, it has quite a complex signature (refactoring this into two
625-
/// functions seems like a good idea).
623+
/// This behemoth of a function translates function calls. Unfortunately, in
624+
/// order to generate more efficient LLVM output at -O0, it has quite a complex
625+
/// signature (refactoring this into two functions seems like a good idea).
626626
///
627-
/// In particular, for lang items, it is invoked with a dest of None, and in that case the return
628-
/// value contains the result of the fn. The lang item must not return a structural type or else
629-
/// all heck breaks loose.
627+
/// In particular, for lang items, it is invoked with a dest of None, and in
628+
/// that case the return value contains the result of the fn. The lang item must
629+
/// not return a structural type or else all heck breaks loose.
630630
///
631-
/// For non-lang items, `dest` is always Some, and hence the result is written into memory
632-
/// somewhere. Nonetheless we return the actual return value of the function.
631+
/// For non-lang items, `dest` is always Some, and hence the result is written
632+
/// into memory somewhere. Nonetheless we return the actual return value of the
633+
/// function.
633634
pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
634635
debug_loc: DebugLoc,
635636
get_callee: F,

‎src/librustc_trans/trans/cleanup.rs

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,9 @@ pub use self::Heap::*;
122122
use llvm::{BasicBlockRef, ValueRef};
123123
use trans::base;
124124
use trans::build;
125-
use trans::callee;
126125
use trans::common;
127-
use trans::common::{Block, FunctionContext, ExprId, NodeIdAndSpan};
126+
use trans::common::{Block, FunctionContext, NodeIdAndSpan};
128127
use trans::debuginfo::{DebugLoc, ToDebugLoc};
129-
use trans::declare;
130128
use trans::glue;
131129
use middle::region;
132130
use trans::type_::Type;
@@ -833,53 +831,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
833831
&[Type::i8p(self.ccx), Type::i32(self.ccx)],
834832
false);
835833

836-
// The exception handling personality function.
837-
//
838-
// If our compilation unit has the `eh_personality` lang item somewhere
839-
// within it, then we just need to translate that. Otherwise, we're
840-
// building an rlib which will depend on some upstream implementation of
841-
// this function, so we just codegen a generic reference to it. We don't
842-
// specify any of the types for the function, we just make it a symbol
843-
// that LLVM can later use.
844-
//
845-
// Note that MSVC is a little special here in that we don't use the
846-
// `eh_personality` lang item at all. Currently LLVM has support for
847-
// both Dwarf and SEH unwind mechanisms for MSVC targets and uses the
848-
// *name of the personality function* to decide what kind of unwind side
849-
// tables/landing pads to emit. It looks like Dwarf is used by default,
850-
// injecting a dependency on the `_Unwind_Resume` symbol for resuming
851-
// an "exception", but for MSVC we want to force SEH. This means that we
852-
// can't actually have the personality function be our standard
853-
// `rust_eh_personality` function, but rather we wired it up to the
854-
// CRT's custom personality function, which forces LLVM to consider
855-
// landing pads as "landing pads for SEH".
856-
let target = &self.ccx.sess().target.target;
857-
let llpersonality = match pad_bcx.tcx().lang_items.eh_personality() {
858-
Some(def_id) if !target.options.is_like_msvc => {
859-
callee::trans_fn_ref(pad_bcx.ccx(), def_id, ExprId(0),
860-
pad_bcx.fcx.param_substs).val
861-
}
862-
_ => {
863-
let mut personality = self.ccx.eh_personality().borrow_mut();
864-
match *personality {
865-
Some(llpersonality) => llpersonality,
866-
None => {
867-
let name = if !target.options.is_like_msvc {
868-
"rust_eh_personality"
869-
} else if target.arch == "x86" {
870-
"_except_handler3"
871-
} else {
872-
"__C_specific_handler"
873-
};
874-
let fty = Type::variadic_func(&[], &Type::i32(self.ccx));
875-
let f = declare::declare_cfn(self.ccx, name, fty,
876-
self.ccx.tcx().types.i32);
877-
*personality = Some(f);
878-
f
879-
}
880-
}
881-
}
882-
};
834+
let llpersonality = pad_bcx.fcx.eh_personality();
883835

884836
// The only landing pad clause will be 'cleanup'
885837
let llretval = build::LandingPad(pad_bcx, llretty, llpersonality, 1);

‎src/librustc_trans/trans/closure.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,10 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
163163
mangle_internal_name_by_path_and_seq(path, "closure")
164164
});
165165

166-
// Currently there’s only a single user of get_or_create_declaration_if_closure and it
167-
// unconditionally defines the function, therefore we use define_* here.
168-
let llfn = declare::define_internal_rust_fn(ccx, &symbol[..], function_type).unwrap_or_else(||{
169-
ccx.sess().bug(&format!("symbol `{}` already defined", symbol));
170-
});
166+
// Currently there’s only a single user of
167+
// get_or_create_declaration_if_closure and it unconditionally defines the
168+
// function, therefore we use define_* here.
169+
let llfn = declare::define_internal_rust_fn(ccx, &symbol[..], function_type);
171170

172171
// set an inline hint for all closures
173172
attributes::inline(llfn, attributes::InlineAttr::Hint);
@@ -388,11 +387,8 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
388387

389388
// Create the by-value helper.
390389
let function_name = link::mangle_internal_name_by_type_and_seq(ccx, llonce_fn_ty, "once_shim");
391-
let lloncefn = declare::define_internal_rust_fn(ccx, &function_name[..], llonce_fn_ty)
392-
.unwrap_or_else(||{
393-
ccx.sess().bug(&format!("symbol `{}` already defined", function_name));
394-
});
395-
390+
let lloncefn = declare::define_internal_rust_fn(ccx, &function_name,
391+
llonce_fn_ty);
396392
let sig = tcx.erase_late_bound_regions(&llonce_bare_fn_ty.sig);
397393
let (block_arena, fcx): (TypedArena<_>, FunctionContext);
398394
block_arena = TypedArena::new();

‎src/librustc_trans/trans/common.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use middle::lang_items::LangItem;
2525
use middle::subst::{self, Substs};
2626
use trans::base;
2727
use trans::build;
28+
use trans::callee;
2829
use trans::cleanup;
2930
use trans::consts;
3031
use trans::datum;
@@ -479,6 +480,56 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
479480
pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
480481
type_needs_drop_given_env(self.ccx.tcx(), ty, &self.param_env)
481482
}
483+
484+
pub fn eh_personality(&self) -> ValueRef {
485+
// The exception handling personality function.
486+
//
487+
// If our compilation unit has the `eh_personality` lang item somewhere
488+
// within it, then we just need to translate that. Otherwise, we're
489+
// building an rlib which will depend on some upstream implementation of
490+
// this function, so we just codegen a generic reference to it. We don't
491+
// specify any of the types for the function, we just make it a symbol
492+
// that LLVM can later use.
493+
//
494+
// Note that MSVC is a little special here in that we don't use the
495+
// `eh_personality` lang item at all. Currently LLVM has support for
496+
// both Dwarf and SEH unwind mechanisms for MSVC targets and uses the
497+
// *name of the personality function* to decide what kind of unwind side
498+
// tables/landing pads to emit. It looks like Dwarf is used by default,
499+
// injecting a dependency on the `_Unwind_Resume` symbol for resuming
500+
// an "exception", but for MSVC we want to force SEH. This means that we
501+
// can't actually have the personality function be our standard
502+
// `rust_eh_personality` function, but rather we wired it up to the
503+
// CRT's custom personality function, which forces LLVM to consider
504+
// landing pads as "landing pads for SEH".
505+
let target = &self.ccx.sess().target.target;
506+
match self.ccx.tcx().lang_items.eh_personality() {
507+
Some(def_id) if !target.options.is_like_msvc => {
508+
callee::trans_fn_ref(self.ccx, def_id, ExprId(0),
509+
self.param_substs).val
510+
}
511+
_ => {
512+
let mut personality = self.ccx.eh_personality().borrow_mut();
513+
match *personality {
514+
Some(llpersonality) => llpersonality,
515+
None => {
516+
let name = if !target.options.is_like_msvc {
517+
"rust_eh_personality"
518+
} else if target.arch == "x86" {
519+
"_except_handler3"
520+
} else {
521+
"__C_specific_handler"
522+
};
523+
let fty = Type::variadic_func(&[], &Type::i32(self.ccx));
524+
let f = declare::declare_cfn(self.ccx, name, fty,
525+
self.ccx.tcx().types.i32);
526+
*personality = Some(f);
527+
f
528+
}
529+
}
530+
}
531+
}
532+
}
482533
}
483534

484535
// Basic block context. We create a block context for each basic block

‎src/librustc_trans/trans/context.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ pub struct LocalCrateContext<'tcx> {
142142
dbg_cx: Option<debuginfo::CrateDebugContext<'tcx>>,
143143

144144
eh_personality: RefCell<Option<ValueRef>>,
145+
rust_try_fn: RefCell<Option<ValueRef>>,
145146

146147
intrinsics: RefCell<FnvHashMap<&'static str, ValueRef>>,
147148

@@ -461,6 +462,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
461462
closure_vals: RefCell::new(FnvHashMap()),
462463
dbg_cx: dbg_cx,
463464
eh_personality: RefCell::new(None),
465+
rust_try_fn: RefCell::new(None),
464466
intrinsics: RefCell::new(FnvHashMap()),
465467
n_llvm_insns: Cell::new(0),
466468
trait_cache: RefCell::new(FnvHashMap()),
@@ -726,6 +728,10 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
726728
&self.local.eh_personality
727729
}
728730

731+
pub fn rust_try_fn<'a>(&'a self) -> &'a RefCell<Option<ValueRef>> {
732+
&self.local.rust_try_fn
733+
}
734+
729735
fn intrinsics<'a>(&'a self) -> &'a RefCell<FnvHashMap<&'static str, ValueRef>> {
730736
&self.local.intrinsics
731737
}
@@ -923,6 +929,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
923929
ifn!("llvm.lifetime.end", fn(t_i64, i8p) -> void);
924930

925931
ifn!("llvm.expect.i1", fn(i1, i1) -> i1);
932+
ifn!("llvm.eh.typeid.for", fn(i8p) -> t_i32);
926933

927934
// Some intrinsics were introduced in later versions of LLVM, but they have
928935
// fallbacks in libc or libm and such.

‎src/librustc_trans/trans/declare.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ pub fn define_global(ccx: &CrateContext, name: &str, ty: Type) -> Option<ValueRe
176176
/// return None if the name already has a definition associated with it. In that
177177
/// case an error should be reported to the user, because it usually happens due
178178
/// to user’s fault (e.g. misuse of #[no_mangle] or #[export_name] attributes).
179-
pub fn define_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, fn_type: Type,
180-
output: ty::FnOutput) -> Option<ValueRef> {
179+
pub fn define_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv,
180+
fn_type: Type, output: ty::FnOutput) -> Option<ValueRef> {
181181
if get_defined_value(ccx, name).is_some() {
182182
None
183183
} else {
@@ -224,20 +224,21 @@ pub fn define_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
224224
/// Declare a Rust function with an intention to define it.
225225
///
226226
/// Use this function when you intend to define a function. This function will
227-
/// return None if the name already has a definition associated with it. In that
228-
/// case an error should be reported to the user, because it usually happens due
229-
/// to user’s fault (e.g. misuse of #[no_mangle] or #[export_name] attributes).
230-
pub fn define_internal_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
231-
fn_type: ty::Ty<'tcx>) -> Option<ValueRef> {
227+
/// return panic if the name already has a definition associated with it. This
228+
/// can happen with #[no_mangle] or #[export_name], for example.
229+
pub fn define_internal_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
230+
name: &str,
231+
fn_type: ty::Ty<'tcx>) -> ValueRef {
232232
if get_defined_value(ccx, name).is_some() {
233-
None
233+
ccx.sess().fatal(&format!("symbol `{}` already defined", name))
234234
} else {
235-
Some(declare_internal_rust_fn(ccx, name, fn_type))
235+
declare_internal_rust_fn(ccx, name, fn_type)
236236
}
237237
}
238238

239239

240-
/// Get defined or externally defined (AvailableExternally linkage) value by name.
240+
/// Get defined or externally defined (AvailableExternally linkage) value by
241+
/// name.
241242
fn get_defined_value(ccx: &CrateContext, name: &str) -> Option<ValueRef> {
242243
debug!("get_defined_value(name={:?})", name);
243244
let namebuf = CString::new(name).unwrap_or_else(|_|{

‎src/librustc_trans/trans/foreign.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -627,9 +627,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
627627
ccx.tcx().map.path_to_string(id),
628628
id, t);
629629

630-
let llfn = declare::define_internal_rust_fn(ccx, &ps[..], t).unwrap_or_else(||{
631-
ccx.sess().bug(&format!("symbol `{}` already defined", ps));
632-
});
630+
let llfn = declare::define_internal_rust_fn(ccx, &ps, t);
633631
attributes::from_fn_attrs(ccx, attrs, llfn);
634632
base::trans_fn(ccx, decl, body, llfn, param_substs, id, &[]);
635633
llfn

‎src/librustc_trans/trans/intrinsic.rs

Lines changed: 341 additions & 3 deletions
Large diffs are not rendered by default.

‎src/librustc_trans/trans/meth.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,9 +550,7 @@ fn trans_object_shim<'a, 'tcx>(
550550
let shim_fn_ty = tcx.mk_fn(None, fty);
551551
let method_bare_fn_ty = tcx.mk_fn(None, method_ty);
552552
let function_name = link::mangle_internal_name_by_type_and_seq(ccx, shim_fn_ty, "object_shim");
553-
let llfn = declare::define_internal_rust_fn(ccx, &function_name, shim_fn_ty).unwrap_or_else(||{
554-
ccx.sess().bug(&format!("symbol `{}` already defined", function_name));
555-
});
553+
let llfn = declare::define_internal_rust_fn(ccx, &function_name, shim_fn_ty);
556554

557555
let sig = ccx.tcx().erase_late_bound_regions(&fty.sig);
558556

‎src/librustc_trans/trans/monomorphize.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,9 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
137137
let lldecl = if abi != abi::Rust {
138138
foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, &s[..])
139139
} else {
140-
// FIXME(nagisa): perhaps needs a more fine grained selection? See setup_lldecl below.
141-
declare::define_internal_rust_fn(ccx, &s[..], mono_ty).unwrap_or_else(||{
142-
ccx.sess().bug(&format!("symbol `{}` already defined", s));
143-
})
140+
// FIXME(nagisa): perhaps needs a more fine grained selection? See
141+
// setup_lldecl below.
142+
declare::define_internal_rust_fn(ccx, &s, mono_ty)
144143
};
145144

146145
ccx.monomorphized().borrow_mut().insert(hash_id.take().unwrap(), lldecl);

‎src/librustc_typeck/check/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5086,6 +5086,21 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
50865086
ty::BrAnon(0))),
50875087
param(ccx, 0))], tcx.types.u64),
50885088

5089+
"try" => {
5090+
let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);
5091+
let fn_ty = ty::BareFnTy {
5092+
unsafety: ast::Unsafety::Normal,
5093+
abi: abi::Rust,
5094+
sig: ty::Binder(FnSig {
5095+
inputs: vec![mut_u8],
5096+
output: ty::FnOutput::FnConverging(tcx.mk_nil()),
5097+
variadic: false,
5098+
}),
5099+
};
5100+
let fn_ty = tcx.mk_bare_fn(fn_ty);
5101+
(0, vec![tcx.mk_fn(None, fn_ty), mut_u8], mut_u8)
5102+
}
5103+
50895104
ref other => {
50905105
span_err!(tcx.sess, it.span, E0093,
50915106
"unrecognized intrinsic function: `{}`", *other);

‎src/libstd/rt/unwind/gcc.rs

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![allow(private_no_mangle_fns)]
12+
1113
use prelude::v1::*;
1214

1315
use any::Any;
14-
use libc::c_void;
1516
use rt::libunwind as uw;
1617

1718
struct Exception {
@@ -41,7 +42,7 @@ pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
4142
}
4243
}
4344

44-
pub unsafe fn cleanup(ptr: *mut c_void) -> Box<Any + Send + 'static> {
45+
pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send + 'static> {
4546
let my_ep = ptr as *mut Exception;
4647
rtdebug!("caught {}", (*my_ep).uwe.exception_class);
4748
let cause = (*my_ep).cause.take();
@@ -89,7 +90,7 @@ pub mod eabi {
8990
use rt::libunwind as uw;
9091
use libc::c_int;
9192

92-
extern "C" {
93+
extern {
9394
fn __gcc_personality_v0(version: c_int,
9495
actions: uw::_Unwind_Action,
9596
exception_class: uw::_Unwind_Exception_Class,
@@ -98,9 +99,8 @@ pub mod eabi {
9899
-> uw::_Unwind_Reason_Code;
99100
}
100101

101-
#[lang="eh_personality"]
102-
#[no_mangle] // referenced from rust_try.ll
103-
#[allow(private_no_mangle_fns)]
102+
#[lang = "eh_personality"]
103+
#[no_mangle]
104104
extern fn rust_eh_personality(
105105
version: c_int,
106106
actions: uw::_Unwind_Action,
@@ -115,8 +115,9 @@ pub mod eabi {
115115
}
116116
}
117117

118-
#[no_mangle] // referenced from rust_try.ll
119-
pub extern "C" fn rust_eh_personality_catch(
118+
#[cfg_attr(not(stage0), lang = "eh_personality_catch")]
119+
#[no_mangle]
120+
pub extern fn rust_eh_personality_catch(
120121
_version: c_int,
121122
actions: uw::_Unwind_Action,
122123
_exception_class: uw::_Unwind_Exception_Class,
@@ -142,7 +143,7 @@ pub mod eabi {
142143
use rt::libunwind as uw;
143144
use libc::c_int;
144145

145-
extern "C" {
146+
extern {
146147
fn __gcc_personality_sj0(version: c_int,
147148
actions: uw::_Unwind_Action,
148149
exception_class: uw::_Unwind_Exception_Class,
@@ -151,9 +152,9 @@ pub mod eabi {
151152
-> uw::_Unwind_Reason_Code;
152153
}
153154

154-
#[lang="eh_personality"]
155-
#[no_mangle] // referenced from rust_try.ll
156-
pub extern "C" fn rust_eh_personality(
155+
#[lang = "eh_personality"]
156+
#[no_mangle]
157+
pub extern fn rust_eh_personality(
157158
version: c_int,
158159
actions: uw::_Unwind_Action,
159160
exception_class: uw::_Unwind_Exception_Class,
@@ -167,8 +168,9 @@ pub mod eabi {
167168
}
168169
}
169170

170-
#[no_mangle] // referenced from rust_try.ll
171-
pub extern "C" fn rust_eh_personality_catch(
171+
#[cfg_attr(not(stage0), lang = "eh_personality_catch")]
172+
#[no_mangle]
173+
pub extern fn rust_eh_personality_catch(
172174
_version: c_int,
173175
actions: uw::_Unwind_Action,
174176
_exception_class: uw::_Unwind_Exception_Class,
@@ -196,17 +198,16 @@ pub mod eabi {
196198
use rt::libunwind as uw;
197199
use libc::c_int;
198200

199-
extern "C" {
201+
extern {
200202
fn __gcc_personality_v0(state: uw::_Unwind_State,
201203
ue_header: *mut uw::_Unwind_Exception,
202204
context: *mut uw::_Unwind_Context)
203205
-> uw::_Unwind_Reason_Code;
204206
}
205207

206-
#[lang="eh_personality"]
207-
#[no_mangle] // referenced from rust_try.ll
208-
#[allow(private_no_mangle_fns)]
209-
extern "C" fn rust_eh_personality(
208+
#[lang = "eh_personality"]
209+
#[no_mangle]
210+
extern fn rust_eh_personality(
210211
state: uw::_Unwind_State,
211212
ue_header: *mut uw::_Unwind_Exception,
212213
context: *mut uw::_Unwind_Context
@@ -217,8 +218,9 @@ pub mod eabi {
217218
}
218219
}
219220

220-
#[no_mangle] // referenced from rust_try.ll
221-
pub extern "C" fn rust_eh_personality_catch(
221+
#[cfg_attr(not(stage0), lang = "eh_personality_catch")]
222+
#[no_mangle]
223+
pub extern fn rust_eh_personality_catch(
222224
state: uw::_Unwind_State,
223225
_ue_header: *mut uw::_Unwind_Exception,
224226
_context: *mut uw::_Unwind_Context
@@ -266,15 +268,15 @@ pub mod eabi {
266268
}
267269

268270
type _Unwind_Personality_Fn =
269-
extern "C" fn(
271+
extern fn(
270272
version: c_int,
271273
actions: uw::_Unwind_Action,
272274
exception_class: uw::_Unwind_Exception_Class,
273275
ue_header: *mut uw::_Unwind_Exception,
274276
context: *mut uw::_Unwind_Context
275277
) -> uw::_Unwind_Reason_Code;
276278

277-
extern "C" {
279+
extern {
278280
fn __gcc_personality_seh0(
279281
exceptionRecord: *mut EXCEPTION_RECORD,
280282
establisherFrame: *mut c_void,
@@ -291,10 +293,9 @@ pub mod eabi {
291293
) -> EXCEPTION_DISPOSITION;
292294
}
293295

294-
#[lang="eh_personality"]
295-
#[no_mangle] // referenced from rust_try.ll
296-
#[allow(private_no_mangle_fns)]
297-
extern "C" fn rust_eh_personality(
296+
#[lang = "eh_personality"]
297+
#[no_mangle]
298+
extern fn rust_eh_personality(
298299
exceptionRecord: *mut EXCEPTION_RECORD,
299300
establisherFrame: *mut c_void,
300301
contextRecord: *mut CONTEXT,
@@ -307,15 +308,16 @@ pub mod eabi {
307308
}
308309
}
309310

310-
#[no_mangle] // referenced from rust_try.ll
311-
pub extern "C" fn rust_eh_personality_catch(
311+
#[cfg_attr(not(stage0), lang = "eh_personality_catch")]
312+
#[no_mangle]
313+
pub extern fn rust_eh_personality_catch(
312314
exceptionRecord: *mut EXCEPTION_RECORD,
313315
establisherFrame: *mut c_void,
314316
contextRecord: *mut CONTEXT,
315317
dispatcherContext: *mut DISPATCHER_CONTEXT
316318
) -> EXCEPTION_DISPOSITION
317319
{
318-
extern "C" fn inner(
320+
extern fn inner(
319321
_version: c_int,
320322
actions: uw::_Unwind_Action,
321323
_exception_class: uw::_Unwind_Exception_Class,

‎src/libstd/rt/unwind/mod.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ use cmp;
6969
use panicking;
7070
use fmt;
7171
use intrinsics;
72-
use libc::c_void;
7372
use mem;
7473
use sync::atomic::{self, Ordering};
7574
use sys_common::mutex::Mutex;
@@ -127,7 +126,7 @@ extern {}
127126
/// run.
128127
pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
129128
let mut f = Some(f);
130-
return inner_try(try_fn::<F>, &mut f as *mut _ as *mut c_void);
129+
return inner_try(try_fn::<F>, &mut f as *mut _ as *mut u8);
131130

132131
// If an inner function were not used here, then this generic function `try`
133132
// uses the native symbol `rust_try`, for which the code is statically
@@ -140,20 +139,26 @@ pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
140139
// `dllexport`, but it's easier to not have conditional `src/rt/rust_try.ll`
141140
// files and instead just have this non-generic shim the compiler can take
142141
// care of exposing correctly.
143-
unsafe fn inner_try(f: extern fn(*mut c_void), data: *mut c_void)
142+
#[cfg(not(stage0))]
143+
unsafe fn inner_try(f: fn(*mut u8), data: *mut u8)
144144
-> Result<(), Box<Any + Send>> {
145145
let prev = PANICKING.with(|s| s.get());
146146
PANICKING.with(|s| s.set(false));
147-
let ep = rust_try(f, data);
147+
let ep = intrinsics::try(f, data);
148148
PANICKING.with(|s| s.set(prev));
149149
if ep.is_null() {
150150
Ok(())
151151
} else {
152152
Err(imp::cleanup(ep))
153153
}
154154
}
155+
#[cfg(stage0)]
156+
unsafe fn inner_try(f: fn(*mut u8), data: *mut u8)
157+
-> Result<(), Box<Any + Send>> {
158+
Ok(f(data))
159+
}
155160

156-
extern fn try_fn<F: FnOnce()>(opt_closure: *mut c_void) {
161+
fn try_fn<F: FnOnce()>(opt_closure: *mut u8) {
157162
let opt_closure = opt_closure as *mut Option<F>;
158163
unsafe { (*opt_closure).take().unwrap()(); }
159164
}
@@ -163,8 +168,8 @@ pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
163168
// When f(...) returns normally, the return value is null.
164169
// When f(...) throws, the return value is a pointer to the caught
165170
// exception object.
166-
fn rust_try(f: extern fn(*mut c_void),
167-
data: *mut c_void) -> *mut c_void;
171+
fn rust_try(f: extern fn(*mut u8),
172+
data: *mut u8) -> *mut u8;
168173
}
169174
}
170175

‎src/libstd/rt/unwind/seh.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
102102
rtabort!("could not unwind stack");
103103
}
104104

105-
pub unsafe fn cleanup(ptr: *mut c_void) -> Box<Any + Send + 'static> {
105+
pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send + 'static> {
106106
// The `ptr` here actually corresponds to the code of the exception, and our
107107
// real data is stored in our thread local.
108108
rtassert!(ptr as DWORD == RUST_PANIC);
@@ -135,8 +135,9 @@ fn rust_eh_personality() {
135135
// to ensure that it's code is RUST_PANIC, which was set by the call to
136136
// `RaiseException` above in the `panic` function.
137137
#[no_mangle]
138+
#[lang = "msvc_try_filter"]
138139
pub extern fn __rust_try_filter(eh_ptrs: *mut EXCEPTION_POINTERS,
139-
_rbp: *mut c_void) -> i32 {
140+
_rbp: *mut u8) -> i32 {
140141
unsafe {
141142
((*(*eh_ptrs).ExceptionRecord).ExceptionCode == RUST_PANIC) as i32
142143
}

‎src/rt/rust_try.ll

Lines changed: 0 additions & 54 deletions
This file was deleted.

‎src/rt/rust_try_msvc_32.ll

Lines changed: 0 additions & 42 deletions
This file was deleted.

‎src/rt/rust_try_msvc_64.ll

Lines changed: 0 additions & 80 deletions
This file was deleted.

‎src/rustllvm/RustWrapper.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr, unsigned
120120
idx, B)));
121121
}
122122

123-
extern "C" void LLVMAddFunctionAttribute(LLVMValueRef Fn, unsigned index, uint64_t Val) {
123+
extern "C" void LLVMAddFunctionAttribute(LLVMValueRef Fn, unsigned index,
124+
uint64_t Val) {
124125
Function *A = unwrap<Function>(Fn);
125126
AttrBuilder B;
126127
B.addRawValue(Val);

0 commit comments

Comments
 (0)
Please sign in to comment.