Introduce SmallCStr and use it where applicable.
This commit is contained in:
parent
9585c5dc1f
commit
88d84b38f1
@ -128,7 +128,7 @@ pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
|
||||
llvm::AddFunctionAttrStringValue(
|
||||
llfn,
|
||||
llvm::AttributePlace::Function,
|
||||
cstr("target-cpu\0"),
|
||||
const_cstr!("target-cpu"),
|
||||
target_cpu.as_c_str());
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
use rustc::ty::TyCtxt;
|
||||
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_data_structures::small_c_str::SmallCStr;
|
||||
use errors::{self, Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId};
|
||||
use errors::emitter::{Emitter};
|
||||
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 triple = &sess.target.target.llvm_target;
|
||||
|
||||
let triple = CString::new(triple.as_bytes()).unwrap();
|
||||
let cpu = sess.target_cpu();
|
||||
let cpu = CString::new(cpu.as_bytes()).unwrap();
|
||||
let triple = SmallCStr::new(&sess.target.target.llvm_target);
|
||||
let cpu = SmallCStr::new(sess.target_cpu());
|
||||
let features = attributes::llvm_target_features(sess)
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
@ -522,7 +520,7 @@ unsafe fn optimize(cgcx: &CodegenContext,
|
||||
// If we're verifying or linting, add them to the function pass
|
||||
// manager.
|
||||
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()) {
|
||||
Some(pass) => pass,
|
||||
None => return false,
|
||||
|
@ -73,6 +73,7 @@
|
||||
use type_of::LayoutLlvmExt;
|
||||
use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet};
|
||||
use CrateInfo;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
||||
use std::any::Any;
|
||||
@ -533,7 +534,7 @@ pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
|
||||
None => return,
|
||||
};
|
||||
unsafe {
|
||||
let buf = CString::new(sect.as_str().as_bytes()).unwrap();
|
||||
let buf = SmallCStr::new(§.as_str());
|
||||
llvm::LLVMSetSection(llval, buf.as_ptr());
|
||||
}
|
||||
}
|
||||
@ -681,7 +682,7 @@ enum MetadataKind {
|
||||
unsafe {
|
||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||
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());
|
||||
|
||||
// Also generate a .section directive to force no
|
||||
|
@ -18,9 +18,9 @@
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::ty::layout::{Align, Size};
|
||||
use rustc::session::{config, Session};
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::ffi::CString;
|
||||
use std::ops::Range;
|
||||
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 {
|
||||
let bx = Builder::with_cx(cx);
|
||||
let llbb = unsafe {
|
||||
let name = CString::new(name).unwrap();
|
||||
let name = SmallCStr::new(name);
|
||||
llvm::LLVMAppendBasicBlockInContext(
|
||||
cx.llcx,
|
||||
llfn,
|
||||
@ -118,7 +118,7 @@ fn count_insn(&self, category: &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 {
|
||||
llvm::LLVMSetValueName(value, cname.as_ptr());
|
||||
}
|
||||
@ -436,7 +436,7 @@ pub fn dynamic_alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Va
|
||||
let alloca = if name.is_empty() {
|
||||
llvm::LLVMBuildAlloca(self.llbuilder, ty, noname())
|
||||
} else {
|
||||
let name = CString::new(name).unwrap();
|
||||
let name = SmallCStr::new(name);
|
||||
llvm::LLVMBuildAlloca(self.llbuilder, ty,
|
||||
name.as_ptr())
|
||||
};
|
||||
|
@ -26,6 +26,7 @@
|
||||
use type_of::PointeeInfo;
|
||||
|
||||
use rustc_data_structures::base_n;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc::mir::mono::Stats;
|
||||
use rustc::session::config::{self, DebugInfo};
|
||||
use rustc::session::Session;
|
||||
@ -34,7 +35,7 @@
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_target::spec::{HasTargetSpec, Target};
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ffi::CStr;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::iter;
|
||||
use std::str;
|
||||
@ -161,7 +162,7 @@ pub unsafe fn create_module(
|
||||
llcx: &'ll llvm::Context,
|
||||
mod_name: &str,
|
||||
) -> &'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);
|
||||
|
||||
// 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());
|
||||
|
||||
let llvm_target = sess.target.target.llvm_target.as_bytes();
|
||||
let llvm_target = CString::new(llvm_target).unwrap();
|
||||
let llvm_target = SmallCStr::new(&sess.target.target.llvm_target);
|
||||
llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
|
||||
|
||||
if is_pie_binary(sess) {
|
||||
|
@ -37,6 +37,7 @@
|
||||
use rustc::session::config;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_fs_util::path2cstr;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
|
||||
use libc::{c_uint, c_longlong};
|
||||
use std::ffi::CString;
|
||||
@ -274,7 +275,7 @@ fn finalize(&self, cx: &CodegenCx<'ll, 'tcx>) -> MetadataCreationResult<'ll> {
|
||||
// ... and attach them to the stub to complete it.
|
||||
set_members_of_composite_type(cx,
|
||||
metadata_stub,
|
||||
&member_descriptions[..]);
|
||||
member_descriptions);
|
||||
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 (usize_size, usize_align) = cx.size_and_align_of(cx.tcx.types.usize);
|
||||
|
||||
let member_descriptions = [
|
||||
let member_descriptions = vec![
|
||||
MemberDescription {
|
||||
name: "data_ptr".to_string(),
|
||||
type_metadata: data_ptr_metadata,
|
||||
@ -374,7 +375,7 @@ fn vec_slice_metadata(
|
||||
slice_ptr_type,
|
||||
&slice_type_name[..],
|
||||
unique_type_id,
|
||||
&member_descriptions,
|
||||
member_descriptions,
|
||||
NO_SCOPE_METADATA,
|
||||
file_metadata,
|
||||
span);
|
||||
@ -460,7 +461,7 @@ fn trait_pointer_metadata(
|
||||
|
||||
let data_ptr_field = layout.field(cx, 0);
|
||||
let vtable_field = layout.field(cx, 1);
|
||||
let member_descriptions = [
|
||||
let member_descriptions = vec![
|
||||
MemberDescription {
|
||||
name: "pointer".to_string(),
|
||||
type_metadata: type_metadata(cx,
|
||||
@ -485,7 +486,7 @@ fn trait_pointer_metadata(
|
||||
trait_object_type,
|
||||
&trait_type_name[..],
|
||||
unique_type_id,
|
||||
&member_descriptions,
|
||||
member_descriptions,
|
||||
containing_scope,
|
||||
file_metadata,
|
||||
syntax_pos::DUMMY_SP)
|
||||
@ -746,8 +747,8 @@ fn file_metadata_raw(cx: &CodegenCx<'ll, '_>,
|
||||
|
||||
debug!("file_metadata: file_name: {}, directory: {}", file_name, directory);
|
||||
|
||||
let file_name = CString::new(file_name).unwrap();
|
||||
let directory = CString::new(directory).unwrap();
|
||||
let file_name = SmallCStr::new(file_name);
|
||||
let directory = SmallCStr::new(directory);
|
||||
|
||||
let file_metadata = unsafe {
|
||||
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 name = CString::new(name).unwrap();
|
||||
let name = SmallCStr::new(name);
|
||||
let ty_metadata = unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateBasicType(
|
||||
DIB(cx),
|
||||
@ -813,7 +814,7 @@ fn pointer_type_metadata(
|
||||
) -> &'ll DIType {
|
||||
let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type);
|
||||
let name = compute_debuginfo_type_name(cx, pointer_type, false);
|
||||
let name = CString::new(name).unwrap();
|
||||
let name = SmallCStr::new(&name);
|
||||
unsafe {
|
||||
llvm::LLVMRustDIBuilderCreatePointerType(
|
||||
DIB(cx),
|
||||
@ -847,9 +848,9 @@ pub fn compile_unit_metadata(tcx: TyCtxt,
|
||||
let producer = format!("clang LLVM (rustc version {})",
|
||||
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
|
||||
|
||||
let name_in_debuginfo = name_in_debuginfo.to_string_lossy().into_owned();
|
||||
let name_in_debuginfo = CString::new(name_in_debuginfo).unwrap();
|
||||
let work_dir = CString::new(&tcx.sess.working_dir.0.to_string_lossy()[..]).unwrap();
|
||||
let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
|
||||
let name_in_debuginfo = SmallCStr::new(&name_in_debuginfo);
|
||||
let work_dir = SmallCStr::new(&tcx.sess.working_dir.0.to_string_lossy());
|
||||
let producer = CString::new(producer).unwrap();
|
||||
let flags = "\0";
|
||||
let split_name = "\0";
|
||||
@ -1187,7 +1188,7 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
|
||||
|
||||
set_members_of_composite_type(cx,
|
||||
variant_type_metadata,
|
||||
&member_descriptions[..]);
|
||||
member_descriptions);
|
||||
vec![
|
||||
MemberDescription {
|
||||
name: "".to_string(),
|
||||
@ -1217,7 +1218,7 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
|
||||
|
||||
set_members_of_composite_type(cx,
|
||||
variant_type_metadata,
|
||||
&member_descriptions);
|
||||
member_descriptions);
|
||||
MemberDescription {
|
||||
name: "".to_string(),
|
||||
type_metadata: variant_type_metadata,
|
||||
@ -1244,7 +1245,7 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
|
||||
|
||||
set_members_of_composite_type(cx,
|
||||
variant_type_metadata,
|
||||
&variant_member_descriptions[..]);
|
||||
variant_member_descriptions);
|
||||
|
||||
// Encode the information about the null variant in the union
|
||||
// member's name.
|
||||
@ -1416,8 +1417,7 @@ fn prepare_enum_metadata(
|
||||
let enumerators_metadata: Vec<_> = def.discriminants(cx.tcx)
|
||||
.zip(&def.variants)
|
||||
.map(|(discr, v)| {
|
||||
let token = v.name.as_str();
|
||||
let name = CString::new(token.as_bytes()).unwrap();
|
||||
let name = SmallCStr::new(&v.name.as_str());
|
||||
unsafe {
|
||||
Some(llvm::LLVMRustDIBuilderCreateEnumerator(
|
||||
DIB(cx),
|
||||
@ -1442,7 +1442,7 @@ fn prepare_enum_metadata(
|
||||
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 name = CString::new(discriminant_name.as_bytes()).unwrap();
|
||||
let name = SmallCStr::new(&discriminant_name);
|
||||
let discriminant_type_metadata = unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateEnumerationType(
|
||||
DIB(cx),
|
||||
@ -1482,10 +1482,10 @@ fn prepare_enum_metadata(
|
||||
|
||||
let (enum_type_size, enum_type_align) = layout.size_and_align();
|
||||
|
||||
let enum_name = CString::new(enum_name).unwrap();
|
||||
let unique_type_id_str = CString::new(
|
||||
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
|
||||
).unwrap();
|
||||
let enum_name = SmallCStr::new(&enum_name);
|
||||
let unique_type_id_str = SmallCStr::new(
|
||||
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
|
||||
);
|
||||
let enum_metadata = unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateUnionType(
|
||||
DIB(cx),
|
||||
@ -1531,7 +1531,7 @@ fn composite_type_metadata(
|
||||
composite_type: Ty<'tcx>,
|
||||
composite_type_name: &str,
|
||||
composite_type_unique_id: UniqueTypeId,
|
||||
member_descriptions: &[MemberDescription<'ll>],
|
||||
member_descriptions: Vec<MemberDescription<'ll>>,
|
||||
containing_scope: Option<&'ll DIScope>,
|
||||
|
||||
// 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, '_>,
|
||||
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
|
||||
// description being used instead of a new one created 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
|
||||
.iter()
|
||||
.into_iter()
|
||||
.map(|member_description| {
|
||||
let member_name = member_description.name.as_bytes();
|
||||
let member_name = CString::new(member_name).unwrap();
|
||||
let member_name = CString::new(member_description.name).unwrap();
|
||||
unsafe {
|
||||
Some(llvm::LLVMRustDIBuilderCreateMemberType(
|
||||
DIB(cx),
|
||||
@ -1613,10 +1612,10 @@ fn create_struct_stub(
|
||||
) -> &'ll DICompositeType {
|
||||
let (struct_size, struct_align) = cx.size_and_align_of(struct_type);
|
||||
|
||||
let name = CString::new(struct_type_name).unwrap();
|
||||
let unique_type_id = CString::new(
|
||||
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
|
||||
).unwrap();
|
||||
let name = SmallCStr::new(struct_type_name);
|
||||
let unique_type_id = SmallCStr::new(
|
||||
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
|
||||
);
|
||||
let metadata_stub = unsafe {
|
||||
// LLVMRustDIBuilderCreateStructType() wants an empty array. A null
|
||||
// pointer will lead to hard to trace and debug LLVM assertions
|
||||
@ -1651,10 +1650,10 @@ fn create_union_stub(
|
||||
) -> &'ll DICompositeType {
|
||||
let (union_size, union_align) = cx.size_and_align_of(union_type);
|
||||
|
||||
let name = CString::new(union_type_name).unwrap();
|
||||
let unique_type_id = CString::new(
|
||||
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
|
||||
).unwrap();
|
||||
let name = SmallCStr::new(union_type_name);
|
||||
let unique_type_id = SmallCStr::new(
|
||||
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
|
||||
);
|
||||
let metadata_stub = unsafe {
|
||||
// LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
|
||||
// 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 variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx);
|
||||
let type_metadata = type_metadata(cx, variable_type, span);
|
||||
let var_name = tcx.item_name(def_id).to_string();
|
||||
let var_name = CString::new(var_name).unwrap();
|
||||
let var_name = SmallCStr::new(&tcx.item_name(def_id).as_str());
|
||||
let linkage_name = if no_mangle {
|
||||
None
|
||||
} else {
|
||||
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);
|
||||
|
@ -34,6 +34,7 @@
|
||||
use rustc::mir;
|
||||
use rustc::session::config::{self, DebugInfo};
|
||||
use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use value::Value;
|
||||
|
||||
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 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;
|
||||
|
||||
@ -407,7 +408,7 @@ fn get_template_parameters(
|
||||
let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
|
||||
let actual_type_metadata =
|
||||
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(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
|
||||
DIB(cx),
|
||||
@ -510,7 +511,7 @@ pub fn declare_local(
|
||||
};
|
||||
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, &[][..]) {
|
||||
(DirectVariable { alloca }, address_operations) |
|
||||
(IndirectVariable {alloca, address_operations}, _) => {
|
||||
|
@ -21,7 +21,7 @@
|
||||
use rustc::hir::map::DefPathData;
|
||||
use common::CodegenCx;
|
||||
|
||||
use std::ffi::CString;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
|
||||
pub fn mangled_name_of_instance<'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()
|
||||
};
|
||||
|
||||
let namespace_name = CString::new(namespace_name.as_bytes()).unwrap();
|
||||
let namespace_name = SmallCStr::new(&namespace_name);
|
||||
|
||||
let scope = unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateNameSpace(
|
||||
|
@ -25,6 +25,7 @@
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::{self, LayoutOf};
|
||||
use rustc::session::config::Sanitizer;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
use abi::{Abi, FnType, FnTypeExt};
|
||||
use attributes;
|
||||
@ -33,7 +34,6 @@
|
||||
use type_::Type;
|
||||
use value::Value;
|
||||
|
||||
use std::ffi::CString;
|
||||
|
||||
/// Declare a global value.
|
||||
///
|
||||
@ -41,9 +41,7 @@
|
||||
/// return its Value instead.
|
||||
pub fn declare_global(cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll Type) -> &'ll Value {
|
||||
debug!("declare_global(name={:?})", name);
|
||||
let namebuf = CString::new(name).unwrap_or_else(|_|{
|
||||
bug!("name {:?} contains an interior null byte", name)
|
||||
});
|
||||
let namebuf = SmallCStr::new(name);
|
||||
unsafe {
|
||||
llvm::LLVMRustGetOrInsertGlobal(cx.llmod, namebuf.as_ptr(), ty)
|
||||
}
|
||||
@ -61,9 +59,7 @@ fn declare_raw_fn(
|
||||
ty: &'ll Type,
|
||||
) -> &'ll Value {
|
||||
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
|
||||
let namebuf = CString::new(name).unwrap_or_else(|_|{
|
||||
bug!("name {:?} contains an interior null byte", name)
|
||||
});
|
||||
let namebuf = SmallCStr::new(name);
|
||||
let llfn = unsafe {
|
||||
llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty)
|
||||
};
|
||||
@ -214,9 +210,7 @@ pub fn define_internal_fn(
|
||||
/// Get declared value by name.
|
||||
pub fn get_declared_value(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Value> {
|
||||
debug!("get_declared_value(name={:?})", name);
|
||||
let namebuf = CString::new(name).unwrap_or_else(|_|{
|
||||
bug!("name {:?} contains an interior null byte", name)
|
||||
});
|
||||
let namebuf = SmallCStr::new(name);
|
||||
unsafe { llvm::LLVMRustGetNamedValue(cx.llmod, namebuf.as_ptr()) }
|
||||
}
|
||||
|
||||
|
@ -24,9 +24,10 @@
|
||||
use std::str::FromStr;
|
||||
use std::string::FromUtf8Error;
|
||||
use std::slice;
|
||||
use std::ffi::{CString, CStr};
|
||||
use std::ffi::CStr;
|
||||
use std::cell::RefCell;
|
||||
use libc::{self, c_uint, c_char, size_t};
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
|
||||
pub mod archive_ro;
|
||||
pub mod diagnostic;
|
||||
@ -264,7 +265,7 @@ pub struct OperandBundleDef<'a> {
|
||||
|
||||
impl OperandBundleDef<'a> {
|
||||
pub fn new(name: &str, vals: &[&'a Value]) -> Self {
|
||||
let name = CString::new(name).unwrap();
|
||||
let name = SmallCStr::new(name);
|
||||
let def = unsafe {
|
||||
LLVMRustBuildOperandBundleDef(name.as_ptr(), vals.as_ptr(), vals.len() as c_uint)
|
||||
};
|
||||
|
@ -19,8 +19,8 @@
|
||||
|
||||
use syntax::ast;
|
||||
use rustc::ty::layout::{self, Align, Size};
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::fmt;
|
||||
|
||||
use libc::c_uint;
|
||||
@ -201,7 +201,7 @@ pub fn struct_(cx: &CodegenCx<'ll, '_>, els: &[&'ll Type], packed: bool) -> &'ll
|
||||
}
|
||||
|
||||
pub fn named_struct(cx: &CodegenCx<'ll, '_>, name: &str) -> &'ll Type {
|
||||
let name = CString::new(name).unwrap();
|
||||
let name = SmallCStr::new(name);
|
||||
unsafe {
|
||||
llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr())
|
||||
}
|
||||
|
@ -70,6 +70,7 @@
|
||||
pub mod owning_ref;
|
||||
pub mod ptr_key;
|
||||
pub mod sip128;
|
||||
pub mod small_c_str;
|
||||
pub mod small_vec;
|
||||
pub mod snapshot_map;
|
||||
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…
Reference in New Issue
Block a user