Introduce const_cstr!() macro and use it where applicable.
This commit is contained in:
parent
f6d43ed842
commit
9585c5dc1f
7 changed files with 56 additions and 17 deletions
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
//! Set and unset common attributes on LLVM values.
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ffi::CString;
|
||||
|
||||
use rustc::hir::CodegenFnAttrFlags;
|
||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
|
@ -75,7 +75,7 @@ pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value)
|
|||
if cx.sess().must_not_eliminate_frame_pointers() {
|
||||
llvm::AddFunctionAttrStringValue(
|
||||
llfn, llvm::AttributePlace::Function,
|
||||
cstr("no-frame-pointer-elim\0"), cstr("true\0"));
|
||||
const_cstr!("no-frame-pointer-elim"), const_cstr!("true"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
|
|||
// This is defined in the `compiler-builtins` crate for each architecture.
|
||||
llvm::AddFunctionAttrStringValue(
|
||||
llfn, llvm::AttributePlace::Function,
|
||||
cstr("probe-stack\0"), cstr("__rust_probestack\0"));
|
||||
const_cstr!("probe-stack"), const_cstr!("__rust_probestack"));
|
||||
}
|
||||
|
||||
pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
|
||||
|
@ -202,7 +202,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
|
|||
let val = CString::new(features).unwrap();
|
||||
llvm::AddFunctionAttrStringValue(
|
||||
llfn, llvm::AttributePlace::Function,
|
||||
cstr("target-features\0"), &val);
|
||||
const_cstr!("target-features"), &val);
|
||||
}
|
||||
|
||||
// Note that currently the `wasm-import-module` doesn't do anything, but
|
||||
|
@ -213,17 +213,13 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
|
|||
llvm::AddFunctionAttrStringValue(
|
||||
llfn,
|
||||
llvm::AttributePlace::Function,
|
||||
cstr("wasm-import-module\0"),
|
||||
const_cstr!("wasm-import-module"),
|
||||
&module,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cstr(s: &'static str) -> &CStr {
|
||||
CStr::from_bytes_with_nul(s.as_bytes()).expect("null-terminated string")
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
providers.target_features_whitelist = |tcx, cnum| {
|
||||
assert_eq!(cnum, LOCAL_CRATE);
|
||||
|
|
|
@ -1255,8 +1255,8 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
// Create the llvm.used variable
|
||||
// This variable has type [N x i8*] and is stored in the llvm.metadata section
|
||||
if !cx.used_statics.borrow().is_empty() {
|
||||
let name = CString::new("llvm.used").unwrap();
|
||||
let section = CString::new("llvm.metadata").unwrap();
|
||||
let name = const_cstr!("llvm.used");
|
||||
let section = const_cstr!("llvm.metadata");
|
||||
let array = C_array(Type::i8(&cx).ptr_to(), &*cx.used_statics.borrow());
|
||||
|
||||
unsafe {
|
||||
|
|
|
@ -975,7 +975,7 @@ impl Builder<'a, 'll, 'tcx> {
|
|||
parent: Option<&'ll Value>,
|
||||
args: &[&'ll Value]) -> &'ll Value {
|
||||
self.count_insn("cleanuppad");
|
||||
let name = CString::new("cleanuppad").unwrap();
|
||||
let name = const_cstr!("cleanuppad");
|
||||
let ret = unsafe {
|
||||
llvm::LLVMRustBuildCleanupPad(self.llbuilder,
|
||||
parent,
|
||||
|
@ -1001,7 +1001,7 @@ impl Builder<'a, 'll, 'tcx> {
|
|||
parent: &'ll Value,
|
||||
args: &[&'ll Value]) -> &'ll Value {
|
||||
self.count_insn("catchpad");
|
||||
let name = CString::new("catchpad").unwrap();
|
||||
let name = const_cstr!("catchpad");
|
||||
let ret = unsafe {
|
||||
llvm::LLVMRustBuildCatchPad(self.llbuilder, parent,
|
||||
args.len() as c_uint, args.as_ptr(),
|
||||
|
@ -1025,7 +1025,7 @@ impl Builder<'a, 'll, 'tcx> {
|
|||
num_handlers: usize,
|
||||
) -> &'ll Value {
|
||||
self.count_insn("catchswitch");
|
||||
let name = CString::new("catchswitch").unwrap();
|
||||
let name = const_cstr!("catchswitch");
|
||||
let ret = unsafe {
|
||||
llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind,
|
||||
num_handlers as c_uint,
|
||||
|
|
|
@ -328,7 +328,7 @@ pub fn codegen_static<'a, 'tcx>(
|
|||
} else {
|
||||
// If we created the global with the wrong type,
|
||||
// correct the type.
|
||||
let empty_string = CString::new("").unwrap();
|
||||
let empty_string = const_cstr!("");
|
||||
let name_str_ref = CStr::from_ptr(llvm::LLVMGetValueName(g));
|
||||
let name_string = CString::new(name_str_ref.to_bytes()).unwrap();
|
||||
llvm::LLVMSetValueName(g, empty_string.as_ptr());
|
||||
|
|
|
@ -883,7 +883,7 @@ pub fn compile_unit_metadata(tcx: TyCtxt,
|
|||
gcov_cu_info.as_ptr(),
|
||||
gcov_cu_info.len() as c_uint);
|
||||
|
||||
let llvm_gcov_ident = CString::new("llvm.gcov").unwrap();
|
||||
let llvm_gcov_ident = const_cstr!("llvm.gcov");
|
||||
llvm::LLVMAddNamedMetadataOperand(debug_context.llmod,
|
||||
llvm_gcov_ident.as_ptr(),
|
||||
gcov_metadata);
|
||||
|
@ -1780,7 +1780,7 @@ pub fn create_vtable_metadata(
|
|||
// later on in llvm/lib/IR/Value.cpp.
|
||||
let empty_array = create_DIArray(DIB(cx), &[]);
|
||||
|
||||
let name = CString::new("vtable").unwrap();
|
||||
let name = const_cstr!("vtable");
|
||||
|
||||
// Create a new one each time. We don't want metadata caching
|
||||
// here, because each vtable will refer to a unique containing
|
||||
|
|
42
src/librustc_data_structures/const_cstr.rs
Normal file
42
src/librustc_data_structures/const_cstr.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
// 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.
|
||||
|
||||
/// This macro creates a zero-overhead &CStr by adding a NUL terminator to
|
||||
/// the string literal passed into it at compile-time. Use it like:
|
||||
///
|
||||
/// ```
|
||||
/// let some_const_cstr = const_cstr!("abc");
|
||||
/// ```
|
||||
///
|
||||
/// The above is roughly equivalent to:
|
||||
///
|
||||
/// ```
|
||||
/// let some_const_cstr = CStr::from_bytes_with_nul(b"abc\0").unwrap()
|
||||
/// ```
|
||||
///
|
||||
/// Note that macro only checks the string literal for internal NULs if
|
||||
/// debug-assertions are enabled in order to avoid runtime overhead in release
|
||||
/// builds.
|
||||
#[macro_export]
|
||||
macro_rules! const_cstr {
|
||||
($s:expr) => ({
|
||||
use std::ffi::CStr;
|
||||
|
||||
let str_plus_nul = concat!($s, "\0");
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
CStr::from_bytes_with_nul(str_plus_nul.as_bytes()).unwrap()
|
||||
} else {
|
||||
unsafe {
|
||||
CStr::from_bytes_with_nul_unchecked(str_plus_nul.as_bytes())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
|
@ -60,6 +60,7 @@ pub mod array_vec;
|
|||
pub mod base_n;
|
||||
pub mod bitslice;
|
||||
pub mod bitvec;
|
||||
pub mod const_cstr;
|
||||
pub mod flock;
|
||||
pub mod fx;
|
||||
pub mod graph;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue