CBMC
destructor_tree.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3  Module: Destructor Tree
4 
5  Author: John Dumbell, john.dumbell@diffblue.com
6 
7 \*******************************************************************/
8 
9 #include "destructor_tree.h"
10 
11 void destructor_treet::add(const codet &destructor)
12 {
13  auto previous_node = get_current_node();
14  auto new_node = destruction_graph.add_node(destructor);
15  destruction_graph.add_edge(previous_node, new_node);
16  current_node = new_node;
17 }
18 
20 {
21  PRECONDITION(index < destruction_graph.size());
22  return destruction_graph[index].destructor_value;
23 }
24 
26  node_indext left_index,
27  node_indext right_index)
28 {
29  std::size_t left_unique_count = 0, right_unique_count = 0;
30  while(right_index != left_index)
31  {
32  if(right_index > left_index)
33  {
34  auto edge_map = destruction_graph[right_index].in;
35  INVARIANT(
36  !edge_map.empty(),
37  "Node at index " + std::to_string(right_index) +
38  " has no parent, can't find an ancestor.");
39  right_index = edge_map.begin()->first, right_unique_count++;
40  }
41  else
42  {
43  auto edge_map = destruction_graph[left_index].in;
44  INVARIANT(
45  !edge_map.empty(),
46  "Node at index " + std::to_string(left_index) +
47  " has no parent, can't find an ancestor.");
48  left_index = edge_map.begin()->first, left_unique_count++;
49  }
50  }
51 
52  // At this point it dosen't matter which index we return as both are the same.
53  return {right_index, left_unique_count, right_unique_count};
54 }
55 
56 const std::vector<destructor_and_idt> destructor_treet::get_destructors(
57  optionalt<node_indext> end_index,
58  optionalt<node_indext> starting_index)
59 {
60  node_indext next_id = starting_index.value_or(get_current_node());
61  node_indext end_id = end_index.value_or(0);
62 
63  std::vector<destructor_and_idt> codes;
64  while(next_id > end_id)
65  {
66  auto node = destruction_graph[next_id];
67  auto &destructor = node.destructor_value;
68  if(destructor)
69  codes.emplace_back(destructor_and_idt(*destructor, next_id));
70 
71  next_id = node.in.begin()->first;
72  }
73 
74  return codes;
75 }
76 
78 {
79  if(val)
80  set_current_node(*val);
81 }
82 
84 {
85  current_node = val;
86 }
87 
89 {
91  if(current_node != 0)
92  {
94  }
95 }
96 
98 {
99  return current_node;
100 }
destructor_treet::descend_tree
void descend_tree()
Walks the current node down to its child.
Definition: destructor_tree.cpp:88
destructor_treet::get_destructor
optionalt< codet > & get_destructor(node_indext index)
Fetches the destructor value for the passed-in node index.
Definition: destructor_tree.cpp:19
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:58
node_indext
std::size_t node_indext
Definition: destructor_tree.h:15
destructor_treet::add
void add(const codet &destructor)
Adds a destructor to the current stack, attaching itself to the current node.
Definition: destructor_tree.cpp:11
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
destructor_tree.h
destructor_treet::current_node
node_indext current_node
Definition: destructor_tree.h:152
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
destructor_treet::destruction_graph
grapht< destructor_nodet > destruction_graph
Definition: destructor_tree.h:151
destructor_treet::set_current_node
void set_current_node(optionalt< node_indext > val)
Sets the current node.
Definition: destructor_tree.cpp:77
destructor_treet::get_current_node
node_indext get_current_node() const
Gets the node that the next addition will be added to as a child.
Definition: destructor_tree.cpp:97
destructor_treet::get_nearest_common_ancestor_info
const ancestry_resultt get_nearest_common_ancestor_info(node_indext left_index, node_indext right_index)
Finds the nearest common ancestor of two nodes and then returns it.
Definition: destructor_tree.cpp:25
destructor_treet::get_destructors
const std::vector< destructor_and_idt > get_destructors(optionalt< node_indext > end_index={}, optionalt< node_indext > starting_index={})
Builds a vector of destructors that start from starting_index and ends at end_index.
Definition: destructor_tree.cpp:56
destructor_and_idt
Result of a tree query holding both destructor codet and the ID of the node that held it.
Definition: destructor_tree.h:45
validation_modet::INVARIANT
@ INVARIANT
ancestry_resultt
Result of an attempt to find ancestor information about two nodes.
Definition: destructor_tree.h:20
codet
Data structure for representing an arbitrary statement in a program.
Definition: std_code_base.h:28