class CfgCreator extends AnyRef
Translation of abstract syntax trees into control flow graphs
The problem of translating an abstract syntax tree into a corresponding control flow graph can be formulated as a recursive problem in which sub trees of the syntax tree are translated and their corresponding control flow graphs are connected according to the control flow semantics of the root node. For example, consider the abstract syntax tree for an if-statement:
( if ) / \ (x < 10) (x += 1) / \ / \ x 10 x 1
This tree can be translated into a control flow graph, by translating the sub tree rooted in x < 10 and that of
x+= 1 and connecting their control flow graphs according to the semantics of if:
[x < 10]---- |t f| [x +=1 ] | |
The semantics of if dictate that the first sub tree to the left is a condition, which is connected to the CFG of the
second sub tree - the body of the if statement - via a control flow edge with the true label (indicated in the
illustration by t), and to the CFG of any follow-up code via a false edge (indicated by f).
A problem that becomes immediately apparent in the illustration is that the result of translating a sub tree may leave us with edges for which a source node is known but the destination node depends on parents or siblings that were not considered in the translation. For example, we know that an outgoing edge from [x<10] must exist, but we do not yet know where it should lead. We refer to the set of nodes of the control flow graph with outgoing edges for which the destination node is yet to be determined as the "fringe" of the control flow graph.
- Alphabetic
- By Inheritance
- CfgCreator
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Instance Constructors
- new CfgCreator(entryNode: Method, diffGraph: DiffGraphBuilder)
Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##: Int
- Definition Classes
- AnyRef → Any
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- def cfgFor(node: AstNode): Cfg
This method dispatches AST nodes by type and calls corresponding conversion methods.
This method dispatches AST nodes by type and calls corresponding conversion methods.
- Attributes
- protected
- def cfgForAndExpression(call: Call): Cfg
The right hand side of a logical AND expression is only evaluated if the left hand side is true as the entire expression can only be true if both expressions are true.
The right hand side of a logical AND expression is only evaluated if the left hand side is true as the entire expression can only be true if both expressions are true. This is encoded in the corresponding control flow graph by creating control flow graphs for the left and right hand expressions and appending the two, where the fringe edge type of the left CFG is
TrueEdge.- Attributes
- protected
- def cfgForBreakStatement(node: ControlStructure): Cfg
The CFG for a break/continue statements contains only the break/continue statement as a single entry node.
The CFG for a break/continue statements contains only the break/continue statement as a single entry node. The fringe is empty, that is, appending another CFG to the break statement will not result in the creation of an edge from the break statement to the entry point of the other CFG. Labeled breaks are treated like gotos and are added to "jumpsToLabel".
- Attributes
- protected
- def cfgForConditionalExpression(call: Call): Cfg
A conditional expression is of the form
condition ? trueExpr ; falseExprwhere bothtrueExprandfalseExprare optional.A conditional expression is of the form
condition ? trueExpr ; falseExprwhere bothtrueExprandfalseExprare optional. We create the corresponding CFGs by creating CFGs for the three expressions and adding edges between them. The new entry node is the condition entry node.- Attributes
- protected
- def cfgForContinueStatement(node: ControlStructure): Cfg
- Attributes
- protected
- def cfgForControlStructure(node: ControlStructure): Cfg
A second layer of dispatching for control structures.
A second layer of dispatching for control structures. This could as well be part of
cfgForand has only been placed into a separate function to increase readability.- Attributes
- protected
- def cfgForDoStatement(node: ControlStructure): Cfg
A Do-Statement is of the form
do body while(condition)where body may be empty.A Do-Statement is of the form
do body while(condition)where body may be empty. We again first calculate the inner CFG as bodyCfg ++ conditionCfg and then connect edges according to the semantics of do-while.- Attributes
- protected
- def cfgForForStatement(node: ControlStructure): Cfg
A for statement is of the form
for(initExpr; condition; loopExpr) bodyand all four components may be empty.A for statement is of the form
for(initExpr; condition; loopExpr) bodyand all four components may be empty. The sequence (condition - body - loopExpr) form the inner part of the loop and we calculate the corresponding CFGinnerCfgso that it is no longer relevant which of these three actually exist and we still have an entry node for the loop and a fringe.- Attributes
- protected
- def cfgForGotoStatement(node: ControlStructure): Cfg
A CFG for a goto statement is one containing the goto node as an entry node and an empty fringe.
A CFG for a goto statement is one containing the goto node as an entry node and an empty fringe. Moreover, we store the goto for dispatching with
withResolvedJumpToLabelonce the CFG for the entire method has been calculated.- Attributes
- protected
- def cfgForIfStatement(node: ControlStructure): Cfg
CFG creation for if statements of the form
if(condition) body, optionally followed byelse body2.CFG creation for if statements of the form
if(condition) body, optionally followed byelse body2.- Attributes
- protected
- def cfgForInlinedCall(call: Call): Cfg
For macros, the AST contains a CALL node, along with child sub trees for all arguments, and a final sub tree that contains the inlined code.
For macros, the AST contains a CALL node, along with child sub trees for all arguments, and a final sub tree that contains the inlined code. The corresponding CFG consists of the CFG for the call, an edge to the exit and an edge to the CFG of the inlined code. We choose this representation because it allows both queries that use the macro reference as well as queries that reference the inline code to be chosen as sources/sinks in data flow queries.
- def cfgForJumpTarget(n: JumpTarget): Cfg
Jump targets ("labels") are included in the CFG.
Jump targets ("labels") are included in the CFG. As these should be connected to the next appended CFG, we specify that the label node is both the entry node and the only node in the fringe. This is achieved by calling
cfgForSingleNodeon the label node. Just like for breaks and continues, we record labels. We store case/default labels separately from other labels, but that is not a relevant implementation detail.- Attributes
- protected
- def cfgForOrExpression(call: Call): Cfg
Same construction recipe as for the AND expression, just that the fringe edge type of the left CFG is
FalseEdge.Same construction recipe as for the AND expression, just that the fringe edge type of the left CFG is
FalseEdge.- Attributes
- protected
- def cfgForReturn(actualRet: Return): Cfg
Return statements may contain expressions as return values, and therefore, the CFG for a return statement consists of the CFG for calculation of that expression, appended to a CFG containing only the return node, connected with a single edge to the method exit node.
Return statements may contain expressions as return values, and therefore, the CFG for a return statement consists of the CFG for calculation of that expression, appended to a CFG containing only the return node, connected with a single edge to the method exit node. The fringe is empty.
- Attributes
- protected
- def cfgForSwitchStatement(node: ControlStructure): Cfg
CFG creation for switch statements of the form
switch { case condition: ... }.CFG creation for switch statements of the form
switch { case condition: ... }.- Attributes
- protected
- def cfgForTryStatement(node: ControlStructure): Cfg
CFG creation for try statements of the form
try { tryBody ] catch { catchBody }, optionally followed byfinally { finallyBody }.CFG creation for try statements of the form
try { tryBody ] catch { catchBody }, optionally followed byfinally { finallyBody }.To avoid very large CFGs for try statements, only edges from the last statement in the
tryblock to eachcatchblock (and optionally thefinallyblock) are created. The last statement in eachcatchblock should then have an outgoing edge to thefinallyblock if it exists (and not to any subsequent catch blocks), or otherwise * be part of the fringe.By default, the first child of the
TRYnode is treated as the try body, while every subsequent node is treated as acatch, with nofinallypresent. To treat the last child of the node as thefinallyblock, thecodefield of theBlocknode must be set tofinally.- Attributes
- protected
- def cfgForWhileStatement(node: ControlStructure): Cfg
CFG creation for while statements of the form
while(condition) body1 else body2where body1 and the else block are optional.CFG creation for while statements of the form
while(condition) body1 else body2where body1 and the else block are optional.- Attributes
- protected
- def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @native() @HotSpotIntrinsicCandidate()
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native() @HotSpotIntrinsicCandidate()
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native() @HotSpotIntrinsicCandidate()
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @HotSpotIntrinsicCandidate()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @HotSpotIntrinsicCandidate()
- def run(): Unit
We return the CFG as a sequence of Diff Graphs that is calculated by first obtaining the CFG for the method and then resolving gotos.
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toString(): String
- Definition Classes
- AnyRef → Any
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException]) @native()
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
Deprecated Value Members
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable]) @Deprecated
- Deprecated