1 pub use crate::llvm
::Type
;
3 use crate::abi
::{FnAbiLlvmExt, LlvmType}
;
5 use crate::context
::CodegenCx
;
7 use crate::llvm
::{Bool, False, True}
;
8 use crate::type_of
::LayoutLlvmExt
;
9 use crate::value
::Value
;
10 use rustc_codegen_ssa
::common
::TypeKind
;
11 use rustc_codegen_ssa
::traits
::*;
12 use rustc_data_structures
::small_c_str
::SmallCStr
;
13 use rustc_middle
::bug
;
14 use rustc_middle
::ty
::layout
::TyAndLayout
;
15 use rustc_middle
::ty
::{self, Ty}
;
16 use rustc_target
::abi
::call
::{CastTarget, FnAbi, Reg}
;
17 use rustc_target
::abi
::{AddressSpace, Align, Integer, Size}
;
24 impl PartialEq
for Type
{
25 fn eq(&self, other
: &Self) -> bool
{
30 impl fmt
::Debug
for Type
{
31 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
33 &llvm
::build_string(|s
| unsafe {
34 llvm
::LLVMRustWriteTypeToString(self, s
);
36 .expect("non-UTF8 type description from LLVM"),
41 impl<'ll
> CodegenCx
<'ll
, '_
> {
42 pub(crate) fn type_named_struct(&self, name
: &str) -> &'ll Type
{
43 let name
= SmallCStr
::new(name
);
44 unsafe { llvm::LLVMStructCreateNamed(self.llcx, name.as_ptr()) }
47 pub(crate) fn set_struct_body(&self, ty
: &'ll Type
, els
: &[&'ll Type
], packed
: bool
) {
48 unsafe { llvm::LLVMStructSetBody(ty, els.as_ptr(), els.len() as c_uint, packed as Bool) }
51 pub(crate) fn type_void(&self) -> &'ll Type
{
52 unsafe { llvm::LLVMVoidTypeInContext(self.llcx) }
55 pub(crate) fn type_metadata(&self) -> &'ll Type
{
56 unsafe { llvm::LLVMRustMetadataTypeInContext(self.llcx) }
59 ///x Creates an integer type with the given number of bits, e.g., i24
60 pub(crate) fn type_ix(&self, num_bits
: u64) -> &'ll Type
{
61 unsafe { llvm::LLVMIntTypeInContext(self.llcx, num_bits as c_uint) }
64 pub(crate) fn type_vector(&self, ty
: &'ll Type
, len
: u64) -> &'ll Type
{
65 unsafe { llvm::LLVMVectorType(ty, len as c_uint) }
68 pub(crate) fn func_params_types(&self, ty
: &'ll Type
) -> Vec
<&'ll Type
> {
70 let n_args
= llvm
::LLVMCountParamTypes(ty
) as usize;
71 let mut args
= Vec
::with_capacity(n_args
);
72 llvm
::LLVMGetParamTypes(ty
, args
.as_mut_ptr());
78 pub(crate) fn type_bool(&self) -> &'ll Type
{
82 pub(crate) fn type_int_from_ty(&self, t
: ty
::IntTy
) -> &'ll Type
{
84 ty
::IntTy
::Isize
=> self.type_isize(),
85 ty
::IntTy
::I8
=> self.type_i8(),
86 ty
::IntTy
::I16
=> self.type_i16(),
87 ty
::IntTy
::I32
=> self.type_i32(),
88 ty
::IntTy
::I64
=> self.type_i64(),
89 ty
::IntTy
::I128
=> self.type_i128(),
93 pub(crate) fn type_uint_from_ty(&self, t
: ty
::UintTy
) -> &'ll Type
{
95 ty
::UintTy
::Usize
=> self.type_isize(),
96 ty
::UintTy
::U8
=> self.type_i8(),
97 ty
::UintTy
::U16
=> self.type_i16(),
98 ty
::UintTy
::U32
=> self.type_i32(),
99 ty
::UintTy
::U64
=> self.type_i64(),
100 ty
::UintTy
::U128
=> self.type_i128(),
104 pub(crate) fn type_float_from_ty(&self, t
: ty
::FloatTy
) -> &'ll Type
{
106 ty
::FloatTy
::F32
=> self.type_f32(),
107 ty
::FloatTy
::F64
=> self.type_f64(),
111 pub(crate) fn type_pointee_for_align(&self, align
: Align
) -> &'ll Type
{
112 // FIXME(eddyb) We could find a better approximation if ity.align < align.
113 let ity
= Integer
::approximate_align(self, align
);
114 self.type_from_integer(ity
)
117 /// Return a LLVM type that has at most the required alignment,
118 /// and exactly the required size, as a best-effort padding array.
119 pub(crate) fn type_padding_filler(&self, size
: Size
, align
: Align
) -> &'ll Type
{
120 let unit
= Integer
::approximate_align(self, align
);
121 let size
= size
.bytes();
122 let unit_size
= unit
.size().bytes();
123 assert_eq
!(size
% unit_size
, 0);
124 self.type_array(self.type_from_integer(unit
), size
/ unit_size
)
127 pub(crate) fn type_variadic_func(&self, args
: &[&'ll Type
], ret
: &'ll Type
) -> &'ll Type
{
128 unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) }
131 pub(crate) fn type_array(&self, ty
: &'ll Type
, len
: u64) -> &'ll Type
{
132 unsafe { llvm::LLVMRustArrayType(ty, len) }
136 impl<'ll
, 'tcx
> BaseTypeMethods
<'tcx
> for CodegenCx
<'ll
, 'tcx
> {
137 fn type_i1(&self) -> &'ll Type
{
138 unsafe { llvm::LLVMInt1TypeInContext(self.llcx) }
141 fn type_i8(&self) -> &'ll Type
{
142 unsafe { llvm::LLVMInt8TypeInContext(self.llcx) }
145 fn type_i16(&self) -> &'ll Type
{
146 unsafe { llvm::LLVMInt16TypeInContext(self.llcx) }
149 fn type_i32(&self) -> &'ll Type
{
150 unsafe { llvm::LLVMInt32TypeInContext(self.llcx) }
153 fn type_i64(&self) -> &'ll Type
{
154 unsafe { llvm::LLVMInt64TypeInContext(self.llcx) }
157 fn type_i128(&self) -> &'ll Type
{
158 unsafe { llvm::LLVMIntTypeInContext(self.llcx, 128) }
161 fn type_isize(&self) -> &'ll Type
{
165 fn type_f32(&self) -> &'ll Type
{
166 unsafe { llvm::LLVMFloatTypeInContext(self.llcx) }
169 fn type_f64(&self) -> &'ll Type
{
170 unsafe { llvm::LLVMDoubleTypeInContext(self.llcx) }
173 fn type_func(&self, args
: &[&'ll Type
], ret
: &'ll Type
) -> &'ll Type
{
174 unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, False) }
177 fn type_struct(&self, els
: &[&'ll Type
], packed
: bool
) -> &'ll Type
{
179 llvm
::LLVMStructTypeInContext(
188 fn type_kind(&self, ty
: &'ll Type
) -> TypeKind
{
189 unsafe { llvm::LLVMRustGetTypeKind(ty).to_generic() }
192 fn type_ptr_to(&self, ty
: &'ll Type
) -> &'ll Type
{
196 "don't call ptr_to on function types, use ptr_to_llvm_type on FnAbi instead or explicitly specify an address space if it makes sense"
198 ty
.ptr_to(AddressSpace
::DATA
)
201 fn type_ptr_to_ext(&self, ty
: &'ll Type
, address_space
: AddressSpace
) -> &'ll Type
{
202 ty
.ptr_to(address_space
)
205 fn element_type(&self, ty
: &'ll Type
) -> &'ll Type
{
206 match self.type_kind(ty
) {
207 TypeKind
::Array
| TypeKind
::Vector
=> unsafe { llvm::LLVMGetElementType(ty) }
,
208 TypeKind
::Pointer
=> bug
!("element_type is not supported for opaque pointers"),
209 other
=> bug
!("element_type called on unsupported type {:?}", other
),
213 fn vector_length(&self, ty
: &'ll Type
) -> usize {
214 unsafe { llvm::LLVMGetVectorSize(ty) as usize }
217 fn float_width(&self, ty
: &'ll Type
) -> usize {
218 match self.type_kind(ty
) {
219 TypeKind
::Float
=> 32,
220 TypeKind
::Double
=> 64,
221 TypeKind
::X86_FP80
=> 80,
222 TypeKind
::FP128
| TypeKind
::PPC_FP128
=> 128,
223 _
=> bug
!("llvm_float_width called on a non-float type"),
227 fn int_width(&self, ty
: &'ll Type
) -> u64 {
228 unsafe { llvm::LLVMGetIntTypeWidth(ty) as u64 }
231 fn val_ty(&self, v
: &'ll Value
) -> &'ll Type
{
237 pub fn i8_llcx(llcx
: &llvm
::Context
) -> &Type
{
238 unsafe { llvm::LLVMInt8TypeInContext(llcx) }
241 // Creates an integer type with the given number of bits, e.g., i24
242 pub fn ix_llcx(llcx
: &llvm
::Context
, num_bits
: u64) -> &Type
{
243 unsafe { llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint) }
246 pub fn i8p_llcx(llcx
: &llvm
::Context
) -> &Type
{
247 Type
::i8_llcx(llcx
).ptr_to(AddressSpace
::DATA
)
250 fn ptr_to(&self, address_space
: AddressSpace
) -> &Type
{
251 unsafe { llvm::LLVMPointerType(self, address_space.0) }
255 impl<'ll
, 'tcx
> LayoutTypeMethods
<'tcx
> for CodegenCx
<'ll
, 'tcx
> {
256 fn backend_type(&self, layout
: TyAndLayout
<'tcx
>) -> &'ll Type
{
257 layout
.llvm_type(self)
259 fn immediate_backend_type(&self, layout
: TyAndLayout
<'tcx
>) -> &'ll Type
{
260 layout
.immediate_llvm_type(self)
262 fn is_backend_immediate(&self, layout
: TyAndLayout
<'tcx
>) -> bool
{
263 layout
.is_llvm_immediate()
265 fn is_backend_scalar_pair(&self, layout
: TyAndLayout
<'tcx
>) -> bool
{
266 layout
.is_llvm_scalar_pair()
268 fn backend_field_index(&self, layout
: TyAndLayout
<'tcx
>, index
: usize) -> u64 {
269 layout
.llvm_field_index(self, index
)
271 fn scalar_pair_element_backend_type(
273 layout
: TyAndLayout
<'tcx
>,
277 layout
.scalar_pair_element_llvm_type(self, index
, immediate
)
279 fn cast_backend_type(&self, ty
: &CastTarget
) -> &'ll Type
{
282 fn fn_decl_backend_type(&self, fn_abi
: &FnAbi
<'tcx
, Ty
<'tcx
>>) -> &'ll Type
{
283 fn_abi
.llvm_type(self)
285 fn fn_ptr_backend_type(&self, fn_abi
: &FnAbi
<'tcx
, Ty
<'tcx
>>) -> &'ll Type
{
286 fn_abi
.ptr_to_llvm_type(self)
288 fn reg_backend_type(&self, ty
: &Reg
) -> &'ll Type
{