CBMC
cpp_scope.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: C++ Language Type Checking
4 
5 Author: Daniel Kroening, kroening@cs.cmu.edu
6 
7 \*******************************************************************/
8 
11 
12 #include "cpp_scope.h"
13 
14 std::ostream &operator << (std::ostream &out, cpp_scopet::lookup_kindt kind)
15 {
16  switch(kind)
17  {
18  case cpp_scopet::QUALIFIED: return out << "QUALIFIED";
19  case cpp_scopet::SCOPE_ONLY: return out << "SCOPE_ONLY";
20  case cpp_scopet::RECURSIVE: return out << "RECURSIVE";
21  default: UNREACHABLE;
22  }
23 
24  return out;
25 }
26 
28  const irep_idt &base_name_to_lookup,
29  lookup_kindt kind,
30  id_sett &id_set)
31 {
32  cpp_id_mapt::iterator lower_it = sub.lower_bound(base_name_to_lookup);
33 
34  if(lower_it!=sub.end())
35  {
36  cpp_id_mapt::iterator upper_it = sub.upper_bound(base_name_to_lookup);
37 
38  for(cpp_id_mapt::iterator n_it=lower_it;
39  n_it!=upper_it; n_it++)
40  id_set.insert(&n_it->second);
41  }
42 
43  if(base_name == base_name_to_lookup)
44  id_set.insert(this);
45 
46  if(kind==SCOPE_ONLY)
47  return; // done
48 
49  // using scopes
50  for(const auto &s_ptr : using_scopes)
51  {
52  cpp_scopet &other_scope = static_cast<cpp_scopet &>(*s_ptr);
53 
54  // Recursive call.
55  // Note the different kind!
56  other_scope.lookup_rec(base_name_to_lookup, QUALIFIED, id_set);
57  }
58 
59  if(!id_set.empty())
60  return; // done, upwards scopes are hidden
61 
62  // secondary scopes
63  for(const auto &s_ptr : secondary_scopes)
64  {
65  cpp_scopet &other_scope = static_cast<cpp_scopet &>(*s_ptr);
66 
67  // Recursive call.
68  // Note the different kind!
69  other_scope.lookup_rec(base_name_to_lookup, QUALIFIED, id_set);
70  }
71 
72  if(kind==QUALIFIED)
73  return; // done
74 
75  if(!id_set.empty())
76  return; // done
77 
78  // ask parent, recursive call
79  if(!is_root_scope())
80  get_parent().lookup_rec(base_name_to_lookup, kind, id_set);
81 }
82 
84  const irep_idt &base_name_to_lookup,
85  lookup_kindt kind,
86  cpp_idt::id_classt identifier_class,
87  id_sett &id_set)
88 {
89  // we have a hack to do full search in case we
90  // are looking for templates!
91 
92  #if 0
93  std::cout << "B: " << base_name_to_lookup << '\n';
94  std::cout << "K: " << kind << '\n';
95  std::cout << "I: " << identifier_class << '\n';
96  std::cout << "THIS: " << base_name << " " << identifier_class
97  << " " << this->identifier << '\n';
98  #endif
99 
100  cpp_id_mapt::iterator lower_it = sub.lower_bound(base_name_to_lookup);
101 
102  if(lower_it!=sub.end())
103  {
104  cpp_id_mapt::iterator upper_it = sub.upper_bound(base_name_to_lookup);
105 
106  for(cpp_id_mapt::iterator n_it=lower_it;
107  n_it!=upper_it; n_it++)
108  {
109  if(n_it->second.id_class == identifier_class)
110  id_set.insert(&n_it->second);
111  }
112  }
113 
114  if(base_name == base_name_to_lookup && id_class == identifier_class)
115  id_set.insert(this);
116 
117  if(kind==SCOPE_ONLY)
118  return; // done
119 
120  // using scopes
121  for(const auto &s_ptr : using_scopes)
122  {
123  cpp_scopet &other_scope = static_cast<cpp_scopet &>(*s_ptr);
124 
125  // Recursive call.
126  // Note the different kind!
127  other_scope.lookup_rec(
128  base_name_to_lookup, QUALIFIED, identifier_class, id_set);
129  }
130 
131  if(!id_set.empty() && identifier_class != id_classt::TEMPLATE)
132  return; // done, upwards scopes are hidden
133 
134  // secondary scopes
135  for(const auto &s_ptr : secondary_scopes)
136  {
137  cpp_scopet &other_scope = static_cast<cpp_scopet &>(*s_ptr);
138 
139  // Recursive call.
140  // Note the different kind!
141  other_scope.lookup_rec(
142  base_name_to_lookup, QUALIFIED, identifier_class, id_set);
143  }
144 
145  if(kind==QUALIFIED)
146  return; // done
147 
148  if(!id_set.empty() && identifier_class != id_classt::TEMPLATE)
149  return; // done, upwards scopes are hidden
150 
151  // ask parent, recursive call
152  if(!is_root_scope())
154  base_name_to_lookup, kind, identifier_class, id_set);
155 }
156 
158  const irep_idt &id,
159  cpp_idt::id_classt identifier_class)
160 {
161  id_sett id_set;
162 
163  for(cpp_id_mapt::iterator n_it=sub.begin();
164  n_it!=sub.end(); n_it++)
165  {
166  if(
167  n_it->second.identifier == id &&
168  n_it->second.id_class == identifier_class)
169  {
170  id_set.insert(&n_it->second);
171  }
172  }
173 
174  if(identifier == id && id_class == identifier_class)
175  id_set.insert(this);
176 
177  #if 0
178  for(std::size_t i=0; i<parents_size(); i++)
179  {
181  if(parent.identifier == id
182  && parent.id_class == identifier_class)
183  id_set.insert(&parent);
184  }
185  #endif
186 
187  return id_set;
188 }
189 
191 {
192  cpp_idt &id=insert(new_scope_name);
193  id.identifier=prefix+id2string(new_scope_name);
194  id.prefix=prefix+id2string(new_scope_name)+"::";
195  id.this_expr=this_expr;
196  id.class_identifier=class_identifier;
197  id.is_scope=true;
198  return (cpp_scopet &)id;
199 }
200 
201 bool cpp_scopet::contains(const irep_idt &base_name_to_lookup)
202 {
203  return !lookup(base_name_to_lookup, SCOPE_ONLY).empty();
204 }
Definition: cpp_id.h:23
irep_idt identifier
Definition: cpp_id.h:72
exprt this_expr
Definition: cpp_id.h:76
scope_listt using_scopes
Definition: cpp_id.h:108
std::string prefix
Definition: cpp_id.h:79
id_classt
Definition: cpp_id.h:28
cpp_id_mapt sub
Definition: cpp_id.h:104
id_classt id_class
Definition: cpp_id.h:45
scope_listt secondary_scopes
Definition: cpp_id.h:108
irep_idt class_identifier
Definition: cpp_id.h:75
irep_idt base_name
Definition: cpp_id.h:72
cpp_idt * parent
Definition: cpp_id.h:109
class cpp_scopet & new_scope(const irep_idt &new_scope_name)
Definition: cpp_scope.cpp:190
cpp_scopet & get_parent() const
Definition: cpp_scope.h:88
@ SCOPE_ONLY
Definition: cpp_scope.h:30
id_sett lookup_identifier(const irep_idt &id, cpp_idt::id_classt identifier_class)
Definition: cpp_scope.cpp:157
std::set< cpp_idt * > id_sett
Definition: cpp_scope.h:28
void lookup_rec(const irep_idt &base_name, lookup_kindt kind, id_sett &)
Definition: cpp_scope.cpp:27
id_sett lookup(const irep_idt &base_name_to_lookup, lookup_kindt kind)
Definition: cpp_scope.h:32
cpp_idt & insert(const irep_idt &_base_name)
Definition: cpp_scope.h:52
bool is_root_scope() const
Definition: cpp_scope.h:77
bool contains(const irep_idt &base_name_to_lookup)
Definition: cpp_scope.cpp:201
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
std::ostream & operator<<(std::ostream &out, cpp_scopet::lookup_kindt kind)
Definition: cpp_scope.cpp:14
C++ Language Type Checking.
const std::string & id2string(const irep_idt &d)
Definition: irep.h:44
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:525