use super::block_id::BlockId;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Terminator {
Fallthrough {
target: BlockId,
},
Jump {
target: BlockId,
},
Branch {
then_target: BlockId,
else_target: BlockId,
},
Return,
Throw,
Abort,
TryEntry {
body_target: BlockId,
catch_target: Option<BlockId>,
finally_target: Option<BlockId>,
},
EndTry {
continuation: BlockId,
},
Unknown,
}
impl Terminator {
#[must_use]
pub fn successors(&self) -> Vec<BlockId> {
match self {
Terminator::Fallthrough { target } => vec![*target],
Terminator::Jump { target } => vec![*target],
Terminator::Branch {
then_target,
else_target,
} => vec![*then_target, *else_target],
Terminator::Return | Terminator::Throw | Terminator::Abort => vec![],
Terminator::TryEntry {
body_target,
catch_target,
finally_target,
} => {
let mut succs = vec![*body_target];
if let Some(c) = catch_target {
succs.push(*c);
}
if let Some(f) = finally_target {
succs.push(*f);
}
succs
}
Terminator::EndTry { continuation } => vec![*continuation],
Terminator::Unknown => vec![],
}
}
#[must_use]
pub fn can_fallthrough(&self) -> bool {
matches!(self, Terminator::Fallthrough { .. })
}
#[must_use]
pub fn is_conditional(&self) -> bool {
matches!(self, Terminator::Branch { .. })
}
}