Generate better function argument names in global_allocator expansion
This commit is contained in:
parent
bc720ad36b
commit
704aa56ba0
5 changed files with 37 additions and 30 deletions
|
@ -33,29 +33,41 @@ pub enum AllocatorTy {
|
||||||
|
|
||||||
pub struct AllocatorMethod {
|
pub struct AllocatorMethod {
|
||||||
pub name: Symbol,
|
pub name: Symbol,
|
||||||
pub inputs: &'static [AllocatorTy],
|
pub inputs: &'static [AllocatorMethodInput],
|
||||||
pub output: AllocatorTy,
|
pub output: AllocatorTy,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct AllocatorMethodInput {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub ty: AllocatorTy,
|
||||||
|
}
|
||||||
|
|
||||||
pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[
|
pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[
|
||||||
AllocatorMethod {
|
AllocatorMethod {
|
||||||
name: sym::alloc,
|
name: sym::alloc,
|
||||||
inputs: &[AllocatorTy::Layout],
|
inputs: &[AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout }],
|
||||||
output: AllocatorTy::ResultPtr,
|
output: AllocatorTy::ResultPtr,
|
||||||
},
|
},
|
||||||
AllocatorMethod {
|
AllocatorMethod {
|
||||||
name: sym::dealloc,
|
name: sym::dealloc,
|
||||||
inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout],
|
inputs: &[
|
||||||
|
AllocatorMethodInput { name: "ptr", ty: AllocatorTy::Ptr },
|
||||||
|
AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout },
|
||||||
|
],
|
||||||
output: AllocatorTy::Unit,
|
output: AllocatorTy::Unit,
|
||||||
},
|
},
|
||||||
AllocatorMethod {
|
AllocatorMethod {
|
||||||
name: sym::realloc,
|
name: sym::realloc,
|
||||||
inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout, AllocatorTy::Usize],
|
inputs: &[
|
||||||
|
AllocatorMethodInput { name: "ptr", ty: AllocatorTy::Ptr },
|
||||||
|
AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout },
|
||||||
|
AllocatorMethodInput { name: "new_size", ty: AllocatorTy::Usize },
|
||||||
|
],
|
||||||
output: AllocatorTy::ResultPtr,
|
output: AllocatorTy::ResultPtr,
|
||||||
},
|
},
|
||||||
AllocatorMethod {
|
AllocatorMethod {
|
||||||
name: sym::alloc_zeroed,
|
name: sym::alloc_zeroed,
|
||||||
inputs: &[AllocatorTy::Layout],
|
inputs: &[AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout }],
|
||||||
output: AllocatorTy::ResultPtr,
|
output: AllocatorTy::ResultPtr,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::util::check_builtin_macro_attribute;
|
||||||
|
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
use rustc_ast::expand::allocator::{
|
use rustc_ast::expand::allocator::{
|
||||||
global_fn_name, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS,
|
global_fn_name, AllocatorMethod, AllocatorMethodInput, AllocatorTy, ALLOCATOR_METHODS,
|
||||||
};
|
};
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::{self as ast, AttrVec, Expr, FnHeader, FnSig, Generics, Param, StmtKind};
|
use rustc_ast::{self as ast, AttrVec, Expr, FnHeader, FnSig, Generics, Param, StmtKind};
|
||||||
|
@ -70,13 +70,7 @@ struct AllocFnFactory<'a, 'b> {
|
||||||
impl AllocFnFactory<'_, '_> {
|
impl AllocFnFactory<'_, '_> {
|
||||||
fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt {
|
fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt {
|
||||||
let mut abi_args = ThinVec::new();
|
let mut abi_args = ThinVec::new();
|
||||||
let mut i = 0;
|
let args = method.inputs.iter().map(|input| self.arg_ty(input, &mut abi_args)).collect();
|
||||||
let mut mk = || {
|
|
||||||
let name = Ident::from_str_and_span(&format!("arg{i}"), self.span);
|
|
||||||
i += 1;
|
|
||||||
name
|
|
||||||
};
|
|
||||||
let args = method.inputs.iter().map(|ty| self.arg_ty(ty, &mut abi_args, &mut mk)).collect();
|
|
||||||
let result = self.call_allocator(method.name, args);
|
let result = self.call_allocator(method.name, args);
|
||||||
let output_ty = self.ret_ty(&method.output);
|
let output_ty = self.ret_ty(&method.output);
|
||||||
let decl = self.cx.fn_decl(abi_args, ast::FnRetTy::Ty(output_ty));
|
let decl = self.cx.fn_decl(abi_args, ast::FnRetTy::Ty(output_ty));
|
||||||
|
@ -113,18 +107,19 @@ impl AllocFnFactory<'_, '_> {
|
||||||
thin_vec![self.cx.attr_word(sym::rustc_std_internal_symbol, self.span)]
|
thin_vec![self.cx.attr_word(sym::rustc_std_internal_symbol, self.span)]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arg_ty(
|
fn arg_ty(&self, input: &AllocatorMethodInput, args: &mut ThinVec<Param>) -> P<Expr> {
|
||||||
&self,
|
match input.ty {
|
||||||
ty: &AllocatorTy,
|
|
||||||
args: &mut ThinVec<Param>,
|
|
||||||
ident: &mut dyn FnMut() -> Ident,
|
|
||||||
) -> P<Expr> {
|
|
||||||
match *ty {
|
|
||||||
AllocatorTy::Layout => {
|
AllocatorTy::Layout => {
|
||||||
|
// If an allocator method is ever introduced having multiple
|
||||||
|
// Layout arguments, these argument names need to be
|
||||||
|
// disambiguated somehow. Currently the generated code would
|
||||||
|
// fail to compile with "identifier is bound more than once in
|
||||||
|
// this parameter list".
|
||||||
|
let size = Ident::from_str_and_span("size", self.span);
|
||||||
|
let align = Ident::from_str_and_span("align", self.span);
|
||||||
|
|
||||||
let usize = self.cx.path_ident(self.span, Ident::new(sym::usize, self.span));
|
let usize = self.cx.path_ident(self.span, Ident::new(sym::usize, self.span));
|
||||||
let ty_usize = self.cx.ty_path(usize);
|
let ty_usize = self.cx.ty_path(usize);
|
||||||
let size = ident();
|
|
||||||
let align = ident();
|
|
||||||
args.push(self.cx.param(self.span, size, ty_usize.clone()));
|
args.push(self.cx.param(self.span, size, ty_usize.clone()));
|
||||||
args.push(self.cx.param(self.span, align, ty_usize));
|
args.push(self.cx.param(self.span, align, ty_usize));
|
||||||
|
|
||||||
|
@ -138,13 +133,13 @@ impl AllocFnFactory<'_, '_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocatorTy::Ptr => {
|
AllocatorTy::Ptr => {
|
||||||
let ident = ident();
|
let ident = Ident::from_str_and_span(input.name, self.span);
|
||||||
args.push(self.cx.param(self.span, ident, self.ptr_u8()));
|
args.push(self.cx.param(self.span, ident, self.ptr_u8()));
|
||||||
self.cx.expr_ident(self.span, ident)
|
self.cx.expr_ident(self.span, ident)
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocatorTy::Usize => {
|
AllocatorTy::Usize => {
|
||||||
let ident = ident();
|
let ident = Ident::from_str_and_span(input.name, self.span);
|
||||||
args.push(self.cx.param(self.span, ident, self.usize()));
|
args.push(self.cx.param(self.span, ident, self.usize()));
|
||||||
self.cx.expr_ident(self.span, ident)
|
self.cx.expr_ident(self.span, ident)
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,8 @@ fn codegen_inner(
|
||||||
if kind == AllocatorKind::Default {
|
if kind == AllocatorKind::Default {
|
||||||
for method in ALLOCATOR_METHODS {
|
for method in ALLOCATOR_METHODS {
|
||||||
let mut arg_tys = Vec::with_capacity(method.inputs.len());
|
let mut arg_tys = Vec::with_capacity(method.inputs.len());
|
||||||
for ty in method.inputs.iter() {
|
for input in method.inputs.iter() {
|
||||||
match *ty {
|
match input.ty {
|
||||||
AllocatorTy::Layout => {
|
AllocatorTy::Layout => {
|
||||||
arg_tys.push(usize_ty); // size
|
arg_tys.push(usize_ty); // size
|
||||||
arg_tys.push(usize_ty); // align
|
arg_tys.push(usize_ty); // align
|
||||||
|
|
|
@ -27,8 +27,8 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam
|
||||||
if kind == AllocatorKind::Default {
|
if kind == AllocatorKind::Default {
|
||||||
for method in ALLOCATOR_METHODS {
|
for method in ALLOCATOR_METHODS {
|
||||||
let mut types = Vec::with_capacity(method.inputs.len());
|
let mut types = Vec::with_capacity(method.inputs.len());
|
||||||
for ty in method.inputs.iter() {
|
for input in method.inputs.iter() {
|
||||||
match *ty {
|
match input.ty {
|
||||||
AllocatorTy::Layout => {
|
AllocatorTy::Layout => {
|
||||||
types.push(usize);
|
types.push(usize);
|
||||||
types.push(usize);
|
types.push(usize);
|
||||||
|
|
|
@ -34,8 +34,8 @@ pub(crate) unsafe fn codegen(
|
||||||
if kind == AllocatorKind::Default {
|
if kind == AllocatorKind::Default {
|
||||||
for method in ALLOCATOR_METHODS {
|
for method in ALLOCATOR_METHODS {
|
||||||
let mut args = Vec::with_capacity(method.inputs.len());
|
let mut args = Vec::with_capacity(method.inputs.len());
|
||||||
for ty in method.inputs.iter() {
|
for input in method.inputs.iter() {
|
||||||
match *ty {
|
match input.ty {
|
||||||
AllocatorTy::Layout => {
|
AllocatorTy::Layout => {
|
||||||
args.push(usize); // size
|
args.push(usize); // size
|
||||||
args.push(usize); // align
|
args.push(usize); // align
|
||||||
|
|
Loading…
Add table
Reference in a new issue