#![forbid(unsafe_code)]
#![allow(missing_docs)]
use rcc_data_structures::FxHashMap;
use rcc_data_structures::IndexVec;
use rcc_hir::{DefId, Local, ObjectQuals, TyId};
use rcc_span::{Span, Symbol};
pub mod build;
pub mod lower;
pub mod pretty;
pub mod verify;
pub use build::{build_bodies, BodyBuilder, BreakCtx, LoopCtx};
pub use lower::{lower_as_place, lower_as_rvalue, lower_stmt, LocalMap, LowerCx};
rcc_data_structures::new_index! {
pub struct BasicBlockId = u32;
}
#[derive(Debug, Clone, Default)]
pub struct Body {
pub def: Option<DefId>,
pub locals: IndexVec<Local, LocalDecl>,
pub blocks: IndexVec<BasicBlockId, BasicBlock>,
pub labels: FxHashMap<Symbol, BasicBlockId>,
pub ret_ty: Option<TyId>,
}
#[derive(Debug, Clone)]
pub struct LocalDecl {
pub name: Option<rcc_span::Symbol>,
pub ty: TyId,
pub quals: ObjectQuals,
pub align_override: Option<u32>,
pub vla_len: Option<Local>,
pub is_param: bool,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct BasicBlock {
pub statements: Vec<Statement>,
pub terminator: Terminator,
}
impl Default for BasicBlock {
fn default() -> Self {
Self {
statements: Vec::new(),
terminator: Terminator { kind: TerminatorKind::Unreachable, span: rcc_span::DUMMY_SP },
}
}
}
#[derive(Debug, Clone)]
pub struct Statement {
pub kind: StatementKind,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct InlineAsm {
pub template: String,
pub volatile: bool,
pub outputs: Vec<InlineAsmOutput>,
pub inputs: Vec<InlineAsmInput>,
pub clobbers: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct InlineAsmOutput {
pub constraint: String,
pub place: Place,
pub ty: TyId,
pub indirect: bool,
}
#[derive(Debug, Clone)]
pub struct InlineAsmInput {
pub constraint: String,
pub arg: InlineAsmArg,
pub ty: TyId,
}
#[derive(Debug, Clone)]
pub enum InlineAsmArg {
Value(Operand),
Address(Place),
}
#[derive(Debug, Clone)]
pub enum StatementKind {
Assign { place: Place, rvalue: Rvalue },
InlineAsm(InlineAsm),
StorageLive(Local),
StorageDead(Local),
Nop,
}
#[derive(Debug, Clone)]
pub struct Terminator {
pub kind: TerminatorKind,
pub span: Span,
}
#[derive(Debug, Clone)]
pub enum TerminatorKind {
Goto(BasicBlockId),
SwitchInt {
discr: Operand,
targets: Vec<(Option<i128>, BasicBlockId)>,
},
Return,
IndirectGoto {
target: Operand,
targets: Vec<BasicBlockId>,
},
Call {
callee: Operand,
args: Vec<Operand>,
destination: Option<Place>,
target: Option<BasicBlockId>,
},
Unreachable,
BuiltinVaStart {
ap: Operand,
last_param: Operand,
target: BasicBlockId,
},
BuiltinVaEnd {
ap: Operand,
target: BasicBlockId,
},
BuiltinVaCopy {
dst: Operand,
src: Operand,
target: BasicBlockId,
},
}
#[derive(Debug, Clone)]
pub struct Place {
pub base: Local,
pub projection: Vec<Projection>,
}
#[derive(Debug, Clone)]
pub enum Projection {
Global(DefId),
Deref,
Field(u32),
Index(Operand),
}
#[derive(Debug, Clone)]
pub enum Operand {
Copy(Place),
Move(Place),
Const(Const),
}
#[derive(Debug, Clone)]
pub struct Const {
pub kind: ConstKind,
pub ty: TyId,
}
#[derive(Debug, Clone)]
pub enum ConstKind {
Int(i128),
Float(f64),
Global(DefId),
BlockAddress(BasicBlockId),
ZeroInit,
}
#[derive(Debug, Clone)]
pub enum Rvalue {
Use(Operand),
BinaryOp(BinOp, Operand, Operand),
UnaryOp(UnOp, Operand),
Cast {
op: Operand,
to: TyId,
kind: CastKind,
},
ComplexFromReal {
real: Operand,
to: TyId,
},
ComplexFromParts {
real: Operand,
imag: Operand,
to: TyId,
},
RealFromComplex {
complex: Operand,
to: TyId,
},
BitfieldPrecision {
op: Operand,
to: TyId,
width: u32,
signed: bool,
},
VectorInit {
ty: TyId,
lanes: Vec<Operand>,
},
VectorSplat {
ty: TyId,
value: Operand,
},
AddressOf(Place),
LoadGlobal {
def: DefId,
ty: TyId,
},
Len(Place),
BuiltinVaArg {
ap: Operand,
ty: TyId,
},
BuiltinBswap {
value: Operand,
bits: u16,
ty: TyId,
},
CheckedOverflow {
op: BinOp,
lhs: Operand,
rhs: Operand,
dst: Option<Operand>,
ty: TyId,
},
BuiltinVaArea,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum CastKind {
IntToInt,
IntToFloat,
FloatToInt,
FloatToFloat,
PtrToPtr,
PtrToInt,
IntToPtr,
VectorBitcast,
VectorElementCast,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum BinOp {
Add,
Sub,
Mul,
SDiv,
UDiv,
SRem,
URem,
FDiv,
Shl,
AShr,
LShr,
BitAnd,
BitXor,
BitOr,
Eq,
Ne,
SLt,
SLe,
SGt,
SGe,
ULt,
ULe,
UGt,
UGe,
FLt,
FLe,
FGt,
FGe,
FAdd,
FSub,
FMul,
PtrAdd,
PtrSub,
PtrDiff,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum UnOp {
Neg,
FNeg,
BitNot,
LogNot,
}