UNPKG

@specs-feup/clava

Version:

A C/C++ source-to-source compiler written in Typescript

91 lines (81 loc) 2.46 kB
import Graph from "@specs-feup/lara/api/lara/graphs/Graph.js"; import cytoscape from "@specs-feup/lara/api/libs/cytoscape-3.26.0.js"; import { Statement } from "../../Joinpoints.js"; import CfgBuilder from "./cfg/CfgBuilder.js"; export default class ControlFlowGraph extends Graph { /** * Maps stmts to graph nodes */ private nodes: Map<string, cytoscape.NodeSingular>; /** * The start node of the CFG */ private start: cytoscape.NodeSingular; /** * The end node of the CFG */ private end: cytoscape.NodeSingular; constructor( graph: cytoscape.Core, nodes: Map<string, cytoscape.NodeSingular>, startNode: cytoscape.NodeSingular, endNode: cytoscape.NodeSingular ) { super(graph); this.nodes = nodes; this.start = startNode; this.end = endNode; } /** * Builds the control flow graph * * @param deterministicIds - If true, uses deterministic ids for the graph ids (e.g. id_0, id_1...). Otherwise, uses $jp.astId whenever possible * @param options - An object containing configuration options for the cfg * @returns A new instance of the ControlFlowGraph class */ static build( $jp: Statement, deterministicIds: boolean = false, options = { /** * If true, statements of each instruction list must be split */ splitInstList: false, /** * If true, the nodes that correspond to goto statements will be excluded from the resulting graph */ removeGotoNodes: false, /** * If true, the nodes that correspond to label statements will be excluded from the resulting graph */ removeLabelNodes: false, /** * If true, the temporary scope statements will be kept in the resulting graph */ keepTemporaryScopeStmts: false, } ): ControlFlowGraph { const builderResult = new CfgBuilder( $jp, deterministicIds, options ).build(); return new ControlFlowGraph(...builderResult); } /** * Returns the graph node where the given statement belongs. * * @param $stmt - A statement join point, or a string with the astId of the join point */ getNode($stmt: Statement | string) { // If string, assume it is astId const astId: string = typeof $stmt === "string" ? $stmt : $stmt.astId; return this.nodes.get(astId); } get startNode() { return this.start; } get endNode() { return this.end; } }