use rucc_base::Symbol;
use crate::TypeId;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash, PartialOrd, Ord)]
pub struct Qualifiers(u8);
impl Qualifiers {
pub const NONE: Qualifiers = Qualifiers(0);
pub const CONST: Qualifiers = Qualifiers(1);
pub const VOLATILE: Qualifiers = Qualifiers(2);
pub const RESTRICT: Qualifiers = Qualifiers(4);
#[inline]
#[must_use]
pub const fn has(self, other: Qualifiers) -> bool {
self.0 & other.0 == other.0
}
#[inline]
#[must_use]
pub const fn with(self, other: Qualifiers) -> Qualifiers {
Qualifiers(self.0 | other.0)
}
#[inline]
#[must_use]
pub const fn without(self, other: Qualifiers) -> Qualifiers {
Qualifiers(self.0 & !other.0)
}
#[inline]
#[must_use]
pub const fn is_none(self) -> bool {
self.0 == 0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum IntKind {
Char,
SChar,
UChar,
Short,
UShort,
Int,
UInt,
Long,
ULong,
LongLong,
ULongLong,
Int128,
UInt128,
}
impl IntKind {
pub const ALL: [IntKind; 13] = [
IntKind::Char,
IntKind::SChar,
IntKind::UChar,
IntKind::Short,
IntKind::UShort,
IntKind::Int,
IntKind::UInt,
IntKind::Long,
IntKind::ULong,
IntKind::LongLong,
IntKind::ULongLong,
IntKind::Int128,
IntKind::UInt128,
];
pub(crate) const fn index(self) -> usize {
match self {
IntKind::Char => 0,
IntKind::SChar => 1,
IntKind::UChar => 2,
IntKind::Short => 3,
IntKind::UShort => 4,
IntKind::Int => 5,
IntKind::UInt => 6,
IntKind::Long => 7,
IntKind::ULong => 8,
IntKind::LongLong => 9,
IntKind::ULongLong => 10,
IntKind::Int128 => 11,
IntKind::UInt128 => 12,
}
}
#[must_use]
pub const fn is_signed(self, char_is_signed: bool) -> bool {
match self {
IntKind::Char => char_is_signed,
IntKind::SChar
| IntKind::Short
| IntKind::Int
| IntKind::Long
| IntKind::LongLong
| IntKind::Int128 => true,
IntKind::UChar
| IntKind::UShort
| IntKind::UInt
| IntKind::ULong
| IntKind::ULongLong
| IntKind::UInt128 => false,
}
}
#[must_use]
pub const fn rank(self) -> u8 {
match self {
IntKind::Char | IntKind::SChar | IntKind::UChar => 1,
IntKind::Short | IntKind::UShort => 2,
IntKind::Int | IntKind::UInt => 3,
IntKind::Long | IntKind::ULong => 4,
IntKind::LongLong | IntKind::ULongLong => 5,
IntKind::Int128 | IntKind::UInt128 => 6,
}
}
#[must_use]
pub const fn flip_sign(self) -> IntKind {
match self {
IntKind::Char | IntKind::SChar => IntKind::UChar,
IntKind::UChar => IntKind::SChar,
IntKind::Short => IntKind::UShort,
IntKind::UShort => IntKind::Short,
IntKind::Int => IntKind::UInt,
IntKind::UInt => IntKind::Int,
IntKind::Long => IntKind::ULong,
IntKind::ULong => IntKind::Long,
IntKind::LongLong => IntKind::ULongLong,
IntKind::ULongLong => IntKind::LongLong,
IntKind::Int128 => IntKind::UInt128,
IntKind::UInt128 => IntKind::Int128,
}
}
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
IntKind::Char => "char",
IntKind::SChar => "signed char",
IntKind::UChar => "unsigned char",
IntKind::Short => "short",
IntKind::UShort => "unsigned short",
IntKind::Int => "int",
IntKind::UInt => "unsigned int",
IntKind::Long => "long",
IntKind::ULong => "unsigned long",
IntKind::LongLong => "long long",
IntKind::ULongLong => "unsigned long long",
IntKind::Int128 => "__int128",
IntKind::UInt128 => "unsigned __int128",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum FloatKind {
Float16,
Float,
Float32,
Double,
Float32x,
Float64,
LongDouble,
Float64x,
Float128,
}
impl FloatKind {
pub const ALL: [FloatKind; 9] = [
FloatKind::Float16,
FloatKind::Float,
FloatKind::Float32,
FloatKind::Double,
FloatKind::Float32x,
FloatKind::Float64,
FloatKind::LongDouble,
FloatKind::Float64x,
FloatKind::Float128,
];
pub(crate) const fn index(self) -> usize {
match self {
FloatKind::Float16 => 0,
FloatKind::Float => 1,
FloatKind::Float32 => 2,
FloatKind::Double => 3,
FloatKind::Float32x => 4,
FloatKind::Float64 => 5,
FloatKind::LongDouble => 6,
FloatKind::Float64x => 7,
FloatKind::Float128 => 8,
}
}
#[must_use]
pub const fn tie_break(self) -> u8 {
match self {
FloatKind::Float32x => 0,
FloatKind::Float64x => 1,
FloatKind::Float => 4,
FloatKind::Double => 5,
FloatKind::LongDouble => 6,
FloatKind::Float16 => 8,
FloatKind::Float32 => 9,
FloatKind::Float64 => 10,
FloatKind::Float128 => 11,
}
}
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
FloatKind::Float16 => "_Float16",
FloatKind::Float => "float",
FloatKind::Float32 => "_Float32",
FloatKind::Double => "double",
FloatKind::Float32x => "_Float32x",
FloatKind::Float64 => "_Float64",
FloatKind::LongDouble => "long double",
FloatKind::Float64x => "_Float64x",
FloatKind::Float128 => "_Float128",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum ArrayLen {
Fixed(u64),
Unknown,
Star,
Variable(VlaId),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct VlaId(pub u32);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum RecordKind {
Struct,
Union,
}
impl RecordKind {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
RecordKind::Struct => "struct",
RecordKind::Union => "union",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TypeKind {
Void,
Bool,
Int(IntKind),
Float(FloatKind),
Complex(FloatKind),
BitInt {
signed: bool,
width: u32,
},
Pointer(TypeId),
Atomic(TypeId),
Array {
elem: TypeId,
len: ArrayLen,
},
Function(FunctionId),
Vector {
elem: TypeId,
len: u32,
},
Record(RecordId),
Enum(EnumId),
Typedef {
name: Symbol,
underlying: TypeId,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Type {
pub kind: TypeKind,
pub quals: Qualifiers,
}
impl Type {
#[must_use]
pub const fn new(kind: TypeKind) -> Type {
Type { kind, quals: Qualifiers::NONE }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct FunctionId(pub(crate) u32);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct RecordId(pub(crate) u32);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct EnumId(pub(crate) u32);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FunctionType {
pub ret: TypeId,
pub params: Vec<TypeId>,
pub variadic: bool,
pub prototyped: bool,
}