|
| 1 | +/** |
| 2 | + * Provides a library for reasoning about control flow at the granularity of basic blocks. |
| 3 | + * This is usually much more efficient than reasoning directly at the level of `ControlFlowNode`s. |
| 4 | + */ |
| 5 | + |
1 | 6 | import cpp |
2 | 7 | private import internal.PrimitiveBasicBlocks |
3 | 8 | private import internal.ConstantExprs |
@@ -148,22 +153,37 @@ predicate bb_successor = bb_successor_cached/2; |
148 | 153 | class BasicBlock extends ControlFlowNodeBase { |
149 | 154 | BasicBlock() { basic_block_entry_node(this) } |
150 | 155 |
|
| 156 | + /** Holds if this basic block contains `node`. */ |
151 | 157 | predicate contains(ControlFlowNode node) { basic_block_member(node, this, _) } |
152 | 158 |
|
| 159 | + /** Gets the `ControlFlowNode` at position `pos` in this basic block. */ |
153 | 160 | ControlFlowNode getNode(int pos) { basic_block_member(result, this, pos) } |
154 | 161 |
|
| 162 | + /** Gets a `ControlFlowNode` in this basic block. */ |
155 | 163 | ControlFlowNode getANode() { basic_block_member(result, this, _) } |
156 | 164 |
|
| 165 | + /** Gets a `BasicBlock` that is a direct successor of this basic block. */ |
157 | 166 | BasicBlock getASuccessor() { bb_successor(this, result) } |
158 | 167 |
|
| 168 | + /** Gets a `BasicBlock` that is a direct predecessor of this basic block. */ |
159 | 169 | BasicBlock getAPredecessor() { bb_successor(result, this) } |
160 | 170 |
|
| 171 | + /** |
| 172 | + * Gets a `BasicBlock` such that the control-flow edge `(this, result)` may be taken |
| 173 | + * when the outgoing edge of this basic block is an expression that is true. |
| 174 | + */ |
161 | 175 | BasicBlock getATrueSuccessor() { result.getStart() = this.getEnd().getATrueSuccessor() } |
162 | 176 |
|
| 177 | + /** |
| 178 | + * Gets a `BasicBlock` such that the control-flow edge `(this, result)` may be taken |
| 179 | + * when the outgoing edge of this basic block is an expression that is false. |
| 180 | + */ |
163 | 181 | BasicBlock getAFalseSuccessor() { result.getStart() = this.getEnd().getAFalseSuccessor() } |
164 | 182 |
|
| 183 | + /** Gets the final `ControlFlowNode` of this basic block. */ |
165 | 184 | ControlFlowNode getEnd() { basic_block_member(result, this, bb_length(this) - 1) } |
166 | 185 |
|
| 186 | + /** Gets the first `ControlFlowNode` of this basic block. */ |
167 | 187 | ControlFlowNode getStart() { result = this } |
168 | 188 |
|
169 | 189 | /** Gets the number of `ControlFlowNode`s in this basic block. */ |
@@ -192,6 +212,7 @@ class BasicBlock extends ControlFlowNodeBase { |
192 | 212 | this.getEnd().getLocation().hasLocationInfo(endf, _, _, endl, endc) |
193 | 213 | } |
194 | 214 |
|
| 215 | + /** Gets the function containing this basic block. */ |
195 | 216 | Function getEnclosingFunction() { result = this.getStart().getControlFlowScope() } |
196 | 217 |
|
197 | 218 | /** |
|
0 commit comments