parent
1171a214a6
commit
0262e4b138
@ -184,6 +184,15 @@ pub enum FileType {
|
||||
ObjectFile = 1
|
||||
}
|
||||
|
||||
pub enum Metadata {
|
||||
MD_dbg = 0,
|
||||
MD_tbaa = 1,
|
||||
MD_prof = 2,
|
||||
MD_fpmath = 3,
|
||||
MD_range = 4,
|
||||
MD_tbaa_struct = 5
|
||||
}
|
||||
|
||||
// Opaque pointer types
|
||||
pub enum Module_opaque {}
|
||||
pub type ModuleRef = *Module_opaque;
|
||||
|
@ -1361,13 +1361,34 @@ pub fn compile_submatch(bcx: block,
|
||||
if opts.len() > 0u {
|
||||
match opts[0] {
|
||||
var(_, vdef) => {
|
||||
if (*ty::enum_variants(tcx, vdef.enm)).len() == 1u {
|
||||
let variants = ty::enum_variants(tcx, vdef.enm);
|
||||
if variants.len() == 1 {
|
||||
kind = single;
|
||||
} else {
|
||||
let enumptr =
|
||||
PointerCast(bcx, val, T_opaque_enum_ptr(ccx));
|
||||
let discrimptr = GEPi(bcx, enumptr, [0u, 0u]);
|
||||
test_val = Load(bcx, discrimptr);
|
||||
|
||||
let mut min_discrim = variants[0].disr_val;
|
||||
for uint::range(1, variants.len()) |idx| {
|
||||
if variants[idx].disr_val < min_discrim {
|
||||
min_discrim = variants[idx].disr_val;
|
||||
}
|
||||
}
|
||||
|
||||
let mut max_discrim = variants[0].disr_val;
|
||||
for uint::range(1, variants.len()) |idx| {
|
||||
if variants[idx].disr_val > max_discrim {
|
||||
max_discrim = variants[idx].disr_val;
|
||||
}
|
||||
}
|
||||
|
||||
test_val = LoadRangeAssert(bcx, discrimptr,
|
||||
min_discrim as c_ulonglong,
|
||||
(max_discrim + 1)
|
||||
as c_ulonglong,
|
||||
lib::llvm::True);
|
||||
|
||||
kind = switch;
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
use lib::llvm::{CallConv, TypeKind, AtomicBinOp, AtomicOrdering};
|
||||
use lib::llvm::{Opcode, IntPredicate, RealPredicate, True, False};
|
||||
use lib::llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef, ModuleRef};
|
||||
use libc::{c_uint, c_int};
|
||||
use libc::{c_uint, c_int, c_ulonglong};
|
||||
use middle::trans::common::*;
|
||||
|
||||
use core::cast::transmute;
|
||||
@ -536,6 +536,27 @@ pub fn Load(cx: block, PointerVal: ValueRef) -> ValueRef {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn LoadRangeAssert(cx: block, PointerVal: ValueRef, lo: c_ulonglong,
|
||||
hi: c_ulonglong, signed: lib::llvm::Bool) -> ValueRef {
|
||||
let value = Load(cx, PointerVal);
|
||||
|
||||
let ccx = cx.fcx.ccx;
|
||||
let ty = val_ty(PointerVal);
|
||||
unsafe {
|
||||
assert llvm::LLVMGetTypeKind(ty) != lib::llvm::Array;
|
||||
|
||||
let min = llvm::LLVMConstInt(ccx.int_type, lo, signed);
|
||||
let max = llvm::LLVMConstInt(ccx.int_type, hi, signed);
|
||||
|
||||
do vec::as_imm_buf([min, max]) |ptr, len| {
|
||||
llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint,
|
||||
llvm::LLVMMDNode(ptr, len as c_uint));
|
||||
}
|
||||
}
|
||||
|
||||
value
|
||||
}
|
||||
|
||||
pub fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) {
|
||||
unsafe {
|
||||
if cx.unreachable { return; }
|
||||
|
Loading…
Reference in New Issue
Block a user