Move doc to trait declarations

This commit is contained in:
Denis Merigoux 2018-09-24 17:35:39 +02:00 committed by Eduard-Mihai Burtescu
parent ac34068ed9
commit 97825a36be
17 changed files with 124 additions and 111 deletions

View File

@ -25,7 +25,6 @@ use libc::{c_uint, c_char};
impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
// Take an inline assembly expression and splat it out via LLVM
fn codegen_inline_asm(
&self,
ia: &hir::InlineAsm,

View File

@ -156,14 +156,14 @@ pub fn bin_op_to_fcmp_predicate(op: hir::BinOpKind) -> RealPredicate {
}
}
pub fn compare_simd_types<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
bx: &Builder,
lhs: Builder::Value,
rhs: Builder::Value,
pub fn compare_simd_types<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
bx: &Bx,
lhs: Bx::Value,
rhs: Bx::Value,
t: Ty<'tcx>,
ret_ty: Builder::Type,
ret_ty: Bx::Type,
op: hir::BinOpKind
) -> Builder::Value {
) -> Bx::Value {
let signed = match t.sty {
ty::Float(_) => {
let cmp = bin_op_to_fcmp_predicate(op);
@ -332,31 +332,31 @@ pub fn coerce_unsized_into<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
}
}
pub fn cast_shift_expr_rhs<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
bx: &Builder,
pub fn cast_shift_expr_rhs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
bx: &Bx,
op: hir::BinOpKind,
lhs: Builder::Value,
rhs: Builder::Value
) -> Builder::Value {
lhs: Bx::Value,
rhs: Bx::Value
) -> Bx::Value {
cast_shift_rhs(bx, op, lhs, rhs, |a, b| bx.trunc(a, b), |a, b| bx.zext(a, b))
}
fn cast_shift_rhs<'a, 'tcx: 'a, F, G, Builder: BuilderMethods<'a, 'tcx>>(
bx: &Builder,
fn cast_shift_rhs<'a, 'tcx: 'a, F, G, Bx: BuilderMethods<'a, 'tcx>>(
bx: &Bx,
op: hir::BinOpKind,
lhs: Builder::Value,
rhs: Builder::Value,
lhs: Bx::Value,
rhs: Bx::Value,
trunc: F,
zext: G
) -> Builder::Value
) -> Bx::Value
where F: FnOnce(
Builder::Value,
Builder::Type
) -> Builder::Value,
Bx::Value,
Bx::Type
) -> Bx::Value,
G: FnOnce(
Builder::Value,
Builder::Type
) -> Builder::Value
Bx::Value,
Bx::Type
) -> Bx::Value
{
// Shifts may have any size int on the rhs
if op.is_shift() {
@ -412,33 +412,33 @@ pub fn from_immediate<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
}
}
pub fn to_immediate<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
bx: &Builder,
val: Builder::Value,
pub fn to_immediate<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
bx: &Bx,
val: Bx::Value,
layout: layout::TyLayout,
) -> Builder::Value {
) -> Bx::Value {
if let layout::Abi::Scalar(ref scalar) = layout.abi {
return to_immediate_scalar(bx, val, scalar);
}
val
}
pub fn to_immediate_scalar<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
bx: &Builder,
val: Builder::Value,
pub fn to_immediate_scalar<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
bx: &Bx,
val: Bx::Value,
scalar: &layout::Scalar,
) -> Builder::Value {
) -> Bx::Value {
if scalar.is_bool() {
return bx.trunc(val, bx.cx().type_i1());
}
val
}
pub fn memcpy_ty<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
bx: &Builder,
dst: Builder::Value,
pub fn memcpy_ty<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
bx: &Bx,
dst: Bx::Value,
dst_align: Align,
src: Builder::Value,
src: Bx::Value,
src_align: Align,
layout: TyLayout<'tcx>,
flags: MemFlags,

View File

