Remove const_{cstr,str_slice,get_elt,get_real} and is_const_real methods from cg_ssa
This introduces the static_panic_msg trait method to StaticBuilderMethods.
This commit is contained in:
parent
a3fa1161d2
commit
7b94195c22
|
@ -5,6 +5,7 @@ use crate::context::CodegenCx;
|
|||
use crate::type_::Type;
|
||||
use crate::type_of::LayoutLlvmExt;
|
||||
use crate::value::Value;
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate};
|
||||
use rustc_codegen_ssa::MemFlags;
|
||||
use libc::{c_uint, c_char};
|
||||
|
@ -1475,6 +1476,36 @@ impl StaticBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
// Forward to the `get_static` method of `CodegenCx`
|
||||
self.cx().get_static(def_id)
|
||||
}
|
||||
|
||||
fn static_panic_msg(
|
||||
&mut self,
|
||||
msg: Option<LocalInternedString>,
|
||||
filename: LocalInternedString,
|
||||
line: Self::Value,
|
||||
col: Self::Value,
|
||||
kind: &str,
|
||||
) -> Self::Value {
|
||||
let align = self.tcx.data_layout.aggregate_align.abi
|
||||
.max(self.tcx.data_layout.i32_align.abi)
|
||||
.max(self.tcx.data_layout.pointer_align.abi);
|
||||
|
||||
let filename = self.const_str_slice(filename);
|
||||
|
||||
let with_msg_components;
|
||||
let without_msg_components;
|
||||
|
||||
let components = if let Some(msg) = msg {
|
||||
let msg = self.const_str_slice(msg);
|
||||
with_msg_components = [msg, filename, line, col];
|
||||
&with_msg_components as &[_]
|
||||
} else {
|
||||
without_msg_components = [filename, line, col];
|
||||
&without_msg_components as &[_]
|
||||
};
|
||||
|
||||
let struct_ = self.const_struct(&components, false);
|
||||
self.static_addr_of(struct_, align, Some(kind))
|
||||
}
|
||||
}
|
||||
|
||||
impl Builder<'a, 'll, 'tcx> {
|
||||
|
|
|
@ -119,6 +119,72 @@ impl CodegenCx<'ll, 'tcx> {
|
|||
pub fn const_bytes(&self, bytes: &[u8]) -> &'ll Value {
|
||||
bytes_in_context(self.llcx, bytes)
|
||||
}
|
||||
|
||||
fn const_cstr(
|
||||
&self,
|
||||
s: LocalInternedString,
|
||||
null_terminated: bool,
|
||||
) -> &'ll Value {
|
||||
unsafe {
|
||||
if let Some(&llval) = self.const_cstr_cache.borrow().get(&s) {
|
||||
return llval;
|
||||
}
|
||||
|
||||
let sc = llvm::LLVMConstStringInContext(self.llcx,
|
||||
s.as_ptr() as *const c_char,
|
||||
s.len() as c_uint,
|
||||
!null_terminated as Bool);
|
||||
let sym = self.generate_local_symbol_name("str");
|
||||
let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{
|
||||
bug!("symbol `{}` is already defined", sym);
|
||||
});
|
||||
llvm::LLVMSetInitializer(g, sc);
|
||||
llvm::LLVMSetGlobalConstant(g, True);
|
||||
llvm::LLVMRustSetLinkage(g, llvm::Linkage::InternalLinkage);
|
||||
|
||||
self.const_cstr_cache.borrow_mut().insert(s, g);
|
||||
g
|
||||
}
|
||||
}
|
||||
|
||||
pub fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value {
|
||||
let len = s.len();
|
||||
let cs = consts::ptrcast(self.const_cstr(s, false),
|
||||
self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self)));
|
||||
self.const_fat_ptr(cs, self.const_usize(len as u64))
|
||||
}
|
||||
|
||||
pub fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value {
|
||||
unsafe {
|
||||
assert_eq!(idx as c_uint as u64, idx);
|
||||
let us = &[idx as c_uint];
|
||||
let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
|
||||
|
||||
debug!("const_get_elt(v={:?}, idx={}, r={:?})",
|
||||
v, idx, r);
|
||||
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
pub fn const_get_real(&self, v: &'ll Value) -> Option<(f64, bool)> {
|
||||
unsafe {
|
||||
if self.is_const_real(v) {
|
||||
let mut loses_info: llvm::Bool = ::std::mem::uninitialized();
|
||||
let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info);
|
||||
let loses_info = if loses_info == 1 { true } else { false };
|
||||
Some((r, loses_info))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_const_real(&self, v: &'ll Value) -> bool {
|
||||
unsafe {
|
||||
llvm::LLVMIsAConstantFP(v).is_some()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
|
@ -183,40 +249,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
self.const_uint(self.type_i8(), i as u64)
|
||||
}
|
||||
|
||||
fn const_cstr(
|
||||
&self,
|
||||
s: LocalInternedString,
|
||||
null_terminated: bool,
|
||||
) -> &'ll Value {
|
||||
unsafe {
|
||||
if let Some(&llval) = self.const_cstr_cache.borrow().get(&s) {
|
||||
return llval;
|
||||
}
|
||||
|
||||
let sc = llvm::LLVMConstStringInContext(self.llcx,
|
||||
s.as_ptr() as *const c_char,
|
||||
s.len() as c_uint,
|
||||
!null_terminated as Bool);
|
||||
let sym = self.generate_local_symbol_name("str");
|
||||
let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{
|
||||
bug!("symbol `{}` is already defined", sym);
|
||||
});
|
||||
llvm::LLVMSetInitializer(g, sc);
|
||||
llvm::LLVMSetGlobalConstant(g, True);
|
||||
llvm::LLVMRustSetLinkage(g, llvm::Linkage::InternalLinkage);
|
||||
|
||||
self.const_cstr_cache.borrow_mut().insert(s, g);
|
||||
g
|
||||
}
|
||||
}
|
||||
|
||||
fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value {
|
||||
let len = s.len();
|
||||
let cs = consts::ptrcast(self.const_cstr(s, false),
|
||||
self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self)));
|
||||
self.const_fat_ptr(cs, self.const_usize(len as u64))
|
||||
}
|
||||
|
||||
fn const_struct(
|
||||
&self,
|
||||
elts: &[&'ll Value],
|
||||
|
@ -225,32 +257,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
struct_in_context(self.llcx, elts, packed)
|
||||
}
|
||||
|
||||
fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value {
|
||||
unsafe {
|
||||
assert_eq!(idx as c_uint as u64, idx);
|
||||
let us = &[idx as c_uint];
|
||||
let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
|
||||
|
||||
debug!("const_get_elt(v={:?}, idx={}, r={:?})",
|
||||
v, idx, r);
|
||||
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
fn const_get_real(&self, v: &'ll Value) -> Option<(f64, bool)> {
|
||||
unsafe {
|
||||
if self.is_const_real(v) {
|
||||
let mut loses_info: llvm::Bool = ::std::mem::uninitialized();
|
||||
let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info);
|
||||
let loses_info = if loses_info == 1 { true } else { false };
|
||||
Some((r, loses_info))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn const_to_uint(&self, v: &'ll Value) -> u64 {
|
||||
unsafe {
|
||||
llvm::LLVMConstIntGetZExtValue(v)
|
||||
|
@ -263,12 +269,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_const_real(&self, v: &'ll Value) -> bool {
|
||||
unsafe {
|
||||
llvm::LLVMIsAConstantFP(v).is_some()
|
||||
}
|
||||
}
|
||||
|
||||
fn const_to_opt_u128(&self, v: &'ll Value, sign_ext: bool) -> Option<u128> {
|
||||
unsafe {
|
||||
if self.is_const_integral(v) {
|
||||
|
|
|
@ -399,12 +399,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
// Get the location information.
|
||||
let loc = bx.sess().source_map().lookup_char_pos(span.lo());
|
||||
let filename = Symbol::intern(&loc.file.name.to_string()).as_str();
|
||||
let filename = bx.const_str_slice(filename);
|
||||
let line = bx.const_u32(loc.line as u32);
|
||||
let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
|
||||
let align = self.cx.tcx().data_layout.aggregate_align.abi
|
||||
.max(self.cx.tcx().data_layout.i32_align.abi)
|
||||
.max(self.cx.tcx().data_layout.pointer_align.abi);
|
||||
|
||||
// Put together the arguments to the panic entry point.
|
||||
let (lang_item, args) = match *msg {
|
||||
|
@ -412,30 +408,28 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
let len = self.codegen_operand(&mut bx, len).immediate();
|
||||
let index = self.codegen_operand(&mut bx, index).immediate();
|
||||
|
||||
let file_line_col = bx.const_struct(&[filename, line, col], false);
|
||||
let file_line_col = bx.static_addr_of(
|
||||
file_line_col,
|
||||
align,
|
||||
Some("panic_bounds_check_loc")
|
||||
let file_line_col = bx.static_panic_msg(
|
||||
None,
|
||||
filename,
|
||||
line,
|
||||
col,
|
||||
"panic_bounds_check_loc",
|
||||
);
|
||||
(lang_items::PanicBoundsCheckFnLangItem,
|
||||
vec![file_line_col, index, len])
|
||||
vec![file_line_col, index, len])
|
||||
}
|
||||
_ => {
|
||||
let str = msg.description();
|
||||
let msg_str = Symbol::intern(str).as_str();
|
||||
let msg_str = bx.const_str_slice(msg_str);
|
||||
let msg_file_line_col = bx.const_struct(
|
||||
&[msg_str, filename, line, col],
|
||||
false
|
||||
);
|
||||
let msg_file_line_col = bx.static_addr_of(
|
||||
msg_file_line_col,
|
||||
align,
|
||||
Some("panic_loc")
|
||||
let msg_file_line_col = bx.static_panic_msg(
|
||||
Some(msg_str),
|
||||
filename,
|
||||
line,
|
||||
col,
|
||||
"panic_loc",
|
||||
);
|
||||
(lang_items::PanicFnLangItem,
|
||||
vec![msg_file_line_col])
|
||||
vec![msg_file_line_col])
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -539,27 +533,20 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
if layout.abi.is_uninhabited() {
|
||||
let loc = bx.sess().source_map().lookup_char_pos(span.lo());
|
||||
let filename = Symbol::intern(&loc.file.name.to_string()).as_str();
|
||||
let filename = bx.const_str_slice(filename);
|
||||
let line = bx.const_u32(loc.line as u32);
|
||||
let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
|
||||
let align = self.cx.tcx().data_layout.aggregate_align.abi
|
||||
.max(self.cx.tcx().data_layout.i32_align.abi)
|
||||
.max(self.cx.tcx().data_layout.pointer_align.abi);
|
||||
|
||||
let str = format!(
|
||||
"Attempted to instantiate uninhabited type {}",
|
||||
ty
|
||||
);
|
||||
let msg_str = Symbol::intern(&str).as_str();
|
||||
let msg_str = bx.const_str_slice(msg_str);
|
||||
let msg_file_line_col = bx.const_struct(
|
||||
&[msg_str, filename, line, col],
|
||||
false,
|
||||
);
|
||||
let msg_file_line_col = bx.static_addr_of(
|
||||
msg_file_line_col,
|
||||
align,
|
||||
Some("panic_loc"),
|
||||
let msg_file_line_col = bx.static_panic_msg(
|
||||
Some(msg_str),
|
||||
filename,
|
||||
line,
|
||||
col,
|
||||
"panic_loc",
|
||||
);
|
||||
|
||||
// Obtain the panic entry point.
|
||||
|
|
|
@ -3,7 +3,6 @@ use crate::mir::place::PlaceRef;
|
|||
use rustc::mir::interpret::Allocation;
|
||||
use rustc::mir::interpret::Scalar;
|
||||
use rustc::ty::layout;
|
||||
use syntax::symbol::LocalInternedString;
|
||||
|
||||
pub trait ConstMethods<'tcx>: BackendTypes {
|
||||
// Constant constructors
|
||||
|
@ -19,20 +18,12 @@ pub trait ConstMethods<'tcx>: BackendTypes {
|
|||
fn const_usize(&self, i: u64) -> Self::Value;
|
||||
fn const_u8(&self, i: u8) -> Self::Value;
|
||||
|
||||
// This is a 'c-like' raw string, which differs from
|
||||
// our boxed-and-length-annotated strings.
|
||||
fn const_cstr(&self, s: LocalInternedString, null_terminated: bool) -> Self::Value;
|
||||
|
||||
fn const_str_slice(&self, s: LocalInternedString) -> Self::Value;
|
||||
fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
|
||||
|
||||
fn const_get_elt(&self, v: Self::Value, idx: u64) -> Self::Value;
|
||||
fn const_get_real(&self, v: Self::Value) -> Option<(f64, bool)>;
|
||||
fn const_to_uint(&self, v: Self::Value) -> u64;
|
||||
fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option<u128>;
|
||||
|
||||
fn is_const_integral(&self, v: Self::Value) -> bool;
|
||||
fn is_const_real(&self, v: Self::Value) -> bool;
|
||||
|
||||
fn scalar_to_backend(
|
||||
&self,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::BackendTypes;
|
||||
use syntax_pos::symbol::LocalInternedString;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::layout::Align;
|
||||
|
||||
|
@ -9,4 +10,12 @@ pub trait StaticMethods: BackendTypes {
|
|||
|
||||
pub trait StaticBuilderMethods<'tcx>: BackendTypes {
|
||||
fn get_static(&mut self, def_id: DefId) -> Self::Value;
|
||||
fn static_panic_msg(
|
||||
&mut self,
|
||||
msg: Option<LocalInternedString>,
|
||||
filename: LocalInternedString,
|
||||
line: Self::Value,
|
||||
col: Self::Value,
|
||||
kind: &str,
|
||||
) -> Self::Value;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue