CfgCreator

class CfgCreator(entryNode: Method, diffGraph: DiffGraphBuilder)

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.

Companion:
object
class Object
trait Matchable
class Any

Value members

Concrete methods

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. 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.

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 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.

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.