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 {
Float,
Double,
LongDouble,
}
impl FloatKind {
pub const ALL: [FloatKind; 3] = [FloatKind::Float, FloatKind::Double, FloatKind::LongDouble];
pub(crate) const fn index(self) -> usize {
match self {
FloatKind::Float => 0,
FloatKind::Double => 1,
FloatKind::LongDouble => 2,
}
}
#[must_use]
pub const fn rank(self) -> u8 {
match self {
FloatKind::Float => 1,
FloatKind::Double => 2,
FloatKind::LongDouble => 3,
}
}
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
FloatKind::Float => "float",
FloatKind::Double => "double",
FloatKind::LongDouble => "long double",
}
}
}
#[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,
}