]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | //! Module that constructs a control-flow graph representing an item. |
2 | //! Uses `Graph` as the underlying representation. | |
3 | ||
8faf50e0 | 4 | use rustc_data_structures::graph::implementation as graph; |
9fa01778 XL |
5 | use crate::ty::TyCtxt; |
6 | use crate::hir; | |
7 | use crate::hir::def_id::DefId; | |
1a4d82fc JJ |
8 | |
9 | mod construct; | |
10 | pub mod graphviz; | |
11 | ||
12 | pub struct CFG { | |
ea8adc8c | 13 | pub owner_def_id: DefId, |
1a4d82fc JJ |
14 | pub graph: CFGGraph, |
15 | pub entry: CFGIndex, | |
16 | pub exit: CFGIndex, | |
17 | } | |
18 | ||
d9579d0f | 19 | #[derive(Copy, Clone, Debug, PartialEq)] |
c34b1796 | 20 | pub enum CFGNodeData { |
ea8adc8c | 21 | AST(hir::ItemLocalId), |
c34b1796 AL |
22 | Entry, |
23 | Exit, | |
24 | Dummy, | |
25 | Unreachable, | |
26 | } | |
27 | ||
28 | impl CFGNodeData { | |
ea8adc8c | 29 | pub fn id(&self) -> hir::ItemLocalId { |
c34b1796 AL |
30 | if let CFGNodeData::AST(id) = *self { |
31 | id | |
32 | } else { | |
ea8adc8c | 33 | hir::DUMMY_ITEM_LOCAL_ID |
c34b1796 AL |
34 | } |
35 | } | |
1a4d82fc JJ |
36 | } |
37 | ||
d9579d0f | 38 | #[derive(Debug)] |
1a4d82fc | 39 | pub struct CFGEdgeData { |
ea8adc8c | 40 | pub exiting_scopes: Vec<hir::ItemLocalId> |
1a4d82fc JJ |
41 | } |
42 | ||
43 | pub type CFGIndex = graph::NodeIndex; | |
44 | ||
45 | pub type CFGGraph = graph::Graph<CFGNodeData, CFGEdgeData>; | |
46 | ||
47 | pub type CFGNode = graph::Node<CFGNodeData>; | |
48 | ||
49 | pub type CFGEdge = graph::Edge<CFGEdgeData>; | |
50 | ||
51 | impl CFG { | |
416331ca | 52 | pub fn new(tcx: TyCtxt<'_>, body: &hir::Body) -> CFG { |
476ff2be | 53 | construct::construct(tcx, body) |
1a4d82fc JJ |
54 | } |
55 | ||
ea8adc8c | 56 | pub fn node_is_reachable(&self, id: hir::ItemLocalId) -> bool { |
a7813a04 | 57 | self.graph.depth_traverse(self.entry, graph::OUTGOING) |
62682a34 | 58 | .any(|idx| self.graph.node_data(idx).id() == id) |
1a4d82fc JJ |
59 | } |
60 | } |