]> git.lizzy.rs Git - rust.git/blob - src/librustc/cfg/mod.rs
StmtKind
[rust.git] / src / librustc / cfg / mod.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Module that constructs a control-flow graph representing an item.
12 //! Uses `Graph` as the underlying representation.
13
14 use rustc_data_structures::graph::implementation as graph;
15 use ty::TyCtxt;
16 use hir;
17 use hir::def_id::DefId;
18
19 mod construct;
20 pub mod graphviz;
21
22 pub struct CFG {
23     pub owner_def_id: DefId,
24     pub graph: CFGGraph,
25     pub entry: CFGIndex,
26     pub exit: CFGIndex,
27 }
28
29 #[derive(Copy, Clone, Debug, PartialEq)]
30 pub enum CFGNodeData {
31     AST(hir::ItemLocalId),
32     Entry,
33     Exit,
34     Dummy,
35     Unreachable,
36 }
37
38 impl CFGNodeData {
39     pub fn id(&self) -> hir::ItemLocalId {
40         if let CFGNodeData::AST(id) = *self {
41             id
42         } else {
43             hir::DUMMY_ITEM_LOCAL_ID
44         }
45     }
46 }
47
48 #[derive(Debug)]
49 pub struct CFGEdgeData {
50     pub exiting_scopes: Vec<hir::ItemLocalId>
51 }
52
53 pub type CFGIndex = graph::NodeIndex;
54
55 pub type CFGGraph = graph::Graph<CFGNodeData, CFGEdgeData>;
56
57 pub type CFGNode = graph::Node<CFGNodeData>;
58
59 pub type CFGEdge = graph::Edge<CFGEdgeData>;
60
61 impl CFG {
62     pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
63                          body: &hir::Body) -> CFG {
64         construct::construct(tcx, body)
65     }
66
67     pub fn node_is_reachable(&self, id: hir::ItemLocalId) -> bool {
68         self.graph.depth_traverse(self.entry, graph::OUTGOING)
69                   .any(|idx| self.graph.node_data(idx).id() == id)
70     }
71 }