}
}
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable)]
pub enum CallTargets {
/// The only target that should be entered when function returns normally.
Return(BasicBlock),
// except according to those terms.
use llvm::BasicBlockRef;
-use middle::infer;
-use middle::ty;
use rustc::mir::repr as mir;
use trans::adt;
use trans::base;
use trans::build;
+use trans::attributes;
use trans::common::{self, Block};
use trans::debuginfo::DebugLoc;
use trans::type_of;
+use trans::type_::Type;
use super::MirContext;
use super::operand::OperandValue::{FatPtr, Immediate, Ref};
// The else branch of the Switch can't be hit, so branch to an unreachable
// instruction so LLVM knows that
- // FIXME it might be nice to have just one such block (created lazilly), we could
- // store it in the "MIR trans" state.
- let unreachable_blk = bcx.fcx.new_temp_block("enum-variant-unreachable");
- build::Unreachable(unreachable_blk);
+ let unreachable_blk = self.unreachable_block();
let switch = build::Switch(bcx, discr, unreachable_blk.llbb, targets.len());
assert_eq!(adt_def.variants.len(), targets.len());
}
}
+ fn unreachable_block(&mut self) -> Block<'bcx, 'tcx> {
+ match self.unreachable_block {
+ Some(b) => b,
+ None => {
+ let bl = self.fcx.new_block(false, "unreachable", None);
+ build::Unreachable(bl);
+ self.unreachable_block = Some(bl);
+ bl
+ }
+ }
+ }
+
fn bcx(&self, bb: mir::BasicBlock) -> Block<'bcx, 'tcx> {
self.blocks[bb.index()]
}
pub struct MirContext<'bcx, 'tcx:'bcx> {
mir: &'bcx mir::Mir<'tcx>,
+ /// Function context
+ fcx: &'bcx common::FunctionContext<'bcx, 'tcx>,
+
/// When unwinding is initiated, we have to store this personality
/// value somewhere so that we can load it and re-use it in the
/// resume instruction. The personality is (afaik) some kind of
/// A `Block` for each MIR `BasicBlock`
blocks: Vec<Block<'bcx, 'tcx>>,
+ /// Cached unreachable block
+ unreachable_block: Option<Block<'bcx, 'tcx>>,
+
/// An LLVM alloca for each MIR `VarDecl`
vars: Vec<LvalueRef<'tcx>>,
let mut mircx = MirContext {
mir: mir,
+ fcx: fcx,
llpersonalityslot: None,
blocks: block_bcxs,
+ unreachable_block: None,
vars: vars,
temps: temps,
args: args,