提交 9585c5dc 编写于 作者: M Michael Woerister

Introduce const_cstr!() macro and use it where applicable.

上级 f6d43ed8
......@@ -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 module_codegen<'a, '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 @@ pub fn cleanup_pad(&self,
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 @@ pub fn catch_pad(&self,
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 @@ pub fn catch_switch(
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
......
// 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 base_n;
pub mod bitslice;
pub mod bitvec;
pub mod const_cstr;
pub mod flock;
pub mod fx;
pub mod graph;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册