@ -1265,7 +1265,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
}
/// Returns the ptr value that should be used for storing `val`.
fn check_store<'b>(&self,
val: &'ll Value,
ptr: &'ll Value) -> &'ll Value {
@ -1285,7 +1284,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
}
/// Returns the args that should be used for a call to `llfn`.
fn check_call<'b>(&self,
typ: &str,
llfn: &'ll Value,
@ -1336,14 +1334,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
self.call_lifetime_intrinsic("llvm.lifetime.end", ptr, size);
}
/// If LLVM lifetime intrinsic support is enabled (i.e. optimizations
/// on), and `ptr` is nonzero-sized, then extracts the size of `ptr`
/// and the intrinsic for `lt` and passes them to `emit`, which is in
/// charge of generating code to call the passed intrinsic on whatever
/// block of generated code is targeted for the intrinsic.
///
/// If LLVM lifetime intrinsic support is disabled (i.e. optimizations
/// off) or `ptr` is zero-sized, then no-op (does not call `emit`).
fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: &'ll Value, size: Size) {
if self.cx.sess().opts.optimize == config::OptLevel::No {
return;

View File

@ -203,9 +203,7 @@ pub fn get_fn(
llfn
}
pub fn resolve_and_get_fn<'tcx,
Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
>(
pub fn resolve_and_get_fn<'tcx, Cx: CodegenMethods<'tcx>>(
cx: &Cx,
def_id: DefId,
substs: &'tcx Substs<'tcx>,

View File

@ -224,7 +224,6 @@ impl BackendTypes for CodegenCx<'ll, 'tcx> {
}
impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
// LLVM constant constructors.
fn const_null(&self, t: &'ll Type) -> &'ll Value {
unsafe {
llvm::LLVMConstNull(t)
@ -286,9 +285,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
self.const_uint(self.type_i8(), i as u64)
}
// This is a 'c-like' raw string, which differs from
// our boxed-and-length-annotated strings.
fn const_cstr(
&self,
s: LocalInternedString,
@ -316,8 +312,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}
// NB: Do not use `do_spill_noroot` to make this into a constant string, or
// you will be kicked off fast isel. See issue #4352 for an example of this.
fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value {
let len = s.len();
let cs = consts::ptrcast(self.const_cstr(s, false),

View File

@ -444,7 +444,6 @@ impl IntrinsicDeclarationMethods<'tcx> for CodegenCx<'b, 'tcx> {
self.declare_intrinsic(key).unwrap_or_else(|| bug!("unknown intrinsic '{}'", key))
}
/// Declare any llvm intrinsics that you might need
fn declare_intrinsic(
&self,
key: &str

View File

@ -285,12 +285,6 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
}
impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
/// Creates the function-specific debug context.
///
/// Returns the FunctionDebugContext for the function which holds state needed
/// for debug info creation. The function may also return another variant of the
/// FunctionDebugContext enum which indicates why no debuginfo should be created
/// for the function.
fn create_function_debug_context(
&self,
instance: Instance<'tcx>,

View File

@ -97,10 +97,6 @@ fn declare_raw_fn(
impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
/// Declare a global value.
///
/// If theres a value with the same name already declared, the function will
/// return its Value instead.
fn declare_global(
&self,
name: &str, ty: &'ll Type
@ -112,13 +108,6 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}
/// Declare a C ABI function.
///
/// Only use this for foreign function ABIs and glue. For Rust functions use
/// `declare_fn` instead.
///
/// If theres a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
fn declare_cfn(
&self,
name: &str,
@ -127,11 +116,6 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
declare_raw_fn(self, name, llvm::CCallConv, fn_type)
}
/// Declare a Rust function.
///
/// If theres a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
fn declare_fn(
&self,
name: &str,
@ -157,13 +141,6 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
llfn
}
/// Declare a global with an intention to define it.
///
/// Use this function when you intend to define a global. This function will
/// return None if the name already has a definition associated with it. In that
/// case an error should be reported to the user, because it usually happens due
/// to users fault (e.g. misuse of #[no_mangle] or #[export_name] attributes).
fn define_global(
&self,
name: &str,
@ -176,20 +153,12 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}
/// Declare a private global
///
/// Use this function when you intend to define a global without a name.
fn define_private_global(&self, ty: &'ll Type) -> &'ll Value {
unsafe {
llvm::LLVMRustInsertPrivateGlobal(self.llmod, ty)
}
}
/// Declare a Rust function with an intention to define it.
///
/// Use this function when you intend to define a function. This function will
/// return panic if the name already has a definition associated with it. This
/// can happen with #[no_mangle] or #[export_name], for example.
fn define_fn(
&self,
name: &str,
@ -202,11 +171,6 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}
/// Declare a Rust function with an intention to define it.
///
/// Use this function when you intend to define a function. This function will
/// return panic if the name already has a definition associated with it. This
/// can happen with #[no_mangle] or #[export_name], for example.
fn define_internal_fn(
&self,
name: &str,
@ -217,16 +181,12 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
llfn
}
/// Get declared value by name.
fn get_declared_value(&self, name: &str) -> Option<&'ll Value> {
debug!("get_declared_value(name={:?})", name);
let namebuf = SmallCStr::new(name);
unsafe { llvm::LLVMRustGetNamedValue(self.llmod, namebuf.as_ptr()) }
}
/// Get defined or externally defined (AvailableExternally linkage) value by
/// name.
fn get_defined_value(&self, name: &str) -> Option<&'ll Value> {
self.get_declared_value(name).and_then(|val|{
let declaration = unsafe {

View File

@ -14,6 +14,7 @@ use mir::place::PlaceRef;
use rustc::hir::{GlobalAsm, InlineAsm};
pub trait AsmBuilderMethods<'tcx>: HasCodegen<'tcx> {
// Take an inline assembly expression and splat it out via LLVM
fn codegen_inline_asm(
&self,
ia: &InlineAsm,

View File

@ -244,7 +244,10 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
fn add_incoming_to_phi(&self, phi: Self::Value, val: Self::Value, bb: Self::BasicBlock);
fn set_invariant_load(&self, load: Self::Value);
/// Returns the ptr value that should be used for storing `val`.
fn check_store(&self, val: Self::Value, ptr: Self::Value) -> Self::Value;
/// Returns the args that should be used for a call to `llfn`.
fn check_call<'b>(
&self,
typ: &str,
@ -256,6 +259,14 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
fn lifetime_start(&self, ptr: Self::Value, size: Size);
fn lifetime_end(&self, ptr: Self::Value, size: Size);
/// If LLVM lifetime intrinsic support is enabled (i.e. optimizations
/// on), and `ptr` is nonzero-sized, then extracts the size of `ptr`
/// and the intrinsic for `lt` and passes them to `emit`, which is in
/// charge of generating code to call the passed intrinsic on whatever
/// block of generated code is targeted for the intrinsic.
///
/// If LLVM lifetime intrinsic support is disabled (i.e. optimizations
/// off) or `ptr` is zero-sized, then no-op (does not call `emit`).
fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: Self::Value, size: Size);
fn call(

View File

@ -17,6 +17,7 @@ use syntax::symbol::LocalInternedString;
pub trait ConstMethods<'tcx>: Backend<'tcx> {
// Constant constructors
fn const_null(&self, t: Self::Type) -> Self::Value;
fn const_undef(&self, t: Self::Type) -> Self::Value;
fn const_int(&self, t: Self::Type, i: i64) -> Self::Value;
@ -28,7 +29,11 @@ pub trait ConstMethods<'tcx>: Backend<'tcx> {
fn const_u64(&self, i: u64) -> Self::Value;
fn const_usize(&self, i: u64) -> Self::Value;
fn const_u8(&self, i: u8) -> Self::Value;
// This is a 'c-like' raw string, which differs from
// our boxed-and-length-annotated strings.
fn const_cstr(&self, s: LocalInternedString, null_terminated: bool) -> Self::Value;
fn const_str_slice(&self, s: LocalInternedString) -> Self::Value;
fn const_fat_ptr(&self, ptr: Self::Value, meta: Self::Value) -> Self::Value;
fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;

View File

@ -21,6 +21,13 @@ use syntax_pos::{SourceFile, Span};
pub trait DebugInfoMethods<'tcx>: Backend<'tcx> {
fn create_vtable_metadata(&self, ty: Ty<'tcx>, vtable: Self::Value);
/// Creates the function-specific debug context.
///
/// Returns the FunctionDebugContext for the function which holds state needed
/// for debug info creation. The function may also return another variant of the
/// FunctionDebugContext enum which indicates why no debuginfo should be created
/// for the function.
fn create_function_debug_context(
&self,
instance: Instance<'tcx>,
@ -28,6 +35,7 @@ pub trait DebugInfoMethods<'tcx>: Backend<'tcx> {
llfn: Self::Value,
mir: &mir::Mir,
) -> FunctionDebugContext<Self::DIScope>;
fn create_mir_scopes(
&self,
mir: &mir::Mir,

View File

@ -15,14 +15,59 @@ use rustc::mir::mono::{Linkage, Visibility};
use rustc::ty;
pub trait DeclareMethods<'tcx>: Backend<'tcx> {
/// Declare a global value.
///
/// If theres a value with the same name already declared, the function will
/// return its Value instead.
fn declare_global(&self, name: &str, ty: Self::Type) -> Self::Value;
/// Declare a C ABI function.
///
/// Only use this for foreign function ABIs and glue. For Rust functions use
/// `declare_fn` instead.
///
/// If theres a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::Value;
/// Declare a Rust function.
///
/// If theres a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
fn declare_fn(&self, name: &str, sig: ty::PolyFnSig<'tcx>) -> Self::Value;
/// Declare a global with an intention to define it.
///
/// Use this function when you intend to define a global. This function will
/// return None if the name already has a definition associated with it. In that
/// case an error should be reported to the user, because it usually happens due
/// to users fault (e.g. misuse of #[no_mangle] or #[export_name] attributes).
fn define_global(&self, name: &str, ty: Self::Type) -> Option<Self::Value>;
/// Declare a private global
///
/// Use this function when you intend to define a global without a name.
fn define_private_global(&self, ty: Self::Type) -> Self::Value;
/// Declare a Rust function with an intention to define it.
///
/// Use this function when you intend to define a function. This function will
/// return panic if the name already has a definition associated with it. This
/// can happen with #[no_mangle] or #[export_name], for example.
fn define_fn(&self, name: &str, fn_sig: ty::PolyFnSig<'tcx>) -> Self::Value;
/// Declare a Rust function with an intention to define it.
///
/// Use this function when you intend to define a function. This function will
/// return panic if the name already has a definition associated with it. This
/// can happen with #[no_mangle] or #[export_name], for example.
fn define_internal_fn(&self, name: &str, fn_sig: ty::PolyFnSig<'tcx>) -> Self::Value;
/// Get declared value by name.
fn get_declared_value(&self, name: &str) -> Option<Self::Value>;
/// Get defined or externally defined (AvailableExternally linkage) value by
/// name.
fn get_defined_value(&self, name: &str) -> Option<Self::Value>;
}

View File

@ -16,6 +16,9 @@ use rustc::ty::Ty;
use syntax_pos::Span;
pub trait IntrinsicCallMethods<'tcx>: HasCodegen<'tcx> {
/// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs,
/// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
/// add them to librustc_codegen_llvm/context.rs
fn codegen_intrinsic_call(
&self,
callee_ty: Ty<'tcx>,
@ -28,5 +31,7 @@ pub trait IntrinsicCallMethods<'tcx>: HasCodegen<'tcx> {
pub trait IntrinsicDeclarationMethods<'tcx>: Backend<'tcx> {
fn get_intrinsic(&self, key: &str) -> Self::Value;
/// Declare any llvm intrinsics that you might need
fn declare_intrinsic(&self, key: &str) -> Option<Self::Value>;
}

View File

@ -29,7 +29,10 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
fn type_i32(&self) -> Self::Type;
fn type_i64(&self) -> Self::Type;
fn type_i128(&self) -> Self::Type;
// Creates an integer type with the given number of bits, e.g. i24
fn type_ix(&self, num_bits: u64) -> Self::Type;
fn type_f32(&self) -> Self::Type;
fn type_f64(&self) -> Self::Type;
fn type_x86_mmx(&self) -> Self::Type;
@ -44,9 +47,14 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
fn set_struct_body(&self, ty: Self::Type, els: &[Self::Type], packed: bool);
fn type_ptr_to(&self, ty: Self::Type) -> Self::Type;
fn element_type(&self, ty: Self::Type) -> Self::Type;
/// Return the number of elements in `self` if it is a LLVM vector type.
fn vector_length(&self, ty: Self::Type) -> usize;
fn func_params_types(&self, ty: Self::Type) -> Vec<Self::Type>;
fn float_width(&self, ty: Self::Type) -> usize;
/// Retrieve the bit width of the integer type `self`.
fn int_width(&self, ty: Self::Type) -> u64;
fn val_ty(&self, v: Self::Value) -> Self::Type;
@ -62,7 +70,13 @@ pub trait DerivedTypeMethods<'tcx>: Backend<'tcx> {
fn type_uint_from_ty(&self, t: ast::UintTy) -> Self::Type;
fn type_float_from_ty(&self, t: ast::FloatTy) -> Self::Type;
fn type_from_integer(&self, i: layout::Integer) -> Self::Type;
/// Return a LLVM type that has at most the required alignment,
/// as a conservative approximation for unknown pointee types.
fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type;
/// Return a LLVM type that has at most the required alignment,
/// and exactly the required size, as a best-effort padding array.
fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type;
fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool;

View File

@ -87,9 +87,6 @@ fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Valu
}
impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
/// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs,
/// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
/// add them to librustc_codegen_llvm/context.rs
fn codegen_intrinsic_call(
&self,
callee_ty: Ty<'tcx>,

View File

@ -100,7 +100,6 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}
// Creates an integer type with the given number of bits, e.g. i24
fn type_ix(&self, num_bits: u64) -> &'ll Type {
unsafe {
llvm::LLVMIntTypeInContext(self.llcx, num_bits as c_uint)
@ -204,7 +203,6 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}
/// Return the number of elements in `self` if it is a LLVM vector type.
fn vector_length(&self, ty: &'ll Type) -> usize {
unsafe {
llvm::LLVMGetVectorSize(ty) as usize
@ -231,7 +229,6 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}
/// Retrieve the bit width of the integer type `self`.
fn int_width(&self, ty: &'ll Type) -> u64 {
unsafe {
llvm::LLVMGetIntTypeWidth(ty) as u64
@ -346,16 +343,12 @@ impl DerivedTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}
/// Return a LLVM type that has at most the required alignment,
/// as a conservative approximation for unknown pointee types.
fn type_pointee_for_abi_align(&self, align: Align) -> &'ll Type {
// FIXME(eddyb) We could find a better approximation if ity.align < align.
let ity = layout::Integer::approximate_abi_align(self, align);
self.type_from_integer(ity)
}
/// Return a LLVM type that has at most the required alignment,
/// and exactly the required size, as a best-effort padding array.
fn type_padding_filler(
&self,
size: Size,