module volt.semantic.cfg

Code Map

module volt.semantic.cfg;


//! A single node in the execution graph.
class Block
{
public:
	//! Where execution could come from.
	parents: Block[];
	children: Block[];
	//! For handling super calls in ctors.
	superCall: bool;
	//! Running this block ends execution of its function (e.g. return).
	terminates: bool;
	//! For handling switches, did this case have a goto or break?
	_goto: bool;
	_break: bool;
	//! For loop bodies; did a break block occur while this was the top of the
	//! breakBlock stack?
	broken: bool;


public:
	this() { }
	this(parent: Block) { }
	this(parents: Block[]) { }
	fn addParent(parent: Block) { }
	fn addChild(child: Block) { }
	fn addParents(parents: Block[]) { }
	fn canReachEntry() bool { }
	fn canReachWithoutBreakGoto() bool { }
	fn canReachWithoutSuper() bool { }
	fn hitsBreakBeforeTarget(target: Block) bool { }
}

//! Builds and checks CFGs on Functions.
class CFGBuilder : ScopeManager, Pass
{
public:
	lp: LanguagePass;
	blocks: BlockStack;
	breakBlocks: BlockStack;
	currentSwitchStatement: ir.SwitchStatement;
	currentSwitchBlocks: Block[];
	currentCaseIndex: i32;
	classStack: ClassStack;


public:
	this(lp: LanguagePass) { }
	fn block(b: Block) Block { }
	//! Returns the last block added.
	fn block() Block { }
	fn transform(m: ir.Module) { }
	fn close() { }
	fn enter(func: ir.Function) Status { }
	fn leave(func: ir.Function) Status { }
	fn enter(rs: ir.ReturnStatement) Status { }
	fn enter(exp: ir.Exp, se: ir.StatementExp) Status { }
	fn enter(es: ir.ExpStatement) Status { }
	fn visit(exp: ir.Exp, eref: ir.ExpReference) Status { }
	//! Generate blocks from an if statement.
	fn enter(ifs: ir.IfStatement) Status { }
	fn enter(fs: ir.ForStatement) Status { }
	fn enter(fes: ir.ForeachStatement) Status { }
	fn enter(ws: ir.WhileStatement) Status { }
	fn enter(ds: ir.DoStatement) Status { }
	fn enter(ls: ir.LabelStatement) Status { }
	fn enter(ss: ir.SwitchStatement) Status { }
	fn visit(cs: ir.ContinueStatement) Status { }
	fn enter(c: ir.Class) Status { }
	fn leave(c: ir.Class) Status { }
	fn enter(gs: ir.GotoStatement) Status { }
	//! Generate blocks from a try statement.
	fn enter(ts: ir.TryStatement) Status { }
	fn enter(ts: ir.ThrowStatement) Status { }
	fn enter(as: ir.AssertStatement) Status { }
	fn visit(bs: ir.BreakStatement) Status { }
	fn leave(ws: ir.WhileStatement) Status { }
	fn leave(ds: ir.DoStatement) Status { }
	fn leave(fs: ir.ForStatement) Status { }
	fn leave(fs: ir.ForeachStatement) Status { }
}

struct BlockStack
{
public:
	enum MaxSize;


public:
	fn length() size_t { }
	fn push(val: T) { }
	fn pop() T { }
	fn peek() T { }
	fn clear() { }
	fn borrowUnsafe() T[] { }
}

//! Returns true if the given block can reach the entry without dgt
//! returning true.
fn canReachWithout(block: Block, dgt: bool delegate(Block)) bool { }
fn canReachChildBefore(block: Block, dgt: bool delegate(Block), target: Block) bool { }
class Block

A single node in the execution graph.

parents: Block[]

Where execution could come from.

superCall: bool

For handling super calls in ctors.

terminates: bool

Running this block ends execution of its function (e.g. return).

_goto: bool

For handling switches, did this case have a goto or break?

broken: bool

For loop bodies; did a break block occur while this was the top of the breakBlock stack?

fn canReachWithout(block: Block, dgt: bool delegate(Block)) bool

Returns true if the given block can reach the entry without dgt returning true.

class CFGBuilder : ScopeManager, Pass

Builds and checks CFGs on Functions.

fn block() Block

Returns the last block added.

fn enter(ifs: ir.IfStatement) Status

Generate blocks from an if statement.

fn enter(ts: ir.TryStatement) Status

Generate blocks from a try statement.

fn constantTrue(e: ir.Exp) bool

Returns true if the given expression evaluates as a constant true.

fn constantFalse(e: ir.Exp) bool

Returns true if the given expression evaluates as a constant false.

fn buildLoop(n: ir.Node, b: ir.BlockStatement, exp: ir.Exp) Status

Convenience function for building blocks for loops.

fn buildDoLoop(n: ir.Node, b: ir.BlockStatement, exp: ir.Exp) Status

Build a do loop. Could be done in enter(DoStatement), but this is neater.

fn ensureNonNullBlock(loc: const(Location))

Sanity check function.