about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_codegen_llvm/builder.rs31
-rw-r--r--src/librustc_codegen_llvm/common.rs132
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs53
-rw-r--r--src/librustc_codegen_ssa/traits/consts.rs9
-rw-r--r--src/librustc_codegen_ssa/traits/statics.rs9
5 files changed, 126 insertions, 108 deletions
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index ebe3a81acc6..3b3b437007a 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -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> {
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index aab0d8ac602..9554e54e414 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -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) {
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index 494355efeaa..f0e8a18c479 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -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.
diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs
index 61db94d53d8..32412f303c1 100644
--- a/src/librustc_codegen_ssa/traits/consts.rs
+++ b/src/librustc_codegen_ssa/traits/consts.rs
@@ -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,
diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs
index 55c1253f106..d8992c15933 100644
--- a/src/librustc_codegen_ssa/traits/statics.rs
+++ b/src/librustc_codegen_ssa/traits/statics.rs
@@ -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;
 }