use crate::{
nodes::Result,
Buffer,
OutputFlags,
Writer,
};
use std::io::Write as _;
bitflags::bitflags! {
#[derive(Clone, Copy, Default, Eq, PartialEq)]
pub(crate) struct Qualifiers: u8 {
const Q_None = 0;
const Q_Const = 1 << 0;
const Q_Volatile = 1 << 1;
const Q_Far = 1 << 2;
const Q_Huge = 1 << 3;
const Q_Unaligned = 1 << 4;
const Q_Restrict = 1 << 5;
const Q_Pointer64 = 1 << 6;
}
}
impl From<SingleQualifier> for Qualifiers {
fn from(value: SingleQualifier) -> Self {
match value {
SingleQualifier::Const => Self::Q_Const,
SingleQualifier::Volatile => Self::Q_Volatile,
SingleQualifier::Restrict => Self::Q_Restrict,
}
}
}
#[derive(Clone, Copy)]
enum SingleQualifier {
Const,
Volatile,
Restrict,
}
impl SingleQualifier {
fn output_single_qualifier<B: Buffer>(
self,
ob: &mut Writer<B>,
flags: OutputFlags,
) -> Result<()> {
let qualifier = match self {
Self::Const => "const",
Self::Volatile => "volatile",
Self::Restrict => {
if flags.no_ms_keywords() {
return Ok(());
}
if flags.no_leading_underscores() {
"restrict"
} else {
"__restrict"
}
}
};
write!(ob, "{qualifier}")?;
Ok(())
}
}
impl Qualifiers {
#[must_use]
pub(super) fn is_const(self) -> bool {
self.contains(Self::Q_Const)
}
#[must_use]
pub(super) fn is_volatile(self) -> bool {
self.contains(Self::Q_Volatile)
}
#[must_use]
pub(super) fn is_unaligned(self) -> bool {
self.contains(Self::Q_Unaligned)
}
#[must_use]
pub(super) fn is_restrict(self) -> bool {
self.contains(Self::Q_Restrict)
}
pub(super) fn output<B: Buffer>(
self,
ob: &mut Writer<B>,
flags: OutputFlags,
space_before: bool,
space_after: bool,
) -> Result<()> {
if self != Self::Q_None {
let len_before = ob.len_bytes();
let space_before =
self.output_if_present(ob, flags, SingleQualifier::Const, space_before)?;
let space_before =
self.output_if_present(ob, flags, SingleQualifier::Volatile, space_before)?;
self.output_if_present(ob, flags, SingleQualifier::Restrict, space_before)?;
let len_after = ob.len_bytes();
if space_after && len_after > len_before {
write!(ob, " ")?;
}
}
Ok(())
}
fn output_if_present<B: Buffer>(
self,
ob: &mut Writer<B>,
flags: OutputFlags,
mask: SingleQualifier,
needs_space: bool,
) -> Result<bool> {
if !self.contains(mask.into()) {
return Ok(needs_space);
}
if needs_space {
write!(ob, " ")?;
}
mask.output_single_qualifier(ob, flags)?;
Ok(true)
}
}
#[derive(Clone, Copy)]
pub(crate) enum StorageClass {
PrivateStatic,
ProtectedStatic,
PublicStatic,
Global,
FunctionLocalStatic,
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub(crate) enum PointerAffinity {
Pointer,
Reference,
RValueReference,
}
#[derive(Clone, Copy)]
pub(crate) enum FunctionRefQualifier {
Reference,
RValueReference,
}
#[derive(Clone, Copy)]
pub(crate) enum CallingConv {
Cdecl,
Pascal,
Thiscall,
Stdcall,
Fastcall,
Clrcall,
Eabi,
Vectorcall,
Swift, SwiftAsync, }
impl CallingConv {
pub(super) fn output<B: Buffer>(self, ob: &mut Writer<B>, flags: OutputFlags) -> Result<()> {
super::output_space_if_necessary(ob)?;
let cc = if flags.no_leading_underscores() {
match self {
CallingConv::Cdecl => "cdecl",
CallingConv::Fastcall => "fastcall",
CallingConv::Pascal => "pascal",
CallingConv::Stdcall => "stdcall",
CallingConv::Thiscall => "thiscall",
CallingConv::Eabi => "eabi",
CallingConv::Vectorcall => "vectorcall",
CallingConv::Clrcall => "clrcall",
CallingConv::Swift => "__attribute__((__swiftcall__)) ",
CallingConv::SwiftAsync => "__attribute__((__swiftasynccall__)) ",
}
} else {
match self {
CallingConv::Cdecl => "__cdecl",
CallingConv::Fastcall => "__fastcall",
CallingConv::Pascal => "__pascal",
CallingConv::Stdcall => "__stdcall",
CallingConv::Thiscall => "__thiscall",
CallingConv::Eabi => "__eabi",
CallingConv::Vectorcall => "__vectorcall",
CallingConv::Clrcall => "__clrcall",
CallingConv::Swift => "__attribute__((__swiftcall__)) ",
CallingConv::SwiftAsync => "__attribute__((__swiftasynccall__)) ",
}
};
write!(ob, "{cc}")?;
Ok(())
}
}
#[derive(Clone, Copy)]
pub(crate) enum PrimitiveKind {
Void,
Bool,
Char,
Schar,
Uchar,
Char8,
Char16,
Char32,
Short,
Ushort,
Int,
Uint,
Long,
Ulong,
Int64,
Uint64,
Wchar,
Float,
Double,
Ldouble,
Nullptr,
Auto,
DecltypeAuto,
}
#[derive(Clone, Copy)]
pub(crate) enum CharKind {
Char,
Char16,
Char32,
Wchar,
}
#[derive(Clone, Copy)]
pub(crate) enum IntrinsicFunctionKind {
New, Delete, Assign, RightShift, LeftShift, LogicalNot, Equals, NotEquals, ArraySubscript, Pointer, Dereference, Increment, Decrement, Minus, Plus, BitwiseAnd, MemberPointer, Divide, Modulus, LessThan, LessThanEqual, GreaterThan, GreaterThanEqual, Comma, Parens, BitwiseNot, BitwiseXor, BitwiseOr, LogicalAnd, LogicalOr, TimesEqual, PlusEqual, MinusEqual, DivEqual, ModEqual, RshEqual, LshEqual, BitwiseAndEqual, BitwiseOrEqual, BitwiseXorEqual, VbaseDtor, VecDelDtor, DefaultCtorClosure, ScalarDelDtor, VecCtorIter, VecDtorIter, VecVbaseCtorIter, VdispMap, EHVecCtorIter, EHVecDtorIter, EHVecVbaseCtorIter, CopyCtorClosure, LocalVftableCtorClosure, ArrayNew, ArrayDelete, ManVectorCtorIter, ManVectorDtorIter, EHVectorCopyCtorIter, EHVectorVbaseCopyCtorIter, VectorCopyCtorIter, VectorVbaseCopyCtorIter, ManVectorVbaseCopyCtorIter, CoAwait, Spaceship, }
#[derive(Clone, Copy)]
pub(crate) enum SpecialIntrinsicKind {
Vftable,
Vbtable,
Typeof,
VcallThunk,
LocalStaticGuard,
StringLiteralSymbol,
UdtReturning,
DynamicInitializer,
DynamicAtexitDestructor,
RttiTypeDescriptor,
RttiBaseClassDescriptor,
RttiBaseClassArray,
RttiClassHierarchyDescriptor,
RttiCompleteObjLocator,
LocalVftable,
LocalStaticThreadGuard,
}
bitflags::bitflags! {
#[derive(Clone, Copy, Default)]
pub(crate) struct FuncClass: u16 {
const FC_None = 0;
const FC_Public = 1 << 0;
const FC_Protected = 1 << 1;
const FC_Private = 1 << 2;
const FC_Global = 1 << 3;
const FC_Static = 1 << 4;
const FC_Virtual = 1 << 5;
const FC_Far = 1 << 6;
const FC_ExternC = 1 << 7;
const FC_NoParameterList = 1 << 8;
const FC_VirtualThisAdjust = 1 << 9;
const FC_VirtualThisAdjustEx = 1 << 10;
const FC_StaticThisAdjust = 1 << 11;
}
}
impl FuncClass {
#[must_use]
pub(crate) fn is_public(self) -> bool {
self.contains(Self::FC_Public)
}
#[must_use]
pub(crate) fn is_protected(self) -> bool {
self.contains(Self::FC_Protected)
}
#[must_use]
pub(crate) fn is_private(self) -> bool {
self.contains(Self::FC_Private)
}
#[must_use]
pub(crate) fn is_global(self) -> bool {
self.contains(Self::FC_Global)
}
#[must_use]
pub(crate) fn is_static(self) -> bool {
self.contains(Self::FC_Static)
}
#[must_use]
pub(crate) fn is_virtual(self) -> bool {
self.contains(Self::FC_Virtual)
}
#[must_use]
pub(crate) fn is_extern_c(self) -> bool {
self.contains(Self::FC_ExternC)
}
#[must_use]
pub(crate) fn no_parameter_list(self) -> bool {
self.contains(Self::FC_NoParameterList)
}
#[must_use]
pub(crate) fn has_virtual_this_adjust(self) -> bool {
self.contains(Self::FC_VirtualThisAdjust)
}
#[must_use]
pub(crate) fn has_virtual_this_adjust_ex(self) -> bool {
self.contains(Self::FC_VirtualThisAdjustEx)
}
#[must_use]
pub(crate) fn has_static_this_adjust(self) -> bool {
self.contains(Self::FC_StaticThisAdjust)
}
}
#[derive(Clone, Copy)]
pub(crate) enum TagKind {
Class,
Struct,
Union,
Enum,
}