Introduce SmallCStr and use it where applicable.
This commit is contained in:
parent
9585c5dc1f
commit
88d84b38f1
13 changed files with 200 additions and 75 deletions
|
@ -128,7 +128,7 @@ pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
|
||||||
llvm::AddFunctionAttrStringValue(
|
llvm::AddFunctionAttrStringValue(
|
||||||
llfn,
|
llfn,
|
||||||
llvm::AttributePlace::Function,
|
llvm::AttributePlace::Function,
|
||||||
cstr("target-cpu\0"),
|
const_cstr!("target-cpu"),
|
||||||
target_cpu.as_c_str());
|
target_cpu.as_c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
use rustc::util::common::{time_ext, time_depth, set_time_depth, print_time_passes_entry};
|
use rustc::util::common::{time_ext, time_depth, set_time_depth, print_time_passes_entry};
|
||||||
use rustc_fs_util::{path2cstr, link_or_copy};
|
use rustc_fs_util::{path2cstr, link_or_copy};
|
||||||
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use errors::{self, Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId};
|
use errors::{self, Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId};
|
||||||
use errors::emitter::{Emitter};
|
use errors::emitter::{Emitter};
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
|
@ -170,11 +171,8 @@ pub fn target_machine_factory(sess: &Session, find_features: bool)
|
||||||
|
|
||||||
let singlethread = sess.target.target.options.singlethread;
|
let singlethread = sess.target.target.options.singlethread;
|
||||||
|
|
||||||
let triple = &sess.target.target.llvm_target;
|
let triple = SmallCStr::new(&sess.target.target.llvm_target);
|
||||||
|
let cpu = SmallCStr::new(sess.target_cpu());
|
||||||
let triple = CString::new(triple.as_bytes()).unwrap();
|
|
||||||
let cpu = sess.target_cpu();
|
|
||||||
let cpu = CString::new(cpu.as_bytes()).unwrap();
|
|
||||||
let features = attributes::llvm_target_features(sess)
|
let features = attributes::llvm_target_features(sess)
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(",");
|
.join(",");
|
||||||
|
@ -522,7 +520,7 @@ unsafe fn optimize(cgcx: &CodegenContext,
|
||||||
// If we're verifying or linting, add them to the function pass
|
// If we're verifying or linting, add them to the function pass
|
||||||
// manager.
|
// manager.
|
||||||
let addpass = |pass_name: &str| {
|
let addpass = |pass_name: &str| {
|
||||||
let pass_name = CString::new(pass_name).unwrap();
|
let pass_name = SmallCStr::new(pass_name);
|
||||||
let pass = match llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) {
|
let pass = match llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) {
|
||||||
Some(pass) => pass,
|
Some(pass) => pass,
|
||||||
None => return false,
|
None => return false,
|
||||||
|
|
|
@ -73,6 +73,7 @@ use type_::Type;
|
||||||
use type_of::LayoutLlvmExt;
|
use type_of::LayoutLlvmExt;
|
||||||
use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet};
|
use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet};
|
||||||
use CrateInfo;
|
use CrateInfo;
|
||||||
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
@ -533,7 +534,7 @@ pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
let buf = CString::new(sect.as_str().as_bytes()).unwrap();
|
let buf = SmallCStr::new(§.as_str());
|
||||||
llvm::LLVMSetSection(llval, buf.as_ptr());
|
llvm::LLVMSetSection(llval, buf.as_ptr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -681,7 +682,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||||
let section_name = metadata::metadata_section_name(&tcx.sess.target.target);
|
let section_name = metadata::metadata_section_name(&tcx.sess.target.target);
|
||||||
let name = CString::new(section_name).unwrap();
|
let name = SmallCStr::new(section_name);
|
||||||
llvm::LLVMSetSection(llglobal, name.as_ptr());
|
llvm::LLVMSetSection(llglobal, name.as_ptr());
|
||||||
|
|
||||||
// Also generate a .section directive to force no
|
// Also generate a .section directive to force no
|
||||||
|
|
|
@ -18,9 +18,9 @@ use libc::{c_uint, c_char};
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
use rustc::ty::layout::{Align, Size};
|
use rustc::ty::layout::{Align, Size};
|
||||||
use rustc::session::{config, Session};
|
use rustc::session::{config, Session};
|
||||||
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::ffi::CString;
|
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ impl Builder<'a, 'll, 'tcx> {
|
||||||
pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b str) -> Self {
|
pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b str) -> Self {
|
||||||
let bx = Builder::with_cx(cx);
|
let bx = Builder::with_cx(cx);
|
||||||
let llbb = unsafe {
|
let llbb = unsafe {
|
||||||
let name = CString::new(name).unwrap();
|
let name = SmallCStr::new(name);
|
||||||
llvm::LLVMAppendBasicBlockInContext(
|
llvm::LLVMAppendBasicBlockInContext(
|
||||||
cx.llcx,
|
cx.llcx,
|
||||||
llfn,
|
llfn,
|
||||||
|
@ -118,7 +118,7 @@ impl Builder<'a, 'll, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_value_name(&self, value: &'ll Value, name: &str) {
|
pub fn set_value_name(&self, value: &'ll Value, name: &str) {
|
||||||
let cname = CString::new(name.as_bytes()).unwrap();
|
let cname = SmallCStr::new(name);
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMSetValueName(value, cname.as_ptr());
|
llvm::LLVMSetValueName(value, cname.as_ptr());
|
||||||
}
|
}
|
||||||
|
@ -436,7 +436,7 @@ impl Builder<'a, 'll, 'tcx> {
|
||||||
let alloca = if name.is_empty() {
|
let alloca = if name.is_empty() {
|
||||||
llvm::LLVMBuildAlloca(self.llbuilder, ty, noname())
|
llvm::LLVMBuildAlloca(self.llbuilder, ty, noname())
|
||||||
} else {
|
} else {
|
||||||
let name = CString::new(name).unwrap();
|
let name = SmallCStr::new(name);
|
||||||
llvm::LLVMBuildAlloca(self.llbuilder, ty,
|
llvm::LLVMBuildAlloca(self.llbuilder, ty,
|
||||||
name.as_ptr())
|
name.as_ptr())
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,6 +26,7 @@ use type_::Type;
|
||||||
use type_of::PointeeInfo;
|
use type_of::PointeeInfo;
|
||||||
|
|
||||||
use rustc_data_structures::base_n;
|
use rustc_data_structures::base_n;
|
||||||
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use rustc::mir::mono::Stats;
|
use rustc::mir::mono::Stats;
|
||||||
use rustc::session::config::{self, DebugInfo};
|
use rustc::session::config::{self, DebugInfo};
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
|
@ -34,7 +35,7 @@ use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
use rustc_target::spec::{HasTargetSpec, Target};
|
use rustc_target::spec::{HasTargetSpec, Target};
|
||||||
|
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::CStr;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
@ -161,7 +162,7 @@ pub unsafe fn create_module(
|
||||||
llcx: &'ll llvm::Context,
|
llcx: &'ll llvm::Context,
|
||||||
mod_name: &str,
|
mod_name: &str,
|
||||||
) -> &'ll llvm::Module {
|
) -> &'ll llvm::Module {
|
||||||
let mod_name = CString::new(mod_name).unwrap();
|
let mod_name = SmallCStr::new(mod_name);
|
||||||
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
|
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
|
||||||
|
|
||||||
// Ensure the data-layout values hardcoded remain the defaults.
|
// Ensure the data-layout values hardcoded remain the defaults.
|
||||||
|
@ -201,11 +202,10 @@ pub unsafe fn create_module(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let data_layout = CString::new(&sess.target.target.data_layout[..]).unwrap();
|
let data_layout = SmallCStr::new(&sess.target.target.data_layout);
|
||||||
llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
|
llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
|
||||||
|
|
||||||
let llvm_target = sess.target.target.llvm_target.as_bytes();
|
let llvm_target = SmallCStr::new(&sess.target.target.llvm_target);
|
||||||
let llvm_target = CString::new(llvm_target).unwrap();
|
|
||||||
llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
|
llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
|
||||||
|
|
||||||
if is_pie_binary(sess) {
|
if is_pie_binary(sess) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ use rustc::ty::layout::{self, Align, LayoutOf, PrimitiveExt, Size, TyLayout};
|
||||||
use rustc::session::config;
|
use rustc::session::config;
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
use rustc_fs_util::path2cstr;
|
use rustc_fs_util::path2cstr;
|
||||||
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
|
|
||||||
use libc::{c_uint, c_longlong};
|
use libc::{c_uint, c_longlong};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
@ -274,7 +275,7 @@ impl RecursiveTypeDescription<'ll, 'tcx> {
|
||||||
// ... and attach them to the stub to complete it.
|
// ... and attach them to the stub to complete it.
|
||||||
set_members_of_composite_type(cx,
|
set_members_of_composite_type(cx,
|
||||||
metadata_stub,
|
metadata_stub,
|
||||||
&member_descriptions[..]);
|
member_descriptions);
|
||||||
return MetadataCreationResult::new(metadata_stub, true);
|
return MetadataCreationResult::new(metadata_stub, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,7 +350,7 @@ fn vec_slice_metadata(
|
||||||
let (pointer_size, pointer_align) = cx.size_and_align_of(data_ptr_type);
|
let (pointer_size, pointer_align) = cx.size_and_align_of(data_ptr_type);
|
||||||
let (usize_size, usize_align) = cx.size_and_align_of(cx.tcx.types.usize);
|
let (usize_size, usize_align) = cx.size_and_align_of(cx.tcx.types.usize);
|
||||||
|
|
||||||
let member_descriptions = [
|
let member_descriptions = vec![
|
||||||
MemberDescription {
|
MemberDescription {
|
||||||
name: "data_ptr".to_string(),
|
name: "data_ptr".to_string(),
|
||||||
type_metadata: data_ptr_metadata,
|
type_metadata: data_ptr_metadata,
|
||||||
|
@ -374,7 +375,7 @@ fn vec_slice_metadata(
|
||||||
slice_ptr_type,
|
slice_ptr_type,
|
||||||
&slice_type_name[..],
|
&slice_type_name[..],
|
||||||
unique_type_id,
|
unique_type_id,
|
||||||
&member_descriptions,
|
member_descriptions,
|
||||||
NO_SCOPE_METADATA,
|
NO_SCOPE_METADATA,
|
||||||
file_metadata,
|
file_metadata,
|
||||||
span);
|
span);
|
||||||
|
@ -460,7 +461,7 @@ fn trait_pointer_metadata(
|
||||||
|
|
||||||
let data_ptr_field = layout.field(cx, 0);
|
let data_ptr_field = layout.field(cx, 0);
|
||||||
let vtable_field = layout.field(cx, 1);
|
let vtable_field = layout.field(cx, 1);
|
||||||
let member_descriptions = [
|
let member_descriptions = vec![
|
||||||
MemberDescription {
|
MemberDescription {
|
||||||
name: "pointer".to_string(),
|
name: "pointer".to_string(),
|
||||||
type_metadata: type_metadata(cx,
|
type_metadata: type_metadata(cx,
|
||||||
|
@ -485,7 +486,7 @@ fn trait_pointer_metadata(
|
||||||
trait_object_type,
|
trait_object_type,
|
||||||
&trait_type_name[..],
|
&trait_type_name[..],
|
||||||
unique_type_id,
|
unique_type_id,
|
||||||
&member_descriptions,
|
member_descriptions,
|
||||||
containing_scope,
|
containing_scope,
|
||||||
file_metadata,
|
file_metadata,
|
||||||
syntax_pos::DUMMY_SP)
|
syntax_pos::DUMMY_SP)
|
||||||
|
@ -746,8 +747,8 @@ fn file_metadata_raw(cx: &CodegenCx<'ll, '_>,
|
||||||
|
|
||||||
debug!("file_metadata: file_name: {}, directory: {}", file_name, directory);
|
debug!("file_metadata: file_name: {}, directory: {}", file_name, directory);
|
||||||
|
|
||||||
let file_name = CString::new(file_name).unwrap();
|
let file_name = SmallCStr::new(file_name);
|
||||||
let directory = CString::new(directory).unwrap();
|
let directory = SmallCStr::new(directory);
|
||||||
|
|
||||||
let file_metadata = unsafe {
|
let file_metadata = unsafe {
|
||||||
llvm::LLVMRustDIBuilderCreateFile(DIB(cx),
|
llvm::LLVMRustDIBuilderCreateFile(DIB(cx),
|
||||||
|
@ -782,7 +783,7 @@ fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
|
||||||
};
|
};
|
||||||
|
|
||||||
let (size, align) = cx.size_and_align_of(t);
|
let (size, align) = cx.size_and_align_of(t);
|
||||||
let name = CString::new(name).unwrap();
|
let name = SmallCStr::new(name);
|
||||||
let ty_metadata = unsafe {
|
let ty_metadata = unsafe {
|
||||||
llvm::LLVMRustDIBuilderCreateBasicType(
|
llvm::LLVMRustDIBuilderCreateBasicType(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
|
@ -813,7 +814,7 @@ fn pointer_type_metadata(
|
||||||
) -> &'ll DIType {
|
) -> &'ll DIType {
|
||||||
let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type);
|
let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type);
|
||||||
let name = compute_debuginfo_type_name(cx, pointer_type, false);
|
let name = compute_debuginfo_type_name(cx, pointer_type, false);
|
||||||
let name = CString::new(name).unwrap();
|
let name = SmallCStr::new(&name);
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustDIBuilderCreatePointerType(
|
llvm::LLVMRustDIBuilderCreatePointerType(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
|
@ -847,9 +848,9 @@ pub fn compile_unit_metadata(tcx: TyCtxt,
|
||||||
let producer = format!("clang LLVM (rustc version {})",
|
let producer = format!("clang LLVM (rustc version {})",
|
||||||
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
|
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
|
||||||
|
|
||||||
let name_in_debuginfo = name_in_debuginfo.to_string_lossy().into_owned();
|
let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
|
||||||
let name_in_debuginfo = CString::new(name_in_debuginfo).unwrap();
|
let name_in_debuginfo = SmallCStr::new(&name_in_debuginfo);
|
||||||
let work_dir = CString::new(&tcx.sess.working_dir.0.to_string_lossy()[..]).unwrap();
|
let work_dir = SmallCStr::new(&tcx.sess.working_dir.0.to_string_lossy());
|
||||||
let producer = CString::new(producer).unwrap();
|
let producer = CString::new(producer).unwrap();
|
||||||
let flags = "\0";
|
let flags = "\0";
|
||||||
let split_name = "\0";
|
let split_name = "\0";
|
||||||
|
@ -1187,7 +1188,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
||||||
|
|
||||||
set_members_of_composite_type(cx,
|
set_members_of_composite_type(cx,
|
||||||
variant_type_metadata,
|
variant_type_metadata,
|
||||||
&member_descriptions[..]);
|
member_descriptions);
|
||||||
vec![
|
vec![
|
||||||
MemberDescription {
|
MemberDescription {
|
||||||
name: "".to_string(),
|
name: "".to_string(),
|
||||||
|
@ -1217,7 +1218,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
||||||
|
|
||||||
set_members_of_composite_type(cx,
|
set_members_of_composite_type(cx,
|
||||||
variant_type_metadata,
|
variant_type_metadata,
|
||||||
&member_descriptions);
|
member_descriptions);
|
||||||
MemberDescription {
|
MemberDescription {
|
||||||
name: "".to_string(),
|
name: "".to_string(),
|
||||||
type_metadata: variant_type_metadata,
|
type_metadata: variant_type_metadata,
|
||||||
|
@ -1244,7 +1245,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
||||||
|
|
||||||
set_members_of_composite_type(cx,
|
set_members_of_composite_type(cx,
|
||||||
variant_type_metadata,
|
variant_type_metadata,
|
||||||
&variant_member_descriptions[..]);
|
variant_member_descriptions);
|
||||||
|
|
||||||
// Encode the information about the null variant in the union
|
// Encode the information about the null variant in the union
|
||||||
// member's name.
|
// member's name.
|
||||||
|
@ -1416,8 +1417,7 @@ fn prepare_enum_metadata(
|
||||||
let enumerators_metadata: Vec<_> = def.discriminants(cx.tcx)
|
let enumerators_metadata: Vec<_> = def.discriminants(cx.tcx)
|
||||||
.zip(&def.variants)
|
.zip(&def.variants)
|
||||||
.map(|(discr, v)| {
|
.map(|(discr, v)| {
|
||||||
let token = v.name.as_str();
|
let name = SmallCStr::new(&v.name.as_str());
|
||||||
let name = CString::new(token.as_bytes()).unwrap();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
Some(llvm::LLVMRustDIBuilderCreateEnumerator(
|
Some(llvm::LLVMRustDIBuilderCreateEnumerator(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
|
@ -1442,7 +1442,7 @@ fn prepare_enum_metadata(
|
||||||
type_metadata(cx, discr.to_ty(cx.tcx), syntax_pos::DUMMY_SP);
|
type_metadata(cx, discr.to_ty(cx.tcx), syntax_pos::DUMMY_SP);
|
||||||
let discriminant_name = get_enum_discriminant_name(cx, enum_def_id).as_str();
|
let discriminant_name = get_enum_discriminant_name(cx, enum_def_id).as_str();
|
||||||
|
|
||||||
let name = CString::new(discriminant_name.as_bytes()).unwrap();
|
let name = SmallCStr::new(&discriminant_name);
|
||||||
let discriminant_type_metadata = unsafe {
|
let discriminant_type_metadata = unsafe {
|
||||||
llvm::LLVMRustDIBuilderCreateEnumerationType(
|
llvm::LLVMRustDIBuilderCreateEnumerationType(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
|
@ -1482,10 +1482,10 @@ fn prepare_enum_metadata(
|
||||||
|
|
||||||
let (enum_type_size, enum_type_align) = layout.size_and_align();
|
let (enum_type_size, enum_type_align) = layout.size_and_align();
|
||||||
|
|
||||||
let enum_name = CString::new(enum_name).unwrap();
|
let enum_name = SmallCStr::new(&enum_name);
|
||||||
let unique_type_id_str = CString::new(
|
let unique_type_id_str = SmallCStr::new(
|
||||||
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
|
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
|
||||||
).unwrap();
|
);
|
||||||
let enum_metadata = unsafe {
|
let enum_metadata = unsafe {
|
||||||
llvm::LLVMRustDIBuilderCreateUnionType(
|
llvm::LLVMRustDIBuilderCreateUnionType(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
|
@ -1531,7 +1531,7 @@ fn composite_type_metadata(
|
||||||
composite_type: Ty<'tcx>,
|
composite_type: Ty<'tcx>,
|
||||||
composite_type_name: &str,
|
composite_type_name: &str,
|
||||||
composite_type_unique_id: UniqueTypeId,
|
composite_type_unique_id: UniqueTypeId,
|
||||||
member_descriptions: &[MemberDescription<'ll>],
|
member_descriptions: Vec<MemberDescription<'ll>>,
|
||||||
containing_scope: Option<&'ll DIScope>,
|
containing_scope: Option<&'ll DIScope>,
|
||||||
|
|
||||||
// Ignore source location information as long as it
|
// Ignore source location information as long as it
|
||||||
|
@ -1555,7 +1555,7 @@ fn composite_type_metadata(
|
||||||
|
|
||||||
fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
|
fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
|
||||||
composite_type_metadata: &'ll DICompositeType,
|
composite_type_metadata: &'ll DICompositeType,
|
||||||
member_descriptions: &[MemberDescription<'ll>]) {
|
member_descriptions: Vec<MemberDescription<'ll>>) {
|
||||||
// In some rare cases LLVM metadata uniquing would lead to an existing type
|
// In some rare cases LLVM metadata uniquing would lead to an existing type
|
||||||
// description being used instead of a new one created in
|
// description being used instead of a new one created in
|
||||||
// create_struct_stub. This would cause a hard to trace assertion in
|
// create_struct_stub. This would cause a hard to trace assertion in
|
||||||
|
@ -1574,10 +1574,9 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let member_metadata: Vec<_> = member_descriptions
|
let member_metadata: Vec<_> = member_descriptions
|
||||||
.iter()
|
.into_iter()
|
||||||
.map(|member_description| {
|
.map(|member_description| {
|
||||||
let member_name = member_description.name.as_bytes();
|
let member_name = CString::new(member_description.name).unwrap();
|
||||||
let member_name = CString::new(member_name).unwrap();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
Some(llvm::LLVMRustDIBuilderCreateMemberType(
|
Some(llvm::LLVMRustDIBuilderCreateMemberType(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
|
@ -1613,10 +1612,10 @@ fn create_struct_stub(
|
||||||
) -> &'ll DICompositeType {
|
) -> &'ll DICompositeType {
|
||||||
let (struct_size, struct_align) = cx.size_and_align_of(struct_type);
|
let (struct_size, struct_align) = cx.size_and_align_of(struct_type);
|
||||||
|
|
||||||
let name = CString::new(struct_type_name).unwrap();
|
let name = SmallCStr::new(struct_type_name);
|
||||||
let unique_type_id = CString::new(
|
let unique_type_id = SmallCStr::new(
|
||||||
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
|
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
|
||||||
).unwrap();
|
);
|
||||||
let metadata_stub = unsafe {
|
let metadata_stub = unsafe {
|
||||||
// LLVMRustDIBuilderCreateStructType() wants an empty array. A null
|
// LLVMRustDIBuilderCreateStructType() wants an empty array. A null
|
||||||
// pointer will lead to hard to trace and debug LLVM assertions
|
// pointer will lead to hard to trace and debug LLVM assertions
|
||||||
|
@ -1651,10 +1650,10 @@ fn create_union_stub(
|
||||||
) -> &'ll DICompositeType {
|
) -> &'ll DICompositeType {
|
||||||
let (union_size, union_align) = cx.size_and_align_of(union_type);
|
let (union_size, union_align) = cx.size_and_align_of(union_type);
|
||||||
|
|
||||||
let name = CString::new(union_type_name).unwrap();
|
let name = SmallCStr::new(union_type_name);
|
||||||
let unique_type_id = CString::new(
|
let unique_type_id = SmallCStr::new(
|
||||||
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
|
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
|
||||||
).unwrap();
|
);
|
||||||
let metadata_stub = unsafe {
|
let metadata_stub = unsafe {
|
||||||
// LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
|
// LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
|
||||||
// pointer will lead to hard to trace and debug LLVM assertions
|
// pointer will lead to hard to trace and debug LLVM assertions
|
||||||
|
@ -1713,13 +1712,12 @@ pub fn create_global_var_metadata(
|
||||||
let is_local_to_unit = is_node_local_to_unit(cx, def_id);
|
let is_local_to_unit = is_node_local_to_unit(cx, def_id);
|
||||||
let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx);
|
let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx);
|
||||||
let type_metadata = type_metadata(cx, variable_type, span);
|
let type_metadata = type_metadata(cx, variable_type, span);
|
||||||
let var_name = tcx.item_name(def_id).to_string();
|
let var_name = SmallCStr::new(&tcx.item_name(def_id).as_str());
|
||||||
let var_name = CString::new(var_name).unwrap();
|
|
||||||
let linkage_name = if no_mangle {
|
let linkage_name = if no_mangle {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id));
|
let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id));
|
||||||
Some(CString::new(linkage_name.to_string()).unwrap())
|
Some(SmallCStr::new(&linkage_name.as_str()))
|
||||||
};
|
};
|
||||||
|
|
||||||
let global_align = cx.align_of(variable_type);
|
let global_align = cx.align_of(variable_type);
|
||||||
|
|
|
@ -34,6 +34,7 @@ use rustc::ty::{self, ParamEnv, Ty, InstanceDef};
|
||||||
use rustc::mir;
|
use rustc::mir;
|
||||||
use rustc::session::config::{self, DebugInfo};
|
use rustc::session::config::{self, DebugInfo};
|
||||||
use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet};
|
use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet};
|
||||||
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use value::Value;
|
use value::Value;
|
||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
|
@ -265,7 +266,7 @@ pub fn create_function_debug_context(
|
||||||
let is_local_to_unit = is_node_local_to_unit(cx, def_id);
|
let is_local_to_unit = is_node_local_to_unit(cx, def_id);
|
||||||
|
|
||||||
let function_name = CString::new(name).unwrap();
|
let function_name = CString::new(name).unwrap();
|
||||||
let linkage_name = CString::new(linkage_name.to_string()).unwrap();
|
let linkage_name = SmallCStr::new(&linkage_name.as_str());
|
||||||
|
|
||||||
let mut flags = DIFlags::FlagPrototyped;
|
let mut flags = DIFlags::FlagPrototyped;
|
||||||
|
|
||||||
|
@ -407,7 +408,7 @@ pub fn create_function_debug_context(
|
||||||
let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
|
let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
|
||||||
let actual_type_metadata =
|
let actual_type_metadata =
|
||||||
type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
|
type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
|
||||||
let name = CString::new(name.as_str().as_bytes()).unwrap();
|
let name = SmallCStr::new(&name.as_str());
|
||||||
Some(unsafe {
|
Some(unsafe {
|
||||||
Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
|
Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
|
@ -510,7 +511,7 @@ pub fn declare_local(
|
||||||
};
|
};
|
||||||
let align = cx.align_of(variable_type);
|
let align = cx.align_of(variable_type);
|
||||||
|
|
||||||
let name = CString::new(variable_name.as_str().as_bytes()).unwrap();
|
let name = SmallCStr::new(&variable_name.as_str());
|
||||||
match (variable_access, &[][..]) {
|
match (variable_access, &[][..]) {
|
||||||
(DirectVariable { alloca }, address_operations) |
|
(DirectVariable { alloca }, address_operations) |
|
||||||
(IndirectVariable {alloca, address_operations}, _) => {
|
(IndirectVariable {alloca, address_operations}, _) => {
|
||||||
|
|
|
@ -21,7 +21,7 @@ use rustc::hir::def_id::DefId;
|
||||||
use rustc::hir::map::DefPathData;
|
use rustc::hir::map::DefPathData;
|
||||||
use common::CodegenCx;
|
use common::CodegenCx;
|
||||||
|
|
||||||
use std::ffi::CString;
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
|
|
||||||
pub fn mangled_name_of_instance<'a, 'tcx>(
|
pub fn mangled_name_of_instance<'a, 'tcx>(
|
||||||
cx: &CodegenCx<'a, 'tcx>,
|
cx: &CodegenCx<'a, 'tcx>,
|
||||||
|
@ -49,7 +49,7 @@ pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
|
||||||
data => data.as_interned_str().as_str()
|
data => data.as_interned_str().as_str()
|
||||||
};
|
};
|
||||||
|
|
||||||
let namespace_name = CString::new(namespace_name.as_bytes()).unwrap();
|
let namespace_name = SmallCStr::new(&namespace_name);
|
||||||
|
|
||||||
let scope = unsafe {
|
let scope = unsafe {
|
||||||
llvm::LLVMRustDIBuilderCreateNameSpace(
|
llvm::LLVMRustDIBuilderCreateNameSpace(
|
||||||
|
|
|
@ -25,6 +25,7 @@ use llvm::AttributePlace::Function;
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use rustc::ty::layout::{self, LayoutOf};
|
use rustc::ty::layout::{self, LayoutOf};
|
||||||
use rustc::session::config::Sanitizer;
|
use rustc::session::config::Sanitizer;
|
||||||
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use rustc_target::spec::PanicStrategy;
|
use rustc_target::spec::PanicStrategy;
|
||||||
use abi::{Abi, FnType, FnTypeExt};
|
use abi::{Abi, FnType, FnTypeExt};
|
||||||
use attributes;
|
use attributes;
|
||||||
|
@ -33,7 +34,6 @@ use common;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
use value::Value;
|
use value::Value;
|
||||||
|
|
||||||
use std::ffi::CString;
|
|
||||||
|
|
||||||
/// Declare a global value.
|
/// Declare a global value.
|
||||||
///
|
///
|
||||||
|
@ -41,9 +41,7 @@ use std::ffi::CString;
|
||||||
/// return its Value instead.
|
/// return its Value instead.
|
||||||
pub fn declare_global(cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll Type) -> &'ll Value {
|
pub fn declare_global(cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll Type) -> &'ll Value {
|
||||||
debug!("declare_global(name={:?})", name);
|
debug!("declare_global(name={:?})", name);
|
||||||
let namebuf = CString::new(name).unwrap_or_else(|_|{
|
let namebuf = SmallCStr::new(name);
|
||||||
bug!("name {:?} contains an interior null byte", name)
|
|
||||||
});
|
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustGetOrInsertGlobal(cx.llmod, namebuf.as_ptr(), ty)
|
llvm::LLVMRustGetOrInsertGlobal(cx.llmod, namebuf.as_ptr(), ty)
|
||||||
}
|
}
|
||||||
|
@ -61,9 +59,7 @@ fn declare_raw_fn(
|
||||||
ty: &'ll Type,
|
ty: &'ll Type,
|
||||||
) -> &'ll Value {
|
) -> &'ll Value {
|
||||||
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
|
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
|
||||||
let namebuf = CString::new(name).unwrap_or_else(|_|{
|
let namebuf = SmallCStr::new(name);
|
||||||
bug!("name {:?} contains an interior null byte", name)
|
|
||||||
});
|
|
||||||
let llfn = unsafe {
|
let llfn = unsafe {
|
||||||
llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty)
|
llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty)
|
||||||
};
|
};
|
||||||
|
@ -214,9 +210,7 @@ pub fn define_internal_fn(
|
||||||
/// Get declared value by name.
|
/// Get declared value by name.
|
||||||
pub fn get_declared_value(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Value> {
|
pub fn get_declared_value(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Value> {
|
||||||
debug!("get_declared_value(name={:?})", name);
|
debug!("get_declared_value(name={:?})", name);
|
||||||
let namebuf = CString::new(name).unwrap_or_else(|_|{
|
let namebuf = SmallCStr::new(name);
|
||||||
bug!("name {:?} contains an interior null byte", name)
|
|
||||||
});
|
|
||||||
unsafe { llvm::LLVMRustGetNamedValue(cx.llmod, namebuf.as_ptr()) }
|
unsafe { llvm::LLVMRustGetNamedValue(cx.llmod, namebuf.as_ptr()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,10 @@ pub use self::Linkage::*;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::ffi::{CString, CStr};
|
use std::ffi::CStr;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use libc::{self, c_uint, c_char, size_t};
|
use libc::{self, c_uint, c_char, size_t};
|
||||||
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
|
|
||||||
pub mod archive_ro;
|
pub mod archive_ro;
|
||||||
pub mod diagnostic;
|
pub mod diagnostic;
|
||||||
|
@ -264,7 +265,7 @@ pub struct OperandBundleDef<'a> {
|
||||||
|
|
||||||
impl OperandBundleDef<'a> {
|
impl OperandBundleDef<'a> {
|
||||||
pub fn new(name: &str, vals: &[&'a Value]) -> Self {
|
pub fn new(name: &str, vals: &[&'a Value]) -> Self {
|
||||||
let name = CString::new(name).unwrap();
|
let name = SmallCStr::new(name);
|
||||||
let def = unsafe {
|
let def = unsafe {
|
||||||
LLVMRustBuildOperandBundleDef(name.as_ptr(), vals.as_ptr(), vals.len() as c_uint)
|
LLVMRustBuildOperandBundleDef(name.as_ptr(), vals.as_ptr(), vals.len() as c_uint)
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,8 +19,8 @@ use context::CodegenCx;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use rustc::ty::layout::{self, Align, Size};
|
use rustc::ty::layout::{self, Align, Size};
|
||||||
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
|
|
||||||
use std::ffi::CString;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
|
@ -201,7 +201,7 @@ impl Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn named_struct(cx: &CodegenCx<'ll, '_>, name: &str) -> &'ll Type {
|
pub fn named_struct(cx: &CodegenCx<'ll, '_>, name: &str) -> &'ll Type {
|
||||||
let name = CString::new(name).unwrap();
|
let name = SmallCStr::new(name);
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr())
|
llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr())
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@ pub mod obligation_forest;
|
||||||
pub mod owning_ref;
|
pub mod owning_ref;
|
||||||
pub mod ptr_key;
|
pub mod ptr_key;
|
||||||
pub mod sip128;
|
pub mod sip128;
|
||||||
|
pub mod small_c_str;
|
||||||
pub mod small_vec;
|
pub mod small_vec;
|
||||||
pub mod snapshot_map;
|
pub mod snapshot_map;
|
||||||
pub use ena::snapshot_vec;
|
pub use ena::snapshot_vec;
|
||||||
|
|
131
src/librustc_data_structures/small_c_str.rs
Normal file
131
src/librustc_data_structures/small_c_str.rs
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
use std::ffi;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
const SIZE: usize = 38;
|
||||||
|
|
||||||
|
/// Like SmallVec but for C strings.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum SmallCStr {
|
||||||
|
OnStack {
|
||||||
|
data: [u8; SIZE],
|
||||||
|
len_with_nul: u8,
|
||||||
|
},
|
||||||
|
OnHeap {
|
||||||
|
data: ffi::CString,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SmallCStr {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(s: &str) -> SmallCStr {
|
||||||
|
if s.len() < SIZE {
|
||||||
|
let mut data = [0; SIZE];
|
||||||
|
data[.. s.len()].copy_from_slice(s.as_bytes());
|
||||||
|
let len_with_nul = s.len() + 1;
|
||||||
|
|
||||||
|
// Make sure once that this is a valid CStr
|
||||||
|
if let Err(e) = ffi::CStr::from_bytes_with_nul(&data[.. len_with_nul]) {
|
||||||
|
panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallCStr::OnStack {
|
||||||
|
data,
|
||||||
|
len_with_nul: len_with_nul as u8,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SmallCStr::OnHeap {
|
||||||
|
data: ffi::CString::new(s).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn as_c_str(&self) -> &ffi::CStr {
|
||||||
|
match *self {
|
||||||
|
SmallCStr::OnStack { ref data, len_with_nul } => {
|
||||||
|
unsafe {
|
||||||
|
let slice = &data[.. len_with_nul as usize];
|
||||||
|
ffi::CStr::from_bytes_with_nul_unchecked(slice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SmallCStr::OnHeap { ref data } => {
|
||||||
|
data.as_c_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn len_with_nul(&self) -> usize {
|
||||||
|
match *self {
|
||||||
|
SmallCStr::OnStack { len_with_nul, .. } => {
|
||||||
|
len_with_nul as usize
|
||||||
|
}
|
||||||
|
SmallCStr::OnHeap { ref data } => {
|
||||||
|
data.as_bytes_with_nul().len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for SmallCStr {
|
||||||
|
type Target = ffi::CStr;
|
||||||
|
|
||||||
|
fn deref(&self) -> &ffi::CStr {
|
||||||
|
self.as_c_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn short() {
|
||||||
|
const TEXT: &str = "abcd";
|
||||||
|
let reference = ffi::CString::new(TEXT.to_string()).unwrap();
|
||||||
|
|
||||||
|
let scs = SmallCStr::new(TEXT);
|
||||||
|
|
||||||
|
assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
|
||||||
|
assert_eq!(scs.as_c_str(), reference.as_c_str());
|
||||||
|
assert!(if let SmallCStr::OnStack { .. } = scs { true } else { false });
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn empty() {
|
||||||
|
const TEXT: &str = "";
|
||||||
|
let reference = ffi::CString::new(TEXT.to_string()).unwrap();
|
||||||
|
|
||||||
|
let scs = SmallCStr::new(TEXT);
|
||||||
|
|
||||||
|
assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
|
||||||
|
assert_eq!(scs.as_c_str(), reference.as_c_str());
|
||||||
|
assert!(if let SmallCStr::OnStack { .. } = scs { true } else { false });
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn long() {
|
||||||
|
const TEXT: &str = "01234567890123456789012345678901234567890123456789\
|
||||||
|
01234567890123456789012345678901234567890123456789\
|
||||||
|
01234567890123456789012345678901234567890123456789";
|
||||||
|
let reference = ffi::CString::new(TEXT.to_string()).unwrap();
|
||||||
|
|
||||||
|
let scs = SmallCStr::new(TEXT);
|
||||||
|
|
||||||
|
assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
|
||||||
|
assert_eq!(scs.as_c_str(), reference.as_c_str());
|
||||||
|
assert!(if let SmallCStr::OnHeap { .. } = scs { true } else { false });
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn internal_nul() {
|
||||||
|
let _ = SmallCStr::new("abcd\0def");
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue