1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- mode: C++ -*-
3 //
4 // Copyright (C) 2013-2020 Red Hat, Inc.
5 //
6 //Author: Dodji Seketeli
7 
8 /// @file
9 ///
10 /// Definitions for the Internal Representation artifacts of libabigail.
11 
12 #include <cxxabi.h>
13 #include <algorithm>
14 #include <cstdint>
15 #include <functional>
16 #include <iterator>
17 #include <memory>
18 #include <sstream>
19 #include <typeinfo>
20 #include <unordered_map>
21 #include <utility>
22 #include <vector>
23 
24 #include "abg-internal.h"
25 // <headers defining libabigail's API go under here>
26 ABG_BEGIN_EXPORT_DECLARATIONS
27 
28 #include "abg-interned-str.h"
29 #include "abg-ir.h"
30 #include "abg-corpus.h"
31 #include "abg-corpus-priv.h"
32 
33 ABG_END_EXPORT_DECLARATIONS
34 // </headers defining libabigail's API>
35 
36 #include "abg-tools-utils.h"
37 #include "abg-comp-filter.h"
38 #include "abg-ir-priv.h"
39 
40 namespace
41 {
42 /// This internal type is a tree walker that walks the sub-tree of a
43 /// type and sets the environment of the type (including its sub-type)
44 /// to a new environment.
45 class environment_setter : public abigail::ir::ir_node_visitor
46 {
47   const abigail::ir::environment* env_;
48 
49 public:
environment_setter(const abigail::ir::environment * env)50   environment_setter(const abigail::ir::environment* env)
51     : env_(env)
52   {}
53 
54   /// This function is called on each sub-tree node that is a
55   /// declaration.  Note that it's also called on some types because
56   /// most types that have a declarations also inherit the type @ref
57   /// decl_base.
58   ///
59   /// @param d the declaration being visited.
60   bool
visit_begin(abigail::ir::decl_base * d)61   visit_begin(abigail::ir::decl_base* d)
62   {
63     if (const abigail::ir::environment* env = d->get_environment())
64       {
65 	ABG_ASSERT(env == env_);
66 	return false;
67       }
68     else
69       d->set_environment(env_);
70 
71     return true;
72 
73   }
74 
75   /// This function is called on each sub-tree node that is a type.
76   ///
77   /// @param t the type being visited.
78   bool
visit_begin(abigail::ir::type_base * t)79   visit_begin(abigail::ir::type_base* t)
80   {
81     if (abigail::ir::environment* env = t->get_environment())
82       {
83 	ABG_ASSERT(env == env_);
84 	return false;
85       }
86     else
87       {
88 	ABG_ASSERT(!t->get_environment());
89 	t->set_environment(env_);
90       }
91     return true;
92   }
93 };
94 
95 /// This internal type is a tree walking that is used to set the
96 /// qualified name of a tree of decls and types.  It used by the
97 /// function update_qualified_name().
98 class qualified_name_setter : public abigail::ir::ir_node_visitor
99 {
100 
101 public:
102   bool
103   do_update(abigail::ir::decl_base* d);
104 
105   bool
106   visit_begin(abigail::ir::decl_base* d);
107 
108   bool
109   visit_begin(abigail::ir::type_base* d);
110 }; // end class qualified_name_setter
111 
112 }// end anon namespace
113 
114 namespace abigail
115 {
116 
117 // Inject.
118 using std::string;
119 using std::list;
120 using std::vector;
121 using std::unordered_map;
122 using std::dynamic_pointer_cast;
123 using std::static_pointer_cast;
124 
125 /// Convenience typedef for a map of string -> string*.
126 typedef unordered_map<string, string*> pool_map_type;
127 
128 /// The type of the private data structure of type @ref
129 /// intered_string_pool.
130 struct interned_string_pool::priv
131 {
132   pool_map_type map;
133 }; //end struc struct interned_string_pool::priv
134 
135 /// Default constructor.
interned_string_pool()136 interned_string_pool::interned_string_pool()
137   : priv_(new priv)
138 {
139   priv_->map[""] = 0;
140 }
141 
142 /// Test if the interned string pool already contains a string with a
143 /// given value.
144 ///
145 /// @param s the string to test for.
146 ///
147 /// @return true if the pool contains a string with the value @p s.
148 bool
has_string(const char * s) const149 interned_string_pool::has_string(const char* s) const
150 {return priv_->map.find(s) != priv_->map.end();}
151 
152 /// Get a pointer to the interned string which has a given value.
153 ///
154 /// @param s the value of the interned string to look for.
155 ///
156 /// @return a pointer to the raw string of characters which has the
157 /// value of @p s.  Or null if no string with value @p s was interned.
158 const char*
get_string(const char * s) const159 interned_string_pool::get_string(const char* s) const
160 {
161   unordered_map<string, string*>::const_iterator i =
162     priv_->map.find(s);
163   if (i == priv_->map.end())
164     return 0;
165   if (i->second)
166     return i->second->c_str();
167   return "";
168 }
169 
170 /// Create an interned string with a given value.
171 ///
172 /// @param str_value the value of the interned string to create.
173 ///
174 /// @return the new created instance of @ref interned_string created.
175 interned_string
create_string(const std::string & str_value)176 interned_string_pool::create_string(const std::string& str_value)
177 {
178   string*& result = priv_->map[str_value];
179   if (!result && !str_value.empty())
180     result = new string(str_value);
181   return interned_string(result);
182 }
183 
184 /// Destructor.
~interned_string_pool()185 interned_string_pool::~interned_string_pool()
186 {
187   for (pool_map_type::iterator i = priv_->map.begin();
188        i != priv_->map.end();
189        ++i)
190     if (i->second)
191       delete i->second;
192 }
193 
194 /// Equality operator.
195 ///
196 /// @param l the instance of std::string on the left-hand-side of the
197 /// equality operator.
198 ///
199 /// @param r the instance of @ref interned_string on the
200 /// right-hand-side of the equality operator.
201 ///
202 /// @return true iff the two string are equal.
203 bool
operator ==(const std::string & l,const interned_string & r)204 operator==(const std::string& l, const interned_string& r)
205 {return r.operator==(l);}
206 
207 bool
operator !=(const std::string & l,const interned_string & r)208 operator!=(const std::string& l, const interned_string& r)
209 {return !(l == r);}
210 
211 /// Streaming operator.
212 ///
213 /// Streams an instance of @ref interned_string to an output stream.
214 ///
215 /// @param o the destination output stream.
216 ///
217 /// @param s the instance of @ref interned_string to stream out.
218 ///
219 /// @return the output stream this function just streamed to.
220 std::ostream&
operator <<(std::ostream & o,const interned_string & s)221 operator<<(std::ostream& o, const interned_string& s)
222 {
223   o << static_cast<std::string>(s);
224   return o;
225 }
226 
227 /// Concatenation operator.
228 ///
229 /// Concatenate two instances of @ref interned_string, builds an
230 /// instance of std::string with the resulting string and return it.
231 ///
232 /// @param s1 the first string to consider.
233 ///
234 /// @param s2 the second string to consider.
235 ///
236 /// @return the resuting concatenated string.
237 std::string
operator +(const interned_string & s1,const std::string & s2)238 operator+(const interned_string& s1,const std::string& s2)
239 {return static_cast<std::string>(s1) + s2;}
240 
241 /// Concatenation operator.
242 ///
243 /// Concatenate two instances of @ref interned_string, builds an
244 /// instance of std::string with the resulting string and return it.
245 ///
246 /// @param s1 the first string to consider.
247 ///
248 /// @param s2 the second string to consider.
249 ///
250 /// @return the resuting concatenated string.
251 std::string
operator +(const std::string & s1,const interned_string & s2)252 operator+(const std::string& s1, const interned_string& s2)
253 {return s1 + static_cast<std::string>(s2);}
254 
255 namespace ir
256 {
257 
258 static size_t
259 hash_as_canonical_type_or_constant(const type_base *t);
260 
261 static bool
262 has_generic_anonymous_internal_type_name(const decl_base *d);
263 
264 static interned_string
265 get_generic_anonymous_internal_type_name(const decl_base *d);
266 
267 /// @brief the location of a token represented in its simplest form.
268 /// Instances of this type are to be stored in a sorted vector, so the
269 /// type must have proper relational operators.
270 class expanded_location
271 {
272   string	path_;
273   unsigned	line_;
274   unsigned	column_;
275 
276   expanded_location();
277 
278 public:
279 
280   friend class location_manager;
281 
expanded_location(const string & path,unsigned line,unsigned column)282   expanded_location(const string& path, unsigned line, unsigned column)
283   : path_(path), line_(line), column_(column)
284   {}
285 
286   bool
operator ==(const expanded_location & l) const287   operator==(const expanded_location& l) const
288   {
289     return (path_ == l.path_
290 	    && line_ == l.line_
291 	    && column_ && l.column_);
292   }
293 
294   bool
operator <(const expanded_location & l) const295   operator<(const expanded_location& l) const
296   {
297     if (path_ < l.path_)
298       return true;
299     else if (path_ > l.path_)
300       return false;
301 
302     if (line_ < l.line_)
303       return true;
304     else if (line_ > l.line_)
305       return false;
306 
307     return column_ < l.column_;
308   }
309 };
310 
311 /// Expand the location into a tripplet path, line and column number.
312 ///
313 /// @param path the output parameter where this function sets the
314 /// expanded path.
315 ///
316 /// @param line the output parameter where this function sets the
317 /// expanded line.
318 ///
319 /// @param column the ouptut parameter where this function sets the
320 /// expanded column.
321 void
expand(std::string & path,unsigned & line,unsigned & column) const322 location::expand(std::string& path, unsigned& line, unsigned& column) const
323 {
324   ABG_ASSERT(get_location_manager());
325   get_location_manager()->expand_location(*this, path, line, column);
326 }
327 
328 
329 /// Expand the location into a string.
330 ///
331 /// @return the string representing the location.
332 string
expand(void) const333 location::expand(void) const
334 {
335   string path, result;
336   unsigned line = 0, column = 0;
337   expand(path, line, column);
338 
339   std::ostringstream o;
340   o << path << ":" << line << ":" << column;
341   return o.str();
342 }
343 
344 struct location_manager::priv
345 {
346   /// This sorted vector contains the expanded locations of the tokens
347   /// coming from a given ABI Corpus.  The index of a given expanded
348   /// location in the table gives us an integer that is used to build
349   /// instance of location types.
350   std::vector<expanded_location> locs;
351 };
352 
location_manager()353 location_manager::location_manager()
354 {priv_ = shared_ptr<location_manager::priv>(new location_manager::priv);}
355 
356 /// Insert the triplet representing a source locus into our internal
357 /// vector of location triplet.  Return an instance of location type,
358 /// built from an integral type that represents the index of the
359 /// source locus triplet into our source locus table.
360 ///
361 /// @param file_path the file path of the source locus
362 /// @param line the line number of the source location
363 /// @param col the column number of the source location
364 location
create_new_location(const std::string & file_path,size_t line,size_t col)365 location_manager::create_new_location(const std::string&	file_path,
366 				      size_t			line,
367 				      size_t			col)
368 {
369   expanded_location l(file_path, line, col);
370 
371   // Just append the new expanded location to the end of the vector
372   // and return its index.  Note that indexes start at 1.
373   priv_->locs.push_back(l);
374   return location(priv_->locs.size(), this);
375 }
376 
377 /// Given an instance of location type, return the triplet
378 /// {path,line,column} that represents the source locus.  Note that
379 /// the location must have been previously created from the function
380 /// location_manager::create_new_location, otherwise this function yields
381 /// unexpected results, including possibly a crash.
382 ///
383 /// @param location the instance of location type to expand
384 /// @param path the resulting path of the source locus
385 /// @param line the resulting line of the source locus
386 /// @param column the resulting colum of the source locus
387 void
expand_location(const location & location,std::string & path,unsigned & line,unsigned & column) const388 location_manager::expand_location(const location&	location,
389 				  std::string&		path,
390 				  unsigned&		line,
391 				  unsigned&		column) const
392 {
393   if (location.value_ == 0)
394     return;
395   expanded_location &l = priv_->locs[location.value_ - 1];
396   path = l.path_;
397   line = l.line_;
398   column = l.column_;
399 }
400 
401 typedef unordered_map<function_type_sptr,
402 		      bool,
403 		      function_type::hash,
404 		      type_shared_ptr_equal> fn_type_ptr_map;
405 
406 // <type_maps stuff>
407 
408 struct type_maps::priv
409 {
410   mutable istring_type_base_wptrs_map_type	basic_types_;
411   mutable istring_type_base_wptrs_map_type	class_types_;
412   mutable istring_type_base_wptrs_map_type	union_types_;
413   mutable istring_type_base_wptrs_map_type	enum_types_;
414   mutable istring_type_base_wptrs_map_type	typedef_types_;
415   mutable istring_type_base_wptrs_map_type	qualified_types_;
416   mutable istring_type_base_wptrs_map_type	pointer_types_;
417   mutable istring_type_base_wptrs_map_type	reference_types_;
418   mutable istring_type_base_wptrs_map_type	array_types_;
419   mutable istring_type_base_wptrs_map_type	subrange_types_;
420   mutable istring_type_base_wptrs_map_type	function_types_;
421   mutable vector<type_base_wptr>		sorted_types_;
422 }; // end struct type_maps::priv
423 
type_maps()424 type_maps::type_maps()
425   : priv_(new priv)
426 {}
427 
428 /// Test if the type_maps is empty.
429 ///
430 /// @return true iff the type_maps is empty.
431 bool
empty() const432 type_maps::empty() const
433 {
434   return (basic_types().empty()
435 	  && class_types().empty()
436 	  && union_types().empty()
437 	  && enum_types().empty()
438 	  && typedef_types().empty()
439 	  && qualified_types().empty()
440 	  && pointer_types().empty()
441 	  && reference_types().empty()
442 	  && array_types().empty()
443 	  && subrange_types().empty()
444 	  && function_types().empty());
445 }
446 
447 /// Getter for the map that associates the name of a basic type to the
448 /// vector instances of type_decl_sptr that represents that type.
449 const istring_type_base_wptrs_map_type&
basic_types() const450 type_maps::basic_types() const
451 {return priv_->basic_types_;}
452 
453 /// Getter for the map that associates the name of a basic type to the
454 /// vector of instances of @ref type_decl_sptr that represents that
455 /// type.
456 istring_type_base_wptrs_map_type&
basic_types()457 type_maps::basic_types()
458 {return priv_->basic_types_;}
459 
460 /// Getter for the map that associates the name of a class type to the
461 /// vector of instances of @ref class_decl_sptr that represents that
462 /// type.
463 const istring_type_base_wptrs_map_type&
class_types() const464 type_maps::class_types() const
465 {return priv_->class_types_;}
466 
467 /// Getter for the map that associates the name of a class type to the
468 /// vector of instances of @ref class_decl_sptr that represents that
469 /// type.
470 istring_type_base_wptrs_map_type&
class_types()471 type_maps::class_types()
472 {return priv_->class_types_;}
473 
474 /// Getter for the map that associates the name of a union type to the
475 /// vector of instances of @ref union_decl_sptr that represents that
476 /// type.
477 istring_type_base_wptrs_map_type&
union_types()478 type_maps::union_types()
479 {return priv_->union_types_;}
480 
481 /// Getter for the map that associates the name of a union type to the
482 /// vector of instances of @ref union_decl_sptr that represents that
483 /// type.
484 const istring_type_base_wptrs_map_type&
union_types() const485 type_maps::union_types() const
486 {return priv_->union_types_;}
487 
488 /// Getter for the map that associates the name of an enum type to the
489 /// vector of instances of @ref enum_type_decl_sptr that represents
490 /// that type.
491 istring_type_base_wptrs_map_type&
enum_types()492 type_maps::enum_types()
493 {return priv_->enum_types_;}
494 
495 /// Getter for the map that associates the name of an enum type to the
496 /// vector of instances of @ref enum_type_decl_sptr that represents
497 /// that type.
498 const istring_type_base_wptrs_map_type&
enum_types() const499 type_maps::enum_types() const
500 {return priv_->enum_types_;}
501 
502 /// Getter for the map that associates the name of a typedef to the
503 /// vector of instances of @ref typedef_decl_sptr that represents tha
504 /// type.
505 istring_type_base_wptrs_map_type&
typedef_types()506 type_maps::typedef_types()
507 {return priv_->typedef_types_;}
508 
509 /// Getter for the map that associates the name of a typedef to the
510 /// vector of instances of @ref typedef_decl_sptr that represents tha
511 /// type.
512 const istring_type_base_wptrs_map_type&
typedef_types() const513 type_maps::typedef_types() const
514 {return priv_->typedef_types_;}
515 
516 /// Getter for the map that associates the name of a qualified type to
517 /// the vector of instances of @ref qualified_type_def_sptr.
518 istring_type_base_wptrs_map_type&
qualified_types()519 type_maps::qualified_types()
520 {return priv_->qualified_types_;}
521 
522 /// Getter for the map that associates the name of a qualified type to
523 /// the vector of instances of @ref qualified_type_def_sptr.
524 const istring_type_base_wptrs_map_type&
qualified_types() const525 type_maps::qualified_types() const
526 {return priv_->qualified_types_;}
527 
528 /// Getter for the map that associates the name of a pointer type to
529 /// the vector of instances of @ref pointer_type_def_sptr that
530 /// represents that type.
531 istring_type_base_wptrs_map_type&
pointer_types()532 type_maps::pointer_types()
533 {return priv_->pointer_types_;}
534 
535 /// Getter for the map that associates the name of a pointer type to
536 /// the vector of instances of @ref pointer_type_def_sptr that
537 /// represents that type.
538 const istring_type_base_wptrs_map_type&
pointer_types() const539 type_maps::pointer_types() const
540 {return priv_->pointer_types_;}
541 
542 /// Getter for the map that associates the name of a reference type to
543 /// the vector of instances of @ref reference_type_def_sptr that
544 /// represents that type.
545 istring_type_base_wptrs_map_type&
reference_types()546 type_maps::reference_types()
547 {return priv_->reference_types_;}
548 
549 /// Getter for the map that associates the name of a reference type to
550 /// the vector of instances of @ref reference_type_def_sptr that
551 /// represents that type.
552 const istring_type_base_wptrs_map_type&
reference_types() const553 type_maps::reference_types() const
554 {return priv_->reference_types_;}
555 
556 /// Getter for the map that associates the name of an array type to
557 /// the vector of instances of @ref array_type_def_sptr that
558 /// represents that type.
559 istring_type_base_wptrs_map_type&
array_types()560 type_maps::array_types()
561 {return priv_->array_types_;}
562 
563 /// Getter for the map that associates the name of an array type to
564 /// the vector of instances of @ref array_type_def_sptr that
565 /// represents that type.
566 const istring_type_base_wptrs_map_type&
array_types() const567 type_maps::array_types() const
568 {return priv_->array_types_;}
569 
570 /// Getter for the map that associates the name of a subrange type to
571 /// the vector of instances of @ref array_type_def::subrange_sptr that
572 /// represents that type.
573 istring_type_base_wptrs_map_type&
subrange_types()574 type_maps::subrange_types()
575 {return priv_->subrange_types_;}
576 
577 /// Getter for the map that associates the name of a subrange type to
578 /// the vector of instances of @ref array_type_def::subrange_sptr that
579 /// represents that type.
580 const istring_type_base_wptrs_map_type&
subrange_types() const581 type_maps::subrange_types() const
582 {return priv_->subrange_types_;}
583 
584 /// Getter for the map that associates the name of a function type to
585 /// the vector of instances of @ref function_type_sptr that represents
586 /// that type.
587 const istring_type_base_wptrs_map_type&
function_types() const588 type_maps::function_types() const
589 {return priv_->function_types_;}
590 
591 /// Getter for the map that associates the name of a function type to
592 /// the vector of instances of @ref function_type_sptr that represents
593 /// that type.
594 istring_type_base_wptrs_map_type&
function_types()595 type_maps::function_types()
596 {return priv_->function_types_;}
597 
598 /// A comparison functor to compare/sort types based on their pretty
599 /// representations.
600 struct type_name_comp
601 {
602   /// Comparison operator for two instances of @ref type_base.
603   ///
604   /// This compares the two types by lexicographically comparing their
605   /// pretty representation.
606   ///
607   /// @param l the left-most type to compare.
608   ///
609   /// @param r the right-most type to compare.
610   ///
611   /// @return true iff @p l < @p r.
612   bool
operator ()abigail::ir::type_name_comp613   operator()(type_base *l, type_base *r) const
614   {
615     if (l == 0 && r == 0)
616       return false;
617 
618     string l_repr = get_pretty_representation(l);
619     string r_repr = get_pretty_representation(r);
620     return l_repr < r_repr;
621   }
622 
623   /// Comparison operator for two instances of @ref type_base.
624   ///
625   /// This compares the two types by lexicographically comparing their
626   /// pretty representation.
627   ///
628   /// @param l the left-most type to compare.
629   ///
630   /// @param r the right-most type to compare.
631   ///
632   /// @return true iff @p l < @p r.
633   bool
operator ()abigail::ir::type_name_comp634   operator()(const type_base_sptr &l, const type_base_sptr &r) const
635   {return operator()(l.get(), r.get());}
636 
637   /// Comparison operator for two instances of @ref type_base.
638   ///
639   /// This compares the two types by lexicographically comparing their
640   /// pretty representation.
641   ///
642   /// @param l the left-most type to compare.
643   ///
644   /// @param r the right-most type to compare.
645   ///
646   /// @return true iff @p l < @p r.
647   bool
operator ()abigail::ir::type_name_comp648   operator()(const type_base_wptr &l, const type_base_wptr &r) const
649   {return operator()(type_base_sptr(l), type_base_sptr(r));}
650 }; // end struct type_name_comp
651 
652 /// Compare two types by comparing their canonical types if present.
653 ///
654 /// If the canonical types are not present (because the types have not
655 /// yet been canonicalized, for instance) then the types are compared
656 /// structurally.
657 ///
658 /// @param l the first type to take into account in the comparison.
659 ///
660 /// @param r the second type to take into account in the comparison.
661 template<typename T>
662 bool
try_canonical_compare(const T * l,const T * r)663 try_canonical_compare(const T *l, const T *r)
664 {
665   if (const type_base *lc = l->get_naked_canonical_type())
666     if (const type_base *rc = r->get_naked_canonical_type())
667       return lc == rc;
668   return equals(*l, *r, 0);
669 }
670 
671 /// Getter of all types types sorted by their pretty representation.
672 ///
673 /// @return a sorted vector of all types sorted by their pretty
674 /// representation.
675 const vector<type_base_wptr>&
get_types_sorted_by_name() const676 type_maps::get_types_sorted_by_name() const
677 {
678   if (priv_->sorted_types_.empty())
679     {
680       istring_type_base_wptrs_map_type::const_iterator i;
681       vector<type_base_wptr>::const_iterator j;
682 
683       for (i = basic_types().begin(); i != basic_types().end(); ++i)
684 	for (j = i->second.begin(); j != i->second.end(); ++j)
685 	  priv_->sorted_types_.push_back(*j);
686 
687       for (i = class_types().begin(); i != class_types().end(); ++i)
688 	for (j = i->second.begin(); j != i->second.end(); ++j)
689 	  priv_->sorted_types_.push_back(*j);
690 
691       for (i = union_types().begin(); i != union_types().end(); ++i)
692 	for (j = i->second.begin(); j != i->second.end(); ++j)
693 	  priv_->sorted_types_.push_back(*j);
694 
695       for (i = enum_types().begin(); i != enum_types().end(); ++i)
696 	for (j = i->second.begin(); j != i->second.end(); ++j)
697 	  priv_->sorted_types_.push_back(*j);
698 
699       for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
700 	for (j = i->second.begin(); j != i->second.end(); ++j)
701 	  priv_->sorted_types_.push_back(*j);
702 
703       type_name_comp comp;
704       sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
705     }
706 
707   return priv_->sorted_types_;
708 }
709 
710 // </type_maps stuff>
711 
712 // <translation_unit stuff>
713 
714 /// Constructor of translation_unit.
715 ///
716 /// @param env the environment of this translation unit.  Please note
717 /// that the life time of the environment must be greater than the
718 /// life time of the translation unit because the translation uses
719 /// resources that are allocated in the environment.
720 ///
721 /// @param path the location of the translation unit.
722 ///
723 /// @param address_size the size of addresses in the translation unit,
724 /// in bits.
translation_unit(const environment * env,const std::string & path,char address_size)725 translation_unit::translation_unit(const environment*	env,
726 				   const std::string&	path,
727 				   char		address_size)
728   : priv_(new priv(env))
729 {
730   priv_->path_ = path;
731   priv_->address_size_ = address_size;
732 }
733 
734 /// Getter of the the global scope of the translation unit.
735 ///
736 /// @return the global scope of the current translation unit.  If
737 /// there is not global scope allocated yet, this function creates one
738 /// and returns it.
739 const scope_decl_sptr&
get_global_scope() const740 translation_unit::get_global_scope() const
741 {
742   return const_cast<translation_unit*>(this)->get_global_scope();
743 }
744 
745 /// Getter of the the global scope of the translation unit.
746 ///
747 /// @return the global scope of the current translation unit.  If
748 /// there is not global scope allocated yet, this function creates one
749 /// and returns it.
750 scope_decl_sptr&
get_global_scope()751 translation_unit::get_global_scope()
752 {
753   if (!priv_->global_scope_)
754     {
755       priv_->global_scope_.reset
756 	(new global_scope(const_cast<translation_unit*>(this)));
757       // The global scope must be out of the same environment as its
758       // translation unit.
759       priv_->global_scope_->
760 	set_environment(const_cast<environment*>(get_environment()));
761       priv_->global_scope_->set_translation_unit
762 	(const_cast<translation_unit*>(this));
763     }
764   return priv_->global_scope_;
765 }
766 
767 /// Getter of the types of the current @ref translation_unit.
768 ///
769 /// @return the maps of the types of the translation unit.
770 const type_maps&
get_types() const771 translation_unit::get_types() const
772 {return priv_->types_;}
773 
774 /// Getter of the types of the current @ref translation_unit.
775 ///
776 /// @return the maps of the types of the translation unit.
777 type_maps&
get_types()778 translation_unit::get_types()
779 {return priv_->types_;}
780 
781 /// Get the vector of function types that are used in the current
782 /// translation unit.
783 ///
784 /// @return the vector of function types that are used in the current
785 /// translation unit.
786 const vector<function_type_sptr>&
get_live_fn_types() const787 translation_unit::get_live_fn_types() const
788 {return priv_->live_fn_types_;}
789 
790 /// Getter of the environment of the current @ref translation_unit.
791 ///
792 /// @return the translation unit of the current translation unit.
793 const environment*
get_environment() const794 translation_unit::get_environment() const
795 {return priv_->env_;}
796 
797 /// Getter of the environment of the current @ref translation_unit.
798 ///
799 /// @return the translation unit of the current translation unit.
800 environment*
get_environment()801 translation_unit::get_environment()
802 {return const_cast<environment*>(priv_->env_);}
803 
804 /// Setter of the environment of the current @ref translation_unit.
805 ///
806 /// @param env the environment.
807 void
set_environment(const environment * env)808 translation_unit::set_environment(const environment* env)
809 {priv_->env_ = env;}
810 
811 /// Getter of the language of the source code of the translation unit.
812 ///
813 /// @return the language of the source code.
814 translation_unit::language
get_language() const815 translation_unit::get_language() const
816 {return priv_->language_;}
817 
818 /// Setter of the language of the source code of the translation unit.
819 ///
820 /// @param l the new language.
821 void
set_language(language l)822 translation_unit::set_language(language l)
823 {priv_->language_ = l;}
824 
825 
826 /// Get the path of the current translation unit.
827 ///
828 /// This path is relative to the build directory of the translation
829 /// unit as returned by translation_unit::get_compilation_dir_path.
830 ///
831 /// @return the relative path of the compilation unit associated to
832 /// the current instance of translation_unit.
833 //
834 const std::string&
get_path() const835 translation_unit::get_path() const
836 {return priv_->path_;}
837 
838 /// Set the path associated to the current instance of
839 /// translation_unit.
840 ///
841 /// This path is relative to the build directory of the translation
842 /// unit as returned by translation_unit::get_compilation_dir_path.
843 ///
844 /// @param a_path the new relative path to set.
845 void
set_path(const string & a_path)846 translation_unit::set_path(const string& a_path)
847 {priv_->path_ = a_path;}
848 
849 
850 /// Get the path of the directory that was 'current' when the
851 /// translation unit was compiled.
852 ///
853 /// Note that the path returned by translation_unit::get_path is
854 /// relative to the path returned by this function.
855 ///
856 /// @return the compilation directory for the current translation
857 /// unit.
858 const std::string&
get_compilation_dir_path() const859 translation_unit::get_compilation_dir_path() const
860 {return priv_->comp_dir_path_;}
861 
862 /// Set the path of the directory that was 'current' when the
863 /// translation unit was compiled.
864 ///
865 /// Note that the path returned by translation_unit::get_path is
866 /// relative to the path returned by this function.
867 ///
868 /// @param the compilation directory for the current translation unit.
869 void
set_compilation_dir_path(const std::string & d)870 translation_unit::set_compilation_dir_path(const std::string& d)
871 {priv_->comp_dir_path_ = d;}
872 
873 /// Get the concatenation of the build directory and the relative path
874 /// of the translation unit.
875 ///
876 /// @return the absolute path of the translation unit.
877 const std::string&
get_absolute_path() const878 translation_unit::get_absolute_path() const
879 {
880   if (priv_->abs_path_.empty())
881     {
882       string path;
883       if (!priv_->path_.empty())
884 	{
885 	  if (!priv_->comp_dir_path_.empty())
886 	    {
887 	      path = priv_->comp_dir_path_;
888 	      path += "/";
889 	    }
890 	  path += priv_->path_;
891 	}
892       priv_->abs_path_ = path;
893     }
894 
895   return priv_->abs_path_;
896 }
897 
898 /// Set the corpus this translation unit is a member of.
899 ///
900 /// Note that adding a translation unit to a @ref corpus automatically
901 /// triggers a call to this member function.
902 ///
903 /// @param corpus the corpus.
904 void
set_corpus(corpus * c)905 translation_unit::set_corpus(corpus* c)
906 {priv_->corp = c;}
907 
908 /// Get the corpus this translation unit is a member of.
909 ///
910 /// @return the parent corpus, or nil if this doesn't belong to any
911 /// corpus yet.
912 corpus*
get_corpus()913 translation_unit::get_corpus()
914 {return priv_->corp;}
915 
916 /// Get the corpus this translation unit is a member of.
917 ///
918 /// @return the parent corpus, or nil if this doesn't belong to any
919 /// corpus yet.
920 const corpus*
get_corpus() const921 translation_unit::get_corpus() const
922 {return const_cast<translation_unit*>(this)->get_corpus();}
923 
924 /// Getter of the location manager for the current translation unit.
925 ///
926 /// @return a reference to the location manager for the current
927 /// translation unit.
928 location_manager&
get_loc_mgr()929 translation_unit::get_loc_mgr()
930 {return priv_->loc_mgr_;}
931 
932 /// const Getter of the location manager.
933 ///
934 /// @return a const reference to the location manager for the current
935 /// translation unit.
936 const location_manager&
get_loc_mgr() const937 translation_unit::get_loc_mgr() const
938 {return priv_->loc_mgr_;}
939 
940 /// Tests whether if the current translation unit contains ABI
941 /// artifacts or not.
942 ///
943 /// @return true iff the current translation unit is empty.
944 bool
is_empty() const945 translation_unit::is_empty() const
946 {return get_global_scope()->is_empty();}
947 
948 /// Getter of the address size in this translation unit.
949 ///
950 /// @return the address size, in bits.
951 char
get_address_size() const952 translation_unit::get_address_size() const
953 {return priv_->address_size_;}
954 
955 /// Setter of the address size in this translation unit.
956 ///
957 /// @param a the new address size in bits.
958 void
set_address_size(char a)959 translation_unit::set_address_size(char a)
960 {priv_->address_size_= a;}
961 
962 /// Getter of the 'is_constructed" flag.  It says if the translation
963 /// unit is fully constructed or not.
964 ///
965 /// This flag is important for cases when comparison might depend on
966 /// if the translation unit is fully built or not.  For instance, when
967 /// reading types from DWARF, the virtual methods of a class are not
968 /// necessarily fully constructed until we have reached the end of the
969 /// translation unit.  In that case, before we've reached the end of
970 /// the translation unit, we might not take virtual functions into
971 /// account when comparing classes.
972 ///
973 /// @return true if the translation unit is constructed.
974 bool
is_constructed() const975 translation_unit::is_constructed() const
976 {return priv_->is_constructed_;}
977 
978 /// Setter of the 'is_constructed" flag.  It says if the translation
979 /// unit is fully constructed or not.
980 ///
981 /// This flag is important for cases when comparison might depend on
982 /// if the translation unit is fully built or not.  For instance, when
983 /// reading types from DWARF, the virtual methods of a class are not
984 /// necessarily fully constructed until we have reached the end of the
985 /// translation unit.  In that case, before we've reached the end of
986 /// the translation unit, we might not take virtual functions into
987 /// account when comparing classes.
988 ///
989 /// @param f true if the translation unit is constructed.
990 void
set_is_constructed(bool f)991 translation_unit::set_is_constructed(bool f)
992 {priv_->is_constructed_ = f;}
993 
994 /// Compare the current translation unit against another one.
995 ///
996 /// @param other the other tu to compare against.
997 ///
998 /// @return true if the two translation units are equal, false
999 /// otherwise.
1000 bool
operator ==(const translation_unit & other) const1001 translation_unit::operator==(const translation_unit& other)const
1002 {
1003   if (get_address_size() != other.get_address_size())
1004     return false;
1005 
1006   return *get_global_scope() == *other.get_global_scope();
1007 }
1008 
1009 /// Inequality operator.
1010 ///
1011 /// @param o the instance of @ref translation_unit to compare the
1012 /// current instance against.
1013 ///
1014 /// @return true iff the current instance is different from @p o.
1015 bool
operator !=(const translation_unit & o) const1016 translation_unit::operator!=(const translation_unit& o) const
1017 {return ! operator==(o);}
1018 
1019 /// Ensure that the life time of a function type is bound to the life
1020 /// time of the current translation unit.
1021 ///
1022 /// @param ftype the function time which life time to bind to the life
1023 /// time of the current instance of @ref translation_unit.  That is,
1024 /// it's onlyh when the translation unit is destroyed that the
1025 /// function type can be destroyed to.
1026 void
bind_function_type_life_time(function_type_sptr ftype) const1027 translation_unit::bind_function_type_life_time(function_type_sptr ftype) const
1028 {
1029   const environment* env = get_environment();
1030   ABG_ASSERT(env);
1031 
1032   const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1033 
1034   interned_string repr = get_type_name(ftype);
1035   const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1036     push_back(ftype);
1037 
1038   // The function type must be out of the same environment as its
1039   // translation unit.
1040   if (const environment* e = ftype->get_environment())
1041     ABG_ASSERT(env == e);
1042   ftype->set_environment(const_cast<environment*>(env));
1043 
1044   if (const translation_unit* existing_tu = ftype->get_translation_unit())
1045     ABG_ASSERT(existing_tu == this);
1046   else
1047     ftype->set_translation_unit(const_cast<translation_unit*>(this));
1048 }
1049 
1050 /// This implements the ir_traversable_base::traverse virtual
1051 /// function.
1052 ///
1053 /// @param v the visitor used on the member nodes of the translation
1054 /// unit during the traversal.
1055 ///
1056 /// @return true if the entire type IR tree got traversed, false
1057 /// otherwise.
1058 bool
traverse(ir_node_visitor & v)1059 translation_unit::traverse(ir_node_visitor& v)
1060 {return get_global_scope()->traverse(v);}
1061 
~translation_unit()1062 translation_unit::~translation_unit()
1063 {}
1064 
1065 /// Converts a translation_unit::language enumerator into a string.
1066 ///
1067 /// @param l the language enumerator to translate.
1068 ///
1069 /// @return the resulting string.
1070 string
translation_unit_language_to_string(translation_unit::language l)1071 translation_unit_language_to_string(translation_unit::language l)
1072 {
1073   switch (l)
1074     {
1075     case translation_unit::LANG_UNKNOWN:
1076       return "LANG_UNKNOWN";
1077     case translation_unit::LANG_Cobol74:
1078       return "LANG_Cobol74";
1079     case translation_unit::LANG_Cobol85:
1080       return "LANG_Cobol85";
1081     case translation_unit::LANG_C89:
1082       return "LANG_C89";
1083     case translation_unit::LANG_C99:
1084       return "LANG_C99";
1085     case translation_unit::LANG_C11:
1086       return "LANG_C11";
1087     case translation_unit::LANG_C:
1088       return "LANG_C";
1089     case translation_unit::LANG_C_plus_plus_11:
1090       return "LANG_C_plus_plus_11";
1091     case translation_unit::LANG_C_plus_plus_14:
1092       return "LANG_C_plus_plus_14";
1093     case translation_unit::LANG_C_plus_plus:
1094       return "LANG_C_plus_plus";
1095     case translation_unit::LANG_ObjC:
1096       return "LANG_ObjC";
1097     case translation_unit::LANG_ObjC_plus_plus:
1098       return "LANG_ObjC_plus_plus";
1099     case translation_unit::LANG_Fortran77:
1100       return "LANG_Fortran77";
1101     case translation_unit::LANG_Fortran90:
1102       return "LANG_Fortran90";
1103     case translation_unit::LANG_Fortran95:
1104       return "LANG_Fortran95";
1105     case translation_unit::LANG_Ada83:
1106       return "LANG_Ada83";
1107     case translation_unit::LANG_Ada95:
1108       return "LANG_Ada95";
1109     case translation_unit::LANG_Pascal83:
1110       return "LANG_Pascal83";
1111     case translation_unit::LANG_Modula2:
1112       return "LANG_Modula2";
1113     case translation_unit::LANG_Java:
1114       return "LANG_Java";
1115     case translation_unit::LANG_PL1:
1116       return "LANG_PL1";
1117     case translation_unit::LANG_UPC:
1118       return "LANG_UPC";
1119     case translation_unit::LANG_D:
1120       return "LANG_D";
1121     case translation_unit::LANG_Python:
1122       return "LANG_Python";
1123     case translation_unit::LANG_Go:
1124       return "LANG_Go";
1125     case translation_unit::LANG_Mips_Assembler:
1126       return "LANG_Mips_Assembler";
1127     default:
1128       return "LANG_UNKNOWN";
1129     }
1130 
1131   return "LANG_UNKNOWN";
1132 }
1133 
1134 /// Parse a string representing a language into a
1135 /// translation_unit::language enumerator into a string.
1136 ///
1137 /// @param l the string representing the language.
1138 ///
1139 /// @return the resulting translation_unit::language enumerator.
1140 translation_unit::language
string_to_translation_unit_language(const string & l)1141 string_to_translation_unit_language(const string& l)
1142 {
1143   if (l == "LANG_Cobol74")
1144     return translation_unit::LANG_Cobol74;
1145   else if (l == "LANG_Cobol85")
1146     return translation_unit::LANG_Cobol85;
1147   else if (l == "LANG_C89")
1148     return translation_unit::LANG_C89;
1149   else if (l == "LANG_C99")
1150     return translation_unit::LANG_C99;
1151   else if (l == "LANG_C11")
1152     return translation_unit::LANG_C11;
1153   else if (l == "LANG_C")
1154     return translation_unit::LANG_C;
1155   else if (l == "LANG_C_plus_plus_11")
1156     return translation_unit::LANG_C_plus_plus_11;
1157   else if (l == "LANG_C_plus_plus_14")
1158     return translation_unit::LANG_C_plus_plus_14;
1159   else if (l == "LANG_C_plus_plus")
1160     return translation_unit::LANG_C_plus_plus;
1161   else if (l == "LANG_ObjC")
1162     return translation_unit::LANG_ObjC;
1163   else if (l == "LANG_ObjC_plus_plus")
1164     return translation_unit::LANG_ObjC_plus_plus;
1165   else if (l == "LANG_Fortran77")
1166     return translation_unit::LANG_Fortran77;
1167   else if (l == "LANG_Fortran90")
1168     return translation_unit::LANG_Fortran90;
1169     else if (l == "LANG_Fortran95")
1170     return translation_unit::LANG_Fortran95;
1171   else if (l == "LANG_Ada83")
1172     return translation_unit::LANG_Ada83;
1173   else if (l == "LANG_Ada95")
1174     return translation_unit::LANG_Ada95;
1175   else if (l == "LANG_Pascal83")
1176     return translation_unit::LANG_Pascal83;
1177   else if (l == "LANG_Modula2")
1178     return translation_unit::LANG_Modula2;
1179   else if (l == "LANG_Java")
1180     return translation_unit::LANG_Java;
1181   else if (l == "LANG_PL1")
1182     return translation_unit::LANG_PL1;
1183   else if (l == "LANG_UPC")
1184     return translation_unit::LANG_UPC;
1185   else if (l == "LANG_D")
1186     return translation_unit::LANG_D;
1187   else if (l == "LANG_Python")
1188     return translation_unit::LANG_Python;
1189   else if (l == "LANG_Go")
1190     return translation_unit::LANG_Go;
1191   else if (l == "LANG_Mips_Assembler")
1192     return translation_unit::LANG_Mips_Assembler;
1193 
1194   return translation_unit::LANG_UNKNOWN;
1195 }
1196 
1197 /// Test if a language enumerator designates the C language.
1198 ///
1199 /// @param l the language enumerator to consider.
1200 ///
1201 /// @return true iff @p l designates the C language.
1202 bool
is_c_language(translation_unit::language l)1203 is_c_language(translation_unit::language l)
1204 {
1205   return (l == translation_unit::LANG_C89
1206 	  || l == translation_unit::LANG_C99
1207 	  || l == translation_unit::LANG_C11
1208 	  || l == translation_unit::LANG_C);
1209 }
1210 
1211 /// Test if a language enumerator designates the C++ language.
1212 ///
1213 /// @param l the language enumerator to consider.
1214 ///
1215 /// @return true iff @p l designates the C++ language.
1216 bool
is_cplus_plus_language(translation_unit::language l)1217 is_cplus_plus_language(translation_unit::language l)
1218 {
1219   return (l == translation_unit::LANG_C_plus_plus_03
1220 	  || l == translation_unit::LANG_C_plus_plus_11
1221 	  || l == translation_unit::LANG_C_plus_plus_14
1222 	  || l == translation_unit::LANG_C_plus_plus);
1223 }
1224 
1225 /// Test if a language enumerator designates the Java language.
1226 ///
1227 /// @param l the language enumerator to consider.
1228 ///
1229 /// @return true iff @p l designates the Java language.
1230 bool
is_java_language(translation_unit::language l)1231 is_java_language(translation_unit::language l)
1232 {return l == translation_unit::LANG_Java;}
1233 
1234 /// Test if a language enumerator designates the Ada language.
1235 ///
1236 /// @param l the language enumerator to consider.
1237 ///
1238 /// @return true iff @p l designates the Ada language.
1239 bool
is_ada_language(translation_unit::language l)1240 is_ada_language(translation_unit::language l)
1241 {
1242   return (l == translation_unit::LANG_Ada83
1243 	 || l == translation_unit::LANG_Ada95);
1244 }
1245 
1246 /// A deep comparison operator for pointers to translation units.
1247 ///
1248 /// @param l the first translation unit to consider for the comparison.
1249 ///
1250 /// @param r the second translation unit to consider for the comparison.
1251 ///
1252 /// @return true if the two translation units are equal, false otherwise.
1253 bool
operator ==(const translation_unit_sptr & l,const translation_unit_sptr & r)1254 operator==(const translation_unit_sptr& l, const translation_unit_sptr& r)
1255 {
1256   if (l.get() == r.get())
1257     return true;
1258 
1259   if (!!l != !!r)
1260     return false;
1261 
1262   return *l == *r;
1263 }
1264 
1265 /// A deep inequality operator for pointers to translation units.
1266 ///
1267 /// @param l the first translation unit to consider for the comparison.
1268 ///
1269 /// @param r the second translation unit to consider for the comparison.
1270 ///
1271 /// @return true iff the two translation units are different.
1272 bool
operator !=(const translation_unit_sptr & l,const translation_unit_sptr & r)1273 operator!=(const translation_unit_sptr& l, const translation_unit_sptr& r)
1274 {return !operator==(l, r);}
1275 
1276 // </translation_unit stuff>
1277 
1278 // <elf_symbol stuff>
1279 struct elf_symbol::priv
1280 {
1281   const environment*	env_;
1282   size_t		index_;
1283   size_t		size_;
1284   string		name_;
1285   elf_symbol::type	type_;
1286   elf_symbol::binding	binding_;
1287   elf_symbol::version	version_;
1288   elf_symbol::visibility visibility_;
1289   bool			is_defined_;
1290   // This flag below says if the symbol is a common elf symbol.  In
1291   // relocatable files, a common symbol is a symbol defined in a
1292   // section of kind SHN_COMMON.
1293   //
1294   // Note that a symbol of kind STT_COMMON is also considered a common
1295   // symbol.  Here is what the gABI says about STT_COMMON and
1296   // SHN_COMMON:
1297   //
1298   //     Symbols with type STT_COMMON label uninitialized common
1299   //     blocks. In relocatable objects, these symbols are not
1300   //     allocated and must have the special section index SHN_COMMON
1301   //     (see below). In shared objects and executables these symbols
1302   //     must be allocated to some section in the defining object.
1303   //
1304   //     In relocatable objects, symbols with type STT_COMMON are
1305   //     treated just as other symbols with index SHN_COMMON. If the
1306   //     link-editor allocates space for the SHN_COMMON symbol in an
1307   //     output section of the object it is producing, it must
1308   //     preserve the type of the output symbol as STT_COMMON.
1309   //
1310   //     When the dynamic linker encounters a reference to a symbol
1311   //     that resolves to a definition of type STT_COMMON, it may (but
1312   //     is not required to) change its symbol resolution rules as
1313   //     follows: instead of binding the reference to the first symbol
1314   //     found with the given name, the dynamic linker searches for
1315   //     the first symbol with that name with type other than
1316   //     STT_COMMON. If no such symbol is found, it looks for the
1317   //     STT_COMMON definition of that name that has the largest size.
1318   bool			is_common_;
1319   bool			is_linux_string_cst_;
1320   bool			is_in_ksymtab_;
1321   uint64_t		crc_;
1322   bool			is_suppressed_;
1323   elf_symbol_wptr	main_symbol_;
1324   elf_symbol_wptr	next_alias_;
1325   elf_symbol_wptr	next_common_instance_;
1326   string		id_string_;
1327 
privabigail::ir::elf_symbol::priv1328   priv()
1329     : env_(),
1330       index_(),
1331       size_(),
1332       type_(elf_symbol::NOTYPE_TYPE),
1333       binding_(elf_symbol::GLOBAL_BINDING),
1334       visibility_(elf_symbol::DEFAULT_VISIBILITY),
1335       is_defined_(false),
1336       is_common_(false),
1337       is_linux_string_cst_(false),
1338       is_in_ksymtab_(false),
1339       crc_(0),
1340       is_suppressed_(false)
1341   {}
1342 
privabigail::ir::elf_symbol::priv1343   priv(const environment*	  e,
1344        size_t			  i,
1345        size_t			  s,
1346        const string&		  n,
1347        elf_symbol::type		  t,
1348        elf_symbol::binding	  b,
1349        bool			  d,
1350        bool			  c,
1351        const elf_symbol::version& ve,
1352        elf_symbol::visibility	  vi,
1353        bool			  is_linux_string_cst,
1354        bool			  is_in_ksymtab,
1355        uint64_t			  crc,
1356        bool			  is_suppressed)
1357     : env_(e),
1358       index_(i),
1359       size_(s),
1360       name_(n),
1361       type_(t),
1362       binding_(b),
1363       version_(ve),
1364       visibility_(vi),
1365       is_defined_(d),
1366       is_common_(c),
1367       is_linux_string_cst_(is_linux_string_cst),
1368       is_in_ksymtab_(is_in_ksymtab),
1369       crc_(crc),
1370       is_suppressed_(is_suppressed)
1371   {
1372     if (!is_common_)
1373       is_common_ = type_ == COMMON_TYPE;
1374   }
1375 }; // end struct elf_symbol::priv
1376 
1377 /// Default constructor of the @ref elf_symbol type.
1378 ///
1379 /// Note that this constructor is private, so client code cannot use
1380 /// it to create instances of @ref elf_symbol.  Rather, client code
1381 /// should use the @ref elf_symbol::create() function to create
1382 /// instances of @ref elf_symbol instead.
elf_symbol()1383 elf_symbol::elf_symbol()
1384   : priv_(new priv)
1385 {}
1386 
1387 /// Constructor of the @ref elf_symbol type.
1388 ///
1389 /// Note that this constructor is private, so client code cannot use
1390 /// it to create instances of @ref elf_symbol.  Rather, client code
1391 /// should use the @ref elf_symbol::create() function to create
1392 /// instances of @ref elf_symbol instead.
1393 ///
1394 /// @param e the environment we are operating from.
1395 ///
1396 /// @param i the index of the symbol in the (ELF) symbol table.
1397 ///
1398 /// @param s the size of the symbol.
1399 ///
1400 /// @param n the name of the symbol.
1401 ///
1402 /// @param t the type of the symbol.
1403 ///
1404 /// @param b the binding of the symbol.
1405 ///
1406 /// @param d true if the symbol is defined, false otherwise.
1407 ///
1408 /// @param c true if the symbol is a common symbol, false otherwise.
1409 ///
1410 /// @param ve the version of the symbol.
1411 ///
1412 /// @param vi the visibility of the symbol.
1413 ///
1414 /// @param is_linux_string_cst true if the symbol is a Linux Kernel
1415 /// string constant defined in the __ksymtab_strings section.
1416 ///
1417 /// @param crc the CRC (modversions) value of Linux Kernel symbols
elf_symbol(const environment * e,size_t i,size_t s,const string & n,type t,binding b,bool d,bool c,const version & ve,visibility vi,bool is_linux_string_cst,bool is_in_ksymtab,uint64_t crc,bool is_suppressed)1418 elf_symbol::elf_symbol(const environment* e,
1419 		       size_t		  i,
1420 		       size_t		  s,
1421 		       const string&	  n,
1422 		       type		  t,
1423 		       binding		  b,
1424 		       bool		  d,
1425 		       bool		  c,
1426 		       const version&	  ve,
1427 		       visibility	  vi,
1428 		       bool		  is_linux_string_cst,
1429 		       bool		  is_in_ksymtab,
1430 		       uint64_t		  crc,
1431 		       bool		  is_suppressed)
1432   : priv_(new priv(e,
1433 		   i,
1434 		   s,
1435 		   n,
1436 		   t,
1437 		   b,
1438 		   d,
1439 		   c,
1440 		   ve,
1441 		   vi,
1442 		   is_linux_string_cst,
1443 		   is_in_ksymtab,
1444 		   crc,
1445 		   is_suppressed))
1446 {}
1447 
1448 /// Factory of instances of @ref elf_symbol.
1449 ///
1450 /// This is the function to use to create instances of @ref elf_symbol.
1451 ///
1452 /// @return a (smart) pointer to a newly created instance of @ref
1453 /// elf_symbol.
1454 elf_symbol_sptr
create()1455 elf_symbol::create()
1456 {
1457   elf_symbol_sptr e(new elf_symbol());
1458   e->priv_->main_symbol_ = e;
1459   return e;
1460 }
1461 
1462 /// Factory of instances of @ref elf_symbol.
1463 ///
1464 /// This is the function to use to create instances of @ref elf_symbol.
1465 ///
1466 /// @param e the environment we are operating from.
1467 ///
1468 /// @param i the index of the symbol in the (ELF) symbol table.
1469 ///
1470 /// @param s the size of the symbol.
1471 ///
1472 /// @param n the name of the symbol.
1473 ///
1474 /// @param t the type of the symbol.
1475 ///
1476 /// @param b the binding of the symbol.
1477 ///
1478 /// @param d true if the symbol is defined, false otherwise.
1479 ///
1480 /// @param c true if the symbol is a common symbol.
1481 ///
1482 /// @param ve the version of the symbol.
1483 ///
1484 /// @param vi the visibility of the symbol.
1485 ///
1486 /// @param is_linux_string_cst if true, it means the symbol represents
1487 /// a string constant from a linux kernel binary.
1488 ///
1489 /// @param crc the CRC (modversions) value of Linux Kernel symbols
1490 ///
1491 /// @return a (smart) pointer to a newly created instance of @ref
1492 /// elf_symbol.
1493 elf_symbol_sptr
create(const environment * e,size_t i,size_t s,const string & n,type t,binding b,bool d,bool c,const version & ve,visibility vi,bool is_linux_string_cst,bool is_in_ksymtab,uint64_t crc,bool is_suppressed)1494 elf_symbol::create(const environment* e,
1495 		   size_t	      i,
1496 		   size_t	      s,
1497 		   const string&      n,
1498 		   type		      t,
1499 		   binding	      b,
1500 		   bool		      d,
1501 		   bool		      c,
1502 		   const version&     ve,
1503 		   visibility	      vi,
1504 		   bool		      is_linux_string_cst,
1505 		   bool		      is_in_ksymtab,
1506 		   uint64_t	      crc,
1507 		   bool		      is_suppressed)
1508 {
1509   elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
1510 				     is_linux_string_cst,
1511 				     is_in_ksymtab, crc, is_suppressed));
1512   sym->priv_->main_symbol_ = sym;
1513   return sym;
1514 }
1515 
1516 /// Test textual equality between two symbols.
1517 ///
1518 /// Textual equality means that the aliases of the compared symbols
1519 /// are not taken into account.  Only the name, type, and version of
1520 /// the symbols are compared.
1521 ///
1522 /// @return true iff the two symbols are textually equal.
1523 static bool
textually_equals(const elf_symbol & l,const elf_symbol & r)1524 textually_equals(const elf_symbol&l,
1525 		 const elf_symbol&r)
1526 {
1527   bool equals = (l.get_name() == r.get_name()
1528 		 && l.get_type() == r.get_type()
1529 		 && l.is_public() == r.is_public()
1530 		 && l.is_defined() == r.is_defined()
1531 		 && l.is_common_symbol() == r.is_common_symbol()
1532 		 && l.get_version() == r.get_version()
1533 		 && (l.get_crc() == 0 || r.get_crc() == 0
1534 		     || l.get_crc() == r.get_crc()));
1535 
1536   if (equals && l.is_variable())
1537     // These are variable symbols.  Let's compare their symbol size.
1538     // The symbol size in this case is the size taken by the storage
1539     // of the variable.  If that size changes, then it's an ABI
1540     // change.
1541     equals = l.get_size() == r.get_size();
1542 
1543   return equals;
1544 }
1545 
1546 /// Getter of the environment used by the current instance of @ref
1547 /// elf_symbol.
1548 ///
1549 /// @return the enviroment used by the current instance of @ref elf_symbol.
1550 const environment*
get_environment() const1551 elf_symbol::get_environment() const
1552 {return priv_->env_;}
1553 
1554 /// Setter of the environment used by the current instance of @ref
1555 /// elf_symbol.
1556 ///
1557 /// @param The new enviroment used by the current instance of @ref
1558 /// elf_symbol.
1559 void
set_environment(const environment * e) const1560 elf_symbol::set_environment(const environment* e) const
1561 {priv_->env_ = e;}
1562 
1563 /// Getter for the index
1564 ///
1565 /// @return the index of the symbol.
1566 size_t
get_index() const1567 elf_symbol::get_index() const
1568 {return priv_->index_;}
1569 
1570 /// Setter for the index.
1571 ///
1572 /// @param s the new index.
1573 void
set_index(size_t s)1574 elf_symbol::set_index(size_t s)
1575 {priv_->index_ = s;}
1576 
1577 /// Test if the ELF symbol is for a string constant of a Linux binary
1578 /// defined in the __ksymtab_strings symbol table.
1579 ///
1580 /// @return true iff ELF symbol is for a string constant of a Linux
1581 /// binary defined in the __ksymtab_strings symbol table.
1582 bool
get_is_linux_string_cst() const1583 elf_symbol::get_is_linux_string_cst() const
1584 {return priv_->is_linux_string_cst_;}
1585 
1586 /// Getter for the name of the @ref elf_symbol.
1587 ///
1588 /// @return a reference to the name of the @ref symbol.
1589 const string&
get_name() const1590 elf_symbol::get_name() const
1591 {return priv_->name_;}
1592 
1593 /// Setter for the name of the current intance of @ref elf_symbol.
1594 ///
1595 /// @param n the new name.
1596 void
set_name(const string & n)1597 elf_symbol::set_name(const string& n)
1598 {
1599   priv_->name_ = n;
1600   priv_->id_string_.clear();
1601 }
1602 
1603 /// Getter for the type of the current instance of @ref elf_symbol.
1604 ///
1605 /// @return the type of the elf symbol.
1606 elf_symbol::type
get_type() const1607 elf_symbol::get_type() const
1608 {return priv_->type_;}
1609 
1610 /// Setter for the type of the current instance of @ref elf_symbol.
1611 ///
1612 /// @param t the new symbol type.
1613 void
set_type(type t)1614 elf_symbol::set_type(type t)
1615 {priv_->type_ = t;}
1616 
1617 /// Getter of the size of the symbol.
1618 ///
1619 /// @return the size of the symbol, in bytes.
1620 size_t
get_size() const1621 elf_symbol::get_size() const
1622 {return priv_->size_;}
1623 
1624 /// Setter of the size of the symbol.
1625 ///
1626 /// @param size the new size of the symbol, in bytes.
1627 void
set_size(size_t size)1628 elf_symbol::set_size(size_t size)
1629 {priv_->size_ = size;}
1630 
1631 /// Getter for the binding of the current instance of @ref elf_symbol.
1632 ///
1633 /// @return the binding of the symbol.
1634 elf_symbol::binding
get_binding() const1635 elf_symbol::get_binding() const
1636 {return priv_->binding_;}
1637 
1638 /// Setter for the binding of the current instance of @ref elf_symbol.
1639 ///
1640 /// @param b the new binding.
1641 void
set_binding(binding b)1642 elf_symbol::set_binding(binding b)
1643 {priv_->binding_ = b;}
1644 
1645 /// Getter for the version of the current instanc of @ref elf_symbol.
1646 ///
1647 /// @return the version of the elf symbol.
1648 elf_symbol::version&
get_version() const1649 elf_symbol::get_version() const
1650 {return priv_->version_;}
1651 
1652 /// Setter for the version of the current instance of @ref elf_symbol.
1653 ///
1654 /// @param v the new version of the elf symbol.
1655 void
set_version(const version & v)1656 elf_symbol::set_version(const version& v)
1657 {
1658   priv_->version_ = v;
1659   priv_->id_string_.clear();
1660 }
1661 
1662 /// Setter of the visibility of the current instance of @ref
1663 /// elf_symbol.
1664 ///
1665 /// @param v the new visibility of the elf symbol.
1666 void
set_visibility(visibility v)1667 elf_symbol::set_visibility(visibility v)
1668 {priv_->visibility_ = v;}
1669 
1670 /// Getter of the visibility of the current instance of @ref
1671 /// elf_symbol.
1672 ///
1673 /// @return the visibility of the elf symbol.
1674 elf_symbol::visibility
get_visibility() const1675 elf_symbol::get_visibility() const
1676 {return priv_->visibility_;}
1677 
1678 /// Test if the current instance of @ref elf_symbol is defined or not.
1679 ///
1680 /// @return true if the current instance of @ref elf_symbol is
1681 /// defined, false otherwise.
1682 bool
is_defined() const1683 elf_symbol::is_defined() const
1684 {return priv_->is_defined_;}
1685 
1686 /// Sets a flag saying if the current instance of @ref elf_symbol is
1687 /// defined
1688 ///
1689 /// @param b the new value of the flag.
1690 void
is_defined(bool d)1691 elf_symbol::is_defined(bool d)
1692 {priv_->is_defined_ = d;}
1693 
1694 /// Test if the current instance of @ref elf_symbol is public or not.
1695 ///
1696 /// This tests if the symbol is defined, has default or protected
1697 ///visibility, and either:
1698 ///		- has global binding
1699 ///		- has weak binding
1700 ///		- or has a GNU_UNIQUE binding.
1701 ///
1702 /// return true if the current instance of @ref elf_symbol is public,
1703 /// false otherwise.
1704 bool
is_public() const1705 elf_symbol::is_public() const
1706 {
1707   return (is_defined()
1708 	  && (get_binding() == GLOBAL_BINDING
1709 	      || get_binding() == WEAK_BINDING
1710 	      || get_binding() == GNU_UNIQUE_BINDING)
1711 	  && (get_visibility() == DEFAULT_VISIBILITY
1712 	      || get_visibility() == PROTECTED_VISIBILITY));
1713 }
1714 
1715 /// Test if the current instance of @ref elf_symbol is a function
1716 /// symbol or not.
1717 ///
1718 /// @return true if the current instance of @ref elf_symbol is a
1719 /// function symbol, false otherwise.
1720 bool
is_function() const1721 elf_symbol::is_function() const
1722 {return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
1723 
1724 /// Test if the current instance of @ref elf_symbol is a variable
1725 /// symbol or not.
1726 ///
1727 /// @return true if the current instance of @ref elf_symbol is a
1728 /// variable symbol, false otherwise.
1729 bool
is_variable() const1730 elf_symbol::is_variable() const
1731 {return get_type() == OBJECT_TYPE || get_type() == TLS_TYPE;}
1732 
1733 /// Getter of the 'is-in-ksymtab' property.
1734 ///
1735 /// @return true iff the current symbol is in the Linux Kernel
1736 /// specific 'ksymtab' symbol table.
1737 bool
is_in_ksymtab() const1738 elf_symbol::is_in_ksymtab() const
1739 {return priv_->is_in_ksymtab_;}
1740 
1741 /// Setter of the 'is-in-ksymtab' property.
1742 ///
1743 /// @param is_in_ksymtab this is true iff the current symbol is in the
1744 /// Linux Kernel specific 'ksymtab' symbol table.
1745 void
set_is_in_ksymtab(bool is_in_ksymtab)1746 elf_symbol::set_is_in_ksymtab(bool is_in_ksymtab)
1747 {priv_->is_in_ksymtab_ = is_in_ksymtab;}
1748 
1749 /// Getter of the 'crc' property.
1750 ///
1751 /// @return the CRC (modversions) value for Linux Kernel symbols (if present)
1752 uint64_t
get_crc() const1753 elf_symbol::get_crc() const
1754 {return priv_->crc_;}
1755 
1756 /// Setter of the 'crc' property.
1757 ///
1758 /// @param crc the new CRC (modversions) value for Linux Kernel symbols
1759 void
set_crc(uint64_t crc)1760 elf_symbol::set_crc(uint64_t crc)
1761 {priv_->crc_ = crc;}
1762 
1763 /// Getter for the 'is-suppressed' property.
1764 ///
1765 /// @return true iff the current symbol has been suppressed by a
1766 /// suppression specification that was provided in the context that
1767 /// led to the creation of the corpus this ELF symbol belongs to.
1768 bool
is_suppressed() const1769 elf_symbol::is_suppressed() const
1770 {return priv_->is_suppressed_;}
1771 
1772 /// Setter for the 'is-suppressed' property.
1773 ///
1774 /// @param true iff the current symbol has been suppressed by a
1775 /// suppression specification that was provided in the context that
1776 /// led to the creation of the corpus this ELF symbol belongs to.
1777 void
set_is_suppressed(bool is_suppressed)1778 elf_symbol::set_is_suppressed(bool is_suppressed)
1779 {priv_->is_suppressed_ = is_suppressed;}
1780 
1781 /// @name Elf symbol aliases
1782 ///
1783 /// An alias A for an elf symbol S is a symbol that is defined at the
1784 /// same address as S.  S is chained to A through the
1785 /// elf_symbol::get_next_alias() method.
1786 ///
1787 /// When there are several aliases to a symbol, the main symbol is the
1788 /// the first symbol found in the symbol table for a given address.
1789 ///
1790 /// The alias chain is circular.  That means if S is the main symbol
1791 /// and A is the alias, S is chained to A and A
1792 /// is chained back to the main symbol S.  The last alias in an alias
1793 ///chain is always chained to the main symbol.
1794 ///
1795 /// Thus, when looping over the aliases of an elf_symbol A, detecting
1796 /// an alias that is equal to the main symbol should logically be a
1797 /// loop exit condition.
1798 ///
1799 /// Accessing and adding aliases for instances of elf_symbol is done
1800 /// through the member functions below.
1801 
1802 /// @{
1803 
1804 /// Get the main symbol of an alias chain.
1805 ///
1806 ///@return the main symbol.
1807 const elf_symbol_sptr
get_main_symbol() const1808 elf_symbol::get_main_symbol() const
1809 {return priv_->main_symbol_.lock();}
1810 
1811 /// Get the main symbol of an alias chain.
1812 ///
1813 ///@return the main symbol.
1814 elf_symbol_sptr
get_main_symbol()1815 elf_symbol::get_main_symbol()
1816 {return priv_->main_symbol_.lock();}
1817 
1818 /// Tests whether this symbol is the main symbol.
1819 ///
1820 /// @return true iff this symbol is the main symbol.
1821 bool
is_main_symbol() const1822 elf_symbol::is_main_symbol() const
1823 {return get_main_symbol().get() == this;}
1824 
1825 /// Get the next alias of the current symbol.
1826 ///
1827 ///@return the alias, or NULL if there is no alias.
1828 elf_symbol_sptr
get_next_alias() const1829 elf_symbol::get_next_alias() const
1830 {return priv_->next_alias_.lock();}
1831 
1832 
1833 /// Check if the current elf_symbol has an alias.
1834 ///
1835 ///@return true iff the current elf_symbol has an alias.
1836 bool
has_aliases() const1837 elf_symbol::has_aliases() const
1838 {return bool(get_next_alias());}
1839 
1840 /// Get the number of aliases to this elf symbol
1841 ///
1842 /// @return the number of aliases to this elf symbol.
1843 int
get_number_of_aliases() const1844 elf_symbol::get_number_of_aliases() const
1845 {
1846   int result = 0;
1847 
1848   for (elf_symbol_sptr a = get_next_alias();
1849        a && a.get() != get_main_symbol().get();
1850        a = a->get_next_alias())
1851     ++result;
1852 
1853   return result;
1854 }
1855 
1856 /// Add an alias to the current elf symbol.
1857 ///
1858 /// @param alias the new alias.  Note that this elf_symbol should *NOT*
1859 /// have aliases prior to the invocation of this function.
1860 void
add_alias(const elf_symbol_sptr & alias)1861 elf_symbol::add_alias(const elf_symbol_sptr& alias)
1862 {
1863   if (!alias)
1864     return;
1865 
1866   ABG_ASSERT(!alias->has_aliases());
1867   ABG_ASSERT(is_main_symbol());
1868 
1869   if (has_aliases())
1870     {
1871       elf_symbol_sptr last_alias;
1872       for (elf_symbol_sptr a = get_next_alias();
1873 	   a && !a->is_main_symbol();
1874 	   a = a->get_next_alias())
1875 	{
1876 	  if (a->get_next_alias()->is_main_symbol())
1877 	    {
1878 	      ABG_ASSERT(last_alias == 0);
1879 	      last_alias = a;
1880 	    }
1881 	}
1882       ABG_ASSERT(last_alias);
1883 
1884       last_alias->priv_->next_alias_ = alias;
1885     }
1886   else
1887     priv_->next_alias_ = alias;
1888 
1889   alias->priv_->next_alias_ = get_main_symbol();
1890   alias->priv_->main_symbol_ = get_main_symbol();
1891 }
1892 
1893 /// Update the main symbol for a group of aliased symbols
1894 ///
1895 /// If after the construction of the symbols (in order of discovery), the
1896 /// actual main symbol can be identified (e.g. as the symbol that actually is
1897 /// defined in the code), this method offers a way of updating the main symbol
1898 /// through one of the aliased symbols.
1899 ///
1900 /// For that, locate the new main symbol by name and update all references to
1901 /// the main symbol among the group of aliased symbols.
1902 ///
1903 /// @param name the name of the main symbol
1904 ///
1905 /// @return the new main elf_symbol
1906 elf_symbol_sptr
update_main_symbol(const std::string & name)1907 elf_symbol::update_main_symbol(const std::string& name)
1908 {
1909   ABG_ASSERT(is_main_symbol());
1910   if (!has_aliases() || get_name() == name)
1911     return get_main_symbol();
1912 
1913   // find the new main symbol
1914   elf_symbol_sptr new_main;
1915   // we've already checked this; check the rest of the aliases
1916   for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
1917        a = a->get_next_alias())
1918     if (a->get_name() == name)
1919       {
1920 	new_main = a;
1921 	break;
1922       }
1923 
1924   if (!new_main)
1925     return get_main_symbol();
1926 
1927   // now update all main symbol references
1928   priv_->main_symbol_ = new_main;
1929   for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
1930        a = a->get_next_alias())
1931     a->priv_->main_symbol_ = new_main;
1932 
1933   return new_main;
1934 }
1935 
1936 /// Return true if the symbol is a common one.
1937 ///
1938 /// @return true iff the symbol is common.
1939 bool
is_common_symbol() const1940 elf_symbol::is_common_symbol() const
1941 {return priv_->is_common_;}
1942 
1943 /// Return true if this common common symbol has other common instances.
1944 ///
1945 /// A common instance of a given common symbol is another common
1946 /// symbol with the same name.  Those exist in relocatable files.  The
1947 /// linker normally allocates all the instances into a common block in
1948 /// the final output file.
1949 ///
1950 /// Note that the current object must be a common symbol, otherwise,
1951 /// this function aborts.
1952 ///
1953 /// @return true iff the current common symbol has other common
1954 /// instances.
1955 bool
has_other_common_instances() const1956 elf_symbol::has_other_common_instances() const
1957 {
1958   ABG_ASSERT(is_common_symbol());
1959   return bool(get_next_common_instance());
1960 }
1961 
1962 /// Get the next common instance of the current common symbol.
1963 ///
1964 /// A common instance of a given common symbol is another common
1965 /// symbol with the same name.  Those exist in relocatable files.  The
1966 /// linker normally allocates all the instances into a common block in
1967 /// the final output file.
1968 ///
1969 /// @return the next common instance, or nil if there is not any.
1970 elf_symbol_sptr
get_next_common_instance() const1971 elf_symbol::get_next_common_instance() const
1972 {return priv_->next_common_instance_.lock();}
1973 
1974 /// Add a common instance to the current common elf symbol.
1975 ///
1976 /// Note that this symbol must be the main symbol.  Being the main
1977 /// symbol means being the first common symbol to appear in the symbol
1978 /// table.
1979 ///
1980 /// @param common the other common instance to add.
1981 void
add_common_instance(const elf_symbol_sptr & common)1982 elf_symbol::add_common_instance(const elf_symbol_sptr& common)
1983 {
1984   if (!common)
1985     return;
1986 
1987   ABG_ASSERT(!common->has_other_common_instances());
1988   ABG_ASSERT(is_common_symbol());
1989   ABG_ASSERT(is_main_symbol());
1990 
1991   if (has_other_common_instances())
1992     {
1993       elf_symbol_sptr last_common_instance;
1994       for (elf_symbol_sptr c = get_next_common_instance();
1995 	   c && (c.get() != get_main_symbol().get());
1996 	   c = c->get_next_common_instance())
1997 	{
1998 	  if (c->get_next_common_instance().get() == get_main_symbol().get())
1999 	    {
2000 	      ABG_ASSERT(last_common_instance == 0);
2001 	      last_common_instance = c;
2002 	    }
2003 	}
2004       ABG_ASSERT(last_common_instance);
2005 
2006       last_common_instance->priv_->next_common_instance_ = common;
2007     }
2008   else
2009     priv_->next_common_instance_ = common;
2010 
2011   common->priv_->next_common_instance_ = get_main_symbol();
2012   common->priv_->main_symbol_ = get_main_symbol();
2013 }
2014 
2015 /// Get a string that is representative of a given elf_symbol.
2016 ///
2017 /// If the symbol has a version, then the ID string is the
2018 /// concatenation of the name of the symbol, the '@' character, and
2019 /// the version of the symbol.  If the version is the default version
2020 /// of the symbol then the '@' character is replaced by a "@@" string.
2021 ///
2022 /// Otherwise, if the symbol does not have any version, this function
2023 /// returns the name of the symbol.
2024 ///
2025 /// @return a the ID string.
2026 const string&
get_id_string() const2027 elf_symbol::get_id_string() const
2028 {
2029   if (priv_->id_string_.empty())
2030     {
2031       string s = get_name ();
2032 
2033       if (!get_version().is_empty())
2034 	{
2035 	  if (get_version().is_default())
2036 	    s += "@@";
2037 	  else
2038 	    s += "@";
2039 	  s += get_version().str();
2040 	}
2041       priv_->id_string_ = s;
2042     }
2043 
2044   return priv_->id_string_;
2045 }
2046 
2047 /// From the aliases of the current symbol, lookup one with a given name.
2048 ///
2049 /// @param name the name of symbol alias we are looking for.
2050 ///
2051 /// @return the symbol alias that has the name @p name, or nil if none
2052 /// has been found.
2053 elf_symbol_sptr
get_alias_from_name(const string & name) const2054 elf_symbol::get_alias_from_name(const string& name) const
2055 {
2056   if (name == get_name())
2057     return elf_symbol_sptr(priv_->main_symbol_);
2058 
2059    for (elf_symbol_sptr a = get_next_alias();
2060 	a && a.get() != get_main_symbol().get();
2061 	a = a->get_next_alias())
2062      if (a->get_name() == name)
2063        return a;
2064 
2065    return elf_symbol_sptr();
2066 }
2067 
2068 /// In the list of aliases of a given elf symbol, get the alias that
2069 /// equals this current symbol.
2070 ///
2071 /// @param other the elf symbol to get the potential aliases from.
2072 ///
2073 /// @return the alias of @p other that texually equals the current
2074 /// symbol, or nil if no alias textually equals the current symbol.
2075 elf_symbol_sptr
get_alias_which_equals(const elf_symbol & other) const2076 elf_symbol::get_alias_which_equals(const elf_symbol& other) const
2077 {
2078   for (elf_symbol_sptr a = other.get_next_alias();
2079        a && a.get() != a->get_main_symbol().get();
2080        a = a->get_next_alias())
2081     if (textually_equals(*this, *a))
2082       return a;
2083   return elf_symbol_sptr();
2084 }
2085 
2086 /// Return a comma separated list of the id of the current symbol as
2087 /// well as the id string of its aliases.
2088 ///
2089 /// @param syms a map of all the symbols of the corpus the current
2090 /// symbol belongs to.
2091 ///
2092 /// @param include_symbol_itself if set to true, then the name of the
2093 /// current symbol is included in the list of alias names that is emitted.
2094 ///
2095 /// @return the string.
2096 string
get_aliases_id_string(const string_elf_symbols_map_type & syms,bool include_symbol_itself) const2097 elf_symbol::get_aliases_id_string(const string_elf_symbols_map_type& syms,
2098 				  bool include_symbol_itself) const
2099 {
2100   string result;
2101 
2102   if (include_symbol_itself)
2103       result = get_id_string();
2104 
2105   vector<elf_symbol_sptr> aliases;
2106   compute_aliases_for_elf_symbol(*this, syms, aliases);
2107   if (!aliases.empty() && include_symbol_itself)
2108     result += ", ";
2109 
2110   for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2111        i != aliases.end();
2112        ++i)
2113     {
2114       if (i != aliases.begin())
2115 	result += ", ";
2116       result += (*i)->get_id_string();
2117     }
2118   return result;
2119 }
2120 
2121 /// Return a comma separated list of the id of the current symbol as
2122 /// well as the id string of its aliases.
2123 ///
2124 /// @param include_symbol_itself if set to true, then the name of the
2125 /// current symbol is included in the list of alias names that is emitted.
2126 ///
2127 /// @return the string.
2128 string
get_aliases_id_string(bool include_symbol_itself) const2129 elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2130 {
2131   vector<elf_symbol_sptr> aliases;
2132   if (include_symbol_itself)
2133     aliases.push_back(get_main_symbol());
2134 
2135   for (elf_symbol_sptr a = get_next_alias();
2136        a && a.get() != get_main_symbol().get();
2137        a = a->get_next_alias())
2138     aliases.push_back(a);
2139 
2140   string result;
2141   for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2142        i != aliases.end();
2143        ++i)
2144     {
2145       if (i != aliases.begin())
2146 	result += ", ";
2147       result += (*i)->get_id_string();
2148     }
2149 
2150   return result;
2151 }
2152 
2153 /// Given the ID of a symbol, get the name and the version of said
2154 /// symbol.
2155 ///
2156 /// @param id the symbol ID to consider.
2157 ///
2158 /// @param name the symbol name extracted from the ID.  This is set
2159 /// only if the function returned true.
2160 ///
2161 /// @param ver the symbol version extracted from the ID.
2162 bool
get_name_and_version_from_id(const string & id,string & name,string & ver)2163 elf_symbol::get_name_and_version_from_id(const string&	id,
2164 					 string&	name,
2165 					 string&	ver)
2166 {
2167   name.clear(), ver.clear();
2168 
2169   string::size_type i = id.find('@');
2170   if (i == string::npos)
2171     {
2172       name = id;
2173       return true;
2174     }
2175 
2176   name = id.substr(0, i);
2177   ++i;
2178 
2179   if (i >= id.size())
2180     return true;
2181 
2182   string::size_type j = id.find('@', i);
2183   if (j == string::npos)
2184     j = i;
2185   else
2186     ++j;
2187 
2188   if (j >= id.size())
2189     {
2190       ver = "";
2191       return true;
2192     }
2193 
2194   ver = id.substr(j);
2195   return true;
2196 }
2197 
2198 ///@}
2199 
2200 /// Test if two main symbols are textually equal, or, if they have
2201 /// aliases that are textually equal.
2202 ///
2203 /// @param other the symbol to compare against.
2204 ///
2205 /// @return true iff the current instance of elf symbol equals the @p
2206 /// other.
2207 bool
operator ==(const elf_symbol & other) const2208 elf_symbol::operator==(const elf_symbol& other) const
2209 {
2210   bool are_equal = textually_equals(*this, other);
2211   if (!are_equal)
2212     are_equal = bool(get_alias_which_equals(other));
2213   return are_equal;
2214 }
2215 
2216 /// Test if the current symbol aliases another one.
2217 ///
2218 /// @param o the other symbol to test against.
2219 ///
2220 /// @return true iff the current symbol aliases @p o.
2221 bool
does_alias(const elf_symbol & o) const2222 elf_symbol::does_alias(const elf_symbol& o) const
2223 {
2224   if (*this == o)
2225     return true;
2226 
2227   if (get_main_symbol() == o.get_main_symbol())
2228     return true;
2229 
2230   for (elf_symbol_sptr a = get_next_alias();
2231        a && !a->is_main_symbol();
2232        a = a->get_next_alias())
2233     {
2234       if (o == *a)
2235 	return true;
2236     }
2237   return false;
2238 }
2239 
2240 /// Equality operator for smart pointers to elf_symbol.
2241 ///
2242 /// @param lhs the first elf symbol to consider.
2243 ///
2244 /// @param rhs the second elf symbol to consider.
2245 ///
2246 /// @return true iff @p lhs equals @p rhs.
2247 bool
operator ==(const elf_symbol_sptr & lhs,const elf_symbol_sptr & rhs)2248 operator==(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
2249 {
2250   if (!!lhs != !!rhs)
2251     return false;
2252 
2253   if (!lhs)
2254     return true;
2255 
2256   return *lhs == *rhs;
2257 }
2258 
2259 /// Inequality operator for smart pointers to elf_symbol.
2260 ///
2261 /// @param lhs the first elf symbol to consider.
2262 ///
2263 /// @param rhs the second elf symbol to consider.
2264 ///
2265 /// @return true iff @p lhs is different from @p rhs.
2266 bool
operator !=(const elf_symbol_sptr & lhs,const elf_symbol_sptr & rhs)2267 operator!=(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
2268 {return !operator==(lhs, rhs);}
2269 
2270 /// Test if two symbols alias.
2271 ///
2272 /// @param s1 the first symbol to consider.
2273 ///
2274 /// @param s2 the second symbol to consider.
2275 ///
2276 /// @return true if @p s1 aliases @p s2.
2277 bool
elf_symbols_alias(const elf_symbol & s1,const elf_symbol & s2)2278 elf_symbols_alias(const elf_symbol& s1, const elf_symbol& s2)
2279 {return s1.does_alias(s2) || s2.does_alias(s1);}
2280 
2281 void
compute_aliases_for_elf_symbol(const elf_symbol & sym,const string_elf_symbols_map_type & symtab,vector<elf_symbol_sptr> & aliases)2282 compute_aliases_for_elf_symbol(const elf_symbol& sym,
2283 			       const string_elf_symbols_map_type& symtab,
2284 			       vector<elf_symbol_sptr>& aliases)
2285 {
2286 
2287   if (elf_symbol_sptr a = sym.get_next_alias())
2288     for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2289       aliases.push_back(a);
2290   else
2291     for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2292 	 i != symtab.end();
2293 	 ++i)
2294       for (elf_symbols::const_iterator j = i->second.begin();
2295 	   j != i->second.end();
2296 	   ++j)
2297 	{
2298 	  if (**j == sym)
2299 	    for (elf_symbol_sptr s = (*j)->get_next_alias();
2300 		 s && !s->is_main_symbol();
2301 		 s = s->get_next_alias())
2302 	      aliases.push_back(s);
2303 	  else
2304 	    for (elf_symbol_sptr s = (*j)->get_next_alias();
2305 		 s && !s->is_main_symbol();
2306 		 s = s->get_next_alias())
2307 	      if (*s == sym)
2308 		aliases.push_back(*j);
2309 	}
2310 }
2311 
2312 /// Test if two symbols alias.
2313 ///
2314 /// @param s1 the first symbol to consider.
2315 ///
2316 /// @param s2 the second symbol to consider.
2317 ///
2318 /// @return true if @p s1 aliases @p s2.
2319 bool
elf_symbols_alias(const elf_symbol * s1,const elf_symbol * s2)2320 elf_symbols_alias(const elf_symbol* s1, const elf_symbol* s2)
2321 {
2322   if (!!s1 != !!s2)
2323     return false;
2324   if (s1 == s2)
2325     return true;
2326   return elf_symbols_alias(*s1, *s2);
2327 }
2328 
2329 /// Test if two symbols alias.
2330 ///
2331 /// @param s1 the first symbol to consider.
2332 ///
2333 /// @param s2 the second symbol to consider.
2334 ///
2335 /// @return true if @p s1 aliases @p s2.
2336 bool
elf_symbols_alias(const elf_symbol_sptr s1,const elf_symbol_sptr s2)2337 elf_symbols_alias(const elf_symbol_sptr s1, const elf_symbol_sptr s2)
2338 {return elf_symbols_alias(s1.get(), s2.get());}
2339 
2340 /// Serialize an instance of @ref symbol_type and stream it to a given
2341 /// output stream.
2342 ///
2343 /// @param o the output stream to serialize the symbole type to.
2344 ///
2345 /// @param t the symbol type to serialize.
2346 std::ostream&
operator <<(std::ostream & o,elf_symbol::type t)2347 operator<<(std::ostream& o, elf_symbol::type t)
2348 {
2349   string repr;
2350 
2351   switch (t)
2352     {
2353     case elf_symbol::NOTYPE_TYPE:
2354       repr = "unspecified symbol type";
2355       break;
2356     case elf_symbol::OBJECT_TYPE:
2357       repr = "variable symbol type";
2358       break;
2359     case elf_symbol::FUNC_TYPE:
2360       repr = "function symbol type";
2361       break;
2362     case elf_symbol::SECTION_TYPE:
2363       repr = "section symbol type";
2364       break;
2365     case elf_symbol::FILE_TYPE:
2366       repr = "file symbol type";
2367       break;
2368     case elf_symbol::COMMON_TYPE:
2369       repr = "common data object symbol type";
2370       break;
2371     case elf_symbol::TLS_TYPE:
2372       repr = "thread local data object symbol type";
2373       break;
2374     case elf_symbol::GNU_IFUNC_TYPE:
2375       repr = "indirect function symbol type";
2376       break;
2377     default:
2378       {
2379 	std::ostringstream s;
2380 	s << "unknown symbol type (" << (char)t << ')';
2381 	repr = s.str();
2382       }
2383       break;
2384     }
2385 
2386   o << repr;
2387   return o;
2388 }
2389 
2390 /// Serialize an instance of @ref symbol_binding and stream it to a
2391 /// given output stream.
2392 ///
2393 /// @param o the output stream to serialize the symbole type to.
2394 ///
2395 /// @param b the symbol binding to serialize.
2396 std::ostream&
operator <<(std::ostream & o,elf_symbol::binding b)2397 operator<<(std::ostream& o, elf_symbol::binding b)
2398 {
2399   string repr;
2400 
2401   switch (b)
2402     {
2403     case elf_symbol::LOCAL_BINDING:
2404       repr = "local binding";
2405       break;
2406     case elf_symbol::GLOBAL_BINDING:
2407       repr = "global binding";
2408       break;
2409     case elf_symbol::WEAK_BINDING:
2410       repr = "weak binding";
2411       break;
2412     case elf_symbol::GNU_UNIQUE_BINDING:
2413       repr = "GNU unique binding";
2414       break;
2415     default:
2416       {
2417 	std::ostringstream s;
2418 	s << "unknown binding (" << (unsigned char) b << ")";
2419 	repr = s.str();
2420       }
2421       break;
2422     }
2423 
2424   o << repr;
2425   return o;
2426 }
2427 
2428 /// Serialize an instance of @ref elf_symbol::visibility and stream it
2429 /// to a given output stream.
2430 ///
2431 /// @param o the output stream to serialize the symbole type to.
2432 ///
2433 /// @param v the symbol visibility to serialize.
2434 std::ostream&
operator <<(std::ostream & o,elf_symbol::visibility v)2435 operator<<(std::ostream& o, elf_symbol::visibility v)
2436 {
2437   string repr;
2438 
2439   switch (v)
2440     {
2441     case elf_symbol::DEFAULT_VISIBILITY:
2442       repr = "default visibility";
2443       break;
2444     case elf_symbol::PROTECTED_VISIBILITY:
2445       repr = "protected visibility";
2446       break;
2447     case elf_symbol::HIDDEN_VISIBILITY:
2448       repr = "hidden visibility";
2449       break;
2450     case elf_symbol::INTERNAL_VISIBILITY:
2451       repr = "internal visibility";
2452       break;
2453     default:
2454       {
2455 	std::ostringstream s;
2456 	s << "unknown visibility (" << (unsigned char) v << ")";
2457 	repr = s.str();
2458       }
2459       break;
2460     }
2461 
2462   o << repr;
2463   return o;
2464 }
2465 
2466 /// Convert a string representing a symbol type into an
2467 /// elf_symbol::type.
2468 ///
2469 ///@param s the string to convert.
2470 ///
2471 ///@param t the resulting elf_symbol::type.
2472 ///
2473 /// @return true iff the conversion completed successfully.
2474 bool
string_to_elf_symbol_type(const string & s,elf_symbol::type & t)2475 string_to_elf_symbol_type(const string& s, elf_symbol::type& t)
2476 {
2477   if (s == "no-type")
2478     t = elf_symbol::NOTYPE_TYPE;
2479   else if (s == "object-type")
2480     t = elf_symbol::OBJECT_TYPE;
2481   else if (s == "func-type")
2482     t = elf_symbol::FUNC_TYPE;
2483   else if (s == "section-type")
2484     t = elf_symbol::SECTION_TYPE;
2485   else if (s == "file-type")
2486     t = elf_symbol::FILE_TYPE;
2487   else if (s == "common-type")
2488     t = elf_symbol::COMMON_TYPE;
2489   else if (s == "tls-type")
2490     t = elf_symbol::TLS_TYPE;
2491   else if (s == "gnu-ifunc-type")
2492     t = elf_symbol::GNU_IFUNC_TYPE;
2493   else
2494     return false;
2495 
2496   return true;
2497 }
2498 
2499 /// Convert a string representing a an elf symbol binding into an
2500 /// elf_symbol::binding.
2501 ///
2502 /// @param s the string to convert.
2503 ///
2504 /// @param b the resulting elf_symbol::binding.
2505 ///
2506 /// @return true iff the conversion completed successfully.
2507 bool
string_to_elf_symbol_binding(const string & s,elf_symbol::binding & b)2508 string_to_elf_symbol_binding(const string& s, elf_symbol::binding& b)
2509 {
2510     if (s == "local-binding")
2511       b = elf_symbol::LOCAL_BINDING;
2512     else if (s == "global-binding")
2513       b = elf_symbol::GLOBAL_BINDING;
2514     else if (s == "weak-binding")
2515       b = elf_symbol::WEAK_BINDING;
2516     else if (s == "gnu-unique-binding")
2517       b = elf_symbol::GNU_UNIQUE_BINDING;
2518     else
2519       return false;
2520 
2521     return true;
2522 }
2523 
2524 /// Convert a string representing a an elf symbol visibility into an
2525 /// elf_symbol::visibility.
2526 ///
2527 /// @param s the string to convert.
2528 ///
2529 /// @param b the resulting elf_symbol::visibility.
2530 ///
2531 /// @return true iff the conversion completed successfully.
2532 bool
string_to_elf_symbol_visibility(const string & s,elf_symbol::visibility & v)2533 string_to_elf_symbol_visibility(const string& s, elf_symbol::visibility& v)
2534 {
2535   if (s == "default-visibility")
2536     v = elf_symbol::DEFAULT_VISIBILITY;
2537   else if (s == "protected-visibility")
2538     v = elf_symbol::PROTECTED_VISIBILITY;
2539   else if (s == "hidden-visibility")
2540     v = elf_symbol::HIDDEN_VISIBILITY;
2541   else if (s == "internal-visibility")
2542     v = elf_symbol::INTERNAL_VISIBILITY;
2543   else
2544     return false;
2545 
2546   return true;
2547 }
2548 
2549 /// Test if the type of an ELF symbol denotes a function symbol.
2550 ///
2551 /// @param t the type of the ELF symbol.
2552 ///
2553 /// @return true iff elf symbol type @p t denotes a function symbol
2554 /// type.
2555 bool
elf_symbol_is_function(elf_symbol::type t)2556 elf_symbol_is_function(elf_symbol::type t)
2557 {return t == elf_symbol::FUNC_TYPE;}
2558 
2559 /// Test if the type of an ELF symbol denotes a function symbol.
2560 ///
2561 /// @param t the type of the ELF symbol.
2562 ///
2563 /// @return true iff elf symbol type @p t denotes a function symbol
2564 /// type.
2565 bool
elf_symbol_is_variable(elf_symbol::type t)2566 elf_symbol_is_variable(elf_symbol::type t)
2567 {return t == elf_symbol::OBJECT_TYPE;}
2568 
2569 // <elf_symbol::version stuff>
2570 
2571 struct elf_symbol::version::priv
2572 {
2573   string	version_;
2574   bool		is_default_;
2575 
privabigail::ir::elf_symbol::version::priv2576   priv()
2577     : is_default_(false)
2578   {}
2579 
privabigail::ir::elf_symbol::version::priv2580   priv(const string& v,
2581        bool d)
2582     : version_(v),
2583       is_default_(d)
2584   {}
2585 }; // end struct elf_symbol::version::priv
2586 
version()2587 elf_symbol::version::version()
2588   : priv_(new priv)
2589 {}
2590 
2591 /// @param v the name of the version.
2592 ///
2593 /// @param is_default true if this is a default version.
version(const string & v,bool is_default)2594 elf_symbol::version::version(const string& v,
2595 			     bool is_default)
2596   : priv_(new priv(v, is_default))
2597 {}
2598 
version(const elf_symbol::version & v)2599 elf_symbol::version::version(const elf_symbol::version& v)
2600   : priv_(new priv(v.str(), v.is_default()))
2601 {
2602 }
2603 
2604 /// Cast the version_type into a string that is its name.
2605 ///
2606 /// @return the name of the version.
operator const string&() const2607 elf_symbol::version::operator const string&() const
2608 {return priv_->version_;}
2609 
2610 /// Getter for the version name.
2611 ///
2612 /// @return the version name.
2613 const string&
str() const2614 elf_symbol::version::str() const
2615 {return priv_->version_;}
2616 
2617 /// Setter for the version name.
2618 ///
2619 /// @param s the version name.
2620 void
str(const string & s)2621 elf_symbol::version::str(const string& s)
2622 {priv_->version_ = s;}
2623 
2624 /// Getter for the 'is_default' property of the version.
2625 ///
2626 /// @return true iff this is a default version.
2627 bool
is_default() const2628 elf_symbol::version::is_default() const
2629 {return priv_->is_default_;}
2630 
2631 /// Setter for the 'is_default' property of the version.
2632 ///
2633 /// @param f true if this is the default version.
2634 void
is_default(bool f)2635 elf_symbol::version::is_default(bool f)
2636 {priv_->is_default_ = f;}
2637 
2638 bool
is_empty() const2639 elf_symbol::version::is_empty() const
2640 {return str().empty();}
2641 
2642 /// Compares the current version against another one.
2643 ///
2644 /// @param o the other version to compare the current one to.
2645 ///
2646 /// @return true iff the current version equals @p o.
2647 bool
operator ==(const elf_symbol::version & o) const2648 elf_symbol::version::operator==(const elf_symbol::version& o) const
2649 {return str() == o.str();}
2650 
2651 /// Inequality operator.
2652 ///
2653 /// @param o the version to compare against the current one.
2654 ///
2655 /// @return true iff both versions are different.
2656 bool
operator !=(const version & o) const2657 elf_symbol::version::operator!=(const version& o) const
2658 {return !operator==(o);}
2659 
2660 /// Assign a version to the current one.
2661 ///
2662 /// @param o the other version to assign to this one.
2663 ///
2664 /// @return a reference to the assigned version.
2665 elf_symbol::version&
operator =(const elf_symbol::version & o)2666 elf_symbol::version::operator=(const elf_symbol::version& o)
2667 {
2668   str(o.str());
2669   is_default(o.is_default());
2670   return *this;
2671 }
2672 
2673 // </elf_symbol::version stuff>
2674 
2675 // </elf_symbol stuff>
2676 
2677 // <class dm_context_rel stuff>
2678 struct dm_context_rel::priv
2679 {
2680   bool is_laid_out_;
2681   size_t offset_in_bits_;
2682   var_decl* anonymous_data_member_;
2683 
privabigail::ir::dm_context_rel::priv2684   priv(bool is_static = false)
2685     : is_laid_out_(!is_static),
2686       offset_in_bits_(0),
2687       anonymous_data_member_()
2688   {}
2689 
privabigail::ir::dm_context_rel::priv2690   priv(bool is_laid_out, size_t offset_in_bits)
2691     : is_laid_out_(is_laid_out),
2692       offset_in_bits_(offset_in_bits),
2693       anonymous_data_member_()
2694   {}
2695 }; //end struct dm_context_rel::priv
2696 
dm_context_rel()2697 dm_context_rel::dm_context_rel()
2698   : context_rel(),
2699     priv_(new priv)
2700 {}
2701 
dm_context_rel(scope_decl * s,bool is_laid_out,size_t offset_in_bits,access_specifier a,bool is_static)2702 dm_context_rel::dm_context_rel(scope_decl* s,
2703 			       bool is_laid_out,
2704 			       size_t offset_in_bits,
2705 			       access_specifier a,
2706 			       bool is_static)
2707   : context_rel(s, a, is_static),
2708     priv_(new priv(is_laid_out, offset_in_bits))
2709 {}
2710 
dm_context_rel(scope_decl * s)2711 dm_context_rel::dm_context_rel(scope_decl* s)
2712   : context_rel(s),
2713     priv_(new priv())
2714 {}
2715 
2716 bool
get_is_laid_out() const2717 dm_context_rel::get_is_laid_out() const
2718 {return priv_->is_laid_out_;}
2719 
2720 void
set_is_laid_out(bool f)2721 dm_context_rel::set_is_laid_out(bool f)
2722 {priv_->is_laid_out_ = f;}
2723 
2724 size_t
get_offset_in_bits() const2725 dm_context_rel::get_offset_in_bits() const
2726 {return priv_->offset_in_bits_;}
2727 
2728 void
set_offset_in_bits(size_t o)2729 dm_context_rel::set_offset_in_bits(size_t o)
2730 {priv_->offset_in_bits_ = o;}
2731 
2732 bool
operator ==(const dm_context_rel & o) const2733 dm_context_rel::operator==(const dm_context_rel& o) const
2734 {
2735   if (!context_rel::operator==(o))
2736     return false;
2737 
2738   return (priv_->is_laid_out_ == o.priv_->is_laid_out_
2739 	    && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
2740 }
2741 
2742 bool
operator !=(const dm_context_rel & o) const2743 dm_context_rel::operator!=(const dm_context_rel& o) const
2744 {return !operator==(o);}
2745 
2746 /// Return a non-nil value if this data member context relationship
2747 /// has an anonymous data member.  That means, if the data member this
2748 /// relation belongs to is part of an anonymous data member.
2749 ///
2750 /// @return the containing anonymous data member of this data member
2751 /// relationship.  Nil if there is none.
2752 const var_decl*
get_anonymous_data_member() const2753 dm_context_rel::get_anonymous_data_member() const
2754 {return priv_->anonymous_data_member_;}
2755 
2756 /// Set the containing anonymous data member of this data member
2757 /// context relationship. That means that the data member this
2758 /// relation belongs to is part of an anonymous data member.
2759 ///
2760 /// @param anon_dm the containing anonymous data member of this data
2761 /// member relationship.  Nil if there is none.
2762 void
set_anonymous_data_member(var_decl * anon_dm)2763 dm_context_rel::set_anonymous_data_member(var_decl* anon_dm)
2764 {priv_->anonymous_data_member_ = anon_dm;}
2765 
~dm_context_rel()2766 dm_context_rel::~dm_context_rel()
2767 {}
2768 // </class dm_context_rel stuff>
2769 
2770 // <environment stuff>
2771 
2772 /// Convenience typedef for a map of interned_string -> bool.
2773 typedef unordered_map<interned_string,
2774 		      bool, hash_interned_string> interned_string_bool_map_type;
2775 
2776 /// The private data of the @ref environment type.
2777 struct environment::priv
2778 {
2779   config			 config_;
2780   canonical_types_map_type	 canonical_types_;
2781   mutable vector<type_base_sptr> sorted_canonical_types_;
2782   type_base_sptr		 void_type_;
2783   type_base_sptr		 variadic_marker_type_;
2784   unordered_set<const class_or_union*>	classes_being_compared_;
2785   unordered_set<const function_type*>	fn_types_being_compared_;
2786   vector<type_base_sptr>	 extra_live_types_;
2787   interned_string_pool		 string_pool_;
2788   bool				 canonicalization_is_done_;
2789   bool				 do_on_the_fly_canonicalization_;
2790   bool				 decl_only_class_equals_definition_;
2791 
privabigail::ir::environment::priv2792   priv()
2793     : canonicalization_is_done_(),
2794       do_on_the_fly_canonicalization_(true),
2795       decl_only_class_equals_definition_(false)
2796   {}
2797 };// end struct environment::priv
2798 
2799 /// Default constructor of the @ref environment type.
environment()2800 environment::environment()
2801   :priv_(new priv)
2802 {}
2803 
2804 /// Destructor for the @ref environment type.
~environment()2805 environment::~environment()
2806 {}
2807 
2808 /// Getter the map of canonical types.
2809 ///
2810 /// @return the map of canonical types.  The key of the map is the
2811 /// hash of the canonical type and its value if the canonical type.
2812 environment::canonical_types_map_type&
get_canonical_types_map()2813 environment::get_canonical_types_map()
2814 {return priv_->canonical_types_;}
2815 
2816 /// Getter the map of canonical types.
2817 ///
2818 /// @return the map of canonical types.  The key of the map is the
2819 /// hash of the canonical type and its value if the canonical type.
2820 const environment::canonical_types_map_type&
get_canonical_types_map() const2821 environment::get_canonical_types_map() const
2822 {return const_cast<environment*>(this)->get_canonical_types_map();}
2823 
2824 /// Helper to detect if a type is either a reference, a pointer, or a
2825 /// qualified type.
2826 static bool
is_ptr_ref_or_qual_type(const type_base * t)2827 is_ptr_ref_or_qual_type(const type_base *t)
2828 {
2829   if (is_pointer_type(t)
2830       || is_reference_type(t)
2831       || is_qualified_type(t))
2832     return true;
2833   return false;
2834 }
2835 
2836 /// A functor to sort decls somewhat topologically.  That is, types
2837 /// are sorted in a way that makes the ones that are defined "first"
2838 /// to come first.
2839 ///
2840 /// The topological criteria is a lexicographic sort of the definition
2841 /// location of the type.  For types that have no location (or the
2842 /// same location), it's their qualified name that is used for the
2843 /// lexicographic sort.
2844 struct decl_topo_comp
2845 {
2846 
2847   /// The "Less Than" comparison operator of this functor.
2848   ///
2849   /// @param f the first decl to be considered for the comparison.
2850   ///
2851   /// @param s the second decl to be considered for the comparison.
2852   ///
2853   /// @return true iff @p f is less than @p s.
2854   bool
operator ()abigail::ir::decl_topo_comp2855   operator()(const decl_base *f,
2856 	     const decl_base *s)
2857   {
2858     if (!!f != !!s)
2859       return f && !s;
2860 
2861     if (!f)
2862       return false;
2863 
2864     location fl = f->get_location();
2865     location sl = s->get_location();
2866     if (fl.get_value() != sl.get_value())
2867       return fl.get_value() < sl.get_value();
2868 
2869     // We reach this point if location data is useless.
2870     return (get_pretty_representation(f, true)
2871 	    < get_pretty_representation(s, true));
2872   }
2873 
2874   /// The "Less Than" comparison operator of this functor.
2875   ///
2876   /// @param f the first decl to be considered for the comparison.
2877   ///
2878   /// @param s the second decl to be considered for the comparison.
2879   ///
2880   /// @return true iff @p f is less than @p s.
2881   bool
operator ()abigail::ir::decl_topo_comp2882   operator()(const decl_base_sptr &f,
2883 	     const decl_base_sptr &s)
2884   {return operator()(f.get(), s.get());}
2885 
2886 }; // end struct decl_topo_comp
2887 
2888 /// A functor to sort types somewhat topologically.  That is, types
2889 /// are sorted in a way that makes the ones that are defined "first"
2890 /// to come first.
2891 ///
2892 /// The topological criteria is a lexicographic sort of the definition
2893 /// location of the type.  For types that have no location, it's their
2894 /// qualified name that is used for the lexicographic sort.
2895 struct type_topo_comp
2896 {
2897   /// The "Less Than" comparison operator of this functor.
2898   ///
2899   /// @param f the first type to be considered for the comparison.
2900   ///
2901   /// @param s the second type to be considered for the comparison.
2902   ///
2903   /// @return true iff @p f is less than @p s.
2904   bool
operator ()abigail::ir::type_topo_comp2905   operator()(const type_base_sptr &f,
2906 	     const type_base_sptr &s)
2907   {return operator()(f.get(), s.get());}
2908 
2909   /// The "Less Than" comparison operator of this functor.
2910   ///
2911   /// @param f the first type to be considered for the comparison.
2912   ///
2913   /// @param s the second type to be considered for the comparison.
2914   ///
2915   /// @return true iff @p f is less than @p s.
2916   bool
operator ()abigail::ir::type_topo_comp2917   operator()(const type_base *f,
2918 	     const type_base *s)
2919   {
2920     bool f_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(f);
2921     bool s_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(s);
2922 
2923     if (f_is_ptr_ref_or_qual != s_is_ptr_ref_or_qual)
2924       return !f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual;
2925 
2926     if (f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual)
2927       {
2928 	string s1 = get_pretty_representation(f, true);
2929 	string s2 = get_pretty_representation(s, true);
2930 	if (s1 == s2)
2931 	  if (qualified_type_def * q = is_qualified_type(f))
2932 	    if (q->get_cv_quals() == qualified_type_def::CV_NONE)
2933 	      if (!is_qualified_type(s))
2934 		// We are looking at two types that are the result of
2935 		// an optimization that happens during the IR
2936 		// construction.  Namely, type f is a cv-qualified
2937 		// type with no qualifier (no const, no volatile, no
2938 		// nothing, we call it an empty-qualified type).
2939 		// These are the result of an optimization which
2940 		// removes "redundant qualifiers" from some types.
2941 		// For instance, consider a "const reference".  The
2942 		// const there is redundant because a reference is
2943 		// always const.  So as a result of the optimizaton
2944 		// that type is going to be transformed into an
2945 		// empty-qualified reference. If we don't make that
2946 		// optimization, then we risk having spurious change
2947 		// reports down the road.  But then, as a consequence
2948 		// of that optimization, we need to sort the
2949 		// empty-qualified type and its non-qualified variant
2950 		// e.g, to ensure stability in the abixml output; both
2951 		// types are logically equal, but here, we decide that
2952 		// the empty-qualified one is topologically "less
2953 		// than" the non-qualified counterpart.
2954 		//
2955 		// So here, type f is an empty-qualified type and type
2956 		// s is its non-qualified variant.  We decide that f
2957 		// is topologically less than s.
2958 		return true;
2959 	return (s1 < s2);
2960       }
2961 
2962     decl_base *fd = is_decl(f);
2963     decl_base *sd = is_decl(s);
2964 
2965     if (!!fd != !!sd)
2966       return fd && !sd;
2967 
2968     if (!fd)
2969       {
2970 	type_base *peeled_f = peel_pointer_or_reference_type(f);
2971 	type_base *peeled_s = peel_pointer_or_reference_type(s);
2972 
2973 	fd = is_decl(peeled_f);
2974 	sd = is_decl(peeled_s);
2975 
2976 	if (!!fd != !!sd)
2977 	  return fd && !sd;
2978 
2979 	if (!fd)
2980 	  return (get_pretty_representation(f, true)
2981 		  < get_pretty_representation(s, true));
2982       }
2983 
2984     // From this point, fd and sd should be non-nil
2985     decl_topo_comp decl_comp;
2986     return decl_comp(fd, sd);
2987   }
2988 }; //end struct type_topo_comp
2989 
2990 /// Get a @ref type_decl that represents a "void" type for the current
2991 /// environment.
2992 ///
2993 /// @return the @ref type_decl that represents a "void" type.
2994 const type_base_sptr&
get_void_type() const2995 environment::get_void_type() const
2996 {
2997   if (!priv_->void_type_)
2998     priv_->void_type_.reset(new type_decl(const_cast<environment*>(this),
2999 					  intern("void"),
3000 					  0, 0, location()));
3001   return priv_->void_type_;
3002 }
3003 
3004 /// Get a @ref type_decl instance that represents a the type of a
3005 /// variadic function parameter.
3006 ///
3007 /// @return the Get a @ref type_decl instance that represents a the
3008 /// type of a variadic function parameter.
3009 const type_base_sptr&
get_variadic_parameter_type() const3010 environment::get_variadic_parameter_type() const
3011 {
3012   if (!priv_->variadic_marker_type_)
3013     priv_->variadic_marker_type_.
3014       reset(new type_decl(const_cast<environment*>(this),
3015 			  intern("variadic parameter type"),
3016 			  0, 0, location()));
3017   return priv_->variadic_marker_type_;
3018 }
3019 
3020 /// Test if the canonicalization of types created out of the current
3021 /// environment is done.
3022 ///
3023 /// @return true iff the canonicalization of types created out of the current
3024 /// environment is done.
3025 bool
canonicalization_is_done() const3026 environment::canonicalization_is_done() const
3027 {return priv_->canonicalization_is_done_;}
3028 
3029 /// Set a flag saying if the canonicalization of types created out of
3030 /// the current environment is done or not.
3031 ///
3032 /// Note that this function must only be called by internal code of
3033 /// the library that creates ABI artifacts (e.g, read an abi corpus
3034 /// from elf or from our own xml format and creates representations of
3035 /// types out of it) and thus needs to canonicalize types to speed-up
3036 /// further type comparison.
3037 ///
3038 /// @param f the new value of the flag.
3039 void
canonicalization_is_done(bool f)3040 environment::canonicalization_is_done(bool f)
3041 {priv_->canonicalization_is_done_ = f;}
3042 
3043 /// Getter for the "on-the-fly-canonicalization" flag.
3044 ///
3045 /// @return true iff @ref OnTheFlyCanonicalization
3046 /// "on-the-fly-canonicalization" is to be performed during
3047 /// comparison.
3048 bool
do_on_the_fly_canonicalization() const3049 environment::do_on_the_fly_canonicalization() const
3050 {return priv_->do_on_the_fly_canonicalization_;}
3051 
3052 /// Setter for the "on-the-fly-canonicalization" flag.
3053 ///
3054 /// @param f If this is true then @ref OnTheFlyCanonicalization
3055 /// "on-the-fly-canonicalization" is to be performed during
3056 /// comparison.
3057 void
do_on_the_fly_canonicalization(bool f)3058 environment::do_on_the_fly_canonicalization(bool f)
3059 {priv_->do_on_the_fly_canonicalization_ = f;}
3060 
3061 /// Getter of the "decl-only-class-equals-definition" flag.
3062 ///
3063 /// Usually, a declaration-only class named 'struct foo' compares
3064 /// equal to any class definition named "struct foo'.  This is at
3065 /// least true for C++.
3066 ///
3067 /// In C, though, because there can be multiple definitions of 'struct
3068 /// foo' in the binary, a declaration-only "struct foo" might be
3069 /// considered to *NOT* resolve to any of the struct foo defined.  In
3070 /// that case, the declaration-only "struct foo" is considered
3071 /// different from the definitions.
3072 ///
3073 /// This flag controls the behaviour of the comparison of an
3074 /// unresolved decl-only class against a definition of the same name.
3075 ///
3076 /// If set to false, the the declaration equals the definition.  If
3077 /// set to false, then the decalration is considered different from
3078 /// the declaration.
3079 ///
3080 /// @return the value of the "decl-only-class-equals-definition" flag.
3081 bool
decl_only_class_equals_definition() const3082 environment::decl_only_class_equals_definition() const
3083 {return priv_->decl_only_class_equals_definition_;}
3084 
3085 /// Setter of the "decl-only-class-equals-definition" flag.
3086 ///
3087 /// Usually, a declaration-only class named 'struct foo' compares
3088 /// equal to any class definition named "struct foo'.  This is at
3089 /// least true for C++.
3090 ///
3091 /// In C, though, because there can be multiple definitions of 'struct
3092 /// foo' in the binary, a declaration-only "struct foo" might be
3093 /// considered to *NOT* resolve to any of the struct foo defined.  In
3094 /// that case, the declaration-only "struct foo" is considered
3095 /// different from the definitions.
3096 ///
3097 /// This flag controls the behaviour of the comparison of an
3098 /// unresolved decl-only class against a definition of the same name.
3099 ///
3100 /// If set to false, the the declaration equals the definition.  If
3101 /// set to false, then the decalration is considered different from
3102 /// the declaration.
3103 ///
3104 /// @param the new value of the "decl-only-class-equals-definition"
3105 /// flag.
3106 void
decl_only_class_equals_definition(bool f) const3107 environment::decl_only_class_equals_definition(bool f) const
3108 {priv_->decl_only_class_equals_definition_ = f;}
3109 
3110 /// Test if a given type is a void type as defined in the current
3111 /// environment.
3112 ///
3113 /// @param t the type to consider.
3114 ///
3115 /// @return true iff @p t is a void type as defined in the current
3116 /// environment.
3117 bool
is_void_type(const type_base_sptr & t) const3118 environment::is_void_type(const type_base_sptr& t) const
3119 {
3120   if (!t)
3121     return false;
3122   return t.get() == get_void_type().get();
3123 }
3124 
3125 /// Test if a given type is a void type as defined in the current
3126 /// environment.
3127 ///
3128 /// @param t the type to consider.
3129 ///
3130 /// @return true iff @p t is a void type as defined in the current
3131 /// environment.
3132 bool
is_void_type(const type_base * t) const3133 environment::is_void_type(const type_base* t) const
3134 {
3135   if (!t)
3136     return false;
3137   return t == get_void_type().get();
3138 }
3139 
3140 /// Test if a type is a variadic parameter type as defined in the
3141 /// current environment.
3142 ///
3143 /// @param t the type to consider.
3144 ///
3145 /// @return true iff @p t is a variadic parameter type as defined in
3146 /// the current environment.
3147 bool
is_variadic_parameter_type(const type_base * t) const3148 environment::is_variadic_parameter_type(const type_base* t) const
3149 {
3150   if (!t)
3151     return false;
3152   return t == get_variadic_parameter_type().get();
3153 }
3154 
3155 /// Test if a type is a variadic parameter type as defined in the
3156 /// current environment.
3157 ///
3158 /// @param t the type to consider.
3159 ///
3160 /// @return true iff @p t is a variadic parameter type as defined in
3161 /// the current environment.
3162 bool
is_variadic_parameter_type(const type_base_sptr & t) const3163 environment::is_variadic_parameter_type(const type_base_sptr& t) const
3164 {return is_variadic_parameter_type(t.get());}
3165 
3166 /// Do intern a string.
3167 ///
3168 /// If a value of this string already exists in the interned string
3169 /// pool of the current environment, then this function returns a new
3170 /// interned_string pointing to that already existing string.
3171 /// Otherwise, a new string is created, stored in the interned string
3172 /// pool and a new interned_string instance is created to point to
3173 /// that new intrerned string, and it's return.
3174 ///
3175 /// @param s the value of the string to intern.
3176 ///
3177 /// @return the interned string.
3178 interned_string
intern(const string & s) const3179 environment::intern(const string& s) const
3180 {return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3181 
3182 /// Getter of the general configuration object.
3183 ///
3184 /// @return the configuration object.
3185 const config&
get_config() const3186 environment::get_config() const
3187 {return priv_->config_;}
3188 
3189 // </environment stuff>
3190 
3191 // <type_or_decl_base stuff>
3192 
3193 /// The private data of @ref type_or_decl_base.
3194 struct type_or_decl_base::priv
3195 {
3196   // This holds the kind of dynamic type of particular instance.
3197   // Yes, this is part of the implementation of a "poor man" runtime
3198   // type identification.  We are doing this because profiling shows
3199   // that using dynamic_cast in some places is really to slow and is
3200   // constituting a hotspot.  This poor man's implementation made
3201   // things be much faster.
3202   enum type_or_decl_kind	kind_;
3203   // This holds the runtime type instance pointer of particular
3204   // instance.  In other words, this is the "this pointer" of the
3205   // dynamic type of a particular instance.
3206   void*			rtti_;
3207   // This holds a pointer to either the type_base sub-object (if the
3208   // current instance is a type) or the decl_base sub-object (if the
3209   // current instance is a decl).  This is used by the is_decl() and
3210   // is_type() functions, which also show up during profiling as
3211   // hotspots, due to their use of dynamic_cast.
3212   void*			type_or_decl_ptr_;
3213   bool				hashing_started_;
3214   const environment*		env_;
3215   translation_unit*		translation_unit_;
3216 
3217   /// Constructor of the type_or_decl_base::priv private type.
3218   ///
3219   /// @param e the environment in which the ABI artifact was created.
3220   ///
3221   /// @param k the identifier of the runtime type of the current
3222   /// instance of ABI artifact.
privabigail::ir::type_or_decl_base::priv3223   priv(const environment* e = 0,
3224        enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL)
3225     : kind_(k),
3226       rtti_(),
3227       type_or_decl_ptr_(),
3228       hashing_started_(),
3229       env_(e),
3230       translation_unit_()
3231   {}
3232 
3233   enum type_or_decl_kind
kindabigail::ir::type_or_decl_base::priv3234   kind() const
3235   {return kind_;}
3236 
3237   void
kindabigail::ir::type_or_decl_base::priv3238   kind (enum type_or_decl_kind k)
3239   {kind_ |= k;}
3240 }; // end struct type_or_decl_base::priv
3241 
3242 /// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
3243 /// bitmap type.
3244 type_or_decl_base::type_or_decl_kind
operator |(type_or_decl_base::type_or_decl_kind l,type_or_decl_base::type_or_decl_kind r)3245 operator|(type_or_decl_base::type_or_decl_kind l,
3246 	  type_or_decl_base::type_or_decl_kind r)
3247 {
3248   return static_cast<type_or_decl_base::type_or_decl_kind>
3249     (static_cast<unsigned>(l) | static_cast<unsigned>(r));
3250 }
3251 
3252 /// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
3253 /// bitmap type.
3254 type_or_decl_base::type_or_decl_kind&
operator |=(type_or_decl_base::type_or_decl_kind & l,type_or_decl_base::type_or_decl_kind r)3255 operator|=(type_or_decl_base::type_or_decl_kind& l,
3256 	   type_or_decl_base::type_or_decl_kind r)
3257 {
3258   l = l | r;
3259   return l;
3260 }
3261 
3262 /// bitwise "AND" operator for the
3263 /// type_or_decl_base::type_or_decl_kind bitmap type.
3264 type_or_decl_base::type_or_decl_kind
operator &(type_or_decl_base::type_or_decl_kind l,type_or_decl_base::type_or_decl_kind r)3265 operator&(type_or_decl_base::type_or_decl_kind l,
3266 	  type_or_decl_base::type_or_decl_kind r)
3267 {
3268   return static_cast<type_or_decl_base::type_or_decl_kind>
3269     (static_cast<unsigned>(l) & static_cast<unsigned>(r));
3270 }
3271 
3272 /// bitwise "A&=" operator for the
3273 /// type_or_decl_base::type_or_decl_kind bitmap type.
3274 type_or_decl_base::type_or_decl_kind&
operator &=(type_or_decl_base::type_or_decl_kind & l,type_or_decl_base::type_or_decl_kind r)3275 operator&=(type_or_decl_base::type_or_decl_kind& l,
3276 	  type_or_decl_base::type_or_decl_kind r)
3277 {
3278   l = l & r;
3279   return l;
3280 }
3281 
3282 /// Default constructor of @ref type_or_decl_base.
type_or_decl_base()3283 type_or_decl_base::type_or_decl_base()
3284   :priv_(new priv)
3285 {}
3286 
3287 /// Constructor of @ref type_or_decl_base.
3288 ///
3289 /// @param the environment the current ABI artifact is constructed
3290 /// from.
3291 ///
3292 /// @param k the runtime identifier bitmap of the type being built.
type_or_decl_base(const environment * e,enum type_or_decl_kind k)3293 type_or_decl_base::type_or_decl_base(const environment* e,
3294 				     enum type_or_decl_kind k)
3295   :priv_(new priv(e, k))
3296 {}
3297 
3298 /// Copy constructor of @ref type_or_decl_base.
type_or_decl_base(const type_or_decl_base & o)3299 type_or_decl_base::type_or_decl_base(const type_or_decl_base& o)
3300 {*priv_ = *o.priv_;}
3301 
3302 /// The destructor of the @ref type_or_decl_base type.
~type_or_decl_base()3303 type_or_decl_base::~type_or_decl_base()
3304 {}
3305 
3306 /// Getter for the "kind" property of @ref type_or_decl_base type.
3307 ///
3308 /// This property holds the identifier bitmap of the runtime type of
3309 /// an ABI artifact.
3310 ///
3311 /// @return the runtime type identifier bitmap of the current ABI
3312 /// artifact.
3313 enum type_or_decl_base::type_or_decl_kind
kind() const3314 type_or_decl_base::kind() const
3315 {return priv_->kind();}
3316 
3317 /// Setter for the "kind" property of @ref type_or_decl_base type.
3318 ///
3319 /// This property holds the identifier bitmap of the runtime type of
3320 /// an ABI artifact.
3321 ///
3322 /// @param the runtime type identifier bitmap of the current ABI
3323 /// artifact.
3324 void
kind(enum type_or_decl_kind k)3325 type_or_decl_base::kind(enum type_or_decl_kind k)
3326 {priv_->kind(k);}
3327 
3328 /// Getter of the pointer to the runtime type sub-object of the
3329 /// current instance.
3330 ///
3331 /// @return the pointer to the runtime type sub-object of the current
3332 /// instance.
3333 const void*
runtime_type_instance() const3334 type_or_decl_base::runtime_type_instance() const
3335 {return priv_->rtti_;}
3336 
3337 /// Getter of the pointer to the runtime type sub-object of the
3338 /// current instance.
3339 ///
3340 /// @return the pointer to the runtime type sub-object of the current
3341 /// instance.
3342 void*
runtime_type_instance()3343 type_or_decl_base::runtime_type_instance()
3344 {return priv_->rtti_;}
3345 
3346 /// Setter of the pointer to the runtime type sub-object of the
3347 /// current instance.
3348 ///
3349 /// @param i the new pointer to the runtime type sub-object of the
3350 /// current instance.
3351 void
runtime_type_instance(void * i)3352 type_or_decl_base::runtime_type_instance(void* i)
3353 {
3354   priv_->rtti_ = i;
3355   if (type_base* t = dynamic_cast<type_base*>(this))
3356     priv_->type_or_decl_ptr_ = t;
3357   else if (decl_base *d = dynamic_cast<decl_base*>(this))
3358     priv_->type_or_decl_ptr_ = d;
3359 }
3360 
3361 /// Getter of the pointer to either the type_base sub-object of the
3362 /// current instance if it's a type, or to the decl_base sub-object of
3363 /// the current instance if it's a decl.
3364 ///
3365 /// @return the pointer to either the type_base sub-object of the
3366 /// current instance if it's a type, or to the decl_base sub-object of
3367 /// the current instance if it's a decl.
3368 const void*
type_or_decl_base_pointer() const3369 type_or_decl_base::type_or_decl_base_pointer() const
3370 {return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
3371 
3372 /// Getter of the pointer to either the type_base sub-object of the
3373 /// current instance if it's a type, or to the decl_base sub-object of
3374 /// the current instance if it's a decl.
3375 ///
3376 /// @return the pointer to either the type_base sub-object of the
3377 /// current instance if it's a type, or to the decl_base sub-object of
3378 /// the current instance if it's a decl.
3379 void*
type_or_decl_base_pointer()3380 type_or_decl_base::type_or_decl_base_pointer()
3381 {return priv_->type_or_decl_ptr_;}
3382 
3383 /// Getter for the 'hashing_started' property.
3384 ///
3385 /// @return the 'hashing_started' property.
3386 bool
hashing_started() const3387 type_or_decl_base::hashing_started() const
3388 {return priv_->hashing_started_;}
3389 
3390 /// Setter for the 'hashing_started' property.
3391 ///
3392 /// @param b the value to set the 'hashing_property' to.
3393 void
hashing_started(bool b) const3394 type_or_decl_base::hashing_started(bool b) const
3395 {priv_->hashing_started_ = b;}
3396 
3397 /// Setter of the environment of the current ABI artifact.
3398 ///
3399 /// This just sets the environment artifact of the current ABI
3400 /// artifact, not on its sub-trees.  If you want to set the
3401 /// environment of an ABI artifact including its sub-tree, use the
3402 /// abigail::ir::set_environment_for_artifact() function.
3403 ///
3404 /// @param env the new environment.
3405 void
set_environment(const environment * env)3406 type_or_decl_base::set_environment(const environment* env)
3407 {priv_->env_ = env;}
3408 
3409 /// Getter of the environment of the current ABI artifact.
3410 ///
3411 /// @return the environment of the artifact.
3412 const environment*
get_environment() const3413 type_or_decl_base::get_environment() const
3414 {return priv_->env_;}
3415 
3416 /// Getter of the environment of the current ABI artifact.
3417 ///
3418 /// @return the environment of the artifact.
3419 environment*
get_environment()3420 type_or_decl_base::get_environment()
3421 {return const_cast<environment*>(priv_->env_);}
3422 
3423 /// Get the @ref corpus this ABI artifact belongs to.
3424 ///
3425 /// @return the corpus this ABI artifact belongs to, or nil if it
3426 /// belongs to none for now.
3427 corpus*
get_corpus()3428 type_or_decl_base::get_corpus()
3429 {
3430   translation_unit* tu = get_translation_unit();
3431   if (!tu)
3432     return 0;
3433   return tu->get_corpus();
3434 }
3435 
3436 
3437 /// Get the @ref corpus this ABI artifact belongs to.
3438 ///
3439 /// @return the corpus this ABI artifact belongs to, or nil if it
3440 /// belongs to none for now.
3441 const corpus*
get_corpus() const3442 type_or_decl_base::get_corpus() const
3443 {return const_cast<type_or_decl_base*>(this)->get_corpus();}
3444 
3445 /// Set the @ref translation_unit this ABI artifact belongs to.
3446 ///
3447 /// Note that adding an ABI artifact to a containining on should
3448 /// invoke this member function.
3449 void
set_translation_unit(translation_unit * tu)3450 type_or_decl_base::set_translation_unit(translation_unit* tu)
3451 {priv_->translation_unit_ = tu;}
3452 
3453 
3454 /// Get the @ref translation_unit this ABI artifact belongs to.
3455 ///
3456 /// @return the translation unit this ABI artifact belongs to, or nil
3457 /// if belongs to none for now.
3458 translation_unit*
get_translation_unit()3459 type_or_decl_base::get_translation_unit()
3460 {return priv_->translation_unit_;}
3461 
3462 /// Get the @ref translation_unit this ABI artifact belongs to.
3463 ///
3464 /// @return the translation unit this ABI artifact belongs to, or nil
3465 /// if belongs to none for now.
3466 const translation_unit*
get_translation_unit() const3467 type_or_decl_base::get_translation_unit() const
3468 {return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
3469 
3470 /// Assignment operator for @ref type_or_decl_base.
3471 ///
3472 /// @param o the other instance to assign the current instance to.
3473 ///
3474 /// return a reference to the assigned instance of @ref
3475 /// type_or_decl_base.
3476 type_or_decl_base&
operator =(const type_or_decl_base & o)3477 type_or_decl_base::operator=(const type_or_decl_base& o)
3478 {
3479   *priv_ = *o.priv_;
3480   return *this;
3481 }
3482 
3483 /// Traverse the the ABI artifact.
3484 ///
3485 /// @param v the visitor used to traverse the sub-tree nodes of the
3486 /// artifact.
3487 bool
traverse(ir_node_visitor &)3488 type_or_decl_base::traverse(ir_node_visitor&)
3489 {return true;}
3490 
3491 /// Set the environment of a given ABI artifact, including recursively
3492 /// setting the environment on the sub-trees of the artifact.
3493 ///
3494 /// @param artifact the artifact to set the environment for.
3495 ///
3496 /// @param env the new environment.
3497 void
set_environment_for_artifact(type_or_decl_base * artifact,const environment * env)3498 set_environment_for_artifact(type_or_decl_base* artifact,
3499 			     const environment* env)
3500 {
3501   ABG_ASSERT(artifact && env);
3502 
3503   ::environment_setter s(env);
3504   artifact->traverse(s);
3505 }
3506 
3507 /// Set the environment of a given ABI artifact, including recursively
3508 /// setting the environment on the sub-trees of the artifact.
3509 ///
3510 /// @param artifact the artifact to set the environment for.
3511 ///
3512 /// @param env the new environment.
3513 void
set_environment_for_artifact(type_or_decl_base_sptr artifact,const environment * env)3514 set_environment_for_artifact(type_or_decl_base_sptr artifact,
3515 			     const environment* env)
3516 {set_environment_for_artifact(artifact.get(), env);}
3517 
3518 /// Non-member equality operator for the @type_or_decl_base type.
3519 ///
3520 /// @param lr the left-hand operand of the equality.
3521 ///
3522 /// @param rr the right-hand operatnr of the equality.
3523 ///
3524 /// @return true iff @p lr equals @p rr.
3525 bool
operator ==(const type_or_decl_base & lr,const type_or_decl_base & rr)3526 operator==(const type_or_decl_base& lr, const type_or_decl_base& rr)
3527 {
3528   const type_or_decl_base* l = &lr;
3529   const type_or_decl_base* r = &rr;
3530 
3531   const decl_base* dl = dynamic_cast<const decl_base*>(l),
3532     *dr = dynamic_cast<const decl_base*>(r);
3533 
3534   if (!!dl != !!dr)
3535     return false;
3536 
3537   if (dl && dr)
3538     return *dl == *dr;
3539 
3540   const type_base* tl = dynamic_cast<const type_base*>(l),
3541     *tr = dynamic_cast<const type_base*>(r);
3542 
3543   if (!!tl != !!tr)
3544     return false;
3545 
3546   if (tl && tr)
3547     return *tl == *tr;
3548 
3549   return false;
3550 }
3551 
3552 /// Non-member equality operator for the @type_or_decl_base type.
3553 ///
3554 /// @param l the left-hand operand of the equality.
3555 ///
3556 /// @param r the right-hand operatnr of the equality.
3557 ///
3558 /// @return true iff @p l equals @p r.
3559 bool
operator ==(const type_or_decl_base_sptr & l,const type_or_decl_base_sptr & r)3560 operator==(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
3561 {
3562   if (!! l != !!r)
3563     return false;
3564 
3565   if (!l)
3566     return true;
3567 
3568   return *r == *l;
3569 }
3570 
3571 /// Non-member inequality operator for the @type_or_decl_base type.
3572 ///
3573 /// @param l the left-hand operand of the equality.
3574 ///
3575 /// @param r the right-hand operator of the equality.
3576 ///
3577 /// @return true iff @p l is different from @p r.
3578 bool
operator !=(const type_or_decl_base_sptr & l,const type_or_decl_base_sptr & r)3579 operator!=(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
3580 {return !operator==(l, r);}
3581 
3582 // </type_or_decl_base stuff>
3583 
3584 // <Decl definition>
3585 
3586 struct decl_base::priv
3587 {
3588   bool			in_pub_sym_tab_;
3589   bool			is_anonymous_;
3590   bool			is_artificial_;
3591   bool			has_anonymous_parent_;
3592   location		location_;
3593   context_rel		*context_;
3594   interned_string	name_;
3595   interned_string	qualified_parent_name_;
3596   // This temporary qualified name is the cache used for the qualified
3597   // name before the type associated to this decl (if applicable) is
3598   // canonicalized.  Once the type is canonicalized, the cached use is
3599   // the data member qualified_parent_name_ above.
3600   interned_string	temporary_qualified_name_;
3601   // This is the fully qualified name of the decl.  It contains the
3602   // name of the decl and the qualified name of its scope.  So if in
3603   // the parent scopes of the decl, there is one anonymous struct,
3604   // somewhere in the name, there is going to by an
3605   // __anonymous_struct__ string, even if the anonymous struct is not
3606   // the direct containing scope of this decl.
3607   interned_string	qualified_name_;
3608   // Unline qualified_name_, scoped_name_ contains the name of the
3609   // decl and the name of its scope; not the qualified name of the
3610   // scope.
3611     interned_string	scoped_name_;
3612   interned_string	linkage_name_;
3613   visibility		visibility_;
3614   decl_base_sptr	declaration_;
3615   decl_base_wptr	definition_of_declaration_;
3616   decl_base*		naked_definition_of_declaration_;
3617   bool			is_declaration_only_;
3618 
privabigail::ir::decl_base::priv3619   priv()
3620     : in_pub_sym_tab_(false),
3621       is_anonymous_(true),
3622       is_artificial_(false),
3623       has_anonymous_parent_(false),
3624       context_(),
3625       visibility_(VISIBILITY_DEFAULT),
3626       naked_definition_of_declaration_(),
3627       is_declaration_only_(false)
3628   {}
3629 
privabigail::ir::decl_base::priv3630   priv(interned_string name, const location& locus,
3631        interned_string linkage_name, visibility vis)
3632     : in_pub_sym_tab_(false),
3633       location_(locus),
3634       context_(),
3635       name_(name),
3636       qualified_name_(name),
3637       linkage_name_(linkage_name),
3638       visibility_(vis),
3639       naked_definition_of_declaration_(),
3640       is_declaration_only_(false)
3641   {
3642     is_anonymous_ = name_.empty();
3643     has_anonymous_parent_ = false;
3644   }
3645 
privabigail::ir::decl_base::priv3646   priv(const location& l)
3647     : in_pub_sym_tab_(false),
3648       is_anonymous_(true),
3649       has_anonymous_parent_(false),
3650       location_(l),
3651       context_(),
3652       visibility_(VISIBILITY_DEFAULT),
3653       naked_definition_of_declaration_(),
3654       is_declaration_only_(false)
3655   {}
3656 
~privabigail::ir::decl_base::priv3657   ~priv()
3658   {
3659     delete context_;
3660   }
3661 };// end struct decl_base::priv
3662 
3663 /// Constructor for the @ref decl_base type.
3664 ///
3665 /// @param e the environment the current @ref decl_base is being
3666 /// created in.
3667 ///
3668 /// @param name the name of the declaration.
3669 ///
3670 /// @param locus the location where to find the declaration in the
3671 /// source code.
3672 ///
3673 /// @param linkage_name the linkage name of the declaration.
3674 ///
3675 /// @param vis the visibility of the declaration.
decl_base(const environment * e,const string & name,const location & locus,const string & linkage_name,visibility vis)3676 decl_base::decl_base(const environment* e,
3677 		     const string&	name,
3678 		     const location&	locus,
3679 		     const string&	linkage_name,
3680 		     visibility	vis)
3681   : type_or_decl_base(e, ABSTRACT_DECL_BASE),
3682     priv_(new priv(e->intern(name), locus, e->intern(linkage_name), vis))
3683 {
3684 }
3685 
3686 /// Constructor.
3687 ///
3688 /// @param e the environment this instance of @ref decl_base is
3689 /// created in.
3690 ///
3691 /// @param name the name of the declaration being constructed.
3692 ///
3693 /// @param locus the source location of the declaration being constructed.
3694 ///
3695 /// @param linkage_name the linkage name of the declaration being
3696 /// constructed.
3697 ///
3698 /// @param vis the visibility of the declaration being constructed.
decl_base(const environment * e,const interned_string & name,const location & locus,const interned_string & linkage_name,visibility vis)3699 decl_base::decl_base(const environment* e,
3700 		     const interned_string& name,
3701 		     const location& locus,
3702 		     const interned_string& linkage_name,
3703 		     visibility vis)
3704   : type_or_decl_base(e, ABSTRACT_DECL_BASE),
3705     priv_(new priv(name, locus, linkage_name, vis))
3706 {}
3707 
3708 /// Constructor for the @ref decl_base type.
3709 ///
3710 ///@param environment the environment this instance of @ref decl_base
3711 /// is being constructed in.
3712 ///
3713 /// @param l the location where to find the declaration in the source
3714 /// code.
decl_base(const environment * e,const location & l)3715 decl_base::decl_base(const environment* e, const location& l)
3716   : type_or_decl_base(e, ABSTRACT_DECL_BASE),
3717     priv_(new priv(l))
3718 {}
3719 
decl_base(const decl_base & d)3720 decl_base::decl_base(const decl_base& d)
3721   : type_or_decl_base(d)
3722 {
3723   priv_->in_pub_sym_tab_ = d.priv_->in_pub_sym_tab_;
3724   priv_->location_ = d.priv_->location_;
3725   priv_->name_ = d.priv_->name_;
3726   priv_->qualified_parent_name_ = d.priv_->qualified_parent_name_;
3727   priv_->qualified_name_ = d.priv_->qualified_name_;
3728   priv_->linkage_name_ = d.priv_->linkage_name_;
3729   priv_->context_ = d.priv_->context_;
3730   priv_->visibility_ = d.priv_->visibility_;
3731 }
3732 
3733 /// Getter for the qualified name.
3734 ///
3735 /// Unlike decl_base::get_qualified_name() this doesn't try to update
3736 /// the qualified name.
3737 ///
3738 /// @return the qualified name.
3739 const interned_string&
peek_qualified_name() const3740 decl_base::peek_qualified_name() const
3741 {return priv_->qualified_name_;}
3742 
3743 /// Clear the qualified name of this decl.
3744 ///
3745 /// This is useful to ensure that the cache for the qualified name of
3746 /// the decl is refreshed right after type canonicalization, for
3747 /// instance.
3748 void
clear_qualified_name()3749 decl_base::clear_qualified_name()
3750 {priv_->qualified_name_.clear();}
3751 
3752 /// Setter for the qualified name.
3753 ///
3754 /// @param n the new qualified name.
3755 void
set_qualified_name(const interned_string & n) const3756 decl_base::set_qualified_name(const interned_string& n) const
3757 {priv_->qualified_name_ = n;}
3758 
3759 /// Getter of the temporary qualified name of the current declaration.
3760 ///
3761 /// This temporary qualified name is used as a qualified name cache by
3762 /// the type for which this is the declaration (when applicable)
3763 /// before the type is canonicalized.  Once the type is canonicalized,
3764 /// it's the result of decl_base::peek_qualified_name() that becomes
3765 /// the qualified name cached.
3766 ///
3767 /// @return the temporary qualified name.
3768 const interned_string&
peek_temporary_qualified_name() const3769 decl_base::peek_temporary_qualified_name() const
3770 {return priv_->temporary_qualified_name_;}
3771 
3772 /// Setter for the temporary qualified name of the current
3773 /// declaration.
3774 ///
3775 ///@param n the new temporary qualified name.
3776 ///
3777 /// This temporary qualified name is used as a qualified name cache by
3778 /// the type for which this is the declaration (when applicable)
3779 /// before the type is canonicalized.  Once the type is canonicalized,
3780 /// it's the result of decl_base::peek_qualified_name() that becomes
3781 /// the qualified name cached.
3782 void
set_temporary_qualified_name(const interned_string & n) const3783 decl_base::set_temporary_qualified_name(const interned_string& n) const
3784 {priv_->temporary_qualified_name_ = n;}
3785 
3786 ///Getter for the context relationship.
3787 ///
3788 ///@return the context relationship for the current decl_base.
3789 const context_rel*
get_context_rel() const3790 decl_base::get_context_rel() const
3791 {return priv_->context_;}
3792 
3793 ///Getter for the context relationship.
3794 ///
3795 ///@return the context relationship for the current decl_base.
3796 context_rel*
get_context_rel()3797 decl_base::get_context_rel()
3798 {return priv_->context_;}
3799 
3800 void
set_context_rel(context_rel * c)3801 decl_base::set_context_rel(context_rel *c)
3802 {priv_->context_ = c;}
3803 
3804 /// Get the hash of a decl.  If the hash hasn't been computed yet,
3805 /// compute it ans store its value; otherwise, just return the hash.
3806 ///
3807 /// @return the hash of the decl.
3808 size_t
get_hash() const3809 decl_base::get_hash() const
3810 {
3811   size_t result = 0;
3812 
3813   if (const type_base* t = dynamic_cast<const type_base*>(this))
3814     {
3815       type_base::dynamic_hash hash;
3816       result = hash(t);
3817     }
3818   else
3819     // If we reach this point, it mean we are missing a virtual
3820     // overload for decl_base::get_hash.  Add it!
3821     abort();
3822 
3823   return result;
3824 }
3825 
3826 /// Test if the decl is defined in a ELF symbol table as a public
3827 /// symbol.
3828 ///
3829 /// @return true iff the decl is defined in a ELF symbol table as a
3830 /// public symbol.
3831 bool
get_is_in_public_symbol_table() const3832 decl_base::get_is_in_public_symbol_table() const
3833 {return priv_->in_pub_sym_tab_;}
3834 
3835 /// Set the flag saying if this decl is from a symbol that is in
3836 /// a public symbols table, defined as public (global or weak).
3837 ///
3838 /// @param f the new flag value.
3839 void
set_is_in_public_symbol_table(bool f)3840 decl_base::set_is_in_public_symbol_table(bool f)
3841 {priv_->in_pub_sym_tab_ = f;}
3842 
3843 /// Get the location of a given declaration.
3844 ///
3845 /// The location is an abstraction for the tripplet {file path,
3846 /// line, column} that defines where the declaration appeared in the
3847 /// source code.
3848 ///
3849 /// To get the value of the tripplet {file path, line, column} from
3850 /// the @ref location, you need to use the
3851 /// location_manager::expand_location() method.
3852 ///
3853 /// The instance of @ref location_manager that you want is
3854 /// accessible from the instance of @ref translation_unit that the
3855 /// current instance of @ref decl_base belongs to, via a call to
3856 /// translation_unit::get_loc_mgr().
3857 ///
3858 /// @return the location of the current instance of @ref decl_base.
3859 const location&
get_location() const3860 decl_base::get_location() const
3861 {return priv_->location_;}
3862 
3863 /// Set the location for a given declaration.
3864 ///
3865 /// The location is an abstraction for the tripplet {file path,
3866 /// line, column} that defines where the declaration appeared in the
3867 /// source code.
3868 ///
3869 /// To create a location from a tripplet {file path, line, column},
3870 /// you need to use the method @ref
3871 /// location_manager::create_new_location().
3872 ///
3873 /// The instance of @ref location_manager that you want is
3874 /// accessible from the instance of @ref translation_unit that the
3875 /// current instance of @ref decl_base belongs to, via a call to
3876 /// translation_unit::get_loc_mgr().
3877 void
set_location(const location & l)3878 decl_base::set_location(const location& l)
3879 {priv_->location_ = l;}
3880 
3881 /// Setter for the name of the decl.
3882 ///
3883 /// @param n the new name to set.
3884 void
set_name(const string & n)3885 decl_base::set_name(const string& n)
3886 {
3887   priv_->name_ = get_environment()->intern(n);
3888   priv_->is_anonymous_ = n.empty();
3889 }
3890 
3891 /// Test if the current declaration is anonymous.
3892 ///
3893 /// Being anonymous means that the declaration was created without a
3894 /// name.  This can usually happen for enum or struct types.
3895 ///
3896 /// @return true iff the type is anonymous.
3897 bool
get_is_anonymous() const3898 decl_base::get_is_anonymous() const
3899 {return priv_->is_anonymous_;}
3900 
3901 /// Set the "is_anonymous" flag of the current declaration.
3902 ///
3903 /// Being anonymous means that the declaration was created without a
3904 /// name.  This can usually happen for enum or struct types.
3905 ///
3906 /// @param f the new value of the flag.
3907 void
set_is_anonymous(bool f)3908 decl_base::set_is_anonymous(bool f)
3909 {priv_->is_anonymous_ = f;}
3910 
3911 /// Getter of the flag that says if the declaration is artificial.
3912 ///
3913 /// Being artificial means the parameter was not explicitely
3914 /// mentionned in the source code, but was rather artificially created
3915 /// by the compiler.
3916 ///
3917 /// @return true iff the declaration is artificial.
3918 bool
get_is_artificial() const3919 decl_base::get_is_artificial() const
3920 {return priv_->is_artificial_;}
3921 
3922 /// Setter of the flag that says if the declaration is artificial.
3923 ///
3924 /// Being artificial means the parameter was not explicitely
3925 /// mentionned in the source code, but was rather artificially created
3926 /// by the compiler.
3927 ///
3928 /// @param f the new value of the flag that says if the declaration is
3929 /// artificial.
3930 void
set_is_artificial(bool f)3931 decl_base::set_is_artificial(bool f)
3932 {priv_->is_artificial_ = f;}
3933 
3934 /// Get the "has_anonymous_parent" flag of the current declaration.
3935 ///
3936 /// Having an anoymous parent means having a anonymous parent scope
3937 /// (containing type or namespace) which is either direct or indirect.
3938 ///
3939 /// @return true iff the current decl has a direct or indirect scope
3940 /// which is anonymous.
3941 bool
get_has_anonymous_parent() const3942 decl_base::get_has_anonymous_parent() const
3943 {return priv_->has_anonymous_parent_;}
3944 
3945 /// Set the "has_anonymous_parent" flag of the current declaration.
3946 ///
3947 /// Having an anonymous parent means having a anonymous parent scope
3948 /// (containing type or namespace) which is either direct or indirect.
3949 ///
3950 /// @param f set the flag which says if the current decl has a direct
3951 /// or indirect scope which is anonymous.
3952 void
set_has_anonymous_parent(bool f) const3953 decl_base::set_has_anonymous_parent(bool f) const
3954 {priv_->has_anonymous_parent_ = f;}
3955 
3956 /// @return the logical "OR" of decl_base::get_is_anonymous() and
3957 /// decl_base::get_has_anonymous_parent().
3958 bool
get_is_anonymous_or_has_anonymous_parent() const3959 decl_base::get_is_anonymous_or_has_anonymous_parent() const
3960 {return get_is_anonymous() || get_has_anonymous_parent();}
3961 
3962 /// Getter for the mangled name.
3963 ///
3964 /// @return the new mangled name.
3965 const interned_string&
get_linkage_name() const3966 decl_base::get_linkage_name() const
3967 {return priv_->linkage_name_;}
3968 
3969 /// Setter for the linkage name.
3970 ///
3971 /// @param m the new linkage name.
3972 void
set_linkage_name(const string & m)3973 decl_base::set_linkage_name(const string& m)
3974 {
3975   const environment* env = get_environment();
3976   ABG_ASSERT(env);
3977   priv_->linkage_name_ = env->intern(m);
3978 }
3979 
3980 /// Getter for the visibility of the decl.
3981 ///
3982 /// @return the new visibility.
3983 decl_base::visibility
get_visibility() const3984 decl_base::get_visibility() const
3985 {return priv_->visibility_;}
3986 
3987 /// Setter for the visibility of the decl.
3988 ///
3989 /// @param v the new visibility.
3990 void
set_visibility(visibility v)3991 decl_base::set_visibility(visibility v)
3992 {priv_->visibility_ = v;}
3993 
3994 /// Return the type containing the current decl, if any.
3995 ///
3996 /// @return the type that contains the current decl, or NULL if there
3997 /// is none.
3998 scope_decl*
get_scope() const3999 decl_base::get_scope() const
4000 {
4001   if (priv_->context_)
4002     return priv_->context_->get_scope();
4003   return 0;
4004 }
4005 
4006 /// Return a copy of the qualified name of the parent of the current
4007 /// decl.
4008 ///
4009 /// @return the newly-built qualified name of the of the current decl.
4010 const interned_string&
get_qualified_parent_name() const4011 decl_base::get_qualified_parent_name() const
4012 {return priv_->qualified_parent_name_;}
4013 
4014 /// Getter for the name of the current decl.
4015 ///
4016 /// @return the name of the current decl.
4017 const interned_string&
get_name() const4018 decl_base::get_name() const
4019 {return priv_->name_;}
4020 
4021 /// Compute the qualified name of the decl.
4022 ///
4023 /// @param qn the resulting qualified name.
4024 ///
4025 /// @param internal set to true if the call is intended for an
4026 /// internal use (for technical use inside the library itself), false
4027 /// otherwise.  If you don't know what this is for, then set it to
4028 /// false.
4029 void
get_qualified_name(interned_string & qn,bool internal) const4030 decl_base::get_qualified_name(interned_string& qn, bool internal) const
4031 {qn = get_qualified_name(internal);}
4032 
4033 /// Get the pretty representatin of the current declaration.
4034 ///
4035 ///
4036 /// @param internal set to true if the call is intended for an
4037 /// internal use (for technical use inside the library itself), false
4038 /// otherwise.  If you don't know what this is for, then set it to
4039 /// false.
4040 ///
4041 /// @param qualified_name if true, names emitted in the pretty
4042 /// representation are fully qualified.
4043 ///
4044 /// @return the default pretty representation for a decl.  This is
4045 /// basically the fully qualified name of the decl optionally prefixed
4046 /// with a meaningful string to add context for the user.
4047 string
get_pretty_representation(bool internal,bool qualified_name) const4048 decl_base::get_pretty_representation(bool internal,
4049 				     bool qualified_name) const
4050 {
4051   if (internal
4052       && get_is_anonymous()
4053       && has_generic_anonymous_internal_type_name(this))
4054     {
4055       // We are looking at an anonymous enum, union or class and we
4056       // want an *internal* pretty representation for it.  All
4057       // anonymous types of this kind in the same namespace must have
4058       // the same internal representation for type canonicalization to
4059       // work properly.
4060       //
4061       // OK, in practise, we are certainly looking at an enum because
4062       // classes and unions should have their own overloaded virtual
4063       // member function for this.
4064       string name = get_generic_anonymous_internal_type_name(this);
4065       if (qualified_name && !get_qualified_parent_name().empty())
4066 	name = get_qualified_parent_name() + "::" + name;
4067       return name;
4068     }
4069 
4070   if (qualified_name)
4071     return get_qualified_name(internal);
4072   return get_name();
4073 }
4074 
4075 /// Return the qualified name of the decl.
4076 ///
4077 /// This is the fully qualified name of the decl.  It's made of the
4078 /// concatenation of the name of the decl with the qualified name of
4079 /// its scope.
4080 ///
4081 /// Note that the value returned by this function is computed by @ref
4082 /// update_qualified_name when the decl is added to its scope.
4083 ///
4084 /// @param internal set to true if the call is intended for an
4085 /// internal use (for technical use inside the library itself), false
4086 /// otherwise.  If you don't know what this is for, then set it to
4087 /// false.
4088 ///
4089 /// @return the resulting qualified name.
4090 const interned_string&
get_qualified_name(bool) const4091 decl_base::get_qualified_name(bool /*internal*/) const
4092 {return priv_->qualified_name_;}
4093 
4094 /// Return the scoped name of the decl.
4095 ///
4096 /// This is made of the concatenation of the name of the decl with the
4097 /// name of its scope.  It doesn't contain the qualified name of its
4098 /// scope, unlike what is returned by decl_base::get_qualified_name.
4099 ///
4100 /// Note that the value returned by this function is computed by @ref
4101 /// update_qualified_name when the decl is added to its scope.
4102 ///
4103 /// @return the scoped name of the decl.
4104 const interned_string&
get_scoped_name() const4105 decl_base::get_scoped_name() const
4106 {return priv_->scoped_name_;}
4107 
4108 /// If this @ref decl_base is a definition, get its earlier
4109 /// declaration.
4110 ///
4111 /// @return the earlier declaration of the class, if any.
4112 const decl_base_sptr
get_earlier_declaration() const4113 decl_base::get_earlier_declaration() const
4114 {return priv_->declaration_;}
4115 
4116 /// set the earlier declaration of this @ref decl_base definition.
4117 ///
4118 /// @param d the earlier declaration to set.  Note that it's set only
4119 /// if it's a pure declaration.
4120 void
set_earlier_declaration(const decl_base_sptr & d)4121 decl_base::set_earlier_declaration(const decl_base_sptr& d)
4122 {
4123   if (d && d->get_is_declaration_only())
4124     priv_->declaration_ = d;
4125 }
4126 
4127 
4128 /// If this @ref decl_base is declaration-only, get its definition, if
4129 /// any.
4130 ///
4131 /// @return the definition of this decl-only @ref decl_base.
4132 const decl_base_sptr
get_definition_of_declaration() const4133 decl_base::get_definition_of_declaration() const
4134 {return priv_->definition_of_declaration_.lock();}
4135 
4136 ///  If this @ref decl_base is declaration-only, get its definition,
4137 ///  if any.
4138 ///
4139 /// Note that this function doesn't return a smart pointer, but rather
4140 /// the underlying pointer managed by the smart pointer.  So it's as
4141 /// fast as possible.  This getter is to be used in code paths that
4142 /// are proven to be performance hot spots; especially, when comparing
4143 /// sensitive types like enums, classes or unions.  Those are compared
4144 /// extremely frequently and thus, their access to the definition of
4145 /// declaration must be fast.
4146 ///
4147 /// @return the definition of the declaration.
4148 const decl_base*
get_naked_definition_of_declaration() const4149 decl_base::get_naked_definition_of_declaration() const
4150 {return priv_->naked_definition_of_declaration_;}
4151 
4152 /// Test if a @ref decl_base is a declaration-only decl.
4153 ///
4154 /// @return true iff the current @ref decl_base is declaration-only.
4155 bool
get_is_declaration_only() const4156 decl_base::get_is_declaration_only() const
4157 {return priv_->is_declaration_only_;}
4158 
4159 /// Set a flag saying if the @ref enum_type_decl is a declaration-only
4160 /// @ref enum_type_decl.
4161 ///
4162 /// @param f true if the @ref enum_type_decl is a declaration-only
4163 /// @ref enum_type_decl.
4164 void
set_is_declaration_only(bool f)4165 decl_base::set_is_declaration_only(bool f)
4166 {
4167   bool update_types_lookup_map = !f && priv_->is_declaration_only_;
4168 
4169   priv_->is_declaration_only_ = f;
4170 
4171   if (update_types_lookup_map)
4172     if (scope_decl* s = get_scope())
4173       {
4174 	scope_decl::declarations::iterator i;
4175 	if (s->find_iterator_for_member(this, i))
4176 	  maybe_update_types_lookup_map(*i);
4177 	else
4178 	  ABG_ASSERT_NOT_REACHED;
4179       }
4180 }
4181 
4182 change_kind
operator |(change_kind l,change_kind r)4183 operator|(change_kind l, change_kind r)
4184 {
4185   return static_cast<change_kind>(static_cast<unsigned>(l)
4186 				  | static_cast<unsigned>(r));
4187 }
4188 
4189 change_kind
operator &(change_kind l,change_kind r)4190 operator&(change_kind l, change_kind r)
4191 {
4192   return static_cast<change_kind>(static_cast<unsigned>(l)
4193 				  & static_cast<unsigned>(r));
4194 }
4195 
4196 change_kind&
operator |=(change_kind & l,change_kind r)4197 operator|=(change_kind& l, change_kind r)
4198 {
4199   l = l | r;
4200   return l;
4201 }
4202 
4203 change_kind&
operator &=(change_kind & l,change_kind r)4204 operator&=(change_kind& l, change_kind r)
4205 {
4206   l = l & r;
4207   return l;
4208 }
4209 
4210 /// Compare the properties that belong to the "is-a-member-relation"
4211 /// of a decl.
4212 ///
4213 /// For instance, access specifiers are part of the
4214 /// "is-a-member-relation" of a decl.
4215 ///
4216 /// This comparison however doesn't take decl names into account.  So
4217 /// typedefs for instance are decls that we want to compare with this
4218 /// function.
4219 ///
4220 /// This function is a sub-routine of the more general 'equals'
4221 /// overload for instances of decl_base.
4222 ///
4223 /// @param l the left-hand side operand of the comparison.
4224 ///
4225 /// @param r the right-hand side operand of the comparison.
4226 ///
4227 /// @return true iff @p l compare equals, as a member decl, to @p r.
4228 bool
maybe_compare_as_member_decls(const decl_base & l,const decl_base & r,change_kind * k)4229 maybe_compare_as_member_decls(const decl_base& l,
4230 			      const decl_base& r,
4231 			      change_kind* k)
4232 {
4233   bool result = true;
4234   if (is_member_decl(l) && is_member_decl(r))
4235     {
4236       context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
4237       context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
4238 
4239       access_specifier la = no_access, ra = no_access;
4240       bool member_types_or_functions =
4241 	((is_type(l) && is_type(r))
4242 	 || (is_function_decl(l) && is_function_decl(r)));
4243 
4244       if (member_types_or_functions)
4245 	{
4246 	  // Access specifiers on member types in DWARF is not
4247 	  // reliable; in the same DSO, the same struct can be either
4248 	  // a class or a struct, and the access specifiers of its
4249 	  // member types are not necessarily given, so they
4250 	  // effectively can be considered differently, again, in the
4251 	  // same DSO.  So, here, let's avoid considering those!
4252 	  // during comparison.
4253 	  la = r1->get_access_specifier();
4254 	  ra = r2->get_access_specifier();
4255 	  r1->set_access_specifier(no_access);
4256 	  r2->set_access_specifier(no_access);
4257 	}
4258 
4259       bool rels_are_different = *r1 != *r2;
4260 
4261       if (member_types_or_functions)
4262 	{
4263 	  // restore the access specifiers.
4264 	  r1->set_access_specifier(la);
4265 	  r2->set_access_specifier(ra);
4266 	}
4267 
4268       if (rels_are_different)
4269 	{
4270 	  result = false;
4271 	  if (k)
4272 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
4273 	}
4274     }
4275   return result;
4276 }
4277 
4278 /// Compares two instances of @ref decl_base.
4279 ///
4280 /// If the two intances are different, set a bitfield to give some
4281 /// insight about the kind of differences there are.
4282 ///
4283 /// @param l the first artifact of the comparison.
4284 ///
4285 /// @param r the second artifact of the comparison.
4286 ///
4287 /// @param k a pointer to a bitfield that gives information about the
4288 /// kind of changes there are between @p l and @p r.  This one is set
4289 /// iff it's non-null and if the function returns false.
4290 ///
4291 /// Please note that setting k to a non-null value does have a
4292 /// negative performance impact because even if @p l and @p r are not
4293 /// equal, the function keeps up the comparison in order to determine
4294 /// the different kinds of ways in which they are different.
4295 ///
4296 /// @return true if @p l equals @p r, false otherwise.
4297 bool
equals(const decl_base & l,const decl_base & r,change_kind * k)4298 equals(const decl_base& l, const decl_base& r, change_kind* k)
4299 {
4300   bool result = true;
4301   const interned_string &l_linkage_name = l.get_linkage_name();
4302   const interned_string &r_linkage_name = r.get_linkage_name();
4303   if (!l_linkage_name.empty() && !r_linkage_name.empty())
4304     {
4305       if (l_linkage_name != r_linkage_name)
4306 	{
4307 	  // Linkage names are different.  That usually means the two
4308 	  // decls are different, unless we are looking at two
4309 	  // function declarations which have two different symbols
4310 	  // that are aliases of each other.
4311 	  const function_decl *f1 = is_function_decl(&l),
4312 	    *f2 = is_function_decl(&r);
4313 	  if (f1 && f2 && function_decls_alias(*f1, *f2))
4314 	    ;// The two functions are aliases, so they are not different.
4315 	  else
4316 	    {
4317 	      result = false;
4318 	      if (k)
4319 		*k |= LOCAL_NON_TYPE_CHANGE_KIND;
4320 	      else
4321 		return false;
4322 	    }
4323 	}
4324     }
4325 
4326   // This is the name of the decls that we want to compare.
4327   interned_string ln = l.get_qualified_name(), rn = r.get_qualified_name();
4328 
4329   /// If both of the current decls have an anonymous scope then let's
4330   /// compare their name component by component by properly handling
4331   /// anonymous scopes. That's the slow path.
4332   ///
4333   /// Otherwise, let's just compare their name, the obvious way.
4334   /// That's the fast path because in that case the names are
4335   /// interned_string and comparing them is much faster.
4336   bool decls_are_same = (ln == rn);
4337   if (!decls_are_same
4338       && l.get_is_anonymous()
4339       && !l.get_has_anonymous_parent()
4340       && r.get_is_anonymous()
4341       && !r.get_has_anonymous_parent()
4342       && (l.get_qualified_parent_name() == r.get_qualified_parent_name()))
4343     // Both decls are anonymous and their scope are *NOT* anonymous.
4344     // So we consider the decls to have equivalent names (both
4345     // anonymous, remember).  We are still in the fast path here.
4346     decls_are_same = true;
4347 
4348   if (!decls_are_same
4349       && l.get_has_anonymous_parent()
4350       && r.get_has_anonymous_parent())
4351     // This is the slow path as we are comparing the decl qualified
4352     // names component by component, properly handling anonymous
4353     // scopes.
4354     decls_are_same = tools_utils::decl_names_equal(ln, rn);
4355 
4356   if (!decls_are_same)
4357     {
4358       result = false;
4359       if (k)
4360 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
4361       else
4362 	return false;
4363     }
4364 
4365   result &= maybe_compare_as_member_decls(l, r, k);
4366 
4367   return result;
4368 }
4369 
4370 /// Return true iff the two decls have the same name.
4371 ///
4372 /// This function doesn't test if the scopes of the the two decls are
4373 /// equal.
4374 ///
4375 /// Note that this virtual function is to be implemented by classes
4376 /// that extend the \p decl_base class.
4377 bool
operator ==(const decl_base & other) const4378 decl_base::operator==(const decl_base& other) const
4379 {return equals(*this, other, 0);}
4380 
4381 /// Inequality operator.
4382 ///
4383 /// @param other to other instance of @ref decl_base to compare the
4384 /// current instance to.
4385 ///
4386 /// @return true iff the current instance of @ref decl_base is
4387 /// different from @p other.
4388 bool
operator !=(const decl_base & other) const4389 decl_base::operator!=(const decl_base& other) const
4390 {return !operator==(other);}
4391 
4392 /// Destructor of the @ref decl_base type.
~decl_base()4393 decl_base::~decl_base()
4394 {delete priv_;}
4395 
4396 /// This implements the ir_traversable_base::traverse pure virtual
4397 /// function.
4398 ///
4399 /// @param v the visitor used on the member nodes of the translation
4400 /// unit during the traversal.
4401 ///
4402 /// @return true if the entire IR node tree got traversed, false
4403 /// otherwise.
4404 bool
traverse(ir_node_visitor &)4405 decl_base::traverse(ir_node_visitor&)
4406 {
4407   // Do nothing in the base class.
4408   return true;
4409 }
4410 
4411 /// Setter of the scope of the current decl.
4412 ///
4413 /// Note that the decl won't hold a reference on the scope.  It's
4414 /// rather the scope that holds a reference on its members.
4415 void
set_scope(scope_decl * scope)4416 decl_base::set_scope(scope_decl* scope)
4417 {
4418   if (!priv_->context_)
4419     priv_->context_ = new context_rel(scope);
4420   else
4421     priv_->context_->set_scope(scope);
4422 }
4423 
4424 // </decl_base definition>
4425 
4426 /// Streaming operator for the decl_base::visibility.
4427 ///
4428 /// @param o the output stream to serialize the visibility to.
4429 ///
4430 /// @param v the visibility to serialize.
4431 ///
4432 /// @return the output stream.
4433 std::ostream&
operator <<(std::ostream & o,decl_base::visibility v)4434 operator<<(std::ostream& o, decl_base::visibility v)
4435 {
4436   string r;
4437   switch (v)
4438     {
4439     case decl_base::VISIBILITY_NONE:
4440       r = "none";
4441       break;
4442     case decl_base::VISIBILITY_DEFAULT:
4443       r = "default";
4444       break;
4445     case decl_base::VISIBILITY_PROTECTED:
4446       r = "protected";
4447       break;
4448     case decl_base::VISIBILITY_HIDDEN:
4449       r = "hidden";
4450       break;
4451     case decl_base::VISIBILITY_INTERNAL:
4452       r = "internal";
4453       break;
4454     }
4455   return o;
4456 }
4457 
4458 /// Streaming operator for decl_base::binding.
4459 ///
4460 /// @param o the output stream to serialize the visibility to.
4461 ///
4462 /// @param b the binding to serialize.
4463 ///
4464 /// @return the output stream.
4465 std::ostream&
operator <<(std::ostream & o,decl_base::binding b)4466 operator<<(std::ostream& o, decl_base::binding b)
4467 {
4468   string r;
4469   switch (b)
4470     {
4471     case decl_base::BINDING_NONE:
4472       r = "none";
4473       break;
4474     case decl_base::BINDING_LOCAL:
4475       r = "local";
4476       break;
4477     case decl_base::BINDING_GLOBAL:
4478       r = "global";
4479       break;
4480     case decl_base::BINDING_WEAK:
4481       r = "weak";
4482       break;
4483     }
4484   o << r;
4485   return o;
4486 }
4487 
4488 /// Turn equality of shared_ptr of decl_base into a deep equality;
4489 /// that is, make it compare the pointed to objects, not just the
4490 /// pointers.
4491 ///
4492 /// @param l the shared_ptr of decl_base on left-hand-side of the
4493 /// equality.
4494 ///
4495 /// @param r the shared_ptr of decl_base on right-hand-side of the
4496 /// equality.
4497 ///
4498 /// @return true if the decl_base pointed to by the shared_ptrs are
4499 /// equal, false otherwise.
4500 bool
operator ==(const decl_base_sptr & l,const decl_base_sptr & r)4501 operator==(const decl_base_sptr& l, const decl_base_sptr& r)
4502 {
4503   if (l.get() == r.get())
4504     return true;
4505   if (!!l != !!r)
4506     return false;
4507 
4508   return *l == *r;
4509 }
4510 
4511 /// Inequality operator of shared_ptr of @ref decl_base.
4512 ///
4513 /// This is a deep equality operator, that is, it compares the
4514 /// pointed-to objects, rather than just the pointers.
4515 ///
4516 /// @param l the left-hand-side operand.
4517 ///
4518 /// @param r the right-hand-side operand.
4519 ///
4520 /// @return true iff @p l is different from @p r.
4521 bool
operator !=(const decl_base_sptr & l,const decl_base_sptr & r)4522 operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
4523 {return !operator==(l, r);}
4524 
4525 /// Turn equality of shared_ptr of type_base into a deep equality;
4526 /// that is, make it compare the pointed to objects too.
4527 ///
4528 /// @param l the shared_ptr of type_base on left-hand-side of the
4529 /// equality.
4530 ///
4531 /// @param r the shared_ptr of type_base on right-hand-side of the
4532 /// equality.
4533 ///
4534 /// @return true if the type_base pointed to by the shared_ptrs are
4535 /// equal, false otherwise.
4536 bool
operator ==(const type_base_sptr & l,const type_base_sptr & r)4537 operator==(const type_base_sptr& l, const type_base_sptr& r)
4538 {
4539     if (l.get() == r.get())
4540     return true;
4541   if (!!l != !!r)
4542     return false;
4543 
4544   return *l == *r;
4545 }
4546 
4547 /// Turn inequality of shared_ptr of type_base into a deep equality;
4548 /// that is, make it compare the pointed to objects..
4549 ///
4550 /// @param l the shared_ptr of type_base on left-hand-side of the
4551 /// equality.
4552 ///
4553 /// @param r the shared_ptr of type_base on right-hand-side of the
4554 /// equality.
4555 ///
4556 /// @return true iff the type_base pointed to by the shared_ptrs are
4557 /// different.
4558 bool
operator !=(const type_base_sptr & l,const type_base_sptr & r)4559 operator!=(const type_base_sptr& l, const type_base_sptr& r)
4560 {return !operator==(l, r);}
4561 
4562 /// Tests if a declaration has got a scope.
4563 ///
4564 /// @param d the declaration to consider.
4565 ///
4566 /// @return true if the declaration has got a scope, false otherwise.
4567 bool
has_scope(const decl_base & d)4568 has_scope(const decl_base& d)
4569 {return (d.get_scope());}
4570 
4571 /// Tests if a declaration has got a scope.
4572 ///
4573 /// @param d the declaration to consider.
4574 ///
4575 /// @return true if the declaration has got a scope, false otherwise.
4576 bool
has_scope(const decl_base_sptr d)4577 has_scope(const decl_base_sptr d)
4578 {return has_scope(*d.get());}
4579 
4580 /// Tests if a declaration is a class member.
4581 ///
4582 /// @param d the declaration to consider.
4583 ///
4584 /// @return true if @p d is a class member, false otherwise.
4585 bool
is_member_decl(const decl_base_sptr d)4586 is_member_decl(const decl_base_sptr d)
4587 {return is_at_class_scope(d) || is_method_decl(d);}
4588 
4589 /// Tests if a declaration is a class member.
4590 ///
4591 /// @param d the declaration to consider.
4592 ///
4593 /// @return true if @p d is a class member, false otherwise.
4594 bool
is_member_decl(const decl_base * d)4595 is_member_decl(const decl_base* d)
4596 {return is_at_class_scope(d) || is_method_decl(d);}
4597 
4598 /// Tests if a declaration is a class member.
4599 ///
4600 /// @param d the declaration to consider.
4601 ///
4602 /// @return true if @p d is a class member, false otherwise.
4603 bool
is_member_decl(const decl_base & d)4604 is_member_decl(const decl_base& d)
4605 {return is_at_class_scope(d) || is_method_decl(d);}
4606 
4607 /// Test if a declaration is a @ref scope_decl.
4608 ///
4609 /// @param d the declaration to take in account.
4610 ///
4611 /// @return the a pointer to the @ref scope_decl sub-object of @p d,
4612 /// if d is a @ref scope_decl.
4613 scope_decl*
is_scope_decl(decl_base * d)4614 is_scope_decl(decl_base* d)
4615 {return dynamic_cast<scope_decl*>(d);}
4616 
4617 /// Test if a declaration is a @ref scope_decl.
4618 ///
4619 /// @param d the declaration to take in account.
4620 ///
4621 /// @return the a pointer to the @ref scope_decl sub-object of @p d,
4622 /// if d is a @ref scope_decl.
4623 scope_decl_sptr
is_scope_decl(const decl_base_sptr & d)4624 is_scope_decl(const decl_base_sptr& d)
4625 {return dynamic_pointer_cast<scope_decl>(d);}
4626 
4627 /// Tests if a type is a class member.
4628 ///
4629 /// @param t the type to consider.
4630 ///
4631 /// @return true if @p t is a class member type, false otherwise.
4632 bool
is_member_type(const type_base_sptr & t)4633 is_member_type(const type_base_sptr& t)
4634 {
4635   decl_base_sptr d = get_type_declaration(t);
4636   return is_member_decl(d);
4637 }
4638 
4639 /// Test if a type is user-defined.
4640 ///
4641 /// A type is considered user-defined if it's a
4642 /// struct/class/union/enum that is *NOT* artificial.
4643 ///
4644 /// @param t the type to consider.
4645 ///
4646 /// @return true iff the type @p t is user-defined.
4647 bool
is_user_defined_type(const type_base * t)4648 is_user_defined_type(const type_base* t)
4649 {
4650   if (t == 0)
4651     return false;
4652 
4653   t = peel_qualified_or_typedef_type(t);
4654   decl_base *d = is_decl(t);
4655 
4656   if ((is_class_or_union_type(t) || is_enum_type(t))
4657       && d && !d->get_is_artificial())
4658     return true;
4659 
4660   return false;
4661 }
4662 
4663 /// Test if a type is user-defined.
4664 ///
4665 /// A type is considered user-defined if it's a
4666 /// struct/class/union/enum.
4667 ///
4668 ///
4669 /// @param t the type to consider.
4670 ///
4671 /// @return true iff the type @p t is user-defined.
4672 bool
is_user_defined_type(const type_base_sptr & t)4673 is_user_defined_type(const type_base_sptr& t)
4674 {return is_user_defined_type(t.get());}
4675 
4676 /// Gets the access specifier for a class member.
4677 ///
4678 /// @param d the declaration of the class member to consider.  Note
4679 /// that this must be a class member otherwise the function aborts the
4680 /// current process.
4681 ///
4682 /// @return the access specifier for the class member @p d.
4683 access_specifier
get_member_access_specifier(const decl_base & d)4684 get_member_access_specifier(const decl_base& d)
4685 {
4686   ABG_ASSERT(is_member_decl(d));
4687 
4688   const context_rel* c = d.get_context_rel();
4689   ABG_ASSERT(c);
4690 
4691   return c->get_access_specifier();
4692 }
4693 
4694 /// Gets the access specifier for a class member.
4695 ///
4696 /// @param d the declaration of the class member to consider.  Note
4697 /// that this must be a class member otherwise the function aborts the
4698 /// current process.
4699 ///
4700 /// @return the access specifier for the class member @p d.
4701 access_specifier
get_member_access_specifier(const decl_base_sptr & d)4702 get_member_access_specifier(const decl_base_sptr& d)
4703 {return get_member_access_specifier(*d);}
4704 
4705 /// Sets the access specifier for a class member.
4706 ///
4707 /// @param d the class member to set the access specifier for.  Note
4708 /// that this must be a class member otherwise the function aborts the
4709 /// current process.
4710 ///
4711 /// @param a the new access specifier to set the class member to.
4712 void
set_member_access_specifier(decl_base & d,access_specifier a)4713 set_member_access_specifier(decl_base& d,
4714 			    access_specifier a)
4715 {
4716   ABG_ASSERT(is_member_decl(d));
4717 
4718   context_rel* c = d.get_context_rel();
4719   ABG_ASSERT(c);
4720 
4721   c->set_access_specifier(a);
4722 }
4723 
4724 /// Sets the access specifier for a class member.
4725 ///
4726 /// @param d the class member to set the access specifier for.  Note
4727 /// that this must be a class member otherwise the function aborts the
4728 /// current process.
4729 ///
4730 /// @param a the new access specifier to set the class member to.
4731 void
set_member_access_specifier(const decl_base_sptr & d,access_specifier a)4732 set_member_access_specifier(const decl_base_sptr& d,
4733 			    access_specifier a)
4734 {set_member_access_specifier(*d, a);}
4735 
4736 /// Gets a flag saying if a class member is static or not.
4737 ///
4738 /// @param d the declaration for the class member to consider. Note
4739 /// that this must be a class member otherwise the function aborts the
4740 /// current process.
4741 ///
4742 /// @return true if the class member @p d is static, false otherwise.
4743 bool
get_member_is_static(const decl_base & d)4744 get_member_is_static(const decl_base&d)
4745 {
4746   ABG_ASSERT(is_member_decl(d));
4747 
4748   const context_rel* c = d.get_context_rel();
4749   ABG_ASSERT(c);
4750 
4751   return c->get_is_static();
4752 }
4753 
4754 /// Gets a flag saying if a class member is static or not.
4755 ///
4756 /// @param d the declaration for the class member to consider. Note
4757 /// that this must be a class member otherwise the function aborts the
4758 /// current process.
4759 ///
4760 /// @return true if the class member @p d is static, false otherwise.
4761 bool
get_member_is_static(const decl_base * d)4762 get_member_is_static(const decl_base* d)
4763 {return get_member_is_static(*d);}
4764 
4765 /// Gets a flag saying if a class member is static or not.
4766 ///
4767 /// @param d the declaration for the class member to consider.  Note
4768 /// that this must be a class member otherwise the function aborts the
4769 /// current process.
4770 ///
4771 /// @return true if the class member @p d is static, false otherwise.
4772 bool
get_member_is_static(const decl_base_sptr & d)4773 get_member_is_static(const decl_base_sptr& d)
4774 {return get_member_is_static(*d);}
4775 
4776 /// Test if a var_decl is a data member.
4777 ///
4778 /// @param v the var_decl to consider.
4779 ///
4780 /// @return true if @p v is data member, false otherwise.
4781 bool
is_data_member(const var_decl & v)4782 is_data_member(const var_decl& v)
4783 {return is_at_class_scope(v);}
4784 
4785 /// Test if a var_decl is a data member.
4786 ///
4787 /// @param v the var_decl to consider.
4788 ///
4789 /// @return true if @p v is data member, false otherwise.
4790 bool
is_data_member(const var_decl * v)4791 is_data_member(const var_decl* v)
4792 {return is_data_member(*v);}
4793 
4794 /// Test if a var_decl is a data member.
4795 ///
4796 /// @param v the var_decl to consider.
4797 ///
4798 /// @return true if @p v is data member, false otherwise.
4799 bool
is_data_member(const var_decl_sptr d)4800 is_data_member(const var_decl_sptr d)
4801 {return is_at_class_scope(d);}
4802 
4803 /// Test if a decl is a data member.
4804 ///
4805 /// @param d the decl to consider.
4806 ///
4807 /// @return a pointer to the data member iff @p d is a data member, or
4808 /// a null pointer.
4809 var_decl_sptr
is_data_member(const decl_base_sptr & d)4810 is_data_member(const decl_base_sptr& d)
4811 {
4812   if (var_decl_sptr v = is_var_decl(d))
4813     {
4814       if (is_data_member(v))
4815 	return v;
4816     }
4817   return var_decl_sptr();
4818 }
4819 
4820 /// Test if a decl is a data member.
4821 ///
4822 /// @param d the decl to consider.
4823 ///
4824 /// @return a pointer to the data member iff @p d is a data member, or
4825 /// a null pointer.
4826 var_decl_sptr
is_data_member(const type_or_decl_base_sptr & d)4827 is_data_member(const type_or_decl_base_sptr& d)
4828 {
4829   if (var_decl_sptr v = is_var_decl(d))
4830     {
4831       if (is_data_member(v))
4832 	return v;
4833     }
4834   return var_decl_sptr();
4835 }
4836 
4837 /// Test if a decl is a data member.
4838 ///
4839 /// @param d the decl to consider.
4840 ///
4841 /// @return a pointer to the data member iff @p d is a data member, or
4842 /// a null pointer.
4843 var_decl*
is_data_member(const type_or_decl_base * d)4844 is_data_member(const type_or_decl_base* d)
4845 {
4846  if (var_decl *v = is_var_decl(d))
4847     if (is_data_member(v))
4848       return v;
4849   return 0;
4850 }
4851 
4852 /// Test if a decl is a data member.
4853 ///
4854 /// @param d the decl to consider.
4855 ///
4856 /// @return a pointer to the data member iff @p d is a data member, or
4857 /// a null pointer.
4858 var_decl*
is_data_member(const decl_base * d)4859 is_data_member(const decl_base *d)
4860 {
4861   if (var_decl *v = is_var_decl(d))
4862     if (is_data_member(v))
4863       return v;
4864   return 0;
4865 }
4866 
4867 /// Get the first non-anonymous data member of a given anonymous data
4868 /// member.
4869 ///
4870 /// E.g:
4871 ///
4872 ///   struct S
4873 ///   {
4874 ///     union // <-- for this anonymous data member, the function
4875 ///           // returns a.
4876 ///     {
4877 ///       int a;
4878 ///       charb;
4879 ///     };
4880 ///   };
4881 ///
4882 /// @return anon_dm the anonymous data member to consider.
4883 ///
4884 /// @return the first non-anonymous data member of @p anon_dm.  If no
4885 /// data member was found then this function returns @p anon_dm.
4886 const var_decl_sptr
get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)4887 get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
4888 {
4889   if (!anon_dm || !is_anonymous_data_member(anon_dm))
4890     return anon_dm;
4891 
4892   class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
4893  var_decl_sptr first = *klass->get_non_static_data_members().begin();
4894 
4895  if (is_anonymous_data_member(first))
4896    return get_first_non_anonymous_data_member(first);
4897 
4898  return first;
4899 }
4900 
4901 /// In the context of a given class or union, this function returns
4902 /// the data member that is located after a given data member.
4903 ///
4904 /// @param klass the class or union to consider.
4905 ///
4906 /// @param the data member to consider.
4907 ///
4908 /// @return the data member that is located right after @p
4909 /// data_member.
4910 const var_decl_sptr
get_next_data_member(const class_or_union_sptr & klass,const var_decl_sptr & data_member)4911 get_next_data_member(const class_or_union_sptr &klass,
4912 		     const var_decl_sptr &data_member)
4913 {
4914   if (!klass ||!data_member)
4915     return var_decl_sptr();
4916 
4917   for (class_or_union::data_members::const_iterator it =
4918 	 klass->get_non_static_data_members().begin();
4919        it != klass->get_non_static_data_members().end();
4920        ++it)
4921     if (**it == *data_member)
4922       {
4923 	++it;
4924 	if (it != klass->get_non_static_data_members().end())
4925 	  return get_first_non_anonymous_data_member(*it);
4926 	break;
4927       }
4928 
4929   return var_decl_sptr();
4930 }
4931 
4932 /// Test if a decl is an anonymous data member.
4933 ///
4934 /// @param d the decl to consider.
4935 ///
4936 /// @return true iff @p d is an anonymous data member.
4937 bool
is_anonymous_data_member(const decl_base & d)4938 is_anonymous_data_member(const decl_base& d)
4939 {return is_anonymous_data_member(&d);}
4940 
4941 /// Test if a decl is an anonymous data member.
4942 ///
4943 /// @param d the decl to consider.
4944 ///
4945 /// @return the var_decl representing the data member iff @p d is an
4946 /// anonymous data member.
4947 const var_decl*
is_anonymous_data_member(const type_or_decl_base * d)4948 is_anonymous_data_member(const type_or_decl_base* d)
4949 {
4950   if (const var_decl* v = is_data_member(d))
4951     {
4952       if (is_anonymous_data_member(v))
4953 	return v;
4954     }
4955   return 0;
4956 }
4957 
4958 /// Test if a decl is an anonymous data member.
4959 ///
4960 /// @param d the decl to consider.
4961 ///
4962 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
4963 /// it's an anonymous data member.  Otherwise returns a nil pointer.
4964 const var_decl*
is_anonymous_data_member(const decl_base * d)4965 is_anonymous_data_member(const decl_base* d)
4966 {
4967   if (const var_decl* v = is_data_member(d))
4968     {
4969       if (is_anonymous_data_member(v))
4970 	return v;
4971     }
4972   return 0;
4973 }
4974 
4975 /// Test if a decl is an anonymous data member.
4976 ///
4977 /// @param d the decl to consider.
4978 ///
4979 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
4980 /// it's an anonymous data member.  Otherwise returns a nil pointer.
4981 var_decl_sptr
is_anonymous_data_member(const type_or_decl_base_sptr & d)4982 is_anonymous_data_member(const type_or_decl_base_sptr& d)
4983 {
4984   if (var_decl_sptr v = is_data_member(d))
4985     {
4986       if (is_anonymous_data_member(v))
4987 	return v;
4988     }
4989   return var_decl_sptr();
4990 }
4991 
4992 /// Test if a decl is an anonymous data member.
4993 ///
4994 /// @param d the decl to consider.
4995 ///
4996 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
4997 /// it's an anonymous data member.  Otherwise returns a nil pointer.
4998 var_decl_sptr
is_anonymous_data_member(const decl_base_sptr & d)4999 is_anonymous_data_member(const decl_base_sptr& d)
5000 {
5001   if (var_decl_sptr v = is_data_member(d))
5002     return is_anonymous_data_member(v);
5003   return var_decl_sptr();
5004 }
5005 
5006 /// Test if a @ref var_decl is an anonymous data member.
5007 ///
5008 /// @param d the @ref var_decl to consider.
5009 ///
5010 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5011 /// it's an anonymous data member.  Otherwise returns a nil pointer.
5012 var_decl_sptr
is_anonymous_data_member(const var_decl_sptr & d)5013 is_anonymous_data_member(const var_decl_sptr& d)
5014 {
5015   if (is_anonymous_data_member(d.get()))
5016     return d;
5017   return var_decl_sptr();
5018 }
5019 
5020 /// Test if a @ref var_decl is an anonymous data member.
5021 ///
5022 /// @param d the @ref var_decl to consider.
5023 ///
5024 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5025 /// it's an anonymous data member.  Otherwise returns a nil pointer.
5026 const var_decl*
is_anonymous_data_member(const var_decl * d)5027 is_anonymous_data_member(const var_decl* d)
5028 {
5029   if (d && is_anonymous_data_member(*d))
5030     return d;
5031   return 0;
5032 }
5033 
5034 /// Test if a @ref var_decl is an anonymous data member.
5035 ///
5036 /// @param d the @ref var_decl to consider.
5037 ///
5038 /// @return true iff @p d is an anonymous data member.
5039 bool
is_anonymous_data_member(const var_decl & d)5040 is_anonymous_data_member(const var_decl& d)
5041 {
5042   return (is_data_member(d)
5043 	  && d.get_name().empty()
5044 	  && is_class_or_union_type(d.get_type()));
5045 }
5046 
5047 /// Get the @ref class_or_union type of a given anonymous data member.
5048 ///
5049 /// @param d the anonymous data member to consider.
5050 ///
5051 /// @return the @ref class_or_union type of the anonymous data member
5052 /// @p d.
5053 class_or_union*
anonymous_data_member_to_class_or_union(const var_decl * d)5054 anonymous_data_member_to_class_or_union(const var_decl* d)
5055 {
5056   if ((d = is_anonymous_data_member(d)))
5057     return is_class_or_union_type(d->get_type().get());
5058   return 0;
5059 }
5060 
5061 /// Test if a data member has annonymous type or not.
5062 ///
5063 /// @param d the data member to consider.
5064 ///
5065 /// @return the anonymous class or union type iff @p turns out to have
5066 /// an anonymous type.  Otherwise, returns nil.
5067 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl & d)5068 data_member_has_anonymous_type(const var_decl& d)
5069 {
5070   if (is_data_member(d))
5071     if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
5072       if (cou->get_is_anonymous())
5073 	return cou;
5074 
5075   return class_or_union_sptr();
5076 }
5077 
5078 /// Test if a data member has annonymous type or not.
5079 ///
5080 /// @param d the data member to consider.
5081 ///
5082 /// @return the anonymous class or union type iff @p turns out to have
5083 /// an anonymous type.  Otherwise, returns nil.
5084 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl * d)5085 data_member_has_anonymous_type(const var_decl* d)
5086 {
5087   if (d)
5088     return data_member_has_anonymous_type(*d);
5089   return class_or_union_sptr();
5090 }
5091 
5092 /// Test if a data member has annonymous type or not.
5093 ///
5094 /// @param d the data member to consider.
5095 ///
5096 /// @return the anonymous class or union type iff @p turns out to have
5097 /// an anonymous type.  Otherwise, returns nil.
5098 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl_sptr & d)5099 data_member_has_anonymous_type(const var_decl_sptr& d)
5100 {return data_member_has_anonymous_type(d.get());}
5101 
5102 /// Get the @ref class_or_union type of a given anonymous data member.
5103 ///
5104 /// @param d the anonymous data member to consider.
5105 ///
5106 /// @return the @ref class_or_union type of the anonymous data member
5107 /// @p d.
5108 class_or_union_sptr
anonymous_data_member_to_class_or_union(const var_decl_sptr & d)5109 anonymous_data_member_to_class_or_union(const var_decl_sptr &d)
5110 {
5111   if (var_decl_sptr v = is_anonymous_data_member(d))
5112     return is_class_or_union_type(v->get_type());
5113   return class_or_union_sptr();
5114 }
5115 
5116 /// Set the offset of a data member into its containing class.
5117 ///
5118 /// @param m the data member to consider.
5119 ///
5120 /// @param o the offset, in bits.
5121 void
set_data_member_offset(var_decl_sptr m,uint64_t o)5122 set_data_member_offset(var_decl_sptr m, uint64_t o)
5123 {
5124   ABG_ASSERT(is_data_member(m));
5125 
5126   dm_context_rel* ctxt_rel =
5127     dynamic_cast<dm_context_rel*>(m->get_context_rel());
5128   ABG_ASSERT(ctxt_rel);
5129 
5130   ctxt_rel->set_offset_in_bits(o);
5131 }
5132 
5133 /// Get the offset of a data member.
5134 ///
5135 /// @param m the data member to consider.
5136 ///
5137 /// @return the offset (in bits) of @p m in its containing class.
5138 uint64_t
get_data_member_offset(const var_decl & m)5139 get_data_member_offset(const var_decl& m)
5140 {
5141   ABG_ASSERT(is_data_member(m));
5142   const dm_context_rel* ctxt_rel =
5143     dynamic_cast<const dm_context_rel*>(m.get_context_rel());
5144   ABG_ASSERT(ctxt_rel);
5145   return ctxt_rel->get_offset_in_bits();
5146 }
5147 
5148 /// Get the offset of a data member.
5149 ///
5150 /// @param m the data member to consider.
5151 ///
5152 /// @return the offset (in bits) of @p m in its containing class.
5153 uint64_t
get_data_member_offset(const var_decl_sptr m)5154 get_data_member_offset(const var_decl_sptr m)
5155 {return get_data_member_offset(*m);}
5156 
5157 /// Get the offset of a data member.
5158 ///
5159 /// @param m the data member to consider.
5160 ///
5161 /// @return the offset (in bits) of @p m in its containing class.
5162 uint64_t
get_data_member_offset(const decl_base_sptr d)5163 get_data_member_offset(const decl_base_sptr d)
5164 {return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
5165 
5166 /// Get the absolute offset of a data member.
5167 ///
5168 /// If the data member is part of an anonymous data member then this
5169 /// returns the absolute offset -- relative to the beginning of the
5170 /// containing class of the anonymous data member.
5171 ///
5172 /// @param m the data member to consider.
5173 ///
5174 /// @return the aboslute offset of the data member @p m.
5175 uint64_t
get_absolute_data_member_offset(const var_decl & m)5176 get_absolute_data_member_offset(const var_decl& m)
5177 {
5178   ABG_ASSERT(is_data_member(m));
5179   const dm_context_rel* ctxt_rel =
5180     dynamic_cast<const dm_context_rel*>(m.get_context_rel());
5181   ABG_ASSERT(ctxt_rel);
5182 
5183   const var_decl *containing_anonymous_data_member =
5184     ctxt_rel->get_anonymous_data_member();
5185 
5186   uint64_t containing_anonymous_data_member_offset = 0;
5187   if (containing_anonymous_data_member)
5188     containing_anonymous_data_member_offset =
5189       get_absolute_data_member_offset(*containing_anonymous_data_member);
5190 
5191   return (ctxt_rel->get_offset_in_bits()
5192 	  +
5193 	  containing_anonymous_data_member_offset);
5194 }
5195 
5196 /// Get the absolute offset of a data member.
5197 ///
5198 /// If the data member is part of an anonymous data member then this
5199 /// returns the absolute offset -- relative to the beginning of the
5200 /// containing class of the anonymous data member.
5201 ///
5202 /// @param m the data member to consider.
5203 ///
5204 /// @return the aboslute offset of the data member @p m.
5205 uint64_t
get_absolute_data_member_offset(const var_decl_sptr & m)5206 get_absolute_data_member_offset(const var_decl_sptr& m)
5207 {
5208   if (!m)
5209     return 0;
5210   return get_absolute_data_member_offset(*m);
5211 }
5212 
5213 /// Get the size of a given variable.
5214 ///
5215 /// @param v the variable to consider.
5216 ///
5217 /// @return the size of variable @p v.
5218 uint64_t
get_var_size_in_bits(const var_decl_sptr & v)5219 get_var_size_in_bits(const var_decl_sptr& v)
5220 {
5221   type_base_sptr t = v->get_type();
5222   ABG_ASSERT(t);
5223 
5224   return t->get_size_in_bits();
5225 }
5226 
5227 /// Set a flag saying if a data member is laid out.
5228 ///
5229 /// @param m the data member to consider.
5230 ///
5231 /// @param l true if @p m is to be considered as laid out.
5232 void
set_data_member_is_laid_out(var_decl_sptr m,bool l)5233 set_data_member_is_laid_out(var_decl_sptr m, bool l)
5234 {
5235   ABG_ASSERT(is_data_member(m));
5236   dm_context_rel* ctxt_rel =
5237     dynamic_cast<dm_context_rel*>(m->get_context_rel());
5238   ctxt_rel->set_is_laid_out(l);
5239 }
5240 
5241 /// Test whether a data member is laid out.
5242 ///
5243 /// @param m the data member to consider.
5244 ///
5245 /// @return true if @p m is laid out, false otherwise.
5246 bool
get_data_member_is_laid_out(const var_decl & m)5247 get_data_member_is_laid_out(const var_decl& m)
5248 {
5249   ABG_ASSERT(is_data_member(m));
5250   const dm_context_rel* ctxt_rel =
5251     dynamic_cast<const dm_context_rel*>(m.get_context_rel());
5252 
5253   return ctxt_rel->get_is_laid_out();
5254 }
5255 
5256 /// Test whether a data member is laid out.
5257 ///
5258 /// @param m the data member to consider.
5259 ///
5260 /// @return true if @p m is laid out, false otherwise.
5261 bool
get_data_member_is_laid_out(const var_decl_sptr m)5262 get_data_member_is_laid_out(const var_decl_sptr m)
5263 {return get_data_member_is_laid_out(*m);}
5264 
5265 /// Test whether a function_decl is a member function.
5266 ///
5267 /// @param f the function_decl to test.
5268 ///
5269 /// @return true if @p f is a member function, false otherwise.
5270 bool
is_member_function(const function_decl & f)5271 is_member_function(const function_decl& f)
5272 {return is_member_decl(f);}
5273 
5274 /// Test whether a function_decl is a member function.
5275 ///
5276 /// @param f the function_decl to test.
5277 ///
5278 /// @return true if @p f is a member function, false otherwise.
5279 bool
is_member_function(const function_decl * f)5280 is_member_function(const function_decl* f)
5281 {return is_member_decl(*f);}
5282 
5283 /// Test whether a function_decl is a member function.
5284 ///
5285 /// @param f the function_decl to test.
5286 ///
5287 /// @return true if @p f is a member function, false otherwise.
5288 bool
is_member_function(const function_decl_sptr & f)5289 is_member_function(const function_decl_sptr& f)
5290 {return is_member_decl(*f);}
5291 
5292 /// Test whether a member function is a constructor.
5293 ///
5294 /// @param f the member function to test.
5295 ///
5296 /// @return true if @p f is a constructor, false otherwise.
5297 bool
get_member_function_is_ctor(const function_decl & f)5298 get_member_function_is_ctor(const function_decl& f)
5299 {
5300   ABG_ASSERT(is_member_function(f));
5301 
5302   const method_decl* m = is_method_decl(&f);
5303   ABG_ASSERT(m);
5304 
5305   const mem_fn_context_rel* ctxt =
5306     dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
5307 
5308   return ctxt->is_constructor();
5309 }
5310 
5311 /// Test whether a member function is a constructor.
5312 ///
5313 /// @param f the member function to test.
5314 ///
5315 /// @return true if @p f is a constructor, false otherwise.
5316 bool
get_member_function_is_ctor(const function_decl_sptr & f)5317 get_member_function_is_ctor(const function_decl_sptr& f)
5318 {return get_member_function_is_ctor(*f);}
5319 
5320 
5321 /// Setter for the is_ctor property of the member function.
5322 ///
5323 /// @param f the member function to set.
5324 ///
5325 /// @param f the new boolean value of the is_ctor property.  Is true
5326 /// if @p f is a constructor, false otherwise.
5327 void
set_member_function_is_ctor(function_decl & f,bool c)5328 set_member_function_is_ctor(function_decl& f, bool c)
5329 {
5330   ABG_ASSERT(is_member_function(f));
5331 
5332   method_decl* m = is_method_decl(&f);
5333   ABG_ASSERT(m);
5334 
5335   mem_fn_context_rel* ctxt =
5336     dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
5337 
5338   ctxt->is_constructor(c);
5339 }
5340 
5341 /// Setter for the is_ctor property of the member function.
5342 ///
5343 /// @param f the member function to set.
5344 ///
5345 /// @param f the new boolean value of the is_ctor property.  Is true
5346 /// if @p f is a constructor, false otherwise.
5347 void
set_member_function_is_ctor(const function_decl_sptr & f,bool c)5348 set_member_function_is_ctor(const function_decl_sptr& f, bool c)
5349 {set_member_function_is_ctor(*f, c);}
5350 
5351 /// Test whether a member function is a destructor.
5352 ///
5353 /// @param f the function to test.
5354 ///
5355 /// @return true if @p f is a destructor, false otherwise.
5356 bool
get_member_function_is_dtor(const function_decl & f)5357 get_member_function_is_dtor(const function_decl& f)
5358 {
5359   ABG_ASSERT(is_member_function(f));
5360 
5361   const method_decl* m = is_method_decl(&f);
5362   ABG_ASSERT(m);
5363 
5364   const mem_fn_context_rel* ctxt =
5365     dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
5366 
5367   return ctxt->is_destructor();
5368 }
5369 
5370 /// Test whether a member function is a destructor.
5371 ///
5372 /// @param f the function to test.
5373 ///
5374 /// @return true if @p f is a destructor, false otherwise.
5375 bool
get_member_function_is_dtor(const function_decl_sptr & f)5376 get_member_function_is_dtor(const function_decl_sptr& f)
5377 {return get_member_function_is_dtor(*f);}
5378 
5379 /// Set the destructor-ness property of a member function.
5380 ///
5381 /// @param f the function to set.
5382 ///
5383 /// @param d true if @p f is a destructor, false otherwise.
5384 void
set_member_function_is_dtor(function_decl & f,bool d)5385 set_member_function_is_dtor(function_decl& f, bool d)
5386 {
5387     ABG_ASSERT(is_member_function(f));
5388 
5389     method_decl* m = is_method_decl(&f);
5390   ABG_ASSERT(m);
5391 
5392   mem_fn_context_rel* ctxt =
5393     dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
5394 
5395   ctxt->is_destructor(d);
5396 }
5397 
5398 /// Set the destructor-ness property of a member function.
5399 ///
5400 /// @param f the function to set.
5401 ///
5402 /// @param d true if @p f is a destructor, false otherwise.
5403 void
set_member_function_is_dtor(const function_decl_sptr & f,bool d)5404 set_member_function_is_dtor(const function_decl_sptr& f, bool d)
5405 {set_member_function_is_dtor(*f, d);}
5406 
5407 /// Test whether a member function is const.
5408 ///
5409 /// @param f the function to test.
5410 ///
5411 /// @return true if @p f is const, false otherwise.
5412 bool
get_member_function_is_const(const function_decl & f)5413 get_member_function_is_const(const function_decl& f)
5414 {
5415   ABG_ASSERT(is_member_function(f));
5416 
5417   const method_decl* m = is_method_decl(&f);
5418   ABG_ASSERT(m);
5419 
5420   const mem_fn_context_rel* ctxt =
5421     dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
5422 
5423   return ctxt->is_const();
5424 }
5425 
5426 /// Test whether a member function is const.
5427 ///
5428 /// @param f the function to test.
5429 ///
5430 /// @return true if @p f is const, false otherwise.
5431 bool
get_member_function_is_const(const function_decl_sptr & f)5432 get_member_function_is_const(const function_decl_sptr& f)
5433 {return get_member_function_is_const(*f);}
5434 
5435 /// set the const-ness property of a member function.
5436 ///
5437 /// @param f the function to set.
5438 ///
5439 /// @param is_const the new value of the const-ness property of @p f
5440 void
set_member_function_is_const(function_decl & f,bool is_const)5441 set_member_function_is_const(function_decl& f, bool is_const)
5442 {
5443   ABG_ASSERT(is_member_function(f));
5444 
5445   method_decl* m = is_method_decl(&f);
5446   ABG_ASSERT(m);
5447 
5448   mem_fn_context_rel* ctxt =
5449     dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
5450 
5451   ctxt->is_const(is_const);
5452 }
5453 
5454 /// set the const-ness property of a member function.
5455 ///
5456 /// @param f the function to set.
5457 ///
5458 /// @param is_const the new value of the const-ness property of @p f
5459 void
set_member_function_is_const(const function_decl_sptr & f,bool is_const)5460 set_member_function_is_const(const function_decl_sptr& f, bool is_const)
5461 {set_member_function_is_const(*f, is_const);}
5462 
5463 /// Test if a virtual member function has a vtable offset set.
5464 ///
5465 /// @param f the virtual member function to consider.
5466 ///
5467 /// @return true iff the virtual member function has its vtable offset
5468 /// set, i.e, if the vtable offset of @p is different from -1.
5469 bool
member_function_has_vtable_offset(const function_decl & f)5470 member_function_has_vtable_offset(const function_decl& f)
5471 {return get_member_function_vtable_offset(f) != -1;}
5472 
5473 /// Get the vtable offset of a member function.
5474 ///
5475 /// @param f the member function to consider.
5476 ///
5477 /// @return the vtable offset of @p f.  Note that a vtable offset of
5478 /// value -1 means that the member function does *NOT* yet have a
5479 /// vtable offset associated to it.
5480 ssize_t
get_member_function_vtable_offset(const function_decl & f)5481 get_member_function_vtable_offset(const function_decl& f)
5482 {
5483   ABG_ASSERT(is_member_function(f));
5484 
5485   const method_decl* m =
5486     dynamic_cast<const method_decl*>(&f);
5487   ABG_ASSERT(m);
5488 
5489   const mem_fn_context_rel* ctxt =
5490     dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
5491 
5492   return ctxt->vtable_offset();
5493 }
5494 
5495 /// Get the vtable offset of a member function.
5496 ///
5497 /// @param f the member function to consider.
5498 ///
5499 /// @return the vtable offset of @p f.  Note that a vtable offset of
5500 /// value -1 means that the member function does *NOT* yet have a
5501 /// vtable offset associated to it.
5502 ssize_t
get_member_function_vtable_offset(const function_decl_sptr & f)5503 get_member_function_vtable_offset(const function_decl_sptr& f)
5504 {return get_member_function_vtable_offset(*f);}
5505 
5506 /// Set the vtable offset of a member function.
5507 ///
5508 /// @param f the member function to consider.
5509 ///
5510 /// @param s the new vtable offset.  Please note that a vtable offset
5511 /// of value -1 means that the virtual member function does not (yet)
5512 /// have any vtable offset associated to it.
5513 void
set_member_function_vtable_offset(function_decl & f,ssize_t s)5514 set_member_function_vtable_offset(function_decl& f, ssize_t s)
5515 {
5516   ABG_ASSERT(is_member_function(f));
5517 
5518   method_decl* m = is_method_decl(&f);
5519   ABG_ASSERT(m);
5520 
5521   mem_fn_context_rel* ctxt =
5522     dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
5523 
5524   ctxt->vtable_offset(s);
5525 }
5526 
5527 /// Get the vtable offset of a member function.
5528 ///
5529 /// @param f the member function to consider.
5530 ///
5531 /// @param s the new vtable offset.  Please note that a vtable offset
5532 /// of value -1 means that the virtual member function does not (yet)
5533 /// have any vtable offset associated to it.
5534 void
set_member_function_vtable_offset(const function_decl_sptr & f,ssize_t s)5535 set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
5536 {return set_member_function_vtable_offset(*f, s);}
5537 
5538 /// Test if a given member function is virtual.
5539 ///
5540 /// @param mem_fn the member function to consider.
5541 ///
5542 /// @return true iff a @p mem_fn is virtual.
5543 bool
get_member_function_is_virtual(const function_decl & f)5544 get_member_function_is_virtual(const function_decl& f)
5545 {
5546   ABG_ASSERT(is_member_function(f));
5547 
5548   const method_decl* m =
5549     dynamic_cast<const method_decl*>(&f);
5550   ABG_ASSERT(m);
5551 
5552   const mem_fn_context_rel* ctxt =
5553     dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
5554 
5555   return ctxt->is_virtual();
5556 }
5557 
5558 /// Test if a given member function is virtual.
5559 ///
5560 /// @param mem_fn the member function to consider.
5561 ///
5562 /// @return true iff a @p mem_fn is virtual.
5563 bool
get_member_function_is_virtual(const function_decl_sptr & mem_fn)5564 get_member_function_is_virtual(const function_decl_sptr& mem_fn)
5565 {return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
5566 
5567 /// Test if a given member function is virtual.
5568 ///
5569 /// @param mem_fn the member function to consider.
5570 ///
5571 /// @return true iff a @p mem_fn is virtual.
5572 bool
get_member_function_is_virtual(const function_decl * mem_fn)5573 get_member_function_is_virtual(const function_decl* mem_fn)
5574 {return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
5575 
5576 /// Set the virtual-ness of a member function.
5577 ///
5578 /// @param f the member function to consider.
5579 ///
5580 /// @param is_virtual set to true if the function is virtual.
5581 void
set_member_function_is_virtual(function_decl & f,bool is_virtual)5582 set_member_function_is_virtual(function_decl& f, bool is_virtual)
5583 {
5584   ABG_ASSERT(is_member_function(f));
5585 
5586   method_decl* m = is_method_decl(&f);
5587   ABG_ASSERT(m);
5588 
5589   mem_fn_context_rel* ctxt =
5590     dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
5591 
5592   ctxt->is_virtual(is_virtual);
5593 }
5594 
5595 /// Set the virtual-ness of a member function.
5596 ///
5597 /// @param f the member function to consider.
5598 ///
5599 /// @param is_virtual set to true if the function is virtual.
5600 void
set_member_function_is_virtual(const function_decl_sptr & fn,bool is_virtual)5601 set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
5602 {
5603   if (fn)
5604     {
5605       set_member_function_is_virtual(*fn, is_virtual);
5606       fixup_virtual_member_function
5607 	(dynamic_pointer_cast<method_decl>(fn));
5608     }
5609 }
5610 
5611 /// Recursively returns the the underlying type of a typedef.  The
5612 /// return type should not be a typedef of anything anymore.
5613 ///
5614 ///
5615 /// Also recursively strip typedefs from the sub-types of the type
5616 /// given in arguments.
5617 ///
5618 /// Note that this function builds types in which typedefs are
5619 /// stripped off.  Usually, types are held by their scope, so their
5620 /// life time is bound to the life time of their scope.  But as this
5621 /// function cannot really insert the built type into it's scope, it
5622 /// must ensure that the newly built type stays live long enough.
5623 ///
5624 /// So, if the newly built type has a canonical type, this function
5625 /// returns the canonical type.  Otherwise, this function ensure that
5626 /// the newly built type has a life time that is the same as the life
5627 /// time of the entire libabigail library.
5628 ///
5629 /// @param type the type to strip the typedefs from.
5630 ///
5631 /// @return the resulting type stripped from its typedefs, or just
5632 /// return @p type if it has no typedef in any of its sub-types.
5633 type_base_sptr
strip_typedef(const type_base_sptr type)5634 strip_typedef(const type_base_sptr type)
5635 {
5636   if (!type)
5637     return type;
5638 
5639   // If type is a class type then do not try to strip typedefs from it.
5640   // And if it has no canonical type (which can mean that it's a
5641   // declaration-only class), then, make sure its live for ever and
5642   // return it.
5643   if (class_decl_sptr cl = is_class_type(type))
5644     {
5645       if (!cl->get_canonical_type())
5646 	keep_type_alive(type);
5647       return type;
5648     }
5649 
5650   environment* env = type->get_environment();
5651   ABG_ASSERT(env);
5652   type_base_sptr t = type;
5653 
5654   if (const typedef_decl_sptr ty = is_typedef(t))
5655     t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
5656   else if (const reference_type_def_sptr ty = is_reference_type(t))
5657     {
5658       type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
5659 						    env));
5660       ABG_ASSERT(p);
5661       t.reset(new reference_type_def(p,
5662 				     ty->is_lvalue(),
5663 				     ty->get_size_in_bits(),
5664 				     ty->get_alignment_in_bits(),
5665 				     ty->get_location()));
5666     }
5667   else if (const pointer_type_def_sptr ty = is_pointer_type(t))
5668     {
5669       type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
5670 						    env));
5671       ABG_ASSERT(p);
5672       t.reset(new pointer_type_def(p,
5673 				   ty->get_size_in_bits(),
5674 				   ty->get_alignment_in_bits(),
5675 				   ty->get_location()));
5676     }
5677   else if (const qualified_type_def_sptr ty = is_qualified_type(t))
5678     {
5679       type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
5680 						    env));
5681       ABG_ASSERT(p);
5682       t.reset(new qualified_type_def(p,
5683 				     ty->get_cv_quals(),
5684 				     ty->get_location()));
5685     }
5686   else if (const array_type_def_sptr ty = is_array_type(t))
5687     {
5688       type_base_sptr p = strip_typedef(ty->get_element_type());
5689       ABG_ASSERT(p);
5690       t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
5691     }
5692   else if (const method_type_sptr ty = is_method_type(t))
5693     {
5694       function_decl::parameters parm;
5695       for (function_decl::parameters::const_iterator i =
5696 	     ty->get_parameters().begin();
5697 	   i != ty->get_parameters().end();
5698 	   ++i)
5699 	{
5700 	  function_decl::parameter_sptr p = *i;
5701 	  type_base_sptr typ = strip_typedef(p->get_type());
5702 	  ABG_ASSERT(typ);
5703 	  function_decl::parameter_sptr stripped
5704 	    (new function_decl::parameter(typ,
5705 					  p->get_index(),
5706 					  p->get_name(),
5707 					  p->get_location(),
5708 					  p->get_variadic_marker(),
5709 					  p->get_is_artificial()));
5710 	  parm.push_back(stripped);
5711 	}
5712       type_base_sptr p = strip_typedef(ty->get_return_type());
5713       ABG_ASSERT(!!p == !!ty->get_return_type());
5714       t.reset(new method_type(p, ty->get_class_type(),
5715 			      parm, ty->get_is_const(),
5716 			      ty->get_size_in_bits(),
5717 			      ty->get_alignment_in_bits()));
5718     }
5719   else if (const function_type_sptr ty = is_function_type(t))
5720     {
5721       function_decl::parameters parm;
5722       for (function_decl::parameters::const_iterator i =
5723 	     ty->get_parameters().begin();
5724 	   i != ty->get_parameters().end();
5725 	   ++i)
5726 	{
5727 	  function_decl::parameter_sptr p = *i;
5728 	  type_base_sptr typ = strip_typedef(p->get_type());
5729 	  ABG_ASSERT(typ);
5730 	  function_decl::parameter_sptr stripped
5731 	    (new function_decl::parameter(typ,
5732 					  p->get_index(),
5733 					  p->get_name(),
5734 					  p->get_location(),
5735 					  p->get_variadic_marker(),
5736 					  p->get_is_artificial()));
5737 	  parm.push_back(stripped);
5738 	}
5739       type_base_sptr p = strip_typedef(ty->get_return_type());
5740       ABG_ASSERT(!!p == !!ty->get_return_type());
5741       t.reset(new function_type(p, parm,
5742 				ty->get_size_in_bits(),
5743 				ty->get_alignment_in_bits()));
5744     }
5745 
5746   if (!t->get_environment())
5747     set_environment_for_artifact(t, env);
5748 
5749   if (!t->get_translation_unit())
5750     t->set_translation_unit(type->get_translation_unit());
5751 
5752   if (!(type->get_canonical_type() && canonicalize(t)))
5753     keep_type_alive(t);
5754 
5755   return t->get_canonical_type() ? t->get_canonical_type() : t;
5756 }
5757 
5758 /// Return the leaf underlying type node of a @ref typedef_decl node.
5759 ///
5760 /// If the underlying type of a @ref typedef_decl node is itself a
5761 /// @ref typedef_decl node, then recursively look at the underlying
5762 /// type nodes to get the first one that is not a a @ref typedef_decl
5763 /// node.  This is what a leaf underlying type node means.
5764 ///
5765 /// Otherwise, if the underlying type node of @ref typedef_decl is
5766 /// *NOT* a @ref typedef_decl node, then just return the underlying
5767 /// type node.
5768 ///
5769 /// And if the type node considered is not a @ref typedef_decl node,
5770 /// then just return it.
5771 ///
5772 /// @return the leaf underlying type node of a @p type.
5773 type_base_sptr
peel_typedef_type(const type_base_sptr & type)5774 peel_typedef_type(const type_base_sptr& type)
5775 {
5776   typedef_decl_sptr t = is_typedef(type);
5777   if (!t)
5778     return type;
5779 
5780   if (is_typedef(t->get_underlying_type()))
5781     return peel_typedef_type(t->get_underlying_type());
5782   return t->get_underlying_type();
5783 }
5784 
5785 /// Return the leaf underlying type node of a @ref typedef_decl node.
5786 ///
5787 /// If the underlying type of a @ref typedef_decl node is itself a
5788 /// @ref typedef_decl node, then recursively look at the underlying
5789 /// type nodes to get the first one that is not a a @ref typedef_decl
5790 /// node.  This is what a leaf underlying type node means.
5791 ///
5792 /// Otherwise, if the underlying type node of @ref typedef_decl is
5793 /// *NOT* a @ref typedef_decl node, then just return the underlying
5794 /// type node.
5795 ///
5796 /// And if the type node considered is not a @ref typedef_decl node,
5797 /// then just return it.
5798 ///
5799 /// @return the leaf underlying type node of a @p type.
5800 const type_base*
peel_typedef_type(const type_base * type)5801 peel_typedef_type(const type_base* type)
5802 {
5803   const typedef_decl* t = is_typedef(type);
5804   if (!t)
5805     return type;
5806 
5807   return peel_typedef_type(t->get_underlying_type()).get();
5808 }
5809 
5810 /// Return the leaf pointed-to type node of a @ref pointer_type_def
5811 /// node.
5812 ///
5813 /// If the pointed-to type of a @ref pointer_type_def node is itself a
5814 /// @ref pointer_type_def node, then recursively look at the
5815 /// pointed-to type nodes to get the first one that is not a a @ref
5816 /// pointer_type_def node.  This is what a leaf pointed-to type node
5817 /// means.
5818 ///
5819 /// Otherwise, if the pointed-to type node of @ref pointer_type_def is
5820 /// *NOT* a @ref pointer_type_def node, then just return the
5821 /// pointed-to type node.
5822 ///
5823 /// And if the type node considered is not a @ref pointer_type_def
5824 /// node, then just return it.
5825 ///
5826 /// @return the leaf pointed-to type node of a @p type.
5827 type_base_sptr
peel_pointer_type(const type_base_sptr & type)5828 peel_pointer_type(const type_base_sptr& type)
5829 {
5830   pointer_type_def_sptr t = is_pointer_type(type);
5831   if (!t)
5832     return type;
5833 
5834   if (is_pointer_type(t->get_pointed_to_type()))
5835     return peel_pointer_type(t->get_pointed_to_type());
5836   return t->get_pointed_to_type();
5837 }
5838 
5839 /// Return the leaf pointed-to type node of a @ref pointer_type_def
5840 /// node.
5841 ///
5842 /// If the pointed-to type of a @ref pointer_type_def node is itself a
5843 /// @ref pointer_type_def node, then recursively look at the
5844 /// pointed-to type nodes to get the first one that is not a a @ref
5845 /// pointer_type_def node.  This is what a leaf pointed-to type node
5846 /// means.
5847 ///
5848 /// Otherwise, if the pointed-to type node of @ref pointer_type_def is
5849 /// *NOT* a @ref pointer_type_def node, then just return the
5850 /// pointed-to type node.
5851 ///
5852 /// And if the type node considered is not a @ref pointer_type_def
5853 /// node, then just return it.
5854 ///
5855 /// @return the leaf pointed-to type node of a @p type.
5856 const type_base*
peel_pointer_type(const type_base * type)5857 peel_pointer_type(const type_base* type)
5858 {
5859   const pointer_type_def* t = is_pointer_type(type);
5860   if (!t)
5861     return type;
5862 
5863   return peel_pointer_type(t->get_pointed_to_type()).get();
5864 }
5865 
5866 /// Return the leaf pointed-to type node of a @ref reference_type_def
5867 /// node.
5868 ///
5869 /// If the pointed-to type of a @ref reference_type_def node is itself
5870 /// a @ref reference_type_def node, then recursively look at the
5871 /// pointed-to type nodes to get the first one that is not a a @ref
5872 /// reference_type_def node.  This is what a leaf pointed-to type node
5873 /// means.
5874 ///
5875 /// Otherwise, if the pointed-to type node of @ref reference_type_def
5876 /// is *NOT* a @ref reference_type_def node, then just return the
5877 /// pointed-to type node.
5878 ///
5879 /// And if the type node considered is not a @ref reference_type_def
5880 /// node, then just return it.
5881 ///
5882 /// @return the leaf pointed-to type node of a @p type.
5883 type_base_sptr
peel_reference_type(const type_base_sptr & type)5884 peel_reference_type(const type_base_sptr& type)
5885 {
5886   reference_type_def_sptr t = is_reference_type(type);
5887   if (!t)
5888     return type;
5889 
5890   if (is_reference_type(t->get_pointed_to_type()))
5891     return peel_reference_type(t->get_pointed_to_type());
5892   return t->get_pointed_to_type();
5893 }
5894 
5895 /// Return the leaf pointed-to type node of a @ref reference_type_def
5896 /// node.
5897 ///
5898 /// If the pointed-to type of a @ref reference_type_def node is itself
5899 /// a @ref reference_type_def node, then recursively look at the
5900 /// pointed-to type nodes to get the first one that is not a a @ref
5901 /// reference_type_def node.  This is what a leaf pointed-to type node
5902 /// means.
5903 ///
5904 /// Otherwise, if the pointed-to type node of @ref reference_type_def
5905 /// is *NOT* a @ref reference_type_def node, then just return the
5906 /// pointed-to type node.
5907 ///
5908 /// And if the type node considered is not a @ref reference_type_def
5909 /// node, then just return it.
5910 ///
5911 /// @return the leaf pointed-to type node of a @p type.
5912 const type_base*
peel_reference_type(const type_base * type)5913 peel_reference_type(const type_base* type)
5914 {
5915   const reference_type_def* t = is_reference_type(type);
5916   if (!t)
5917     return type;
5918 
5919   return peel_reference_type(t->get_pointed_to_type()).get();
5920 }
5921 
5922 /// Return the leaf element type of an array.
5923 ///
5924 /// If the element type is itself an array, then recursively return
5925 /// the element type of that array itself.
5926 ///
5927 /// @param type the array type to consider.  If this is not an array
5928 /// type, this type is returned by the function.
5929 ///
5930 /// @return the leaf element type of the array @p type, or, if it's
5931 /// not an array type, then just return @p.
5932 const type_base_sptr
peel_array_type(const type_base_sptr & type)5933 peel_array_type(const type_base_sptr& type)
5934 {
5935   const array_type_def_sptr t = is_array_type(type);
5936   if (!t)
5937     return type;
5938 
5939   return peel_array_type(t->get_element_type());
5940 }
5941 
5942 /// Return the leaf element type of an array.
5943 ///
5944 /// If the element type is itself an array, then recursively return
5945 /// the element type of that array itself.
5946 ///
5947 /// @param type the array type to consider.  If this is not an array
5948 /// type, this type is returned by the function.
5949 ///
5950 /// @return the leaf element type of the array @p type, or, if it's
5951 /// not an array type, then just return @p.
5952 const type_base*
peel_array_type(const type_base * type)5953 peel_array_type(const type_base* type)
5954 {
5955   const array_type_def* t = is_array_type(type);
5956   if (!t)
5957     return type;
5958 
5959   return peel_array_type(t->get_element_type()).get();
5960 }
5961 
5962 /// Return the leaf underlying type of a qualified type.
5963 ///
5964 /// If the underlying type is itself a qualified type, then
5965 /// recursively return the first underlying type of that qualified
5966 /// type to return the first underlying type that is not a qualified type.
5967 ///
5968 /// If the underlying type is NOT a qualified type, then just return
5969 /// that underlying type.
5970 ///
5971 /// @param type the qualified type to consider.
5972 ///
5973 /// @return the leaf underlying type.
5974 const type_base*
peel_qualified_type(const type_base * type)5975 peel_qualified_type(const type_base* type)
5976 {
5977   const qualified_type_def* t = is_qualified_type(type);
5978   if (!t)
5979     return type;
5980 
5981   return peel_qualified_type(t->get_underlying_type().get());
5982 }
5983 
5984 /// Return the leaf underlying type of a qualified type.
5985 ///
5986 /// If the underlying type is itself a qualified type, then
5987 /// recursively return the first underlying type of that qualified
5988 /// type to return the first underlying type that is not a qualified type.
5989 ///
5990 /// If the underlying type is NOT a qualified type, then just return
5991 /// that underlying type.
5992 ///
5993 /// @param type the qualified type to consider.
5994 ///
5995 /// @return the leaf underlying type.
5996 const type_base_sptr
peel_qualified_type(const type_base_sptr & type)5997 peel_qualified_type(const type_base_sptr& type)
5998 {
5999   const qualified_type_def_sptr t = is_qualified_type(type);
6000   if (!t)
6001     return type;
6002 
6003   return peel_qualified_type(t->get_underlying_type());
6004 }
6005 
6006 /// Return the leaf underlying type of a qualified or typedef type.
6007 ///
6008 /// If the underlying type is itself a qualified or typedef type, then
6009 /// recursively return the first underlying type of that qualified or
6010 /// typedef type to return the first underlying type that is not a
6011 /// qualified or typedef type.
6012 ///
6013 /// If the underlying type is NOT a qualified nor a typedef type, then
6014 /// just return that underlying type.
6015 ///
6016 /// @param type the qualified or typedef type to consider.
6017 ///
6018 /// @return the leaf underlying type.
6019 type_base*
peel_qualified_or_typedef_type(const type_base * type)6020 peel_qualified_or_typedef_type(const type_base* type)
6021 {
6022   while (is_typedef(type) || is_qualified_type(type))
6023     {
6024       if (const typedef_decl* t = is_typedef(type))
6025 	type = peel_typedef_type(t);
6026 
6027       if (const qualified_type_def* t = is_qualified_type(type))
6028 	type = peel_qualified_type(t);
6029     }
6030 
6031   return const_cast<type_base*>(type);
6032 }
6033 
6034 /// Return the leaf underlying type of a qualified or typedef type.
6035 ///
6036 /// If the underlying type is itself a qualified or typedef type, then
6037 /// recursively return the first underlying type of that qualified or
6038 /// typedef type to return the first underlying type that is not a
6039 /// qualified or typedef type.
6040 ///
6041 /// If the underlying type is NOT a qualified nor a typedef type, then
6042 /// just return that underlying type.
6043 ///
6044 /// @param type the qualified or typedef type to consider.
6045 ///
6046 /// @return the leaf underlying type.
6047 type_base_sptr
peel_qualified_or_typedef_type(const type_base_sptr & t)6048 peel_qualified_or_typedef_type(const type_base_sptr &t)
6049 {
6050   type_base_sptr type = t;
6051   while (is_typedef(type) || is_qualified_type(type))
6052     {
6053       if (typedef_decl_sptr t = is_typedef(type))
6054 	type = peel_typedef_type(t);
6055 
6056       if (qualified_type_def_sptr t = is_qualified_type(type))
6057 	type = peel_qualified_type(t);
6058     }
6059 
6060   return type;
6061 }
6062 
6063 /// Return the leaf underlying or pointed-to type node of a @ref
6064 /// typedef_decl, @ref pointer_type_def or @ref reference_type_def
6065 /// node.
6066 ///
6067 /// @param type the type to peel.
6068 ///
6069 /// @return the leaf underlying or pointed-to type node of @p type.
6070 type_base_sptr
peel_typedef_pointer_or_reference_type(const type_base_sptr type)6071 peel_typedef_pointer_or_reference_type(const type_base_sptr type)
6072 {
6073   type_base_sptr typ = type;
6074   while (is_typedef(typ)
6075 	 || is_pointer_type(typ)
6076 	 || is_reference_type(typ))
6077     {
6078       if (typedef_decl_sptr t = is_typedef(typ))
6079 	typ = peel_typedef_type(t);
6080 
6081       if (pointer_type_def_sptr t = is_pointer_type(typ))
6082 	typ = peel_pointer_type(t);
6083 
6084       if (reference_type_def_sptr t = is_reference_type(typ))
6085 	typ = peel_reference_type(t);
6086     }
6087 
6088   return typ;
6089 }
6090 
6091 /// Return the leaf underlying or pointed-to type node of a @ref
6092 /// typedef_decl, @ref pointer_type_def or @ref reference_type_def
6093 /// node.
6094 ///
6095 /// @param type the type to peel.
6096 ///
6097 /// @return the leaf underlying or pointed-to type node of @p type.
6098 type_base*
peel_typedef_pointer_or_reference_type(const type_base * type)6099 peel_typedef_pointer_or_reference_type(const type_base* type)
6100 {
6101   while (is_typedef(type)
6102 	 || is_pointer_type(type)
6103 	 || is_reference_type(type))
6104     {
6105       if (const typedef_decl* t = is_typedef(type))
6106 	type = peel_typedef_type(t);
6107 
6108       if (const pointer_type_def* t = is_pointer_type(type))
6109 	type = peel_pointer_type(t);
6110 
6111       if (const reference_type_def* t = is_reference_type(type))
6112 	type = peel_reference_type(t);
6113     }
6114 
6115   return const_cast<type_base*>(type);
6116 }
6117 
6118 /// Return the leaf underlying or pointed-to type node of a, @ref
6119 /// pointer_type_def, @ref reference_type_def or @ref
6120 /// qualified_type_def type node.
6121 ///
6122 /// @param type the type to peel.
6123 ///
6124 /// @param peel_qualified_type if true, also peel qualified types.
6125 ///
6126 /// @return the leaf underlying or pointed-to type node of @p type.
6127 type_base*
peel_pointer_or_reference_type(const type_base * type,bool peel_qual_type)6128 peel_pointer_or_reference_type(const type_base *type,
6129 			       bool peel_qual_type)
6130 {
6131   while (is_pointer_type(type)
6132 	 || is_reference_type(type)
6133 	 || (peel_qual_type && is_qualified_type(type)))
6134     {
6135       if (const pointer_type_def* t = is_pointer_type(type))
6136 	type = peel_pointer_type(t);
6137 
6138       if (const reference_type_def* t = is_reference_type(type))
6139 	type = peel_reference_type(t);
6140 
6141       if (const array_type_def* t = is_array_type(type))
6142 	type = peel_array_type(t);
6143 
6144       if (peel_qual_type)
6145 	if (const qualified_type_def* t = is_qualified_type(type))
6146 	  type = peel_qualified_type(t);
6147     }
6148 
6149   return const_cast<type_base*>(type);
6150 }
6151 
6152 /// Clone an array type.
6153 ///
6154 /// Note that the element type of the new array is shared witht the
6155 /// old one.
6156 ///
6157 /// @param array the array type to clone.
6158 ///
6159 /// @return a newly built array type.  Note that it needs to be added
6160 /// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
6161 /// bound to the one of that scope.  Otherwise, its lifetime is bound
6162 /// to the lifetime of its containing shared pointer.
6163 array_type_def_sptr
clone_array(const array_type_def_sptr & array)6164 clone_array(const array_type_def_sptr& array)
6165 {
6166   vector<array_type_def::subrange_sptr> subranges;
6167 
6168   for (vector<array_type_def::subrange_sptr>::const_iterator i =
6169 	 array->get_subranges().begin();
6170        i != array->get_subranges().end();
6171        ++i)
6172     {
6173       array_type_def::subrange_sptr subrange
6174 	(new array_type_def::subrange_type(array->get_environment(),
6175 					   (*i)->get_name(),
6176 					   (*i)->get_lower_bound(),
6177 					   (*i)->get_upper_bound(),
6178 					   (*i)->get_underlying_type(),
6179 					   (*i)->get_location(),
6180 					   (*i)->get_language()));
6181       subrange->is_infinite((*i)->is_infinite());
6182       if (scope_decl *scope = (*i)->get_scope())
6183 	add_decl_to_scope(subrange, scope);
6184       subranges.push_back(subrange);
6185     }
6186 
6187   array_type_def_sptr result
6188     (new array_type_def(array->get_element_type(),
6189 			subranges, array->get_location()));
6190 
6191   return result;
6192 }
6193 
6194 /// Clone a typedef type.
6195 ///
6196 /// Note that the underlying type of the newly constructed typedef is
6197 /// shared with the old one.
6198 ///
6199 /// @param t the typedef to clone.
6200 ///
6201 /// @return the newly constructed typedef.  Note that it needs to be
6202 /// added to a scope (e.g, using add_decl_to_scope) for its lifetime
6203 /// to be bound to the one of that scope.  Otherwise, its lifetime is
6204 /// bound to the lifetime of its containing shared pointer.
6205 typedef_decl_sptr
clone_typedef(const typedef_decl_sptr & t)6206 clone_typedef(const typedef_decl_sptr& t)
6207 {
6208   if (!t)
6209     return t;
6210 
6211   typedef_decl_sptr result
6212     (new typedef_decl(t->get_name(), t->get_underlying_type(),
6213 		      t->get_location(), t->get_linkage_name(),
6214 		      t->get_visibility()));
6215   return result;
6216 }
6217 
6218 /// Clone a qualifiend type.
6219 ///
6220 /// Note that underlying type of the newly constructed qualified type
6221 /// is shared with the old one.
6222 ///
6223 /// @param t the qualified type to clone.
6224 ///
6225 /// @return the newly constructed qualified type.  Note that it needs
6226 /// to be added to a scope (e.g, using add_decl_to_scope) for its
6227 /// lifetime to be bound to the one of that scope.  Otherwise, its
6228 /// lifetime is bound to the lifetime of its containing shared
6229 /// pointer.
6230 qualified_type_def_sptr
clone_qualified_type(const qualified_type_def_sptr & t)6231 clone_qualified_type(const qualified_type_def_sptr& t)
6232 {
6233   if (!t)
6234     return t;
6235 
6236   qualified_type_def_sptr result
6237     (new qualified_type_def(t->get_underlying_type(),
6238 			    t->get_cv_quals(), t->get_location()));
6239 
6240   return result;
6241 }
6242 
6243 /// Clone a typedef, an array or a qualified tree.
6244 ///
6245 /// @param type the typedef, array or qualified tree to clone.  any
6246 /// order.
6247 ///
6248 /// @return the cloned type, or NULL if @type was neither a typedef,
6249 /// array nor a qualified type.
6250 static type_base_sptr
clone_typedef_array_qualified_type(type_base_sptr type)6251 clone_typedef_array_qualified_type(type_base_sptr type)
6252 {
6253   if (!type)
6254     return type;
6255 
6256   scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
6257   type_base_sptr result;
6258 
6259   if (typedef_decl_sptr t = is_typedef(type))
6260     result = clone_typedef(is_typedef(t));
6261   else if (qualified_type_def_sptr t = is_qualified_type(type))
6262     result = clone_qualified_type(t);
6263   else if (array_type_def_sptr t = is_array_type(type))
6264     result = clone_array(t);
6265   else
6266     return type_base_sptr();
6267 
6268   if (scope)
6269     add_decl_to_scope(is_decl(result), scope);
6270 
6271   return result;
6272 }
6273 
6274 /// Clone a type tree made of an array or a typedef of array.
6275 ///
6276 /// Note that this can be a tree which root node is a typedef an which
6277 /// sub-tree can be any arbitrary combination of typedef, qualified
6278 /// type and arrays.
6279 ///
6280 /// @param t the array or typedef of qualified array to consider.
6281 ///
6282 /// @return a clone of @p t.
6283 type_base_sptr
clone_array_tree(const type_base_sptr t)6284 clone_array_tree(const type_base_sptr t)
6285 {
6286   ABG_ASSERT(is_typedef_of_array(t) || is_array_type(t));
6287 
6288   scope_decl* scope = is_decl(t)->get_scope();
6289   type_base_sptr result = clone_typedef_array_qualified_type(t);
6290   ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
6291 
6292   type_base_sptr subtree;
6293   if (typedef_decl_sptr type = is_typedef(result))
6294     {
6295       type_base_sptr s =
6296 	clone_typedef_array_qualified_type(type->get_underlying_type());
6297       if (s)
6298 	{
6299 	  subtree = s;
6300 	  type->set_underlying_type(subtree);
6301 	}
6302     }
6303   else if (array_type_def_sptr type = is_array_type(result))
6304     {
6305       type_base_sptr s =
6306 	clone_typedef_array_qualified_type(type->get_element_type());
6307       if (s)
6308 	{
6309 	  subtree = s;
6310 	  type->set_element_type(subtree);
6311 	}
6312     }
6313   add_decl_to_scope(is_decl(subtree), scope);
6314 
6315   for (;;)
6316     {
6317       if (typedef_decl_sptr t = is_typedef(subtree))
6318 	{
6319 	  type_base_sptr s =
6320 	    clone_typedef_array_qualified_type(t->get_underlying_type());
6321 	  if (s)
6322 	    {
6323 	      scope_decl* scope =
6324 		is_decl(t->get_underlying_type())->get_scope();
6325 	      ABG_ASSERT(scope);
6326 	      add_decl_to_scope(is_decl(s), scope);
6327 	      t->set_underlying_type (s);
6328 	      subtree = s;
6329 	    }
6330 	  else
6331 	    break;
6332 	}
6333       else if (qualified_type_def_sptr t = is_qualified_type(subtree))
6334 	{
6335 	  type_base_sptr s =
6336 	    clone_typedef_array_qualified_type(t->get_underlying_type());
6337 	  if (s)
6338 	    {
6339 	      scope_decl* scope =
6340 		is_decl(t->get_underlying_type())->get_scope();
6341 	      ABG_ASSERT(scope);
6342 	      add_decl_to_scope(is_decl(s), scope);
6343 	      t->set_underlying_type(s);
6344 	      subtree = s;
6345 	    }
6346 	  else
6347 	    break;
6348 	}
6349       else if (array_type_def_sptr t = is_array_type(subtree))
6350 	{
6351 	  type_base_sptr e = t->get_element_type();
6352 	  if (is_typedef(e) || is_qualified_type(e))
6353 	    {
6354 	      type_base_sptr s =
6355 		clone_typedef_array_qualified_type(e);
6356 	      if (s)
6357 		{
6358 		  scope_decl* scope = is_decl(e)->get_scope();
6359 		  ABG_ASSERT(scope);
6360 		  add_decl_to_scope(is_decl(s), scope);
6361 		  t->set_element_type(s);
6362 		}
6363 	      else
6364 		break;
6365 	    }
6366 	  break;
6367 	}
6368       else
6369 	break;
6370     }
6371   return result;
6372 }
6373 
6374 /// Update the qualified name of a given sub-tree.
6375 ///
6376 /// @param d the sub-tree for which to update the qualified name.
6377 static void
update_qualified_name(decl_base * d)6378 update_qualified_name(decl_base * d)
6379 {
6380   ::qualified_name_setter setter;
6381   d->traverse(setter);
6382 }
6383 
6384 /// Update the qualified name of a given sub-tree.
6385 ///
6386 /// @param d the sub-tree for which to update the qualified name.
6387 static void
update_qualified_name(decl_base_sptr d)6388 update_qualified_name(decl_base_sptr d)
6389 {return update_qualified_name(d.get());}
6390 
6391 // <scope_decl stuff>
6392 
6393 /// Hash a type by returning the pointer value of its canonical type.
6394 ///
6395 /// @param l the type to hash.
6396 ///
6397 /// @return the the pointer value of the canonical type of @p l.
6398 size_t
operator ()(const type_base_sptr & l) const6399 canonical_type_hash::operator()(const type_base_sptr& l) const
6400 {return operator()(l.get());}
6401 
6402 /// Hash a (canonical) type by returning its pointer value
6403 ///
6404 /// @param l the canonical type to hash.
6405 ///
6406 /// @return the pointer value of the canonical type of @p l.
6407 size_t
operator ()(const type_base * l) const6408 canonical_type_hash::operator()(const type_base *l) const
6409 {return reinterpret_cast<size_t>(l);}
6410 
6411 struct scope_decl::priv
6412 {
6413   declarations members_;
6414   declarations sorted_members_;
6415   scopes member_scopes_;
6416   canonical_type_sptr_set_type canonical_types_;
6417   type_base_sptrs_type sorted_canonical_types_;
6418 }; // end struct scope_decl::priv
6419 
6420 /// Constructor of the @ref scope_decl type.
6421 ///
6422 /// @param the environment to use for the new instance.
6423 ///
6424 /// @param the name of the scope decl.
6425 ///
6426 /// @param locus the source location where the scope_decl is defined.
6427 ///
6428 /// @param vis the visibility of the declaration.
scope_decl(const environment * env,const string & name,const location & locus,visibility vis)6429 scope_decl::scope_decl(const environment* env,
6430 		       const string& name,
6431 		       const location& locus,
6432 		       visibility vis)
6433   : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
6434     decl_base(env, name, locus, /*mangled_name=*/name, vis),
6435     priv_(new priv)
6436 {}
6437 
6438 /// Constructor of the @ref scope_decl type.
6439 ///
6440 /// @param the environment to use for the new instance.
6441 ///
6442 /// @param l the source location where the scope_decl is defined.
6443 ///
6444 /// @param vis the visibility of the declaration.
scope_decl(const environment * env,location & l)6445 scope_decl::scope_decl(const environment* env, location& l)
6446   : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
6447     decl_base(env, "", l),
6448     priv_(new priv)
6449 {}
6450 
6451 /// @eturn the set of canonical types of the the current scope.
6452 canonical_type_sptr_set_type&
get_canonical_types()6453 scope_decl::get_canonical_types()
6454 {return priv_->canonical_types_;}
6455 
6456 /// @eturn the set of canonical types of the the current scope.
6457 const canonical_type_sptr_set_type&
get_canonical_types() const6458 scope_decl::get_canonical_types() const
6459 {return const_cast<scope_decl*>(this)->get_canonical_types();}
6460 
6461 /// Return a vector of sorted canonical types of the current scope.
6462 ///
6463 /// The types are sorted "almost topologically". That means, they are
6464 /// sorted using the lexicographic order of the string representing
6465 /// the location their definition point.  If a type doesn't have a
6466 /// location, then its pretty representation is used.
6467 ///
6468 /// @return a vector of sorted canonical types of the current scope.
6469 const type_base_sptrs_type&
get_sorted_canonical_types() const6470 scope_decl::get_sorted_canonical_types() const
6471 {
6472   if (priv_->sorted_canonical_types_.empty())
6473     {
6474       for (canonical_type_sptr_set_type::const_iterator e =
6475 	     get_canonical_types().begin();
6476 	   e != get_canonical_types().end();
6477 	   ++e)
6478 	priv_->sorted_canonical_types_.push_back(*e);
6479 
6480       type_topo_comp comp;
6481       std::stable_sort(priv_->sorted_canonical_types_.begin(),
6482 		       priv_->sorted_canonical_types_.end(),
6483 		       comp);
6484     }
6485   return priv_->sorted_canonical_types_;
6486 }
6487 
6488 /// Getter for the member declarations carried by the current @ref
6489 /// scope_decl.
6490 ///
6491 /// @return the member declarations carried by the current @ref
6492 /// scope_decl.
6493 const scope_decl::declarations&
get_member_decls() const6494 scope_decl::get_member_decls() const
6495 {return priv_->members_;}
6496 
6497 /// Getter for the member declarations carried by the current @ref
6498 /// scope_decl.
6499 ///
6500 /// @return the member declarations carried by the current @ref
6501 /// scope_decl.
6502 scope_decl::declarations&
get_member_decls()6503 scope_decl::get_member_decls()
6504 {return priv_->members_;}
6505 
6506 /// Getter for the sorted member declarations carried by the current
6507 /// @ref scope_decl.
6508 ///
6509 /// @return the sorted member declarations carried by the current @ref
6510 /// scope_decl.  The declarations are sorted topologically.
6511 const scope_decl::declarations&
get_sorted_member_decls() const6512 scope_decl::get_sorted_member_decls() const
6513 {
6514   decl_topo_comp comp;
6515   if (priv_->sorted_members_.empty())
6516     {
6517       for (declarations::const_iterator i = get_member_decls().begin();
6518 	   i != get_member_decls().end();
6519 	   ++i)
6520 	priv_->sorted_members_.push_back(*i);
6521 
6522       std::stable_sort(priv_->sorted_members_.begin(),
6523 		       priv_->sorted_members_.end(),
6524 		       comp);
6525     }
6526   return priv_->sorted_members_;
6527 }
6528 
6529 /// Getter for the number of anonymous classes contained in this
6530 /// scope.
6531 ///
6532 /// @return the number of anonymous classes contained in this scope.
6533 size_t
get_num_anonymous_member_classes() const6534 scope_decl::get_num_anonymous_member_classes() const
6535 {
6536   int result = 0;
6537   for (declarations::const_iterator it = get_member_decls().begin();
6538        it != get_member_decls().end();
6539        ++it)
6540     if (class_decl_sptr t = is_class_type(*it))
6541       if (t->get_is_anonymous())
6542 	++result;
6543 
6544   return result;
6545 }
6546 
6547 /// Getter for the number of anonymous unions contained in this
6548 /// scope.
6549 ///
6550 /// @return the number of anonymous unions contained in this scope.
6551 size_t
get_num_anonymous_member_unions() const6552 scope_decl::get_num_anonymous_member_unions() const
6553 {
6554   int result = 0;
6555   for (declarations::const_iterator it = get_member_decls().begin();
6556        it != get_member_decls().end();
6557        ++it)
6558     if (union_decl_sptr t = is_union_type(*it))
6559       if (t->get_is_anonymous())
6560 	++result;
6561 
6562   return result;
6563 }
6564 
6565 /// Getter for the number of anonymous enums contained in this
6566 /// scope.
6567 ///
6568 /// @return the number of anonymous enums contained in this scope.
6569 size_t
get_num_anonymous_member_enums() const6570 scope_decl::get_num_anonymous_member_enums() const
6571 {
6572   int result = 0;
6573   for (declarations::const_iterator it = get_member_decls().begin();
6574        it != get_member_decls().end();
6575        ++it)
6576     if (enum_type_decl_sptr t = is_enum_type(*it))
6577       if (t->get_is_anonymous())
6578 	++result;
6579 
6580   return result;
6581 }
6582 
6583 /// Getter for the scopes carried by the current scope.
6584 ///
6585 /// @return the scopes carried by the current scope.
6586 scope_decl::scopes&
get_member_scopes()6587 scope_decl::get_member_scopes()
6588 {return priv_->member_scopes_;}
6589 
6590 /// Getter for the scopes carried by the current scope.
6591 ///
6592 /// @return the scopes carried by the current scope.
6593 const scope_decl::scopes&
get_member_scopes() const6594 scope_decl::get_member_scopes() const
6595 {return priv_->member_scopes_;}
6596 
6597 /// Test if the current scope is empty.
6598 ///
6599 /// @return true iff the current scope is empty.
6600 bool
is_empty() const6601 scope_decl::is_empty() const
6602 {
6603   return (get_member_decls().empty()
6604 	  && get_canonical_types().empty());
6605 }
6606 
6607 /// Add a member decl to this scope.  Note that user code should not
6608 /// use this, but rather use add_decl_to_scope.
6609 ///
6610 /// Note that this function updates the qualified name of the member
6611 /// decl that is added.  It also sets the scope of the member.  Thus,
6612 /// it ABG_ASSERTs that member should not have its scope set, prior to
6613 /// calling this function.
6614 ///
6615 /// @param member the new member decl to add to this scope.
6616 decl_base_sptr
add_member_decl(const decl_base_sptr & member)6617 scope_decl::add_member_decl(const decl_base_sptr& member)
6618 {
6619   ABG_ASSERT(!has_scope(member));
6620 
6621   member->set_scope(this);
6622   priv_->members_.push_back(member);
6623 
6624   if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
6625     priv_->member_scopes_.push_back(m);
6626 
6627   update_qualified_name(member);
6628 
6629   // Propagate scope anonymity
6630   if (get_has_anonymous_parent()
6631       || (!is_global_scope(this) && get_is_anonymous()))
6632     member->set_has_anonymous_parent(true);
6633 
6634   if (const environment* env = get_environment())
6635     set_environment_for_artifact(member, env);
6636 
6637   if (translation_unit* tu = get_translation_unit())
6638     {
6639       if (translation_unit* existing_tu = member->get_translation_unit())
6640 	ABG_ASSERT(tu == existing_tu);
6641       else
6642 	member->set_translation_unit(tu);
6643     }
6644 
6645   maybe_update_types_lookup_map(member);
6646 
6647   return member;
6648 }
6649 
6650 /// Insert a member decl to this scope, right before an element
6651 /// pointed to by a given iterator.  Note that user code should not
6652 /// use this, but rather use insert_decl_into_scope.
6653 ///
6654 /// Note that this function updates the qualified name of the inserted
6655 /// member.
6656 ///
6657 /// @param member the new member decl to add to this scope.
6658 ///
6659 /// @param before an interator pointing to the element before which
6660 /// the new member should be inserted.
6661 decl_base_sptr
insert_member_decl(decl_base_sptr member,declarations::iterator before)6662 scope_decl::insert_member_decl(decl_base_sptr member,
6663 			       declarations::iterator before)
6664 {
6665   ABG_ASSERT(!member->get_scope());
6666 
6667   member->set_scope(this);
6668   priv_->members_.insert(before, member);
6669 
6670   if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
6671    priv_-> member_scopes_.push_back(m);
6672 
6673   update_qualified_name(member);
6674 
6675   if (const environment* env = get_environment())
6676     set_environment_for_artifact(member, env);
6677 
6678   if (translation_unit* tu = get_translation_unit())
6679     {
6680       if (translation_unit* existing_tu = member->get_translation_unit())
6681 	ABG_ASSERT(tu == existing_tu);
6682       else
6683 	member->set_translation_unit(tu);
6684     }
6685 
6686   maybe_update_types_lookup_map(member);
6687 
6688   return member;
6689 }
6690 
6691 /// Remove a declaration from the current scope.
6692 ///
6693 /// @param member the declaration to remove from the scope.
6694 void
remove_member_decl(decl_base_sptr member)6695 scope_decl::remove_member_decl(decl_base_sptr member)
6696 {
6697   for (declarations::iterator i = priv_->members_.begin();
6698        i != priv_->members_.end();
6699        ++i)
6700     {
6701       if (**i == *member)
6702 	{
6703 	  priv_->members_.erase(i);
6704 	  // Do not access i after this point as it's invalided by the
6705 	  // erase call.
6706 	  break;
6707 	}
6708     }
6709 
6710   scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
6711   if (scope)
6712     {
6713       for (scopes::iterator i = priv_->member_scopes_.begin();
6714 	   i != priv_->member_scopes_.end();
6715 	   ++i)
6716 	{
6717 	  if (**i == *member)
6718 	    {
6719 	      priv_->member_scopes_.erase(i);
6720 	      break;
6721 	    }
6722 	}
6723     }
6724 }
6725 
6726 /// Return the hash value for the current instance of scope_decl.
6727 ///
6728 /// This method can trigger the computing of the hash value, if need be.
6729 ///
6730 /// @return the hash value.
6731 size_t
get_hash() const6732 scope_decl::get_hash() const
6733 {
6734   scope_decl::hash hash_scope;
6735   return hash_scope(this);
6736 }
6737 
6738 /// Compares two instances of @ref scope_decl.
6739 ///
6740 /// If the two intances are different, set a bitfield to give some
6741 /// insight about the kind of differences there are.
6742 ///
6743 /// @param l the first artifact of the comparison.
6744 ///
6745 /// @param r the second artifact of the comparison.
6746 ///
6747 /// @param k a pointer to a bitfield that gives information about the
6748 /// kind of changes there are between @p l and @p r.  This one is set
6749 /// iff @p k is non-null and the function returns false.
6750 ///
6751 /// Please note that setting k to a non-null value does have a
6752 /// negative performance impact because even if @p l and @p r are not
6753 /// equal, the function keeps up the comparison in order to determine
6754 /// the different kinds of ways in which they are different.
6755 ///
6756 /// @return true if @p l equals @p r, false otherwise.
6757 bool
equals(const scope_decl & l,const scope_decl & r,change_kind * k)6758 equals(const scope_decl& l, const scope_decl& r, change_kind* k)
6759 {
6760   bool result = true;
6761 
6762   if (!l.decl_base::operator==(r))
6763     {
6764       result = false;
6765       if (k)
6766 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
6767       else
6768 	return false;
6769     }
6770 
6771   scope_decl::declarations::const_iterator i, j;
6772   for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
6773        i != l.get_member_decls().end() && j != r.get_member_decls().end();
6774        ++i, ++j)
6775     {
6776       if (**i != **j)
6777 	{
6778 	  result = false;
6779 	  if (k)
6780 	    {
6781 	      *k |= SUBTYPE_CHANGE_KIND;
6782 	      break;
6783 	    }
6784 	  else
6785 	    return false;
6786 	}
6787     }
6788 
6789   if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
6790     {
6791       result = false;
6792       if (k)
6793 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
6794       else
6795 	return false;
6796     }
6797 
6798   return result;
6799 }
6800 
6801 /// Return true iff both scopes have the same names and have the same
6802 /// member decls.
6803 ///
6804 /// This function doesn't check for equality of the scopes of its
6805 /// arguments.
6806 bool
operator ==(const decl_base & o) const6807 scope_decl::operator==(const decl_base& o) const
6808 {
6809   const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
6810   if (!other)
6811     return false;
6812 
6813   return equals(*this, *other, 0);
6814 }
6815 
6816 /// Equality operator for @ref scope_decl_sptr.
6817 ///
6818 /// @param l the left hand side operand of the equality operator.
6819 ///
6820 /// @pram r the right hand side operand of the equalify operator.
6821 ///
6822 /// @return true iff @p l equals @p r.
6823 bool
operator ==(const scope_decl_sptr & l,const scope_decl_sptr & r)6824 operator==(const scope_decl_sptr& l, const scope_decl_sptr& r)
6825 {
6826   if (!!l != !!r)
6827     return false;
6828   if (l.get() == r.get())
6829     return true;
6830   return *l == *r;
6831 }
6832 
6833 /// Inequality operator for @ref scope_decl_sptr.
6834 ///
6835 /// @param l the left hand side operand of the equality operator.
6836 ///
6837 /// @pram r the right hand side operand of the equalify operator.
6838 ///
6839 /// @return true iff @p l equals @p r.
6840 bool
operator !=(const scope_decl_sptr & l,const scope_decl_sptr & r)6841 operator!=(const scope_decl_sptr& l, const scope_decl_sptr& r)
6842 {return !operator==(l, r);}
6843 
6844 /// Find a member of the current scope and return an iterator on it.
6845 ///
6846 /// @param decl the scope member to find.
6847 ///
6848 /// @param i the iterator to set to the member @p decl.  This is set
6849 /// iff the function returns true.
6850 ///
6851 /// @return true if the member decl was found, false otherwise.
6852 bool
find_iterator_for_member(const decl_base * decl,declarations::iterator & i)6853 scope_decl::find_iterator_for_member(const decl_base* decl,
6854 				     declarations::iterator& i)
6855 {
6856   if (!decl)
6857     return false;
6858 
6859   if (get_member_decls().empty())
6860     {
6861       i = get_member_decls().end();
6862       return false;
6863     }
6864 
6865   for (declarations::iterator it = get_member_decls().begin();
6866        it != get_member_decls().end();
6867        ++it)
6868     {
6869       if ((*it).get() == decl)
6870 	{
6871 	  i = it;
6872 	  return true;
6873 	}
6874     }
6875 
6876   return false;
6877 }
6878 
6879 /// Find a member of the current scope and return an iterator on it.
6880 ///
6881 /// @param decl the scope member to find.
6882 ///
6883 /// @param i the iterator to set to the member @p decl.  This is set
6884 /// iff the function returns true.
6885 ///
6886 /// @return true if the member decl was found, false otherwise.
6887 bool
find_iterator_for_member(const decl_base_sptr decl,declarations::iterator & i)6888 scope_decl::find_iterator_for_member(const decl_base_sptr decl,
6889 				     declarations::iterator& i)
6890 {return find_iterator_for_member(decl.get(), i);}
6891 
6892 /// This implements the ir_traversable_base::traverse pure virtual
6893 /// function.
6894 ///
6895 /// @param v the visitor used on the current instance of scope_decl
6896 /// and on its member nodes.
6897 ///
6898 /// @return true if the traversal of the tree should continue, false
6899 /// otherwise.
6900 bool
traverse(ir_node_visitor & v)6901 scope_decl::traverse(ir_node_visitor &v)
6902 {
6903   if (visiting())
6904     return true;
6905 
6906   if (v.visit_begin(this))
6907     {
6908       visiting(true);
6909       for (scope_decl::declarations::const_iterator i =
6910 	     get_member_decls().begin();
6911 	   i != get_member_decls ().end();
6912 	   ++i)
6913 	if (!(*i)->traverse(v))
6914 	  break;
6915       visiting(false);
6916     }
6917   return v.visit_end(this);
6918 }
6919 
~scope_decl()6920 scope_decl::~scope_decl()
6921 {}
6922 
6923 /// Appends a declaration to a given scope, if the declaration
6924 /// doesn't already belong to one.
6925 ///
6926 /// @param decl the declaration to add to the scope
6927 ///
6928 /// @param scope the scope to append the declaration to
6929 decl_base_sptr
add_decl_to_scope(decl_base_sptr decl,scope_decl * scope)6930 add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
6931 {
6932   ABG_ASSERT(scope);
6933 
6934   if (scope && decl && !decl->get_scope())
6935     decl = scope->add_member_decl(decl);
6936 
6937   return decl;
6938 }
6939 
6940 /// Appends a declaration to a given scope, if the declaration doesn't
6941 /// already belong to a scope.
6942 ///
6943 /// @param decl the declaration to add append to the scope
6944 ///
6945 /// @param scope the scope to append the decl to
6946 decl_base_sptr
add_decl_to_scope(decl_base_sptr decl,const scope_decl_sptr & scope)6947 add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
6948 {return add_decl_to_scope(decl, scope.get());}
6949 
6950 /// Remove a given decl from its scope
6951 ///
6952 /// @param decl the decl to remove from its scope.
6953 void
remove_decl_from_scope(decl_base_sptr decl)6954 remove_decl_from_scope(decl_base_sptr decl)
6955 {
6956   if (!decl)
6957     return;
6958 
6959   scope_decl* scope = decl->get_scope();
6960   scope->remove_member_decl(decl);
6961   decl->set_scope(0);
6962 }
6963 
6964 /// Inserts a declaration into a given scope, before a given IR child
6965 /// node of the scope.
6966 ///
6967 /// @param decl the declaration to insert into the scope.
6968 ///
6969 /// @param before an iterator pointing to the child IR node before
6970 /// which to insert the declaration.
6971 ///
6972 /// @param scope the scope into which to insert the declaration.
6973 decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,scope_decl::declarations::iterator before,scope_decl * scope)6974 insert_decl_into_scope(decl_base_sptr decl,
6975 		       scope_decl::declarations::iterator before,
6976 		       scope_decl* scope)
6977 {
6978   if (scope && decl && !decl->get_scope())
6979     {
6980       decl_base_sptr d = scope->insert_member_decl(decl, before);
6981       decl = d;
6982     }
6983   return decl;
6984 }
6985 
6986 /// Inserts a declaration into a given scope, before a given IR child
6987 /// node of the scope.
6988 ///
6989 /// @param decl the declaration to insert into the scope.
6990 ///
6991 /// @param before an iterator pointing to the child IR node before
6992 /// which to insert the declaration.
6993 ///
6994 /// @param scope the scope into which to insert the declaration.
6995 decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,scope_decl::declarations::iterator before,scope_decl_sptr scope)6996 insert_decl_into_scope(decl_base_sptr decl,
6997 		       scope_decl::declarations::iterator before,
6998 		       scope_decl_sptr scope)
6999 {return insert_decl_into_scope(decl, before, scope.get());}
7000 
7001 /// Constructor of the @ref global_scope type.
7002 ///
7003 /// @param tu the translation unit the scope belongs to.
global_scope(translation_unit * tu)7004 global_scope::global_scope(translation_unit *tu)
7005   : type_or_decl_base(tu->get_environment(),
7006 		      GLOBAL_SCOPE_DECL
7007 		      | ABSTRACT_DECL_BASE
7008 		      | ABSTRACT_SCOPE_DECL),
7009     decl_base(tu->get_environment(), "", location()),
7010     scope_decl(tu->get_environment(), "", location()),
7011     translation_unit_(tu)
7012 {
7013   runtime_type_instance(this);
7014 }
7015 
7016 /// return the global scope as seen by a given declaration.
7017 ///
7018 /// @param decl the declaration to consider.
7019 ///
7020 /// @return the global scope of the decl, or a null pointer if the
7021 /// decl is not yet added to a translation_unit.
7022 const global_scope*
get_global_scope(const decl_base & decl)7023 get_global_scope(const decl_base& decl)
7024 {
7025   if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
7026     return s;
7027 
7028   scope_decl* scope = decl.get_scope();
7029   while (scope && !dynamic_cast<global_scope*>(scope))
7030     scope = scope->get_scope();
7031 
7032   return scope ? dynamic_cast<global_scope*> (scope) : 0;
7033 }
7034 
7035 /// return the global scope as seen by a given declaration.
7036 ///
7037 /// @param decl the declaration to consider.
7038 ///
7039 /// @return the global scope of the decl, or a null pointer if the
7040 /// decl is not yet added to a translation_unit.
7041 const global_scope*
get_global_scope(const decl_base * decl)7042 get_global_scope(const decl_base* decl)
7043 {return get_global_scope(*decl);}
7044 
7045 /// Return the global scope as seen by a given declaration.
7046 ///
7047 /// @param decl the declaration to consider.
7048 ///
7049 /// @return the global scope of the decl, or a null pointer if the
7050 /// decl is not yet added to a translation_unit.
7051 const global_scope*
get_global_scope(const shared_ptr<decl_base> decl)7052 get_global_scope(const shared_ptr<decl_base> decl)
7053 {return get_global_scope(decl.get());}
7054 
7055 /// Return the a scope S containing a given declaration and that is
7056 /// right under a given scope P.
7057 ///
7058 /// Note that @p scope must come before @p decl in topological
7059 /// order.
7060 ///
7061 /// @param decl the decl for which to find a scope.
7062 ///
7063 /// @param scope the scope under which the resulting scope must be.
7064 ///
7065 /// @return the resulting scope.
7066 const scope_decl*
get_top_most_scope_under(const decl_base * decl,const scope_decl * scope)7067 get_top_most_scope_under(const decl_base* decl,
7068 			 const scope_decl* scope)
7069 {
7070   if (!decl)
7071     return 0;
7072 
7073   if (scope == 0)
7074     return get_global_scope(decl);
7075 
7076   // Handle the case where decl is a scope itself.
7077   const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
7078   if (!s)
7079     s = decl->get_scope();
7080 
7081   if (is_global_scope(s))
7082     return scope;
7083 
7084   // Here, decl is in the scope 'scope', or decl and 'scope' are the
7085   // same.  The caller needs to be prepared to deal with this case.
7086   if (s == scope)
7087     return s;
7088 
7089   while (s && !is_global_scope(s) && s->get_scope() != scope)
7090     s = s->get_scope();
7091 
7092   if (!s || is_global_scope(s))
7093     // SCOPE must come before decl in topological order, but I don't
7094     // know how to ensure that ...
7095     return scope;
7096   ABG_ASSERT(s);
7097 
7098   return s;
7099 }
7100 
7101 /// Return the a scope S containing a given declaration and that is
7102 /// right under a given scope P.
7103 ///
7104 /// @param decl the decl for which to find a scope.
7105 ///
7106 /// @param scope the scope under which the resulting scope must be.
7107 ///
7108 /// @return the resulting scope.
7109 const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,const scope_decl * scope)7110 get_top_most_scope_under(const decl_base_sptr decl,
7111 			 const scope_decl* scope)
7112 {return get_top_most_scope_under(decl.get(), scope);}
7113 
7114 /// Return the a scope S containing a given declaration and that is
7115 /// right under a given scope P.
7116 ///
7117 /// @param decl the decl for which to find a scope.
7118 ///
7119 /// @param scope the scope under which the resulting scope must be.
7120 ///
7121 /// @return the resulting scope.
7122 const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,const scope_decl_sptr scope)7123 get_top_most_scope_under(const decl_base_sptr decl,
7124 			 const scope_decl_sptr scope)
7125 {return get_top_most_scope_under(decl, scope.get());}
7126 
7127 // </scope_decl stuff>
7128 
7129 
7130 /// Get the string representation of a CV qualifier bitmap.
7131 ///
7132 /// @param cv_quals the bitmap of CV qualifiers to consider.
7133 ///
7134 /// @return the string representation.
7135 string
get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)7136 get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)
7137 {
7138   string repr;
7139   if (cv_quals & qualified_type_def::CV_RESTRICT)
7140     repr = "restrict";
7141   if (cv_quals & qualified_type_def::CV_CONST)
7142     {
7143       if (!repr.empty())
7144 	repr += ' ';
7145       repr += "const";
7146     }
7147   if (cv_quals & qualified_type_def::CV_VOLATILE)
7148     {
7149       if (!repr.empty())
7150 	repr += ' ';
7151       repr += "volatile";
7152     }
7153   return repr;
7154 }
7155 
7156 /// Build and return a copy of the name of an ABI artifact that is
7157 /// either a type or a decl.
7158 ///
7159 /// @param tod the ABI artifact to get the name for.
7160 ///
7161 /// @param qualified if yes, return the qualified name of @p tod;
7162 /// otherwise, return the non-qualified name;
7163 ///
7164 /// @return the name of @p tod.
7165 string
get_name(const type_or_decl_base * tod,bool qualified)7166 get_name(const type_or_decl_base *tod, bool qualified)
7167 {
7168   string result;
7169 
7170   type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
7171 
7172   if (type_base* t = dynamic_cast<type_base*>(a))
7173     result = get_type_name(t, qualified);
7174   else if (decl_base *d = dynamic_cast<decl_base*>(a))
7175     {
7176       if (qualified)
7177 	result = d->get_qualified_name();
7178       else
7179 	result = d->get_name();
7180     }
7181   else
7182     // We should never reach this point.
7183     abort();
7184 
7185   return result;
7186 }
7187 
7188 /// Build and return a copy of the name of an ABI artifact that is
7189 /// either a type of a decl.
7190 ///
7191 /// @param tod the ABI artifact to get the name for.
7192 ///
7193 /// @param qualified if yes, return the qualified name of @p tod;
7194 /// otherwise, return the non-qualified name;
7195 ///
7196 /// @return the name of @p tod.
7197 string
get_name(const type_or_decl_base_sptr & tod,bool qualified)7198 get_name(const type_or_decl_base_sptr& tod, bool qualified)
7199 {return get_name(tod.get(), qualified);}
7200 
7201 /// Build and return a qualified name from a name and its scope.
7202 ///
7203 /// The name is supposed to be for an entity that is part of the
7204 /// scope.
7205 ///
7206 /// @param the scope to consider.
7207 ///
7208 /// @param name of the name to consider.
7209 ///
7210 /// @return a copy of the string that represents the qualified name.
7211 string
build_qualified_name(const scope_decl * scope,const string & name)7212 build_qualified_name(const scope_decl* scope, const string& name)
7213 {
7214   if (name.empty())
7215     return "";
7216 
7217   string qualified_name;
7218   if (scope)
7219     qualified_name = scope->get_qualified_name();
7220 
7221   if (qualified_name.empty())
7222     qualified_name = name;
7223   else
7224     qualified_name = qualified_name + "::" + name;
7225 
7226   return qualified_name;
7227 }
7228 
7229 /// Build and return the qualified name of a type in its scope.
7230 ///
7231 /// @param scope the scope of the type to consider.
7232 ///
7233 /// @param type the type to consider.
7234 string
build_qualified_name(const scope_decl * scope,const type_base_sptr & type)7235 build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
7236 {return build_qualified_name(scope, get_name((type)));}
7237 
7238 // </scope_decl stuff>
7239 
7240 /// Get the location of the declaration of a given type.
7241 ///
7242 /// @param type the type to consider.
7243 ///
7244 /// @return the location of the declaration of type @p type.
7245 location
get_location(const type_base_sptr & type)7246 get_location(const type_base_sptr& type)
7247 {
7248   if (decl_base_sptr decl = get_type_declaration(type))
7249     return get_location(decl);
7250   return location();
7251 }
7252 
7253 /// Get the location of a given declaration.
7254 ///
7255 /// @param decl the declaration to consider.
7256 ///
7257 /// @return the location of the declaration @p decl.
7258 location
get_location(const decl_base_sptr & decl)7259 get_location(const decl_base_sptr& decl)
7260 {
7261   location loc = decl->get_location();
7262   if (!loc)
7263     {
7264       if (class_or_union_sptr c = is_class_or_union_type(decl))
7265 	if (c->get_is_declaration_only() && c->get_definition_of_declaration())
7266 	  {
7267 	    c = is_class_or_union_type(c->get_definition_of_declaration());
7268 	    loc = c->get_location();
7269 	  }
7270     }
7271   return loc;
7272 }
7273 
7274 /// Get the scope of a given type.
7275 ///
7276 /// @param t the type to consider.
7277 ///
7278 /// @return the scope of type @p t or 0 if the type has no scope yet.
7279 scope_decl*
get_type_scope(type_base * t)7280 get_type_scope(type_base* t)
7281 {
7282   if (!t)
7283     return 0;
7284 
7285   decl_base* d = get_type_declaration(t);
7286   if (d)
7287     return d->get_scope();
7288   return 0;
7289 }
7290 
7291 /// Get the scope of a given type.
7292 ///
7293 /// @param t the type to consider.
7294 ///
7295 /// @return the scope of type @p t or 0 if the type has no scope yet.
7296 scope_decl*
get_type_scope(const type_base_sptr & t)7297 get_type_scope(const type_base_sptr& t)
7298 {return get_type_scope(t.get());}
7299 
7300 /// Get the name of a given type and return a copy of it.
7301 ///
7302 /// @param t the type to consider.
7303 ///
7304 /// @param qualified if true then return the qualified name of the
7305 /// type.
7306 ///
7307 /// @param internal set to true if the call is intended for an
7308 /// internal use (for technical use inside the library itself), false
7309 /// otherwise.  If you don't know what this is for, then set it to
7310 /// false.
7311 ///
7312 /// @return a copy of the type name if the type has a name, or the
7313 /// empty string if it does not.
7314 interned_string
get_type_name(const type_base_sptr & t,bool qualified,bool internal)7315 get_type_name(const type_base_sptr& t, bool qualified, bool internal)
7316 {return get_type_name(t.get(), qualified, internal);}
7317 
7318 /// Return true iff a decl is for a type type that has a generic
7319 /// anonymous internal type name.
7320 ///
7321 /// @param d the decl to considier.
7322 ///
7323 /// @return true iff @p d is for a type type that has a generic
7324 /// anonymous internal type name.
7325 static bool
has_generic_anonymous_internal_type_name(const decl_base * d)7326 has_generic_anonymous_internal_type_name(const decl_base *d)
7327 {
7328   return is_class_or_union_type(d) || is_enum_type(d);
7329 }
7330 
7331 /// Return the generic internal name of an anonymous type.
7332 ///
7333 /// For internal purposes, we want to define a generic name for all
7334 /// anonymous types of a certain kind.  For instance, all anonymous
7335 /// structs will be have a generic name of "__anonymous_struct__", all
7336 /// anonymous unions will have a generic name of
7337 /// "__anonymous_union__", etc.
7338 ///
7339 /// That generic name can be used as a hash to put all anonymous types
7340 /// of a certain kind in the same hash table bucket, for instance.
7341 static interned_string
get_generic_anonymous_internal_type_name(const decl_base * d)7342 get_generic_anonymous_internal_type_name(const decl_base *d)
7343 {
7344   ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
7345 
7346   const environment *env = d->get_environment();
7347 
7348   interned_string result;
7349   if (is_class_type(d))
7350     result =
7351       env->intern(tools_utils::get_anonymous_struct_internal_name_prefix());
7352   else if (is_union_type(d))
7353     result =
7354       env->intern(tools_utils::get_anonymous_union_internal_name_prefix());
7355   else if (is_enum_type(d))
7356     result =
7357       env->intern(tools_utils::get_anonymous_enum_internal_name_prefix());
7358   else
7359     ABG_ASSERT_NOT_REACHED;
7360 
7361   return result;
7362 }
7363 
7364 /// Get the name of a given type and return a copy of it.
7365 ///
7366 /// @param t the type to consider.
7367 ///
7368 /// @param qualified if true then return the qualified name of the
7369 /// type.
7370 ///
7371 /// @param internal set to true if the call is intended for an
7372 /// internal use (for technical use inside the library itself), false
7373 /// otherwise.  If you don't know what this is for, then set it to
7374 /// false.
7375 ///
7376 /// @return a copy of the type name if the type has a name, or the
7377 /// empty string if it does not.
7378 interned_string
get_type_name(const type_base * t,bool qualified,bool internal)7379 get_type_name(const type_base* t, bool qualified, bool internal)
7380 {
7381   const decl_base* d = dynamic_cast<const decl_base*>(t);
7382   if (!d)
7383     {
7384       const function_type* fn_type = is_function_type(t);
7385       ABG_ASSERT(fn_type);
7386       return fn_type->get_cached_name(internal);
7387     }
7388 
7389   // All anonymous types of a given kind get to have the same internal
7390   // name for internal purpose.  This to allow them to be compared
7391   // among themselves during type canonicalization.
7392   if (internal && d->get_is_anonymous())
7393     {
7394       string r;
7395       if (qualified)
7396 	{
7397 	  r = d->get_qualified_parent_name();
7398 	  if (!r.empty())
7399 	    r += "::";
7400 	}
7401       r += get_generic_anonymous_internal_type_name(d);
7402       return t->get_environment()->intern(r);
7403     }
7404 
7405   if (qualified)
7406     return d->get_qualified_name(internal);
7407   return d->get_name();
7408 }
7409 
7410 /// Get the name of a given type and return a copy of it.
7411 ///
7412 /// @param t the type to consider.
7413 ///
7414 /// @param qualified if true then return the qualified name of the
7415 /// type.
7416 ///
7417 /// @param internal set to true if the call is intended for an
7418 /// internal use (for technical use inside the library itself), false
7419 /// otherwise.  If you don't know what this is for, then set it to
7420 /// false.
7421 ///
7422 /// @return a copy of the type name if the type has a name, or the
7423 /// empty string if it does not.
7424 interned_string
get_type_name(const type_base & t,bool qualified,bool internal)7425 get_type_name(const type_base& t, bool qualified, bool internal)
7426 {return get_type_name(&t, qualified, internal);}
7427 
7428 /// Get the name of the pointer to a given type.
7429 ///
7430 /// @param pointed_to_type the pointed-to-type to consider.
7431 ///
7432 /// @param qualified this is true if the resulting name should be of a
7433 /// pointer to a *fully-qualified* pointed-to-type.
7434 ///
7435 /// @param internal true if the name is for libabigail-internal
7436 /// purposes.
7437 ///
7438 /// @return the name (string representation) of the pointer.
7439 interned_string
get_name_of_pointer_to_type(const type_base & pointed_to_type,bool qualified,bool internal)7440 get_name_of_pointer_to_type(const type_base& pointed_to_type,
7441 			    bool qualified, bool internal)
7442 {
7443   const environment* env = pointed_to_type.get_environment();
7444   ABG_ASSERT(env);
7445 
7446   string tn = get_type_name(pointed_to_type, qualified, internal);
7447   tn =  tn + "*";
7448 
7449   return env->intern(tn);
7450 }
7451 
7452 /// Get the name of the reference to a given type.
7453 ///
7454 /// @param pointed_to_type the pointed-to-type to consider.
7455 ///
7456 /// @param qualified this is true if the resulting name should be of a
7457 /// reference to a *fully-qualified* pointed-to-type.
7458 ///
7459 /// @param internal true if the name is for libabigail-internal
7460 /// purposes.
7461 ///
7462 /// @return the name (string representation) of the reference.
7463 interned_string
get_name_of_reference_to_type(const type_base & pointed_to_type,bool lvalue_reference,bool qualified,bool internal)7464 get_name_of_reference_to_type(const type_base& pointed_to_type,
7465 			      bool lvalue_reference,
7466 			      bool qualified, bool internal)
7467 {
7468   const environment* env = pointed_to_type.get_environment();
7469   ABG_ASSERT(env);
7470 
7471   string name = get_type_name(pointed_to_type, qualified, internal);
7472   if (lvalue_reference)
7473     name = name + "&";
7474   else
7475     name = name + "&&";
7476 
7477   return env->intern(name);
7478 }
7479 
7480 /// Get the name of a qualified type, given the underlying type and
7481 /// its qualifiers.
7482 ///
7483 /// @param underlying_type the underlying type to consider.
7484 ///
7485 /// @param quals the CV qualifiers of the name.
7486 ///
7487 /// @param qualified true if we should consider the fully qualified
7488 /// name of @p underlying_type.
7489 ///
7490 /// @param internal true if the result is to be used for
7491 /// libabigail-internal purposes.
7492 ///
7493 /// @return the name (string representation) of the qualified type.
7494 interned_string
get_name_of_qualified_type(const type_base_sptr & underlying_type,qualified_type_def::CV quals,bool qualified,bool internal)7495 get_name_of_qualified_type(const type_base_sptr& underlying_type,
7496 			   qualified_type_def::CV quals,
7497 			   bool qualified, bool internal)
7498 {
7499   const environment* env = underlying_type->get_environment();
7500   ABG_ASSERT(env);
7501 
7502   string quals_repr = get_string_representation_of_cv_quals(quals);
7503   string name = get_type_name(underlying_type, qualified, internal);
7504 
7505   if (quals_repr.empty() && internal)
7506     // We are asked to return the internal name, that might be used
7507     // for type canonicalization.  For that canonicalization, we need
7508     // to make a difference between a no-op qualified type which
7509     // underlying type is foo (the qualified type is named "none
7510     // foo"), and the name of foo, which is just "foo".
7511     //
7512     // Please remember that this has to be kept in sync with what is
7513     // done in die_qualified_name, in abg-dwarf-reader.cc.  So if you
7514     // change this code here, please change that code there too.
7515     quals_repr = "";
7516 
7517   if (!quals_repr.empty())
7518     {
7519       if (is_pointer_type(underlying_type)
7520 	  || is_reference_type(underlying_type)
7521 	  || is_array_type(underlying_type))
7522 	{
7523 	  name += " ";
7524 	  name += quals_repr;
7525 	}
7526       else
7527 	name = quals_repr + " " + name;
7528     }
7529 
7530   return env->intern(name);
7531 }
7532 
7533 /// Get the name of a given function type and return a copy of it.
7534 ///
7535 /// @param fn_type the function type to consider.
7536 ///
7537 /// @param internal set to true if the call is intended for an
7538 /// internal use (for technical use inside the library itself), false
7539 /// otherwise.  If you don't know what this is for, then set it to
7540 /// false.
7541 ///
7542 /// @return a copy of the function type name
7543 interned_string
get_function_type_name(const function_type_sptr & fn_type,bool internal)7544 get_function_type_name(const function_type_sptr& fn_type,
7545 		       bool internal)
7546 {return get_function_type_name(fn_type.get(), internal);}
7547 
7548 /// Get the name of a given function type and return a copy of it.
7549 ///
7550 /// @param fn_type the function type to consider.
7551 ///
7552 /// @param internal set to true if the call is intended for an
7553 /// internal use (for technical use inside the library itself), false
7554 /// otherwise.  If you don't know what this is for, then set it to
7555 /// false.
7556 ///
7557 /// @return a copy of the function type name
7558 interned_string
get_function_type_name(const function_type * fn_type,bool internal)7559 get_function_type_name(const function_type* fn_type,
7560 		       bool internal)
7561 {
7562   ABG_ASSERT(fn_type);
7563 
7564   if (const method_type* method = is_method_type(fn_type))
7565     return get_method_type_name(method, internal);
7566 
7567   return get_function_type_name(*fn_type, internal);
7568 }
7569 
7570 /// Get the name of a given function type and return a copy of it.
7571 ///
7572 /// @param fn_type the function type to consider.
7573 ///
7574 /// @param internal set to true if the call is intended for an
7575 /// internal use (for technical use inside the library itself), false
7576 /// otherwise.  If you don't know what this is for, then set it to
7577 /// false.
7578 ///
7579 /// @return a copy of the function type name
7580 interned_string
get_function_type_name(const function_type & fn_type,bool internal)7581 get_function_type_name(const function_type& fn_type,
7582 		       bool internal)
7583 {
7584   std::ostringstream o;
7585   type_base_sptr return_type = fn_type.get_return_type();
7586   const environment* env = fn_type.get_environment();
7587   ABG_ASSERT(env);
7588 
7589   o <<  get_pretty_representation(return_type, internal);
7590 
7591   o << " (";
7592   for (function_type::parameters::const_iterator i =
7593 	 fn_type.get_parameters().begin();
7594        i != fn_type.get_parameters().end();
7595        ++i)
7596     {
7597       if (i != fn_type.get_parameters().begin())
7598 	o << ", ";
7599       o << get_pretty_representation((*i)->get_type(), internal);
7600     }
7601   o <<")";
7602 
7603   return env->intern(o.str());
7604 }
7605 
7606 /// Get the name of a given method type and return a copy of it.
7607 ///
7608 /// @param fn_type the function type to consider.
7609 ///
7610 /// @param internal set to true if the call is intended for an
7611 /// internal use (for technical use inside the library itself), false
7612 /// otherwise.  If you don't know what this is for, then set it to
7613 /// false.
7614 ///
7615 /// @return a copy of the function type name
7616 interned_string
get_method_type_name(const method_type_sptr fn_type,bool internal)7617 get_method_type_name(const method_type_sptr fn_type,
7618 		     bool internal)
7619 {return get_method_type_name(fn_type.get(), internal);}
7620 
7621 /// Get the name of a given method type and return a copy of it.
7622 ///
7623 /// @param fn_type the function type to consider.
7624 ///
7625 /// @param internal set to true if the call is intended for an
7626 /// internal use (for technical use inside the library itself), false
7627 /// otherwise.  If you don't know what this is for, then set it to
7628 /// false.
7629 ///
7630 /// @return a copy of the function type name
7631 interned_string
get_method_type_name(const method_type * fn_type,bool internal)7632 get_method_type_name(const method_type* fn_type,
7633 		     bool internal)
7634 {
7635   if (fn_type)
7636     return get_method_type_name(*fn_type, internal);
7637 
7638   return interned_string();
7639 }
7640 
7641 /// Get the name of a given method type and return a copy of it.
7642 ///
7643 /// @param fn_type the function type to consider.
7644 ///
7645 /// @param internal set to true if the call is intended for an
7646 /// internal use (for technical use inside the library itself), false
7647 /// otherwise.  If you don't know what this is for, then set it to
7648 /// false.
7649 ///
7650 /// @return a copy of the function type name
7651 interned_string
get_method_type_name(const method_type & fn_type,bool internal)7652 get_method_type_name(const method_type& fn_type,
7653 		     bool internal)
7654 {
7655   std::ostringstream o;
7656   type_base_sptr return_type= fn_type.get_return_type();
7657   const environment* env = fn_type.get_environment();
7658   ABG_ASSERT(env);
7659 
7660   if (return_type)
7661     o << return_type->get_cached_pretty_representation(internal);
7662   else
7663     // There are still some abixml files out there in which "void"
7664     // can be expressed as an empty type.
7665     o << "void";
7666 
7667   class_or_union_sptr class_type = fn_type.get_class_type();
7668   ABG_ASSERT(class_type);
7669 
7670   o << " (" << class_type->get_qualified_name(internal) << "::*)"
7671     << " (";
7672 
7673   for (function_type::parameters::const_iterator i =
7674 	 fn_type.get_parameters().begin();
7675        i != fn_type.get_parameters().end();
7676        ++i)
7677     {
7678       if (i != fn_type.get_parameters().begin())
7679 	o << ", ";
7680       if (*i)
7681 	o << (*i)->get_type()->get_cached_pretty_representation(internal);
7682       else
7683 	// There are still some abixml files out there in which "void"
7684 	// can be expressed as an empty type.
7685 	o << "void";
7686     }
7687   o <<")";
7688 
7689   return env->intern(o.str());
7690 }
7691 
7692 /// Build and return a copy of the pretty representation of an ABI
7693 /// artifact that could be either a type of a decl.
7694 ///
7695 /// param tod the ABI artifact to consider.
7696 ///
7697 /// @param internal set to true if the call is intended for an
7698 /// internal use (for technical use inside the library itself), false
7699 /// otherwise.  If you don't know what this is for, then set it to
7700 /// false.
7701 ///
7702 /// @return a copy of the pretty representation of an ABI artifact
7703 /// that could be either a type of a decl.
7704 string
get_pretty_representation(const type_or_decl_base * tod,bool internal)7705 get_pretty_representation(const type_or_decl_base* tod, bool internal)
7706 {
7707   string result;
7708 
7709   if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
7710     result = get_pretty_representation(t, internal);
7711   else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
7712     result =  get_pretty_representation(d, internal);
7713   else
7714     // We should never reach this point
7715     abort();
7716 
7717   return result;
7718 }
7719 
7720 /// Build and return a copy of the pretty representation of an ABI
7721 /// artifact that could be either a type of a decl.
7722 ///
7723 /// param tod the ABI artifact to consider.
7724 ///
7725 /// @param internal set to true if the call is intended for an
7726 /// internal use (for technical use inside the library itself), false
7727 /// otherwise.  If you don't know what this is for, then set it to
7728 /// false.
7729 ///
7730 /// @return a copy of the pretty representation of an ABI artifact
7731 /// that could be either a type of a decl.
7732 string
get_pretty_representation(const type_or_decl_base_sptr & tod,bool internal)7733 get_pretty_representation(const type_or_decl_base_sptr& tod, bool internal)
7734 {return get_pretty_representation(tod.get(), internal);}
7735 
7736 /// Get a copy of the pretty representation of a decl.
7737 ///
7738 /// @param d the decl to consider.
7739 ///
7740 /// @param internal set to true if the call is intended for an
7741 /// internal use (for technical use inside the library itself), false
7742 /// otherwise.  If you don't know what this is for, then set it to
7743 /// false.
7744 ///
7745 /// @return the pretty representation of the decl.
7746 string
get_pretty_representation(const decl_base * d,bool internal)7747 get_pretty_representation(const decl_base* d, bool internal)
7748 {
7749   if (!d)
7750     return "";
7751   return d->get_pretty_representation(internal);
7752 }
7753 
7754 /// Get a copy of the pretty representation of a type.
7755 ///
7756 /// @param d the type to consider.
7757 ///
7758 /// @param internal set to true if the call is intended for an
7759 /// internal use (for technical use inside the library itself), false
7760 /// otherwise.  If you don't know what this is for, then set it to
7761 /// false.
7762 ///
7763 /// @return the pretty representation of the type.
7764 string
get_pretty_representation(const type_base * t,bool internal)7765 get_pretty_representation(const type_base* t, bool internal)
7766 {
7767   if (!t)
7768     return "void";
7769   if (const function_type* fn_type = is_function_type(t))
7770     return get_pretty_representation(fn_type, internal);
7771 
7772   const decl_base* d = get_type_declaration(t);
7773   ABG_ASSERT(d);
7774   return get_pretty_representation(d, internal);
7775 }
7776 
7777 /// Get a copy of the pretty representation of a decl.
7778 ///
7779 /// @param d the decl to consider.
7780 ///
7781 /// @param internal set to true if the call is intended for an
7782 /// internal use (for technical use inside the library itself), false
7783 /// otherwise.  If you don't know what this is for, then set it to
7784 /// false.
7785 ///
7786 /// @return the pretty representation of the decl.
7787 string
get_pretty_representation(const decl_base_sptr & d,bool internal)7788 get_pretty_representation(const decl_base_sptr& d, bool internal)
7789 {return get_pretty_representation(d.get(), internal);}
7790 
7791 /// Get a copy of the pretty representation of a type.
7792 ///
7793 /// @param d the type to consider.
7794 ///
7795 /// @param internal set to true if the call is intended for an
7796 /// internal use (for technical use inside the library itself), false
7797 /// otherwise.  If you don't know what this is for, then set it to
7798 /// false.
7799 ///
7800 /// @return the pretty representation of the type.
7801 string
get_pretty_representation(const type_base_sptr & t,bool internal)7802 get_pretty_representation(const type_base_sptr& t, bool internal)
7803 {return get_pretty_representation(t.get(), internal);}
7804 
7805 /// Get the pretty representation of a function type.
7806 ///
7807 /// @param fn_type the function type to consider.
7808 ///
7809 /// @param internal set to true if the call is intended for an
7810 /// internal use (for technical use inside the library itself), false
7811 /// otherwise.  If you don't know what this is for, then set it to
7812 /// false.
7813 ///
7814 /// @return the string represenation of the function type.
7815 string
get_pretty_representation(const function_type_sptr & fn_type,bool internal)7816 get_pretty_representation(const function_type_sptr& fn_type,
7817 			  bool internal)
7818 {return get_pretty_representation(fn_type.get(), internal);}
7819 
7820 /// Get the pretty representation of a function type.
7821 ///
7822 /// @param fn_type the function type to consider.
7823 ///
7824 /// @param internal set to true if the call is intended for an
7825 /// internal use (for technical use inside the library itself), false
7826 /// otherwise.  If you don't know what this is for, then set it to
7827 /// false.
7828 ///
7829 /// @return the string represenation of the function type.
7830 string
get_pretty_representation(const function_type * fn_type,bool internal)7831 get_pretty_representation(const function_type* fn_type, bool internal)
7832 {
7833   if (!fn_type)
7834     return "void";
7835 
7836   if (const method_type* method = is_method_type(fn_type))
7837     return get_pretty_representation(method, internal);
7838 
7839   return get_pretty_representation(*fn_type, internal);
7840 }
7841 
7842 /// Get the pretty representation of a function type.
7843 ///
7844 /// @param fn_type the function type to consider.
7845 ///
7846 /// @param internal set to true if the call is intended for an
7847 /// internal use (for technical use inside the library itself), false
7848 /// otherwise.  If you don't know what this is for, then set it to
7849 /// false.
7850 ///
7851 /// @return the string represenation of the function type.
7852 string
get_pretty_representation(const function_type & fn_type,bool internal)7853 get_pretty_representation(const function_type& fn_type, bool internal)
7854 {
7855   std::ostringstream o;
7856   o << "function type " << get_function_type_name(fn_type, internal);
7857   return o.str();
7858 }
7859 
7860 /// Get the pretty representation of a method type.
7861 ///
7862 /// @param method the method type to consider.
7863 ///
7864 /// @param internal set to true if the call is intended for an
7865 /// internal use (for technical use inside the library itself), false
7866 /// otherwise.  If you don't know what this is for, then set it to
7867 /// false.
7868 ///
7869 /// @return the string represenation of the method type.
7870 string
get_pretty_representation(const method_type & method,bool internal)7871 get_pretty_representation(const method_type& method, bool internal)
7872 {
7873   std::ostringstream o;
7874   o << "method type " << get_method_type_name(method, internal);
7875   return o.str();
7876 }
7877 
7878 /// Get the pretty representation of a method type.
7879 ///
7880 /// @param method the method type to consider.
7881 ///
7882 /// @param internal set to true if the call is intended for an
7883 /// internal use (for technical use inside the library itself), false
7884 /// otherwise.  If you don't know what this is for, then set it to
7885 /// false.
7886 ///
7887 /// @return the string represenation of the method type.
7888 string
get_pretty_representation(const method_type * method,bool internal)7889 get_pretty_representation(const method_type* method, bool internal)
7890 {
7891   if (!method)
7892     return "void";
7893   return get_pretty_representation(*method, internal);
7894 }
7895 
7896 /// Get the pretty representation of a method type.
7897 ///
7898 /// @param method the method type to consider.
7899 ///
7900 /// @param internal set to true if the call is intended for an
7901 /// internal use (for technical use inside the library itself), false
7902 /// otherwise.  If you don't know what this is for, then set it to
7903 /// false.
7904 ///
7905 /// @return the string represenation of the method type.
7906 string
get_pretty_representation(const method_type_sptr method,bool internal)7907 get_pretty_representation(const method_type_sptr method, bool internal)
7908 {return get_pretty_representation(method.get(), internal);}
7909 
7910 /// Get the flat representation of an instance of @ref class_or_union
7911 /// type.
7912 ///
7913 /// The flat representation of a given @ref class_or_union type is the
7914 /// actual definition of the type, for instance:
7915 ///
7916 ///   struct foo {int a; char b;}
7917 ///
7918 ///@param cou the instance of @ref class_or_union to consider.
7919 ///
7920 ///@param indent the identation spaces to use in the representation.
7921 ///
7922 ///@param one_line if true, then the flat representation stands on one
7923 ///line.  Otherwise, it stands on multiple lines.
7924 ///
7925 ///@return the resulting flat representation.
7926 string
get_class_or_union_flat_representation(const class_or_union & cou,const string & indent,bool one_line,bool internal,bool qualified_names)7927 get_class_or_union_flat_representation(const class_or_union& cou,
7928 				       const string& indent,
7929 				       bool one_line,
7930 				       bool internal,
7931 				       bool qualified_names)
7932 {
7933   string repr;
7934   string local_indent = "  ";
7935 
7936   if (class_decl* clazz = is_class_type(&cou))
7937     {
7938       repr = indent;
7939       if (!internal && clazz->is_struct())
7940 	repr += "struct";
7941       else
7942 	repr += "class";
7943     }
7944   else if (is_union_type(cou))
7945     repr = indent + "union";
7946   else
7947     return "";
7948 
7949   repr += " ";
7950 
7951   string name = cou.get_qualified_name();
7952 
7953   if (!cou.get_is_anonymous())
7954     repr += name;
7955 
7956   repr += "{";
7957 
7958   if (!one_line)
7959     repr += "\n";
7960 
7961   string real_indent;
7962   const class_or_union::data_members &dmems = cou.get_data_members();
7963   for (class_or_union::data_members::const_iterator dm = dmems.begin();
7964        dm != dmems.end();
7965        ++dm)
7966     {
7967       if (dm != dmems.begin())
7968 	{
7969 	  if (one_line)
7970 	    real_indent = " ";
7971 	  else
7972 	    real_indent = "\n" + indent + local_indent;
7973 	}
7974 
7975       if (var_decl_sptr v = is_anonymous_data_member(*dm))
7976 	repr +=
7977 	  get_class_or_union_flat_representation
7978 	  (anonymous_data_member_to_class_or_union(*dm),
7979 	   real_indent, one_line, internal, qualified_names);
7980       else
7981 	{
7982 	  if (one_line)
7983 	    {
7984 	      if (dm != dmems.begin())
7985 		repr += real_indent;
7986 	      repr += (*dm)->get_pretty_representation(internal,
7987 						       qualified_names);
7988 	    }
7989 	  else
7990 	    repr +=
7991 	      real_indent+ (*dm)->get_pretty_representation(internal,
7992 							    qualified_names);
7993 	}
7994       repr += ";";
7995     }
7996 
7997   if (one_line)
7998     repr += "}";
7999   else
8000     repr += indent + "}";
8001 
8002   return repr;
8003 }
8004 
8005 /// Get the flat representation of an instance of @ref class_or_union
8006 /// type.
8007 ///
8008 /// The flat representation of a given @ref class_or_union type is the
8009 /// actual definition of the type, for instance:
8010 ///
8011 ///   struct foo {int a; char b;}
8012 ///
8013 ///@param cou the instance of @ref class_or_union to consider.
8014 ///
8015 ///@param indent the identation spaces to use in the representation.
8016 ///
8017 ///@param one_line if true, then the flat representation stands on one
8018 ///line.  Otherwise, it stands on multiple lines.
8019 ///
8020 ///@return the resulting flat representation.
8021 string
get_class_or_union_flat_representation(const class_or_union * cou,const string & indent,bool one_line,bool internal,bool qualified_names)8022 get_class_or_union_flat_representation(const class_or_union* cou,
8023 				       const string& indent,
8024 				       bool one_line,
8025 				       bool internal,
8026 				       bool qualified_names)
8027 {
8028   if (cou)
8029     return get_class_or_union_flat_representation(*cou, indent, one_line,
8030 						  internal, qualified_names);
8031   return "";
8032 }
8033 
8034 /// Get the flat representation of an instance of @ref class_or_union
8035 /// type.
8036 ///
8037 /// The flat representation of a given @ref class_or_union type is the
8038 /// actual definition of the type, for instance:
8039 ///
8040 ///   struct foo {int a; char b;}
8041 ///
8042 ///@param cou the instance of @ref class_or_union to consider.
8043 ///
8044 ///@param indent the identation spaces to use in the representation.
8045 ///
8046 ///@param one_line if true, then the flat representation stands on one
8047 ///line.  Otherwise, it stands on multiple lines.
8048 ///
8049 ///@return the resulting flat representation.
8050 string
get_class_or_union_flat_representation(const class_or_union_sptr & cou,const string & indent,bool one_line,bool internal,bool qualified_names)8051 get_class_or_union_flat_representation(const class_or_union_sptr& cou,
8052 				       const string& indent,
8053 				       bool one_line,
8054 				       bool internal,
8055 				       bool qualified_names)
8056 {return get_class_or_union_flat_representation(cou.get(),
8057 					       indent,
8058 					       one_line,
8059 					       internal,
8060 					       qualified_names);}
8061 
8062 /// By looking at the language of the TU a given ABI artifact belongs
8063 /// to, test if the ONE Definition Rule should apply.
8064 ///
8065 /// To date, it applies to c++, java and ada.
8066 ///
8067 /// @param artifact the ABI artifact to consider.
8068 ///
8069 /// @return true iff the One Definition Rule should apply.
8070 bool
odr_is_relevant(const type_or_decl_base & artifact)8071 odr_is_relevant(const type_or_decl_base& artifact)
8072 {
8073   translation_unit::language l =
8074     artifact.get_translation_unit()->get_language();
8075 
8076   if (is_cplus_plus_language(l)
8077       || is_java_language(l)
8078       || is_ada_language(l))
8079     return true;
8080 
8081   return false;
8082 }
8083 
8084 /// Get the declaration for a given type.
8085 ///
8086 /// @param t the type to consider.
8087 ///
8088 /// @return the declaration for the type to return.
8089 const decl_base*
get_type_declaration(const type_base * t)8090 get_type_declaration(const type_base* t)
8091 {return dynamic_cast<const decl_base*>(t);}
8092 
8093 /// Get the declaration for a given type.
8094 ///
8095 /// @param t the type to consider.
8096 ///
8097 /// @return the declaration for the type to return.
8098 decl_base*
get_type_declaration(type_base * t)8099 get_type_declaration(type_base* t)
8100 {return dynamic_cast<decl_base*>(t);}
8101 
8102 /// Get the declaration for a given type.
8103 ///
8104 /// @param t the type to consider.
8105 ///
8106 /// @return the declaration for the type to return.
8107 decl_base_sptr
get_type_declaration(const type_base_sptr t)8108 get_type_declaration(const type_base_sptr t)
8109 {return dynamic_pointer_cast<decl_base>(t);}
8110 
8111 /// Test if two types are equal modulo a typedef.
8112 ///
8113 /// Type A and B are compatible if
8114 ///
8115 ///	- A and B are equal
8116 ///	- or if one type is a typedef of the other one.
8117 ///
8118 /// @param type1 the first type to consider.
8119 ///
8120 /// @param type2 the second type to consider.
8121 ///
8122 /// @return true iff @p type1 and @p type2 are compatible.
8123 bool
types_are_compatible(const type_base_sptr type1,const type_base_sptr type2)8124 types_are_compatible(const type_base_sptr type1,
8125 		     const type_base_sptr type2)
8126 {
8127   if (!type1 || !type2)
8128     return false;
8129 
8130   if (type1 == type2)
8131     return true;
8132 
8133   // Normally we should strip typedefs entirely, but this is
8134   // potentially costly, especially on binaries with huge changesets
8135   // like the Linux Kernel.  So we just get the leaf types for now.
8136   //
8137   // Maybe there should be an option by which users accepts to pay the
8138   // CPU usage toll in exchange for finer filtering?
8139 
8140   // type_base_sptr t1 = strip_typedef(type1);
8141   // type_base_sptr t2 = strip_typedef(type2);
8142 
8143   type_base_sptr t1 = peel_typedef_type(type1);
8144   type_base_sptr t2 = peel_typedef_type(type2);
8145 
8146   return t1 == t2;
8147 }
8148 
8149 /// Test if two types are equal modulo a typedef.
8150 ///
8151 /// Type A and B are compatible if
8152 ///
8153 ///	- A and B are equal
8154 ///	- or if one type is a typedef of the other one.
8155 ///
8156 /// @param type1 the declaration of the first type to consider.
8157 ///
8158 /// @param type2 the declaration of the second type to consider.
8159 ///
8160 /// @return true iff @p type1 and @p type2 are compatible.
8161 bool
types_are_compatible(const decl_base_sptr d1,const decl_base_sptr d2)8162 types_are_compatible(const decl_base_sptr d1,
8163 		     const decl_base_sptr d2)
8164 {return types_are_compatible(is_type(d1), is_type(d2));}
8165 
8166 /// Return the translation unit a declaration belongs to.
8167 ///
8168 /// @param decl the declaration to consider.
8169 ///
8170 /// @return the resulting translation unit, or null if the decl is not
8171 /// yet added to a translation unit.
8172 translation_unit*
get_translation_unit(const decl_base & decl)8173 get_translation_unit(const decl_base& decl)
8174 {return const_cast<translation_unit*>(decl.get_translation_unit());}
8175 
8176 /// Return the translation unit a declaration belongs to.
8177 ///
8178 /// @param decl the declaration to consider.
8179 ///
8180 /// @return the resulting translation unit, or null if the decl is not
8181 /// yet added to a translation unit.
8182 translation_unit*
get_translation_unit(const decl_base * decl)8183 get_translation_unit(const decl_base* decl)
8184 {return decl ? get_translation_unit(*decl) : 0;}
8185 
8186 /// Return the translation unit a declaration belongs to.
8187 ///
8188 /// @param decl the declaration to consider.
8189 ///
8190 /// @return the resulting translation unit, or null if the decl is not
8191 /// yet added to a translation unit.
8192 translation_unit*
get_translation_unit(const shared_ptr<decl_base> decl)8193 get_translation_unit(const shared_ptr<decl_base> decl)
8194 {return get_translation_unit(decl.get());}
8195 
8196 /// Tests whether if a given scope is the global scope.
8197 ///
8198 /// @param scope the scope to consider.
8199 ///
8200 /// @return true iff the current scope is the global one.
8201 bool
is_global_scope(const scope_decl & scope)8202 is_global_scope(const scope_decl& scope)
8203 {return !!dynamic_cast<const global_scope*>(&scope);}
8204 
8205 /// Tests whether if a given scope is the global scope.
8206 ///
8207 /// @param scope the scope to consider.
8208 ///
8209 /// @return the @ref global_scope* representing the scope @p scope or
8210 /// 0 if @p scope is not a global scope.
8211 const global_scope*
is_global_scope(const scope_decl * scope)8212 is_global_scope(const scope_decl* scope)
8213 {return dynamic_cast<const global_scope*>(scope);}
8214 
8215 /// Tests whether if a given scope is the global scope.
8216 ///
8217 /// @param scope the scope to consider.
8218 ///
8219 /// @return true iff the current scope is the global one.
8220 bool
is_global_scope(const shared_ptr<scope_decl> scope)8221 is_global_scope(const shared_ptr<scope_decl>scope)
8222 {return is_global_scope(scope.get());}
8223 
8224 /// Tests whether a given declaration is at global scope.
8225 ///
8226 /// @param decl the decl to consider.
8227 ///
8228 /// @return true iff decl is at global scope.
8229 bool
is_at_global_scope(const decl_base & decl)8230 is_at_global_scope(const decl_base& decl)
8231 {return (is_global_scope(decl.get_scope()));}
8232 
8233 /// Tests whether a given declaration is at global scope.
8234 ///
8235 /// @param decl the decl to consider.
8236 ///
8237 /// @return true iff decl is at global scope.
8238 bool
is_at_global_scope(const decl_base_sptr decl)8239 is_at_global_scope(const decl_base_sptr decl)
8240 {return (decl && is_global_scope(decl->get_scope()));}
8241 
8242 /// Tests whether a given decl is at class scope.
8243 ///
8244 /// @param decl the decl to consider.
8245 ///
8246 /// @return true iff decl is at class scope.
8247 class_or_union*
is_at_class_scope(const decl_base_sptr decl)8248 is_at_class_scope(const decl_base_sptr decl)
8249 {return is_at_class_scope(decl.get());}
8250 
8251 /// Tests whether a given decl is at class scope.
8252 ///
8253 /// @param decl the decl to consider.
8254 ///
8255 /// @return true iff decl is at class scope.
8256 class_or_union*
is_at_class_scope(const decl_base * decl)8257 is_at_class_scope(const decl_base* decl)
8258 {
8259   if (!decl)
8260     return 0;
8261 
8262   return is_at_class_scope(*decl);
8263 }
8264 
8265 /// Tests whether a given decl is at class scope.
8266 ///
8267 /// @param decl the decl to consider.
8268 ///
8269 /// @return true iff decl is at class scope.
8270 class_or_union*
is_at_class_scope(const decl_base & decl)8271 is_at_class_scope(const decl_base& decl)
8272 {
8273   scope_decl* scope = decl.get_scope();
8274   if (class_or_union* cl = is_class_type(scope))
8275     return cl;
8276   if (class_or_union* cl = is_union_type(scope))
8277     return cl;
8278   return 0;
8279 }
8280 
8281 /// Find a data member inside an anonymous data member.
8282 ///
8283 /// An anonymous data member has a type which is a class or union.
8284 /// This function looks for a data member inside the type of that
8285 /// anonymous data member.
8286 ///
8287 /// @param anon_dm the anonymous data member to consider.
8288 ///
8289 /// @param name the name of the data member to look for.
8290 var_decl_sptr
find_data_member_from_anonymous_data_member(const var_decl_sptr & anon_dm,const string & name)8291 find_data_member_from_anonymous_data_member(const var_decl_sptr& anon_dm,
8292 					    const string& name)
8293 {
8294   const class_or_union* containing_class_or_union =
8295     anonymous_data_member_to_class_or_union(anon_dm.get());
8296 
8297   if (!containing_class_or_union)
8298     return var_decl_sptr();
8299 
8300   var_decl_sptr result = containing_class_or_union->find_data_member(name);
8301   return result;
8302 }
8303 
8304 /// Tests whether a given decl is at template scope.
8305 ///
8306 /// Note that only template parameters , types that are compositions,
8307 /// and template patterns (function or class) can be at template scope.
8308 ///
8309 /// @param decl the decl to consider.
8310 ///
8311 /// @return true iff the decl is at template scope.
8312 bool
is_at_template_scope(const shared_ptr<decl_base> decl)8313 is_at_template_scope(const shared_ptr<decl_base> decl)
8314 {return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
8315 
8316 /// Tests whether a decl is a template parameter.
8317 ///
8318 /// @param decl the decl to consider.
8319 ///
8320 /// @return true iff decl is a template parameter.
8321 bool
is_template_parameter(const shared_ptr<decl_base> decl)8322 is_template_parameter(const shared_ptr<decl_base> decl)
8323 {
8324   return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
8325 		   || dynamic_pointer_cast<non_type_tparameter>(decl)
8326 		   || dynamic_pointer_cast<template_tparameter>(decl)));
8327 }
8328 
8329 /// Test whether a declaration is a @ref function_decl.
8330 ///
8331 /// @param d the declaration to test for.
8332 ///
8333 /// @return a shared pointer to @ref function_decl if @p d is a @ref
8334 /// function_decl.  Otherwise, a nil shared pointer.
8335 function_decl*
is_function_decl(const type_or_decl_base * d)8336 is_function_decl(const type_or_decl_base* d)
8337 {return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
8338 
8339 /// Test whether a declaration is a @ref function_decl.
8340 ///
8341 /// @param d the declaration to test for.
8342 ///
8343 /// @return true if @p d is a function_decl.
8344 bool
is_function_decl(const type_or_decl_base & d)8345 is_function_decl(const type_or_decl_base& d)
8346 {return is_function_decl(&d);}
8347 
8348 /// Test whether a declaration is a @ref function_decl.
8349 ///
8350 /// @param d the declaration to test for.
8351 ///
8352 /// @return a shared pointer to @ref function_decl if @p d is a @ref
8353 /// function_decl.  Otherwise, a nil shared pointer.
8354 function_decl_sptr
is_function_decl(const type_or_decl_base_sptr & d)8355 is_function_decl(const type_or_decl_base_sptr& d)
8356 {return dynamic_pointer_cast<function_decl>(d);}
8357 
8358 /// Test whether a declaration is a @ref function_decl.
8359 ///
8360 /// @param d the declaration to test for.
8361 ///
8362 /// @return a pointer to @ref function_decl if @p d is a @ref
8363 /// function_decl.  Otherwise, a nil shared pointer.
8364 function_decl::parameter*
is_function_parameter(const type_or_decl_base * tod)8365 is_function_parameter(const type_or_decl_base* tod)
8366 {
8367   return dynamic_cast<function_decl::parameter*>
8368     (const_cast<type_or_decl_base*>(tod));
8369 }
8370 
8371 /// Test whether an ABI artifact is a @ref function_decl.
8372 ///
8373 /// @param tod the declaration to test for.
8374 ///
8375 /// @return a pointer to @ref function_decl if @p d is a @ref
8376 /// function_decl.  Otherwise, a nil shared pointer.
8377 function_decl::parameter_sptr
is_function_parameter(const type_or_decl_base_sptr tod)8378 is_function_parameter(const type_or_decl_base_sptr tod)
8379 {return dynamic_pointer_cast<function_decl::parameter>(tod);}
8380 
8381 /// Test if an ABI artifact is a declaration.
8382 ///
8383 /// @param d the artifact to consider.
8384 ///
8385 /// @param return the declaration sub-object of @p d if it's a
8386 /// declaration, or NULL if it is not.
8387 decl_base*
is_decl(const type_or_decl_base * d)8388 is_decl(const type_or_decl_base* d)
8389 {
8390   if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
8391     {
8392       if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
8393 	// The artifact is a decl-only (like a function or a
8394 	// variable).  That is, it's not a type that also has a
8395 	// declaration.  In this case, we are in the fast path and we
8396 	// have a pointer to the decl sub-object handy.  Just return
8397 	// it ...
8398 	return reinterpret_cast<decl_base*>
8399 	  (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
8400 
8401       // ... Otherwise, we are in the slow path, which is that the
8402       // artifact is a type which has a declaration.  In that case,
8403       // let's use the slow dynamic_cast because we don't have the
8404       // pointer to the decl sub-object handily present.
8405       return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
8406     }
8407   return 0;
8408 }
8409 
8410 /// Test if an ABI artifact is a declaration.
8411 ///
8412 /// @param d the artifact to consider.
8413 ///
8414 /// @param return the declaration sub-object of @p d if it's a
8415 /// declaration, or NULL if it is not.
8416 decl_base_sptr
is_decl(const type_or_decl_base_sptr & d)8417 is_decl(const type_or_decl_base_sptr& d)
8418 {return dynamic_pointer_cast<decl_base>(d);}
8419 
8420 /// Test if an ABI artifact is a declaration.
8421 ///
8422 /// This is done using a slow path that uses dynamic_cast.
8423 ///
8424 /// @param d the artifact to consider.
8425 ///
8426 /// @param return the declaration sub-object of @p d if it's a
8427 decl_base*
is_decl_slow(const type_or_decl_base * t)8428 is_decl_slow(const type_or_decl_base* t)
8429 {return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
8430 
8431 /// Test if an ABI artifact is a declaration.
8432 ///
8433 /// This is done using a slow path that uses dynamic_cast.
8434 ///
8435 /// @param d the artifact to consider.
8436 ///
8437 /// @param return the declaration sub-object of @p d if it's a
8438 decl_base_sptr
is_decl_slow(const type_or_decl_base_sptr & t)8439 is_decl_slow(const type_or_decl_base_sptr& t)
8440 {return dynamic_pointer_cast<decl_base>(t);}
8441 
8442 /// Test whether a declaration is a type.
8443 ///
8444 /// @param d the IR artefact to test for.
8445 ///
8446 /// @return true if the artifact is a type, false otherwise.
8447 bool
is_type(const type_or_decl_base & tod)8448 is_type(const type_or_decl_base& tod)
8449 {
8450   if (dynamic_cast<const type_base*>(&tod))
8451     return true;
8452   return false;
8453 }
8454 
8455 /// Test whether a declaration is a type.
8456 ///
8457 /// @param d the IR artefact to test for.
8458 ///
8459 /// @return true if the artifact is a type, false otherwise.
8460 type_base*
is_type(const type_or_decl_base * t)8461 is_type(const type_or_decl_base* t)
8462 {
8463   if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
8464     return reinterpret_cast<type_base*>
8465       (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
8466 
8467   return 0;
8468 }
8469 
8470 /// Test whether a declaration is a type.
8471 ///
8472 /// @param d the IR artefact to test for.
8473 ///
8474 /// @return true if the artifact is a type, false otherwise.
8475 type_base_sptr
is_type(const type_or_decl_base_sptr & tod)8476 is_type(const type_or_decl_base_sptr& tod)
8477 {return dynamic_pointer_cast<type_base>(tod);}
8478 
8479 /// Test whether a declaration is a type.
8480 ///
8481 /// @param d the declaration to test for.
8482 ///
8483 /// @return true if the declaration is a type, false otherwise.
8484 
8485 /// Test if a given type is anonymous.
8486 ///
8487 /// Note that this function considers that an anonymous class that is
8488 /// named by a typedef is not anonymous anymore.  This is the C idiom:
8489 ///
8490 ///       typedef struct {int member;} s_type;
8491 ///
8492 /// The typedef s_type becomes the name of the originally anonymous
8493 /// struct.
8494 ///
8495 /// @param t the type to consider.
8496 ///
8497 /// @return true iff @p t is anonymous.
8498 bool
is_anonymous_type(type_base * t)8499 is_anonymous_type(type_base* t)
8500 {
8501   decl_base* d = get_type_declaration(t);
8502   if (d)
8503     if (d->get_is_anonymous())
8504       {
8505 	if (class_or_union *cou = is_class_or_union_type(t))
8506 	  {
8507 	    // An anonymous class that is named by a typedef is not
8508 	    // considered anonymous anymore.
8509 	    if (!cou->get_naming_typedef())
8510 	      return true;
8511 	  }
8512 	else
8513 	  return true;
8514       }
8515   return false;
8516 }
8517 
8518 /// Test if a given type is anonymous.
8519 ///
8520 /// @param t the type to consider.
8521 ///
8522 /// @return true iff @p t is anonymous.
8523 bool
is_anonymous_type(const type_base_sptr & t)8524 is_anonymous_type(const type_base_sptr& t)
8525 {return is_anonymous_type(t.get());}
8526 
8527 /// Test whether a type is a type_decl (a builtin type).
8528 ///
8529 /// @return the type_decl* for @t if it's type_decl, otherwise, return
8530 /// nil.
8531 const type_decl*
is_type_decl(const type_or_decl_base * t)8532 is_type_decl(const type_or_decl_base* t)
8533 {return dynamic_cast<const type_decl*>(t);}
8534 
8535 /// Test whether a type is a type_decl (a builtin type).
8536 ///
8537 /// @return the type_decl_sptr for @t if it's type_decl, otherwise,
8538 /// return nil.
8539 type_decl_sptr
is_type_decl(const type_or_decl_base_sptr & t)8540 is_type_decl(const type_or_decl_base_sptr& t)
8541 {return dynamic_pointer_cast<type_decl>(t);}
8542 
8543 /// Test whether a type is a typedef.
8544 ///
8545 /// @param t the type to test for.
8546 ///
8547 /// @return the typedef declaration of the @p t, or NULL if it's not a
8548 /// typedef.
8549 typedef_decl_sptr
is_typedef(const type_or_decl_base_sptr t)8550 is_typedef(const type_or_decl_base_sptr t)
8551 {return dynamic_pointer_cast<typedef_decl>(t);}
8552 
8553 /// Test whether a type is a typedef.
8554 ///
8555 /// @param t the declaration of the type to test for.
8556 ///
8557 /// @return the typedef declaration of the @p t, or NULL if it's not a
8558 /// typedef.
8559 const typedef_decl*
is_typedef(const type_base * t)8560 is_typedef(const type_base* t)
8561 {return dynamic_cast<const typedef_decl*>(t);}
8562 
8563 /// Test whether a type is a typedef.
8564 ///
8565 /// @param t the declaration of the type to test for.
8566 ///
8567 /// @return the typedef declaration of the @p t, or NULL if it's not a
8568 /// typedef.
8569 typedef_decl*
is_typedef(type_base * t)8570 is_typedef(type_base* t)
8571 {return dynamic_cast<typedef_decl*>(t);}
8572 
8573 /// Test if a type is an enum. This function looks through typedefs.
8574 ///
8575 /// @parm t the type to consider.
8576 ///
8577 /// @return the enum_decl if @p t is an @ref enum_decl or null
8578 /// otherwise.
8579 enum_type_decl_sptr
is_compatible_with_enum_type(const type_base_sptr & t)8580 is_compatible_with_enum_type(const type_base_sptr& t)
8581 {
8582   if (!t)
8583     return enum_type_decl_sptr();
8584 
8585   // Normally we should strip typedefs entirely, but this is
8586   // potentially costly, especially on binaries with huge changesets
8587   // like the Linux Kernel.  So we just get the leaf types for now.
8588   //
8589   // Maybe there should be an option by which users accepts to pay the
8590   // CPU usage toll in exchange for finer filtering?
8591 
8592   // type_base_sptr ty = strip_typedef(t);
8593   type_base_sptr ty = peel_typedef_type(t);;
8594   return is_enum_type(ty);
8595 }
8596 
8597 /// Test if a type is an enum. This function looks through typedefs.
8598 ///
8599 /// @parm t the type to consider.
8600 ///
8601 /// @return the enum_decl if @p t is an @ref enum_decl or null
8602 /// otherwise.
8603 enum_type_decl_sptr
is_compatible_with_enum_type(const decl_base_sptr & t)8604 is_compatible_with_enum_type(const decl_base_sptr& t)
8605 {return is_compatible_with_enum_type(is_type(t));}
8606 
8607 /// Test if a decl is an enum_type_decl
8608 ///
8609 /// @param d the decl to test for.
8610 ///
8611 /// @return the enum_type_decl* if @p d is an enum, nil otherwise.
8612 const enum_type_decl*
is_enum_type(const type_or_decl_base * d)8613 is_enum_type(const type_or_decl_base* d)
8614 {return dynamic_cast<const enum_type_decl*>(d);}
8615 
8616 /// Test if a decl is an enum_type_decl
8617 ///
8618 /// @param d the decl to test for.
8619 ///
8620 /// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
8621 enum_type_decl_sptr
is_enum_type(const type_or_decl_base_sptr & d)8622 is_enum_type(const type_or_decl_base_sptr& d)
8623 {return dynamic_pointer_cast<enum_type_decl>(d);}
8624 
8625 /// Test if a type is a class. This function looks through typedefs.
8626 ///
8627 /// @parm t the type to consider.
8628 ///
8629 /// @return the class_decl if @p t is a class_decl or null otherwise.
8630 class_decl_sptr
is_compatible_with_class_type(const type_base_sptr & t)8631 is_compatible_with_class_type(const type_base_sptr& t)
8632 {
8633   if (!t)
8634     return class_decl_sptr();
8635 
8636   // Normally we should strip typedefs entirely, but this is
8637   // potentially costly, especially on binaries with huge changesets
8638   // like the Linux Kernel.  So we just get the leaf types for now.
8639   //
8640   // Maybe there should be an option by which users accepts to pay the
8641   // CPU usage toll in exchange for finer filtering?
8642 
8643   // type_base_sptr ty = strip_typedef(t);
8644   type_base_sptr ty = peel_typedef_type(t);
8645   return is_class_type(ty);
8646 }
8647 
8648 /// Test if a type is a class. This function looks through typedefs.
8649 ///
8650 /// @parm t the type to consider.
8651 ///
8652 /// @return the class_decl if @p t is a class_decl or null otherwise.
8653 class_decl_sptr
is_compatible_with_class_type(const decl_base_sptr & t)8654 is_compatible_with_class_type(const decl_base_sptr& t)
8655 {return is_compatible_with_class_type(is_type(t));}
8656 
8657 /// Test whether a type is a class.
8658 ///
8659 /// @parm t the type to consider.
8660 ///
8661 /// @return true iff @p t is a class_decl.
8662 bool
is_class_type(const type_or_decl_base & t)8663 is_class_type(const type_or_decl_base& t)
8664 {return is_class_type(&t);}
8665 
8666 /// Test whether a type is a class.
8667 ///
8668 /// @parm t the type to consider.
8669 ///
8670 /// @return the class_decl if @p t is a class_decl or null otherwise.
8671 class_decl*
is_class_type(const type_or_decl_base * t)8672 is_class_type(const type_or_decl_base* t)
8673 {
8674   if (!t)
8675     return 0;
8676 
8677   if (t->kind() & type_or_decl_base::CLASS_TYPE)
8678     return reinterpret_cast<class_decl*>
8679       (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
8680 
8681   return 0;
8682 }
8683 
8684 /// Test whether a type is a class.
8685 ///
8686 /// @parm t the type to consider.
8687 ///
8688 /// @return the class_decl if @p t is a class_decl or null otherwise.
8689 class_decl_sptr
is_class_type(const type_or_decl_base_sptr & d)8690 is_class_type(const type_or_decl_base_sptr& d)
8691 {return dynamic_pointer_cast<class_decl>(d);}
8692 
8693 
8694 /// Test wheter a type is a declaration-only class.
8695 ///
8696 /// @param t the type to considier.
8697 ///
8698 /// @return true iff @p t is a declaration-only class.
8699 bool
is_declaration_only_class_or_union_type(const type_base * t)8700 is_declaration_only_class_or_union_type(const type_base *t)
8701 {
8702   if (const class_or_union *klass = is_class_or_union_type(t))
8703     return klass->get_is_declaration_only();
8704   return false;
8705 }
8706 
8707 /// Test wheter a type is a declaration-only class.
8708 ///
8709 /// @param t the type to considier.
8710 ///
8711 /// @return true iff @p t is a declaration-only class.
8712 bool
is_declaration_only_class_type(const type_base_sptr & t)8713 is_declaration_only_class_type(const type_base_sptr& t)
8714 {return is_declaration_only_class_or_union_type(t.get());}
8715 
8716 /// Test if a type is a @ref class_or_union.
8717 ///
8718 /// @param t the type to consider.
8719 ///
8720 /// @return the @ref class_or_union is @p is a @ref class_or_union, or
8721 /// nil otherwise.
8722 class_or_union*
is_class_or_union_type(const type_or_decl_base * t)8723 is_class_or_union_type(const type_or_decl_base* t)
8724 {return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
8725 
8726 /// Test if a type is a @ref class_or_union.
8727 ///
8728 /// @param t the type to consider.
8729 ///
8730 /// @return the @ref class_or_union is @p is a @ref class_or_union, or
8731 /// nil otherwise.
8732 shared_ptr<class_or_union>
is_class_or_union_type(const shared_ptr<type_or_decl_base> & t)8733 is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
8734 {return dynamic_pointer_cast<class_or_union>(t);}
8735 
8736 /// Test if a type is a @ref union_decl.
8737 ///
8738 /// @param t the type to consider.
8739 ///
8740 /// @return true iff @p t is a union_decl.
8741 bool
is_union_type(const type_or_decl_base & t)8742 is_union_type(const type_or_decl_base& t)
8743 {return is_union_type(&t);}
8744 
8745 /// Test if a type is a @ref union_decl.
8746 ///
8747 /// @param t the type to consider.
8748 ///
8749 /// @return the @ref union_decl is @p is a @ref union_decl, or nil
8750 /// otherwise.
8751 union_decl*
is_union_type(const type_or_decl_base * t)8752 is_union_type(const type_or_decl_base* t)
8753 {return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
8754 
8755 /// Test if a type is a @ref union_decl.
8756 ///
8757 /// @param t the type to consider.
8758 ///
8759 /// @return the @ref union_decl is @p is a @ref union_decl, or nil
8760 /// otherwise.
8761 union_decl_sptr
is_union_type(const shared_ptr<type_or_decl_base> & t)8762 is_union_type(const shared_ptr<type_or_decl_base>& t)
8763 {return dynamic_pointer_cast<union_decl>(t);}
8764 
8765 /// Test whether a type is a pointer_type_def.
8766 ///
8767 /// @param t the type to test.
8768 ///
8769 /// @return the @ref pointer_type_def_sptr if @p t is a
8770 /// pointer_type_def, null otherwise.
8771 pointer_type_def*
is_pointer_type(type_or_decl_base * t)8772 is_pointer_type(type_or_decl_base* t)
8773 {
8774   if (!t)
8775     return 0;
8776 
8777   if (t->kind() & type_or_decl_base::POINTER_TYPE)
8778     return reinterpret_cast<pointer_type_def*>
8779       (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
8780 
8781   return 0;
8782 }
8783 
8784 /// Test whether a type is a pointer_type_def.
8785 ///
8786 /// @param t the type to test.
8787 ///
8788 /// @return the @ref pointer_type_def_sptr if @p t is a
8789 /// pointer_type_def, null otherwise.
8790 const pointer_type_def*
is_pointer_type(const type_or_decl_base * t)8791 is_pointer_type(const type_or_decl_base* t)
8792 {
8793   return is_pointer_type(const_cast<type_or_decl_base*>(t));
8794 }
8795 
8796 /// Test whether a type is a pointer_type_def.
8797 ///
8798 /// @param t the type to test.
8799 ///
8800 /// @return the @ref pointer_type_def_sptr if @p t is a
8801 /// pointer_type_def, null otherwise.
8802 pointer_type_def_sptr
is_pointer_type(const type_or_decl_base_sptr & t)8803 is_pointer_type(const type_or_decl_base_sptr &t)
8804 {return dynamic_pointer_cast<pointer_type_def>(t);}
8805 
8806 /// Test whether a type is a reference_type_def.
8807 ///
8808 /// @param t the type to test.
8809 ///
8810 /// @return the @ref reference_type_def_sptr if @p t is a
8811 /// reference_type_def, null otherwise.
8812 reference_type_def*
is_reference_type(type_or_decl_base * t)8813 is_reference_type(type_or_decl_base* t)
8814 {return dynamic_cast<reference_type_def*>(t);}
8815 
8816 /// Test whether a type is a reference_type_def.
8817 ///
8818 /// @param t the type to test.
8819 ///
8820 /// @return the @ref reference_type_def_sptr if @p t is a
8821 /// reference_type_def, null otherwise.
8822 const reference_type_def*
is_reference_type(const type_or_decl_base * t)8823 is_reference_type(const type_or_decl_base* t)
8824 {return dynamic_cast<const reference_type_def*>(t);}
8825 
8826 /// Test whether a type is a reference_type_def.
8827 ///
8828 /// @param t the type to test.
8829 ///
8830 /// @return the @ref reference_type_def_sptr if @p t is a
8831 /// reference_type_def, null otherwise.
8832 reference_type_def_sptr
is_reference_type(const type_or_decl_base_sptr & t)8833 is_reference_type(const type_or_decl_base_sptr& t)
8834 {return dynamic_pointer_cast<reference_type_def>(t);}
8835 
8836 /// Test if a type is a pointer to void type.
8837 ///
8838 /// Note that this looks trough typedefs or CV qualifiers to look for
8839 /// the void pointer.
8840 ///
8841 /// @param type the type to consider.
8842 ///
8843 /// @return the actual void pointer if @p is a void pointer or NULL if
8844 /// it's not.
8845 const type_base*
is_void_pointer_type(const type_base * type)8846 is_void_pointer_type(const type_base* type)
8847 {
8848   type = peel_qualified_or_typedef_type(type);
8849 
8850   const pointer_type_def * t = is_pointer_type(type);
8851   if (!t)
8852     return 0;
8853 
8854   // Look through typedefs in the pointed-to type as well.
8855   type_base * ty = t->get_pointed_to_type().get();
8856   ty = peel_qualified_or_typedef_type(ty);
8857   if (ty->get_environment()->is_void_type(ty))
8858     return ty;
8859 
8860   return 0;
8861 }
8862 
8863 /// Test whether a type is a reference_type_def.
8864 ///
8865 /// @param t the type to test.
8866 ///
8867 /// @return the @ref reference_type_def_sptr if @p t is a
8868 /// reference_type_def, null otherwise.
8869 qualified_type_def*
is_qualified_type(const type_or_decl_base * t)8870 is_qualified_type(const type_or_decl_base* t)
8871 {return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
8872 
8873 /// Test whether a type is a qualified_type_def.
8874 ///
8875 /// @param t the type to test.
8876 ///
8877 /// @return the @ref qualified_type_def_sptr if @p t is a
8878 /// qualified_type_def, null otherwise.
8879 qualified_type_def_sptr
is_qualified_type(const type_or_decl_base_sptr & t)8880 is_qualified_type(const type_or_decl_base_sptr& t)
8881 {return dynamic_pointer_cast<qualified_type_def>(t);}
8882 
8883 /// Strip a type from its top level no-op qualifier.
8884 ///
8885 /// Note that a no-op qualifier is how we represents, for instance, a
8886 /// "const reference".  As a reference is always const, that const
8887 /// qualifier just adds noise in terms of change analysis.  Se we
8888 /// represent it as a no-op qualifier so that we can strip it.
8889 ///
8890 /// @param t to type to strip from its potential top-level no-op
8891 /// qualifier.
8892 ///
8893 /// @return If @t is a no-op qualified type, then return the first
8894 /// underlying type that is not a no-op qualified type.
8895 type_base_sptr
look_through_no_op_qualified_type(const type_base_sptr & t)8896 look_through_no_op_qualified_type(const type_base_sptr& t)
8897 {
8898   type_base_sptr ty;
8899   if (qualified_type_def_sptr qt = is_qualified_type(t))
8900     if (qt->get_cv_quals() == qualified_type_def::CV_NONE)
8901       ty = qt->get_underlying_type();
8902 
8903   if (is_qualified_type(ty))
8904     return look_through_no_op_qualified_type(ty);
8905 
8906   return ty ? ty : t;
8907 }
8908 
8909 /// Test whether a type is a function_type.
8910 ///
8911 /// @param t the type to test.
8912 ///
8913 /// @return the @ref function_type_sptr if @p t is a
8914 /// function_type, null otherwise.
8915 function_type_sptr
is_function_type(const type_or_decl_base_sptr & t)8916 is_function_type(const type_or_decl_base_sptr& t)
8917 {return dynamic_pointer_cast<function_type>(t);}
8918 
8919 /// Test whether a type is a function_type.
8920 ///
8921 /// @param t the type to test.
8922 ///
8923 /// @return the @ref function_type_sptr if @p t is a
8924 /// function_type, null otherwise.
8925 function_type*
is_function_type(type_or_decl_base * t)8926 is_function_type(type_or_decl_base* t)
8927 {return dynamic_cast<function_type*>(t);}
8928 
8929 /// Test whether a type is a function_type.
8930 ///
8931 /// @param t the type to test.
8932 ///
8933 /// @return the @ref function_type_sptr if @p t is a
8934 /// function_type, null otherwise.
8935 const function_type*
is_function_type(const type_or_decl_base * t)8936 is_function_type(const type_or_decl_base* t)
8937 {return dynamic_cast<const function_type*>(t);}
8938 
8939 /// Test whether a type is a method_type.
8940 ///
8941 /// @param t the type to test.
8942 ///
8943 /// @return the @ref method_type_sptr if @p t is a
8944 /// method_type, null otherwise.
8945 method_type_sptr
is_method_type(const type_or_decl_base_sptr & t)8946 is_method_type(const type_or_decl_base_sptr& t)
8947 {return dynamic_pointer_cast<method_type>(t);}
8948 
8949 /// Test whether a type is a method_type.
8950 ///
8951 /// @param t the type to test.
8952 ///
8953 /// @return the @ref method_type_sptr if @p t is a
8954 /// method_type, null otherwise.
8955 const method_type*
is_method_type(const type_or_decl_base * t)8956 is_method_type(const type_or_decl_base* t)
8957 {return dynamic_cast<const method_type*>(t);}
8958 
8959 /// Test whether a type is a method_type.
8960 ///
8961 /// @param t the type to test.
8962 ///
8963 /// @return the @ref method_type_sptr if @p t is a
8964 /// method_type, null otherwise.
8965 method_type*
is_method_type(type_or_decl_base * t)8966 is_method_type(type_or_decl_base* t)
8967 {return dynamic_cast<method_type*>(t);}
8968 
8969 /// If a class (or union) is a decl-only class, get its definition.
8970 /// Otherwise, just return the initial class.
8971 ///
8972 /// @param the_class the class (or union) to consider.
8973 ///
8974 /// @return either the definition of the class, or the class itself.
8975 class_or_union*
look_through_decl_only_class(class_or_union * the_class)8976 look_through_decl_only_class(class_or_union* the_class)
8977 {return is_class_or_union_type(look_through_decl_only(the_class));}
8978 
8979 /// If a class (or union) is a decl-only class, get its definition.
8980 /// Otherwise, just return the initial class.
8981 ///
8982 /// @param the_class the class (or union) to consider.
8983 ///
8984 /// @return either the definition of the class, or the class itself.
8985 class_or_union_sptr
look_through_decl_only_class(const class_or_union & the_class)8986 look_through_decl_only_class(const class_or_union& the_class)
8987 {return is_class_or_union_type(look_through_decl_only(the_class));}
8988 
8989 /// If a class (or union) is a decl-only class, get its definition.
8990 /// Otherwise, just return the initial class.
8991 ///
8992 /// @param klass the class (or union) to consider.
8993 ///
8994 /// @return either the definition of the class, or the class itself.
8995 class_or_union_sptr
look_through_decl_only_class(class_or_union_sptr klass)8996 look_through_decl_only_class(class_or_union_sptr klass)
8997 {return is_class_or_union_type(look_through_decl_only(klass));}
8998 
8999 /// If an enum is a decl-only enum, get its definition.
9000 /// Otherwise, just return the initial enum.
9001 ///
9002 /// @param the_enum the enum to consider.
9003 ///
9004 /// @return either the definition of the enum, or the enum itself.
9005 enum_type_decl_sptr
look_through_decl_only_enum(const enum_type_decl & the_enum)9006 look_through_decl_only_enum(const enum_type_decl& the_enum)
9007 {return is_enum_type(look_through_decl_only(the_enum));}
9008 
9009 /// If an enum is a decl-only enum, get its definition.
9010 /// Otherwise, just return the initial enum.
9011 ///
9012 /// @param enom the enum to consider.
9013 ///
9014 /// @return either the definition of the enum, or the enum itself.
9015 enum_type_decl_sptr
look_through_decl_only_enum(enum_type_decl_sptr enom)9016 look_through_decl_only_enum(enum_type_decl_sptr enom)
9017 {return is_enum_type(look_through_decl_only(enom));}
9018 
9019 /// If a decl is decl-only get its definition.  Otherwise, just return nil.
9020 ///
9021 /// @param d the decl to consider.
9022 ///
9023 /// @return either the definition of the decl, or nil.
9024 decl_base_sptr
look_through_decl_only(const decl_base & d)9025 look_through_decl_only(const decl_base& d)
9026 {
9027   decl_base_sptr decl;
9028   if (d.get_is_declaration_only())
9029     decl = d.get_definition_of_declaration();
9030 
9031   if (!decl)
9032     return decl;
9033 
9034   while (decl->get_is_declaration_only()
9035 	 && decl->get_definition_of_declaration())
9036     decl = decl->get_definition_of_declaration();
9037 
9038   return decl;
9039 }
9040 
9041 /// If a decl is decl-only enum, get its definition.  Otherwise, just
9042 /// return the initial decl.
9043 ///
9044 /// @param d the decl to consider.
9045 ///
9046 /// @return either the definition of the enum, or the decl itself.
9047 decl_base*
look_through_decl_only(decl_base * d)9048 look_through_decl_only(decl_base* d)
9049 {
9050   if (!d)
9051     return d;
9052 
9053   decl_base* result = look_through_decl_only(*d).get();
9054   if (!result)
9055     result = d;
9056 
9057   return result;
9058 }
9059 
9060 /// If a decl is decl-only get its definition.  Otherwise, just return nil.
9061 ///
9062 /// @param d the decl to consider.
9063 ///
9064 /// @return either the definition of the decl, or nil.
9065 decl_base_sptr
look_through_decl_only(const decl_base_sptr & d)9066 look_through_decl_only(const decl_base_sptr& d)
9067 {
9068   if (!d)
9069     return d;
9070 
9071   decl_base_sptr result = look_through_decl_only(*d);
9072   if (!result)
9073     result = d;
9074 
9075   return result;
9076 }
9077 
9078 /// Tests if a declaration is a variable declaration.
9079 ///
9080 /// @param decl the decl to test.
9081 ///
9082 /// @return the var_decl_sptr iff decl is a variable declaration; nil
9083 /// otherwise.
9084 var_decl*
is_var_decl(const type_or_decl_base * tod)9085 is_var_decl(const type_or_decl_base* tod)
9086 {return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
9087 
9088 /// Tests if a declaration is a variable declaration.
9089 ///
9090 /// @param decl the decl to test.
9091 ///
9092 /// @return the var_decl_sptr iff decl is a variable declaration; nil
9093 /// otherwise.
9094 var_decl_sptr
is_var_decl(const type_or_decl_base_sptr & decl)9095 is_var_decl(const type_or_decl_base_sptr& decl)
9096 {return dynamic_pointer_cast<var_decl>(decl);}
9097 
9098 /// Tests if a declaration is a namespace declaration.
9099 ///
9100 /// @param d the decalration to consider.
9101 ///
9102 /// @return the namespace declaration if @p d is a namespace.
9103 namespace_decl_sptr
is_namespace(const decl_base_sptr & d)9104 is_namespace(const decl_base_sptr& d)
9105 {return dynamic_pointer_cast<namespace_decl>(d);}
9106 
9107 /// Tests if a declaration is a namespace declaration.
9108 ///
9109 /// @param d the decalration to consider.
9110 ///
9111 /// @return the namespace declaration if @p d is a namespace.
9112 namespace_decl*
is_namespace(const decl_base * d)9113 is_namespace(const decl_base* d)
9114 {return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
9115 
9116 /// Tests whether a decl is a template parameter composition type.
9117 ///
9118 /// @param decl the declaration to consider.
9119 ///
9120 /// @return true iff decl is a template parameter composition type.
9121 bool
is_template_parm_composition_type(const shared_ptr<decl_base> decl)9122 is_template_parm_composition_type(const shared_ptr<decl_base> decl)
9123 {
9124   return (decl
9125 	  && is_at_template_scope(decl)
9126 	  && is_type(decl)
9127 	  && !is_template_parameter(decl));
9128 }
9129 
9130 /// Test whether a decl is the pattern of a function template.
9131 ///
9132 /// @param decl the decl to consider.
9133 ///
9134 /// @return true iff decl is the pattern of a function template.
9135 bool
is_function_template_pattern(const shared_ptr<decl_base> decl)9136 is_function_template_pattern(const shared_ptr<decl_base> decl)
9137 {
9138   return (decl
9139 	  && dynamic_pointer_cast<function_decl>(decl)
9140 	  && dynamic_cast<template_decl*>(decl->get_scope()));
9141 }
9142 
9143 /// Test if a type is an array_type_def.
9144 ///
9145 /// @param type the type to consider.
9146 ///
9147 /// @return true iff @p type is an array_type_def.
9148 array_type_def*
is_array_type(const type_or_decl_base * type)9149 is_array_type(const type_or_decl_base* type)
9150 {return dynamic_cast<array_type_def*>(const_cast<type_or_decl_base*>(type));}
9151 
9152 /// Test if a type is an array_type_def.
9153 ///
9154 /// @param type the type to consider.
9155 ///
9156 /// @return true iff @p type is an array_type_def.
9157 array_type_def_sptr
is_array_type(const type_or_decl_base_sptr & type)9158 is_array_type(const type_or_decl_base_sptr& type)
9159 {return dynamic_pointer_cast<array_type_def>(type);}
9160 
9161 /// Tests if the element of a given array is a qualified type.
9162 ///
9163 /// @param array the array type to consider.
9164 ///
9165 /// @return the qualified element of the array iff it's a qualified
9166 /// type.  Otherwise, return a nil object.
9167 qualified_type_def_sptr
is_array_of_qualified_element(const array_type_def_sptr & array)9168 is_array_of_qualified_element(const array_type_def_sptr& array)
9169 {
9170   if (!array)
9171     return qualified_type_def_sptr();
9172 
9173   return is_qualified_type(array->get_element_type());
9174 }
9175 
9176 /// Test if an array type is an array to a qualified element type.
9177 ///
9178 /// @param type the array type to consider.
9179 ///
9180 /// @return true the array @p type iff it's an array to a qualified
9181 /// element type.
9182 array_type_def_sptr
is_array_of_qualified_element(const type_base_sptr & type)9183 is_array_of_qualified_element(const type_base_sptr& type)
9184 {
9185   if (array_type_def_sptr array = is_array_type(type))
9186     if (is_array_of_qualified_element(array))
9187       return array;
9188 
9189   return array_type_def_sptr();
9190 }
9191 
9192 /// Test if a type is a typedef of an array.
9193 ///
9194 /// Note that the function looks through qualified and typedefs types
9195 /// of the underlying type of the current typedef.  In other words, if
9196 /// we are looking at a typedef of a CV-qualified array, or at a
9197 /// typedef of a CV-qualified typedef of an array, this function will
9198 /// still return TRUE.
9199 ///
9200 /// @param t the type to consider.
9201 ///
9202 /// @return true if t is a typedef which underlying type is an array.
9203 /// That array might be either cv-qualified array or a typedef'ed
9204 /// array, or a combination of both.
9205 array_type_def_sptr
is_typedef_of_array(const type_base_sptr & t)9206 is_typedef_of_array(const type_base_sptr& t)
9207 {
9208   array_type_def_sptr result;
9209 
9210   if (typedef_decl_sptr typdef = is_typedef(t))
9211     {
9212       type_base_sptr u =
9213 	peel_qualified_or_typedef_type(typdef->get_underlying_type());
9214       result = is_array_type(u);
9215     }
9216 
9217   return result;
9218 }
9219 
9220 /// Test if a type is an array_type_def::subrange_type.
9221 ///
9222 /// @param type the type to consider.
9223 ///
9224 /// @return the array_type_def::subrange_type which @p type is a type
9225 /// of, or nil if it's not of that type.
9226 array_type_def::subrange_type*
is_subrange_type(const type_or_decl_base * type)9227 is_subrange_type(const type_or_decl_base *type)
9228 {
9229   return dynamic_cast<array_type_def::subrange_type*>
9230     (const_cast<type_or_decl_base*>(type));
9231 }
9232 
9233 /// Test if a type is an array_type_def::subrange_type.
9234 ///
9235 /// @param type the type to consider.
9236 ///
9237 /// @return the array_type_def::subrange_type which @p type is a type
9238 /// of, or nil if it's not of that type.
9239 array_type_def::subrange_sptr
is_subrange_type(const type_or_decl_base_sptr & type)9240 is_subrange_type(const type_or_decl_base_sptr &type)
9241 {return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
9242 
9243 /// Tests whether a decl is a template.
9244 ///
9245 /// @param decl the decl to consider.
9246 ///
9247 /// @return true iff decl is a function template, class template, or
9248 /// template template parameter.
9249 bool
is_template_decl(const shared_ptr<decl_base> decl)9250 is_template_decl(const shared_ptr<decl_base> decl)
9251 {return decl && dynamic_pointer_cast<template_decl>(decl);}
9252 
9253 /// This enum describe the kind of entity to lookup, while using the
9254 /// lookup API.
9255 enum lookup_entity_kind
9256 {
9257   LOOKUP_ENTITY_TYPE,
9258   LOOKUP_ENTITY_VAR,
9259 };
9260 
9261 /// Find the first relevant delimiter (the "::" string) in a fully
9262 /// qualified C++ type name, starting from a given position.  The
9263 /// delimiter returned separates a type name from the name of its
9264 /// context.
9265 ///
9266 /// This is supposed to work correctly on names in cases like this:
9267 ///
9268 ///    foo<ns1::name1, ns2::name2>
9269 ///
9270 /// In that case when called with with parameter @p begin set to 0, no
9271 /// delimiter is returned, because the type name in this case is:
9272 /// 'foo<ns1::name1, ns2::name2>'.
9273 ///
9274 /// But in this case:
9275 ///
9276 ///   foo<p1, bar::name>::some_type
9277 ///
9278 /// The "::" returned is the one right before 'some_type'.
9279 ///
9280 /// @param fqn the fully qualified name of the type to consider.
9281 ///
9282 /// @param begin the position from which to look for the delimiter.
9283 ///
9284 /// @param delim_pos out parameter. Is set to the position of the
9285 /// delimiter iff the function returned true.
9286 ///
9287 /// @return true iff the function found and returned the delimiter.
9288 static bool
find_next_delim_in_cplus_type(const string & fqn,size_t begin,size_t & delim_pos)9289 find_next_delim_in_cplus_type(const string&	fqn,
9290 			      size_t		begin,
9291 			      size_t&		delim_pos)
9292 {
9293   int angle_count = 0;
9294   bool found = false;
9295   size_t i = begin;
9296   for (; i < fqn.size(); ++i)
9297     {
9298       if (fqn[i] == '<')
9299 	++angle_count;
9300       else if (fqn[i] == '>')
9301 	--angle_count;
9302       else if (i + 1 < fqn.size()
9303 	       && !angle_count
9304 	       && fqn[i] == ':'
9305 	       && fqn[i+1] == ':')
9306 	{
9307 	  delim_pos = i;
9308 	  found = true;
9309 	  break;
9310 	}
9311     }
9312   return found;
9313 }
9314 
9315 /// Decompose a fully qualified name into the list of its components.
9316 ///
9317 /// @param fqn the fully qualified name to decompose.
9318 ///
9319 /// @param comps the resulting list of component to fill.
9320 void
fqn_to_components(const string & fqn,list<string> & comps)9321 fqn_to_components(const string& fqn,
9322 		  list<string>& comps)
9323 {
9324   string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
9325   do
9326     {
9327       if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
9328 	comp_end = fqn_size;
9329 
9330       string comp = fqn.substr(comp_begin, comp_end - comp_begin);
9331       comps.push_back(comp);
9332 
9333       comp_begin = comp_end + 2;
9334       if (comp_begin >= fqn_size)
9335 	break;
9336     } while (true);
9337 }
9338 
9339 /// Turn a set of qualified name components (that name a type) into a
9340 /// qualified name string.
9341 ///
9342 /// @param comps the name components
9343 ///
9344 /// @return the resulting string, which would be the qualified name of
9345 /// a type.
9346 string
components_to_type_name(const list<string> & comps)9347 components_to_type_name(const list<string>& comps)
9348 {
9349   string result;
9350   for (list<string>::const_iterator c = comps.begin();
9351        c != comps.end();
9352        ++c)
9353     if (c == comps.begin())
9354       result = *c;
9355     else
9356       result += "::" + *c;
9357   return result;
9358 }
9359 
9360 /// This predicate returns true if a given container iterator points
9361 /// to the last element of the container, false otherwise.
9362 ///
9363 /// @tparam T the type of the container of the iterator.
9364 ///
9365 /// @param container the container the iterator points into.
9366 ///
9367 /// @param i the iterator to consider.
9368 ///
9369 /// @return true iff the iterator points to the last element of @p
9370 /// container.
9371 template<typename T>
9372 static bool
iterator_is_last(T & container,typename T::const_iterator i)9373 iterator_is_last(T& container,
9374 		 typename T::const_iterator i)
9375 {
9376   typename T::const_iterator next = i;
9377   ++next;
9378   return (next == container.end());
9379 }
9380 
9381 //--------------------------------
9382 // <type and decls lookup stuff>
9383 // ------------------------------
9384 
9385 /// Lookup all the type*s* that have a given fully qualified name.
9386 ///
9387 /// @param type_name the fully qualified name of the type to
9388 /// lookup.
9389 ///
9390 /// @param type_map the map to look into.
9391 ///
9392 /// @return the vector containing the types named @p type_name.  If
9393 /// the lookup didn't yield any type, then this function returns nil.
9394 static const type_base_wptrs_type*
lookup_types_in_map(const interned_string & type_name,const istring_type_base_wptrs_map_type & type_map)9395 lookup_types_in_map(const interned_string& type_name,
9396 		    const istring_type_base_wptrs_map_type& type_map)
9397 {
9398   istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
9399   if (i != type_map.end())
9400     return &i->second;
9401   return 0;
9402 }
9403 
9404 /// Lookup a type (with a given name) in a map that associates a type
9405 /// name to a type.  If there are several types with a given name,
9406 /// then return the last of such types, that is, the last one that got
9407 /// registered.
9408 ///
9409 /// @tparam TypeKind the type of the type this function is supposed to
9410 /// return.
9411 ///
9412 /// @param type_name the name of the type to lookup.
9413 ///
9414 /// @param type_map the map in which to look.
9415 ///
9416 /// @return a shared_ptr to the type found.  If no type was found or
9417 /// if the type found was not of type @p TypeKind then the function
9418 /// returns nil.
9419 template <class TypeKind>
9420 static shared_ptr<TypeKind>
lookup_type_in_map(const interned_string & type_name,const istring_type_base_wptrs_map_type & type_map)9421 lookup_type_in_map(const interned_string& type_name,
9422 		   const istring_type_base_wptrs_map_type& type_map)
9423 {
9424   istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
9425   if (i != type_map.end())
9426     return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
9427   return shared_ptr<TypeKind>();
9428 }
9429 
9430 /// Lookup a basic type from a translation unit.
9431 ///
9432 /// This is done by looking the type up in the type map that is
9433 /// maintained in the translation unit.  So this is as fast as
9434 /// possible.
9435 ///
9436 /// @param type_name the name of the basic type to look for.
9437 ///
9438 /// @param tu the translation unit to look into.
9439 ///
9440 /// @return the basic type found or nil if no basic type was found.
9441 type_decl_sptr
lookup_basic_type(const interned_string & type_name,const translation_unit & tu)9442 lookup_basic_type(const interned_string& type_name, const translation_unit& tu)
9443 {
9444   return lookup_type_in_map<type_decl>(type_name,
9445 				       tu.get_types().basic_types());
9446 }
9447 
9448 /// Lookup a basic type from a translation unit.
9449 ///
9450 /// This is done by looking the type up in the type map that is
9451 /// maintained in the translation unit.  So this is as fast as
9452 /// possible.
9453 ///
9454 /// @param type_name the name of the basic type to look for.
9455 ///
9456 /// @param tu the translation unit to look into.
9457 ///
9458 /// @return the basic type found or nil if no basic type was found.
9459 type_decl_sptr
lookup_basic_type(const string & type_name,const translation_unit & tu)9460 lookup_basic_type(const string& type_name, const translation_unit& tu)
9461 {
9462   const environment* env = tu.get_environment();
9463   ABG_ASSERT(env);
9464 
9465   interned_string s = env->intern(type_name);
9466   return lookup_basic_type(s, tu);
9467 }
9468 
9469 /// Lookup a class type from a translation unit.
9470 ///
9471 /// This is done by looking the type up in the type map that is
9472 /// maintained in the translation unit.  So this is as fast as
9473 /// possible.
9474 ///
9475 /// @param fqn the fully qualified name of the class type node to look
9476 /// up.
9477 ///
9478 /// @param tu the translation unit to perform lookup from.
9479 ///
9480 /// @return the declaration of the class type IR node found, NULL
9481 /// otherwise.
9482 class_decl_sptr
lookup_class_type(const string & fqn,const translation_unit & tu)9483 lookup_class_type(const string& fqn, const translation_unit& tu)
9484 {
9485   const environment* env = tu.get_environment();
9486   ABG_ASSERT(env);
9487 
9488   interned_string s = env->intern(fqn);
9489   return lookup_class_type(s, tu);
9490 }
9491 
9492 /// Lookup a class type from a translation unit.
9493 ///
9494 /// This is done by looking the type up in the type map that is
9495 /// maintained in the translation unit.  So this is as fast as
9496 /// possible.
9497 ///
9498 /// @param type_name the name of the class type to look for.
9499 ///
9500 /// @param tu the translation unit to look into.
9501 ///
9502 /// @return the class type found or nil if no class type was found.
9503 class_decl_sptr
lookup_class_type(const interned_string & type_name,const translation_unit & tu)9504 lookup_class_type(const interned_string& type_name, const translation_unit& tu)
9505 {
9506   return lookup_type_in_map<class_decl>(type_name,
9507 					tu.get_types().class_types());
9508 }
9509 
9510 /// Lookup a union type from a translation unit.
9511 ///
9512 /// This is done by looking the type up in the type map that is
9513 /// maintained in the translation unit.  So this is as fast as
9514 /// possible.
9515 ///
9516 /// @param type_name the name of the union type to look for.
9517 ///
9518 /// @param tu the translation unit to look into.
9519 ///
9520 /// @return the union type found or nil if no union type was found.
9521 union_decl_sptr
lookup_union_type(const interned_string & type_name,const translation_unit & tu)9522 lookup_union_type(const interned_string& type_name, const translation_unit& tu)
9523 {
9524   return lookup_type_in_map<union_decl>(type_name,
9525 					tu.get_types().union_types());
9526 }
9527 
9528 /// Lookup a union type from a translation unit.
9529 ///
9530 /// This is done by looking the type up in the type map that is
9531 /// maintained in the translation unit.  So this is as fast as
9532 /// possible.
9533 ///
9534 /// @param fqn the fully qualified name of the type to lookup.
9535 ///
9536 /// @param tu the translation unit to look into.
9537 ///
9538 /// @return the union type found or nil if no union type was found.
9539 union_decl_sptr
lookup_union_type(const string & fqn,const translation_unit & tu)9540 lookup_union_type(const string& fqn, const translation_unit& tu)
9541 {
9542   const environment* env = tu.get_environment();
9543   ABG_ASSERT(env);
9544 
9545   interned_string s = env->intern(fqn);
9546   return lookup_union_type(s, tu);
9547 }
9548 
9549 /// Lookup a union type in a given corpus, from its location.
9550 ///
9551 /// @param loc the location of the union type to look for.
9552 ///
9553 /// @param corp the corpus to look it from.
9554 ///
9555 /// @return the resulting union_decl.
9556 union_decl_sptr
lookup_union_type_per_location(const interned_string & loc,const corpus & corp)9557 lookup_union_type_per_location(const interned_string &loc, const corpus& corp)
9558 {
9559   const istring_type_base_wptrs_map_type& m =
9560     corp.get_type_per_loc_map().union_types();
9561   union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
9562 
9563   return result;
9564 }
9565 
9566 /// Lookup a union type in a given corpus, from its location.
9567 ///
9568 /// @param loc the location of the union type to look for.
9569 ///
9570 /// @param corp the corpus to look it from.
9571 ///
9572 /// @return the resulting union_decl.
9573 union_decl_sptr
lookup_union_type_per_location(const string & loc,const corpus & corp)9574 lookup_union_type_per_location(const string& loc, const corpus& corp)
9575 {
9576   const environment* env = corp.get_environment();
9577   ABG_ASSERT(env);
9578 
9579   return lookup_union_type_per_location(env->intern(loc), corp);
9580 }
9581 
9582 /// Lookup an enum type from a translation unit.
9583 ///
9584 /// This is done by looking the type up in the type map that is
9585 /// maintained in the translation unit.  So this is as fast as
9586 /// possible.
9587 ///
9588 /// @param type_name the name of the enum type to look for.
9589 ///
9590 /// @param tu the translation unit to look into.
9591 ///
9592 /// @return the enum type found or nil if no enum type was found.
9593 enum_type_decl_sptr
lookup_enum_type(const interned_string & type_name,const translation_unit & tu)9594 lookup_enum_type(const interned_string& type_name, const translation_unit& tu)
9595 {
9596   return lookup_type_in_map<enum_type_decl>(type_name,
9597 					    tu.get_types().enum_types());
9598 }
9599 
9600 /// Lookup an enum type from a translation unit.
9601 ///
9602 /// This is done by looking the type up in the type map that is
9603 /// maintained in the translation unit.  So this is as fast as
9604 /// possible.
9605 ///
9606 /// @param type_name the name of the enum type to look for.
9607 ///
9608 /// @param tu the translation unit to look into.
9609 ///
9610 /// @return the enum type found or nil if no enum type was found.
9611 enum_type_decl_sptr
lookup_enum_type(const string & type_name,const translation_unit & tu)9612 lookup_enum_type(const string& type_name, const translation_unit& tu)
9613 {
9614   const environment* env = tu.get_environment();
9615   ABG_ASSERT(env);
9616 
9617   interned_string s = env->intern(type_name);
9618   return lookup_enum_type(s, tu);
9619 }
9620 
9621 /// Lookup a typedef type from a translation unit.
9622 ///
9623 /// This is done by looking the type up in the type map that is
9624 /// maintained in the translation unit.  So this is as fast as
9625 /// possible.
9626 ///
9627 /// @param type_name the name of the typedef type to look for.
9628 ///
9629 /// @param tu the translation unit to look into.
9630 ///
9631 /// @return the typedef type found or nil if no typedef type was
9632 /// found.
9633 typedef_decl_sptr
lookup_typedef_type(const interned_string & type_name,const translation_unit & tu)9634 lookup_typedef_type(const interned_string& type_name,
9635 		    const translation_unit& tu)
9636 {
9637   return lookup_type_in_map<typedef_decl>(type_name,
9638 					  tu.get_types().typedef_types());
9639 }
9640 
9641 /// Lookup a typedef type from a translation unit.
9642 ///
9643 /// This is done by looking the type up in the type map that is
9644 /// maintained in the translation unit.  So this is as fast as
9645 /// possible.
9646 ///
9647 /// @param type_name the name of the typedef type to look for.
9648 ///
9649 /// @param tu the translation unit to look into.
9650 ///
9651 /// @return the typedef type found or nil if no typedef type was
9652 /// found.
9653 typedef_decl_sptr
lookup_typedef_type(const string & type_name,const translation_unit & tu)9654 lookup_typedef_type(const string& type_name, const translation_unit& tu)
9655 {
9656   const environment* env = tu.get_environment();
9657   ABG_ASSERT(env);
9658 
9659   interned_string s = env->intern(type_name);
9660   return lookup_typedef_type(s, tu);
9661 }
9662 
9663 /// Lookup a qualified type from a translation unit.
9664 ///
9665 /// This is done by looking the type up in the type map that is
9666 /// maintained in the translation unit.  So this is as fast as
9667 /// possible.
9668 ///
9669 /// @param type_name the name of the qualified type to look for.
9670 ///
9671 /// @param tu the translation unit to look into.
9672 ///
9673 /// @return the qualified type found or nil if no qualified type was
9674 /// found.
9675 qualified_type_def_sptr
lookup_qualified_type(const interned_string & type_name,const translation_unit & tu)9676 lookup_qualified_type(const interned_string& type_name,
9677 		      const translation_unit& tu)
9678 {
9679   const type_maps& m = tu.get_types();
9680   return lookup_type_in_map<qualified_type_def>(type_name,
9681 						m.qualified_types());
9682 }
9683 
9684 /// Lookup a qualified type from a translation unit.
9685 ///
9686 /// This is done by looking the type up in the type map that is
9687 /// maintained in the translation unit.  So this is as fast as
9688 /// possible.
9689 ///
9690 /// @param underlying_type the underying type of the qualified type to
9691 /// look up.
9692 ///
9693 /// @param quals the CV-qualifiers of the qualified type to look for.
9694 ///
9695 /// @param tu the translation unit to look into.
9696 ///
9697 /// @return the qualified type found or nil if no qualified type was
9698 /// found.
9699 qualified_type_def_sptr
lookup_qualified_type(const type_base_sptr & underlying_type,qualified_type_def::CV quals,const translation_unit & tu)9700 lookup_qualified_type(const type_base_sptr& underlying_type,
9701 		      qualified_type_def::CV quals,
9702 		      const translation_unit& tu)
9703 {
9704   interned_string type_name = get_name_of_qualified_type(underlying_type,
9705 							 quals);
9706   return lookup_qualified_type(type_name, tu);
9707 }
9708 
9709 /// Lookup a pointer type from a translation unit.
9710 ///
9711 /// This is done by looking the type up in the type map that is
9712 /// maintained in the translation unit.  So this is as fast as
9713 /// possible.
9714 ///
9715 /// @param type_name the name of the pointer type to look for.
9716 ///
9717 /// @param tu the translation unit to look into.
9718 ///
9719 /// @return the pointer type found or nil if no pointer type was
9720 /// found.
9721 pointer_type_def_sptr
lookup_pointer_type(const interned_string & type_name,const translation_unit & tu)9722 lookup_pointer_type(const interned_string& type_name,
9723 		    const translation_unit& tu)
9724 {
9725   const type_maps& m = tu.get_types();
9726   return lookup_type_in_map<pointer_type_def>(type_name,
9727 					      m.pointer_types());
9728 }
9729 
9730 /// Lookup a pointer type from a translation unit.
9731 ///
9732 /// This is done by looking the type up in the type map that is
9733 /// maintained in the translation unit.  So this is as fast as
9734 /// possible.
9735 ///
9736 /// @param type_name the name of the pointer type to look for.
9737 ///
9738 /// @param tu the translation unit to look into.
9739 ///
9740 /// @return the pointer type found or nil if no pointer type was
9741 /// found.
9742 pointer_type_def_sptr
lookup_pointer_type(const string & type_name,const translation_unit & tu)9743 lookup_pointer_type(const string& type_name, const translation_unit& tu)
9744 {
9745   const environment* env = tu.get_environment();
9746   ABG_ASSERT(env);
9747 
9748   interned_string s = env->intern(type_name);
9749   return lookup_pointer_type(s, tu);
9750 }
9751 
9752 /// Lookup a pointer type from a translation unit.
9753 ///
9754 /// This is done by looking the type up in the type map that is
9755 /// maintained in the translation unit.  So this is as fast as
9756 /// possible.
9757 ///
9758 /// @param pointed_to_type the pointed-to-type of the pointer to look for.
9759 ///
9760 /// @param tu the translation unit to look into.
9761 ///
9762 /// @return the pointer type found or nil if no pointer type was
9763 /// found.
9764 pointer_type_def_sptr
lookup_pointer_type(const type_base_sptr & pointed_to_type,const translation_unit & tu)9765 lookup_pointer_type(const type_base_sptr& pointed_to_type,
9766 		    const translation_unit& tu)
9767 {
9768   interned_string type_name = get_name_of_pointer_to_type(*pointed_to_type);
9769   return lookup_pointer_type(type_name, tu);
9770 }
9771 
9772 /// Lookup a reference type from a translation unit.
9773 ///
9774 /// This is done by looking the type up in the type map that is
9775 /// maintained in the translation unit.  So this is as fast as
9776 /// possible.
9777 ///
9778 /// @param type_name the name of the reference type to look for.
9779 ///
9780 /// @param tu the translation unit to look into.
9781 ///
9782 /// @return the reference type found or nil if no reference type was
9783 /// found.
9784 reference_type_def_sptr
lookup_reference_type(const interned_string & type_name,const translation_unit & tu)9785 lookup_reference_type(const interned_string& type_name,
9786 		      const translation_unit& tu)
9787 {
9788   const type_maps& m = tu.get_types();
9789   return lookup_type_in_map<reference_type_def>(type_name,
9790 						m.reference_types());
9791 }
9792 
9793 /// Lookup a reference type from a translation unit.
9794 ///
9795 /// This is done by looking the type up in the type map that is
9796 /// maintained in the translation unit.  So this is as fast as
9797 /// possible.
9798 ///
9799 /// @param pointed_to_type the pointed-to-type of the reference to
9800 /// look up.
9801 ///
9802 /// @param tu the translation unit to look into.
9803 ///
9804 /// @return the reference type found or nil if no reference type was
9805 /// found.
9806 const reference_type_def_sptr
lookup_reference_type(const type_base_sptr & pointed_to_type,bool lvalue_reference,const translation_unit & tu)9807 lookup_reference_type(const type_base_sptr& pointed_to_type,
9808 		      bool lvalue_reference,
9809 		      const translation_unit& tu)
9810 {
9811   interned_string type_name =
9812     get_name_of_reference_to_type(*pointed_to_type, lvalue_reference);
9813   return lookup_reference_type(type_name, tu);
9814 }
9815 
9816 /// Lookup an array type from a translation unit.
9817 ///
9818 /// This is done by looking the type up in the type map that is
9819 /// maintained in the translation unit.  So this is as fast as
9820 /// possible.
9821 ///
9822 /// @param type_name the name of the array type to look for.
9823 ///
9824 /// @param tu the translation unit to look into.
9825 ///
9826 /// @return the array type found or nil if no array type was found.
9827 array_type_def_sptr
lookup_array_type(const interned_string & type_name,const translation_unit & tu)9828 lookup_array_type(const interned_string& type_name,
9829 		  const translation_unit& tu)
9830 {
9831   const type_maps& m = tu.get_types();
9832   return lookup_type_in_map<array_type_def>(type_name,
9833 					    m.array_types());
9834 }
9835 
9836 /// Lookup a function type from a translation unit.
9837 ///
9838 /// This is done by looking the type up in the type map that is
9839 /// maintained in the translation unit.  So this is as fast as
9840 /// possible.
9841 ///
9842 /// @param type_name the name of the type to lookup.
9843 ///
9844 /// @param tu the translation unit to look into.
9845 ///
9846 /// @return the function type found, or NULL of none was found.
9847 function_type_sptr
lookup_function_type(const interned_string & type_name,const translation_unit & tu)9848 lookup_function_type(const interned_string& type_name,
9849 		     const translation_unit& tu)
9850 {
9851   const type_maps& m = tu.get_types();
9852   return lookup_type_in_map<function_type>(type_name,
9853 					   m.function_types());
9854 }
9855 
9856 /// Lookup a function type from a translation unit.
9857 ///
9858 /// This walks all the function types held by the translation unit and
9859 /// compare their sub-type *names*.  If the names match then return
9860 /// the function type found in the translation unit.
9861 ///
9862 /// @param t the function type to look for.
9863 ///
9864 /// @param tu the translation unit to look into.
9865 ///
9866 /// @return the function type found, or NULL of none was found.
9867 function_type_sptr
lookup_function_type(const function_type & t,const translation_unit & tu)9868 lookup_function_type(const function_type& t,
9869 		     const translation_unit& tu)
9870 {
9871   interned_string type_name = get_type_name(t);
9872   return lookup_function_type(type_name, tu);
9873 }
9874 
9875 /// Lookup a function type from a translation unit.
9876 ///
9877 /// This is done by looking the type up in the type map that is
9878 /// maintained in the translation unit.  So this is as fast as
9879 /// possible.
9880 ///
9881 /// @param t the function type to look for.
9882 ///
9883 /// @param tu the translation unit to look into.
9884 ///
9885 /// @return the function type found, or NULL of none was found.
9886 function_type_sptr
lookup_function_type(const function_type_sptr & t,const translation_unit & tu)9887 lookup_function_type(const function_type_sptr& t,
9888 		     const translation_unit& tu)
9889 {return lookup_function_type(*t, tu);}
9890 
9891 /// Lookup a type in a translation unit.
9892 ///
9893 /// @param fqn the fully qualified name of the type to lookup.
9894 ///
9895 /// @param tu the translation unit to consider.
9896 ///
9897 /// @return the declaration of the type if found, NULL otherwise.
9898 const type_base_sptr
lookup_type(const interned_string & fqn,const translation_unit & tu)9899 lookup_type(const interned_string& fqn,
9900 	    const translation_unit& tu)
9901 {
9902   type_base_sptr result;
9903   ((result = lookup_typedef_type(fqn, tu))
9904    || (result = lookup_class_type(fqn, tu))
9905    || (result = lookup_union_type(fqn, tu))
9906    || (result = lookup_enum_type(fqn, tu))
9907    || (result = lookup_qualified_type(fqn, tu))
9908    || (result = lookup_pointer_type(fqn, tu))
9909    || (result = lookup_reference_type(fqn, tu))
9910    || (result = lookup_array_type(fqn, tu))
9911    || (result = lookup_function_type(fqn, tu))
9912    || (result = lookup_basic_type(fqn, tu)));
9913 
9914   return result;
9915 }
9916 
9917 /// Lookup a type in a translation unit, starting from the global
9918 /// namespace.
9919 ///
9920 /// @param fqn the fully qualified name of the type to lookup.
9921 ///
9922 /// @param tu the translation unit to consider.
9923 ///
9924 /// @return the declaration of the type if found, NULL otherwise.
9925 type_base_sptr
lookup_type(const string & fqn,const translation_unit & tu)9926 lookup_type(const string& fqn, const translation_unit& tu)
9927 {
9928   const environment *env = tu.get_environment();
9929   ABG_ASSERT(env);
9930   interned_string ifqn = env->intern(fqn);
9931   return lookup_type(ifqn, tu);
9932 }
9933 
9934 /// Lookup a type from a translation unit.
9935 ///
9936 /// @param fqn the components of the fully qualified name of the node
9937 /// to look up.
9938 ///
9939 /// @param tu the translation unit to perform lookup from.
9940 ///
9941 /// @return the declaration of the IR node found, NULL otherwise.
9942 const type_base_sptr
lookup_type(const type_base_sptr type,const translation_unit & tu)9943 lookup_type(const type_base_sptr type,
9944 	    const translation_unit& tu)
9945 {
9946   interned_string type_name = get_type_name(type);
9947   return lookup_type(type_name, tu);
9948 }
9949 
9950 /// Lookup a type in a scope.
9951 ///
9952 /// This is really slow as it walks the member types of the scope in
9953 /// sequence to find the type with a given name.
9954 ///
9955 /// If possible, users should prefer looking up types from the
9956 /// enclosing translation unit or even ABI corpus because both the
9957 /// translation unit and the corpus have a map of type, indexed by
9958 /// their name.  Looking up a type from those maps is thus much
9959 /// faster.
9960 ///
9961 /// @param fqn the fully qualified name of the type to lookup.
9962 ///
9963 /// @param skope the scope to look into.
9964 ///
9965 /// @return the declaration of the type if found, NULL otherwise.
9966 const type_base_sptr
lookup_type_in_scope(const string & fqn,const scope_decl_sptr & skope)9967 lookup_type_in_scope(const string& fqn,
9968 		     const scope_decl_sptr& skope)
9969 {
9970   list<string> comps;
9971   fqn_to_components(fqn, comps);
9972   return lookup_type_in_scope(comps, skope);
9973 }
9974 
9975 /// Lookup a @ref var_decl in a scope.
9976 ///
9977 /// @param fqn the fuly qualified name of the @var_decl to lookup.
9978 ///
9979 /// @param skope the scope to look into.
9980 ///
9981 /// @return the declaration of the @ref var_decl if found, NULL
9982 /// otherwise.
9983 const decl_base_sptr
lookup_var_decl_in_scope(const string & fqn,const scope_decl_sptr & skope)9984 lookup_var_decl_in_scope(const string& fqn,
9985 			 const scope_decl_sptr& skope)
9986 {
9987   list<string> comps;
9988   fqn_to_components(fqn, comps);
9989   return lookup_var_decl_in_scope(comps, skope);
9990 }
9991 
9992 /// A generic function (template) to get the name of a node, whatever
9993 /// node it is.  This has to be specialized for the kind of node we
9994 /// want.
9995 ///
9996 /// Note that a node is a member of a scope.
9997 ///
9998 /// @tparam NodeKind the kind of node to consider.
9999 ///
10000 /// @param node the node to get the name from.
10001 ///
10002 /// @return the name of the node.
10003 template<typename NodeKind>
10004 static const interned_string&
10005 get_node_name(shared_ptr<NodeKind> node);
10006 
10007 /// Gets the name of a class_decl node.
10008 ///
10009 /// @param node the decl_base node to get the name from.
10010 ///
10011 /// @return the name of the node.
10012 template<>
10013 const interned_string&
get_node_name(class_decl_sptr node)10014 get_node_name(class_decl_sptr node)
10015 {return node->get_name();}
10016 
10017 /// Gets the name of a type_base node.
10018 ///
10019 /// @param node the type_base node to get the name from.
10020 ///
10021 /// @return the name of the node.
10022 template<>
10023 const interned_string&
get_node_name(type_base_sptr node)10024 get_node_name(type_base_sptr node)
10025 {return get_type_declaration(node)->get_name();}
10026 
10027 /// Gets the name of a var_decl node.
10028 ///
10029 /// @param node the var_decl node to get the name from.
10030 ///
10031 /// @return the name of the node.
10032 template<>
10033 const interned_string&
get_node_name(var_decl_sptr node)10034 get_node_name(var_decl_sptr node)
10035 {return node->get_name();}
10036 
10037 /// Generic function to get the declaration of a given node, whatever
10038 /// it is.  There has to be specializations for the kind of the nodes
10039 /// we want to support.
10040 ///
10041 /// @tparam NodeKind the type of the node we are looking at.
10042 ///
10043 /// @return the declaration.
10044 template<typename NodeKind>
10045 static decl_base_sptr
10046 convert_node_to_decl(shared_ptr<NodeKind> node);
10047 
10048 /// Lookup a node in a given scope.
10049 ///
10050 /// @tparam the type of the node to lookup.
10051 ///
10052 /// @param fqn the components of the fully qualified name of the node
10053 /// to lookup.
10054 ///
10055 /// @param skope the scope to look into.
10056 ///
10057 /// @return the declaration of the looked up node, or NULL if it
10058 /// wasn't found.
10059 template<typename NodeKind>
10060 static const type_or_decl_base_sptr
lookup_node_in_scope(const list<string> & fqn,const scope_decl_sptr & skope)10061 lookup_node_in_scope(const list<string>& fqn,
10062 		     const scope_decl_sptr& skope)
10063 {
10064   type_or_decl_base_sptr resulting_decl;
10065   shared_ptr<NodeKind> node;
10066   bool it_is_last = false;
10067   scope_decl_sptr cur_scope = skope, new_scope, scope;
10068 
10069   for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
10070     {
10071       new_scope.reset();
10072       it_is_last = iterator_is_last(fqn, c);
10073       for (scope_decl::declarations::const_iterator m =
10074 	     cur_scope->get_member_decls().begin();
10075 	   m != cur_scope->get_member_decls().end();
10076 	   ++m)
10077 	{
10078 	  if (!it_is_last)
10079 	    {
10080 	      // looking for a scope
10081 	      scope = dynamic_pointer_cast<scope_decl>(*m);
10082 	      if (scope && scope->get_name() == *c)
10083 		{
10084 		  new_scope = scope;
10085 		  break;
10086 		}
10087 	    }
10088 	  else
10089 	    {
10090 	      //looking for a final type.
10091 	      node = dynamic_pointer_cast<NodeKind>(*m);
10092 	      if (node && get_node_name(node) == *c)
10093 		{
10094 		  if (class_decl_sptr cl =
10095 		      dynamic_pointer_cast<class_decl>(node))
10096 		    if (cl->get_is_declaration_only()
10097 			&& !cl->get_definition_of_declaration())
10098 		      continue;
10099 		  resulting_decl = node;
10100 		  break;
10101 		}
10102 	    }
10103 	}
10104       if (!new_scope && !resulting_decl)
10105 	return decl_base_sptr();
10106       cur_scope = new_scope;
10107     }
10108   ABG_ASSERT(resulting_decl);
10109   return resulting_decl;
10110 }
10111 
10112 /// lookup a type in a scope.
10113 ///
10114 ///
10115 /// This is really slow as it walks the member types of the scope in
10116 /// sequence to find the type with a given name.
10117 ///
10118 /// If possible, users should prefer looking up types from the
10119 /// enclosing translation unit or even ABI corpus because both the
10120 /// translation unit and the corpus have a map of type, indexed by
10121 /// their name.  Looking up a type from those maps is thus much
10122 /// faster.
10123 ///
10124 /// @param comps the components of the fully qualified name of the
10125 /// type to lookup.
10126 ///
10127 /// @param skope the scope to look into.
10128 ///
10129 /// @return the declaration of the type found.
10130 const type_base_sptr
lookup_type_in_scope(const list<string> & comps,const scope_decl_sptr & scope)10131 lookup_type_in_scope(const list<string>& comps,
10132 		     const scope_decl_sptr& scope)
10133 {return is_type(lookup_node_in_scope<type_base>(comps, scope));}
10134 
10135 /// lookup a type in a scope.
10136 ///
10137 /// This is really slow as it walks the member types of the scope in
10138 /// sequence to find the type with a given name.
10139 ///
10140 /// If possible, users should prefer looking up types from the
10141 /// enclosing translation unit or even ABI corpus because both the
10142 /// translation unit and the corpus have a map of type, indexed by
10143 /// their name.  Looking up a type from those maps is thus much
10144 /// faster.
10145 ///
10146 /// @param type the type to look for.
10147 ///
10148 /// @param access_path a vector of scopes the path of scopes to follow
10149 /// before reaching the scope into which to look for @p type.  Note
10150 /// that the deepest scope (the one immediately containing @p type) is
10151 /// at index 0 of this vector, and the top-most scope is the last
10152 /// element of the vector.
10153 ///
10154 /// @param scope the top-most scope into which to look for @p type.
10155 ///
10156 /// @return the scope found in @p scope, or NULL if it wasn't found.
10157 static const type_base_sptr
lookup_type_in_scope(const type_base & type,const vector<scope_decl * > & access_path,const scope_decl * scope)10158 lookup_type_in_scope(const type_base& type,
10159 		     const vector<scope_decl*>& access_path,
10160 		     const scope_decl* scope)
10161 {
10162   vector<scope_decl*> a = access_path;
10163   type_base_sptr result;
10164 
10165   scope_decl* first_scope = 0;
10166   if (!a.empty())
10167     {
10168       first_scope = a.back();
10169       ABG_ASSERT(first_scope->get_name() == scope->get_name());
10170       a.pop_back();
10171     }
10172 
10173   if (a.empty())
10174     {
10175       interned_string n = get_type_name(type, false);
10176       for (scope_decl::declarations::const_iterator i =
10177 	     scope->get_member_decls().begin();
10178 	   i != scope->get_member_decls().end();
10179 	   ++i)
10180 	if (is_type(*i) && (*i)->get_name() == n)
10181 	  {
10182 	    result = is_type(*i);
10183 	    break;
10184 	  }
10185     }
10186   else
10187     {
10188       first_scope = a.back();
10189       interned_string scope_name, cur_scope_name = first_scope->get_name();
10190       for (scope_decl::scopes::const_iterator i =
10191 	     scope->get_member_scopes().begin();
10192 	   i != scope->get_member_scopes().end();
10193 	   ++i)
10194 	{
10195 	  scope_name = (*i)->get_name();
10196 	  if (scope_name == cur_scope_name)
10197 	    {
10198 	      result = lookup_type_in_scope(type, a, (*i).get());
10199 	      break;
10200 	    }
10201 	}
10202     }
10203   return result;
10204 }
10205 
10206 /// lookup a type in a scope.
10207 ///
10208 /// This is really slow as it walks the member types of the scope in
10209 /// sequence to find the type with a given name.
10210 ///
10211 /// If possible, users should prefer looking up types from the
10212 /// enclosing translation unit or even ABI corpus because both the
10213 /// translation unit and the corpus have a map of type, indexed by
10214 /// their name.  Looking up a type from those maps is thus much
10215 /// faster.
10216 ///
10217 /// @param type the type to look for.
10218 ///
10219 /// @param scope the top-most scope into which to look for @p type.
10220 ///
10221 /// @return the scope found in @p scope, or NULL if it wasn't found.
10222 static const type_base_sptr
lookup_type_in_scope(const type_base_sptr type,const scope_decl * scope)10223 lookup_type_in_scope(const type_base_sptr type,
10224 		     const scope_decl* scope)
10225 {
10226   if (!type || is_function_type(type))
10227     return type_base_sptr();
10228 
10229   decl_base_sptr type_decl = get_type_declaration(type);
10230   ABG_ASSERT(type_decl);
10231   vector<scope_decl*> access_path;
10232   for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
10233     {
10234       access_path.push_back(s);
10235       if (is_global_scope(s))
10236 	break;
10237     }
10238   return lookup_type_in_scope(*type, access_path, scope);
10239 }
10240 
10241 /// Lookup a type from a translation unit by walking the scopes of the
10242 /// translation unit in sequence and looking into them.
10243 ///
10244 /// This is really slow as it walks the member types of the scopes in
10245 /// sequence to find the type with a given name.
10246 ///
10247 /// If possible, users should prefer looking up types from the
10248 /// translation unit or even ABI corpus in a more direct way, by using
10249 /// the lookup_type() functins.
10250 ///
10251 ///
10252 /// This is because both the translation unit and the corpus have a
10253 /// map of types, indexed by their name.  Looking up a type from those
10254 /// maps is thus much faster.  @param fqn the components of the fully
10255 /// qualified name of the node to look up.
10256 ///
10257 /// @param tu the translation unit to perform lookup from.
10258 ///
10259 /// @return the declaration of the IR node found, NULL otherwise.
10260 const type_base_sptr
lookup_type_through_scopes(const type_base_sptr type,const translation_unit & tu)10261 lookup_type_through_scopes(const type_base_sptr type,
10262 			   const translation_unit& tu)
10263 {
10264   if (function_type_sptr fn_type = is_function_type(type))
10265     return lookup_function_type(fn_type, tu);
10266   return lookup_type_in_scope(type, tu.get_global_scope().get());
10267 }
10268 
10269 /// lookup a var_decl in a scope.
10270 ///
10271 /// @param comps the components of the fully qualified name of the
10272 /// var_decl to lookup.
10273 ///
10274 /// @param skope the scope to look into.
10275 const decl_base_sptr
lookup_var_decl_in_scope(const std::list<string> & comps,const scope_decl_sptr & skope)10276 lookup_var_decl_in_scope(const std::list<string>& comps,
10277 			 const scope_decl_sptr& skope)
10278 {return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
10279 
10280 /// Lookup an IR node from a translation unit.
10281 ///
10282 /// @tparam NodeKind the type of the IR node to lookup from the
10283 /// translation unit.
10284 ///
10285 /// @param fqn the components of the fully qualified name of the node
10286 /// to look up.
10287 ///
10288 /// @param tu the translation unit to perform lookup from.
10289 ///
10290 /// @return the declaration of the IR node found, NULL otherwise.
10291 template<typename NodeKind>
10292 static const type_or_decl_base_sptr
lookup_node_in_translation_unit(const list<string> & fqn,const translation_unit & tu)10293 lookup_node_in_translation_unit(const list<string>& fqn,
10294 				const translation_unit& tu)
10295 {return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
10296 
10297 /// Lookup a type from a translation unit by walking its scopes in
10298 /// sequence and by looking into them.
10299 ///
10300 /// This is much slower than using the lookup_type() function.
10301 ///
10302 /// @param fqn the components of the fully qualified name of the node
10303 /// to look up.
10304 ///
10305 /// @param tu the translation unit to perform lookup from.
10306 ///
10307 /// @return the declaration of the IR node found, NULL otherwise.
10308 type_base_sptr
lookup_type_through_scopes(const list<string> & fqn,const translation_unit & tu)10309 lookup_type_through_scopes(const list<string>& fqn,
10310 			   const translation_unit& tu)
10311 {return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
10312 
10313 
10314 /// Lookup a class type from a translation unit by walking its scopes
10315 /// in sequence and by looking into them.
10316 ///
10317 /// This is much slower than using the lookup_class_type() function
10318 /// because it walks all the scopes of the translation unit in
10319 /// sequence and lookup the types to find one that has a given name.
10320 ///
10321 /// @param fqn the components of the fully qualified name of the class
10322 /// type node to look up.
10323 ///
10324 /// @param tu the translation unit to perform lookup from.
10325 ///
10326 /// @return the declaration of the class type IR node found, NULL
10327 /// otherwise.
10328 class_decl_sptr
lookup_class_type_through_scopes(const list<string> & fqn,const translation_unit & tu)10329 lookup_class_type_through_scopes(const list<string>& fqn,
10330 				 const translation_unit& tu)
10331 {return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
10332 
10333 /// Lookup a basic type from all the translation units of a given
10334 /// corpus.
10335 ///
10336 /// @param fqn the components of the fully qualified name of the basic
10337 /// type node to look up.
10338 ///
10339 /// @param tu the translation unit to perform lookup from.
10340 ///
10341 /// @return the declaration of the basic type IR node found, NULL
10342 /// otherwise.
10343 static type_decl_sptr
lookup_basic_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10344 lookup_basic_type_through_translation_units(const interned_string& type_name,
10345 					    const corpus& abi_corpus)
10346 {
10347   type_decl_sptr result;
10348 
10349   for (translation_units::const_iterator tu =
10350 	 abi_corpus.get_translation_units().begin();
10351        tu != abi_corpus.get_translation_units().end();
10352        ++tu)
10353     if ((result = lookup_basic_type(type_name, **tu)))
10354       break;
10355 
10356   return result;
10357 }
10358 
10359 /// Lookup a union type from all the translation units of a given
10360 /// corpus.
10361 ///
10362 /// @param fqn the components of the fully qualified name of the union
10363 /// type node to look up.
10364 ///
10365 /// @param tu the translation unit to perform lookup from.
10366 ///
10367 /// @return the declaration of the union type IR node found, NULL
10368 /// otherwise.
10369 static union_decl_sptr
lookup_union_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10370 lookup_union_type_through_translation_units(const interned_string& type_name,
10371 					    const corpus & abi_corpus)
10372 {
10373  union_decl_sptr result;
10374 
10375   for (translation_units::const_iterator tu =
10376 	 abi_corpus.get_translation_units().begin();
10377        tu != abi_corpus.get_translation_units().end();
10378        ++tu)
10379     if ((result = lookup_union_type(type_name, **tu)))
10380       break;
10381 
10382   return result;
10383 }
10384 
10385 /// Lookup an enum type from all the translation units of a given
10386 /// corpus.
10387 ///
10388 /// @param fqn the components of the fully qualified name of the enum
10389 /// type node to look up.
10390 ///
10391 /// @param tu the translation unit to perform lookup from.
10392 ///
10393 /// @return the declaration of the enum type IR node found, NULL
10394 /// otherwise.
10395 static enum_type_decl_sptr
lookup_enum_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10396 lookup_enum_type_through_translation_units(const interned_string& type_name,
10397 					   const corpus & abi_corpus)
10398 {
10399   enum_type_decl_sptr result;
10400 
10401   for (translation_units::const_iterator tu =
10402 	 abi_corpus.get_translation_units().begin();
10403        tu != abi_corpus.get_translation_units().end();
10404        ++tu)
10405     if ((result = lookup_enum_type(type_name, **tu)))
10406       break;
10407 
10408   return result;
10409 }
10410 
10411 /// Lookup a typedef type definition in all the translation units of a
10412 /// given ABI corpus.
10413 ///
10414 /// @param @param qn the fully qualified name of the typedef type to lookup.
10415 ///
10416 /// @param abi_corpus the ABI corpus which to look the type up in.
10417 ///
10418 /// @return the type definition if any was found, or a NULL pointer.
10419 static typedef_decl_sptr
lookup_typedef_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10420 lookup_typedef_type_through_translation_units(const interned_string& type_name,
10421 					      const corpus & abi_corpus)
10422 {
10423   typedef_decl_sptr result;
10424 
10425   for (translation_units::const_iterator tu =
10426 	 abi_corpus.get_translation_units().begin();
10427        tu != abi_corpus.get_translation_units().end();
10428        ++tu)
10429     if ((result = lookup_typedef_type(type_name, **tu)))
10430       break;
10431 
10432   return result;
10433 }
10434 
10435 /// Lookup a qualified type definition in all the translation units of a
10436 /// given ABI corpus.
10437 ///
10438 /// @param @param qn the fully qualified name of the qualified type to
10439 /// lookup.
10440 ///
10441 /// @param abi_corpus the ABI corpus which to look the type up in.
10442 ///
10443 /// @return the type definition if any was found, or a NULL pointer.
10444 static qualified_type_def_sptr
lookup_qualified_type_through_translation_units(const interned_string & t_name,const corpus & abi_corpus)10445 lookup_qualified_type_through_translation_units(const interned_string& t_name,
10446 						const corpus & abi_corpus)
10447 {
10448   qualified_type_def_sptr result;
10449 
10450   for (translation_units::const_iterator tu =
10451 	 abi_corpus.get_translation_units().begin();
10452        tu != abi_corpus.get_translation_units().end();
10453        ++tu)
10454     if ((result = lookup_qualified_type(t_name, **tu)))
10455       break;
10456 
10457   return result;
10458 }
10459 
10460 /// Lookup a pointer type definition in all the translation units of a
10461 /// given ABI corpus.
10462 ///
10463 /// @param @param qn the fully qualified name of the pointer type to
10464 /// lookup.
10465 ///
10466 /// @param abi_corpus the ABI corpus which to look the type up in.
10467 ///
10468 /// @return the type definition if any was found, or a NULL pointer.
10469 static pointer_type_def_sptr
lookup_pointer_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10470 lookup_pointer_type_through_translation_units(const interned_string& type_name,
10471 					      const corpus & abi_corpus)
10472 {
10473   pointer_type_def_sptr result;
10474 
10475   for (translation_units::const_iterator tu =
10476 	 abi_corpus.get_translation_units().begin();
10477        tu != abi_corpus.get_translation_units().end();
10478        ++tu)
10479     if ((result = lookup_pointer_type(type_name, **tu)))
10480       break;
10481 
10482   return result;
10483 }
10484 
10485 /// Lookup a reference type definition in all the translation units of a
10486 /// given ABI corpus.
10487 ///
10488 /// @param @param qn the fully qualified name of the reference type to
10489 /// lookup.
10490 ///
10491 /// @param abi_corpus the ABI corpus which to look the type up in.
10492 ///
10493 /// @return the type definition if any was found, or a NULL pointer.
10494 static reference_type_def_sptr
lookup_reference_type_through_translation_units(const interned_string & t_name,const corpus & abi_corpus)10495 lookup_reference_type_through_translation_units(const interned_string& t_name,
10496 						const corpus & abi_corpus)
10497 {
10498   reference_type_def_sptr result;
10499 
10500   for (translation_units::const_iterator tu =
10501 	 abi_corpus.get_translation_units().begin();
10502        tu != abi_corpus.get_translation_units().end();
10503        ++tu)
10504     if ((result = lookup_reference_type(t_name, **tu)))
10505       break;
10506 
10507   return result;
10508 }
10509 
10510 /// Lookup a array type definition in all the translation units of a
10511 /// given ABI corpus.
10512 ///
10513 /// @param @param qn the fully qualified name of the array type to
10514 /// lookup.
10515 ///
10516 /// @param abi_corpus the ABI corpus which to look the type up in.
10517 ///
10518 /// @return the type definition if any was found, or a NULL pointer.
10519 static array_type_def_sptr
lookup_array_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10520 lookup_array_type_through_translation_units(const interned_string& type_name,
10521 					    const corpus & abi_corpus)
10522 {
10523   array_type_def_sptr result;
10524 
10525   for (translation_units::const_iterator tu =
10526 	 abi_corpus.get_translation_units().begin();
10527        tu != abi_corpus.get_translation_units().end();
10528        ++tu)
10529     if ((result = lookup_array_type(type_name, **tu)))
10530       break;
10531 
10532   return result;
10533 }
10534 
10535 /// Lookup a function type definition in all the translation units of
10536 /// a given ABI corpus.
10537 ///
10538 /// @param @param qn the fully qualified name of the function type to
10539 /// lookup.
10540 ///
10541 /// @param abi_corpus the ABI corpus which to look the type up in.
10542 ///
10543 /// @return the type definition if any was found, or a NULL pointer.
10544 static function_type_sptr
lookup_function_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10545 lookup_function_type_through_translation_units(const interned_string& type_name,
10546 					       const corpus & abi_corpus)
10547 {
10548   function_type_sptr result;
10549 
10550   for (translation_units::const_iterator tu =
10551 	 abi_corpus.get_translation_units().begin();
10552        tu != abi_corpus.get_translation_units().end();
10553        ++tu)
10554     if ((result = lookup_function_type(type_name, **tu)))
10555       break;
10556 
10557   return result;
10558 }
10559 
10560 /// Lookup a type definition in all the translation units of a given
10561 /// ABI corpus.
10562 ///
10563 /// @param @param qn the fully qualified name of the type to lookup.
10564 ///
10565 /// @param abi_corpus the ABI corpus which to look the type up in.
10566 ///
10567 /// @return the type definition if any was found, or a NULL pointer.
10568 type_base_sptr
lookup_type_through_translation_units(const string & qn,const corpus & abi_corpus)10569 lookup_type_through_translation_units(const string& qn,
10570 				      const corpus& abi_corpus)
10571 {
10572   type_base_sptr result;
10573 
10574   for (translation_units::const_iterator tu =
10575 	 abi_corpus.get_translation_units().begin();
10576        tu != abi_corpus.get_translation_units().end();
10577        ++tu)
10578     if ((result = lookup_type(qn, **tu)))
10579       break;
10580 
10581   return result;
10582 }
10583 
10584 /// Lookup a type from a given translation unit present in a give corpus.
10585 ///
10586 /// @param type_name the name of the type to look for.
10587 ///
10588 /// @parm tu_path the path of the translation unit to consider.
10589 ///
10590 /// @param corp the corpus to consider.
10591 ///
10592 /// @return the resulting type, if any.
10593 type_base_sptr
lookup_type_from_translation_unit(const string & type_name,const string & tu_path,const corpus & corp)10594 lookup_type_from_translation_unit(const string& type_name,
10595 				  const string& tu_path,
10596 				  const corpus& corp)
10597 {
10598   string_tu_map_type::const_iterator i =  corp.priv_->path_tu_map.find(tu_path);
10599   if (i == corp.priv_->path_tu_map.end())
10600     return type_base_sptr();
10601 
10602   translation_unit_sptr tu = i->second;
10603   ABG_ASSERT(tu);
10604 
10605   type_base_sptr t = lookup_type(type_name, *tu);
10606   return t;
10607 }
10608 
10609 /// Look into an ABI corpus for a function type.
10610 ///
10611 /// @param fn_type the function type to be looked for in the ABI
10612 /// corpus.
10613 ///
10614 /// @param corpus the ABI corpus into which to look for the function
10615 /// type.
10616 ///
10617 /// @return the function type found in the corpus.
10618 function_type_sptr
lookup_or_synthesize_fn_type(const function_type_sptr & fn_t,const corpus & corpus)10619 lookup_or_synthesize_fn_type(const function_type_sptr& fn_t,
10620 			     const corpus& corpus)
10621 {
10622   ABG_ASSERT(fn_t);
10623 
10624   function_type_sptr result;
10625 
10626   if ((result = lookup_function_type(fn_t, corpus)))
10627     return result;
10628 
10629   for (translation_units::const_iterator i =
10630 	 corpus.get_translation_units().begin();
10631        i != corpus.get_translation_units().end();
10632        ++i)
10633     if ((result = synthesize_function_type_from_translation_unit(*fn_t,
10634 								 **i)))
10635       return result;
10636 
10637   return result;
10638 }
10639 
10640 /// Look into a given corpus to find a type which has the same
10641 /// qualified name as a giventype.
10642 ///
10643 /// If the per-corpus type map is non-empty (because the corpus allows
10644 /// the One Definition Rule) then the type islooked up in that
10645 /// per-corpus type map.  Otherwise, the type is looked-up in each
10646 /// translation unit.
10647 ///
10648 /// @param t the type which has the same qualified name as the type we
10649 /// are looking for.
10650 ///
10651 /// @param corp the ABI corpus to look into for the type.
10652 type_decl_sptr
lookup_basic_type(const type_decl & t,const corpus & corp)10653 lookup_basic_type(const type_decl& t, const corpus& corp)
10654 {return lookup_basic_type(t.get_name(), corp);}
10655 
10656 /// Look into a given corpus to find a basic type which has a given
10657 /// qualified name.
10658 ///
10659 /// If the per-corpus type map is non-empty (because the corpus allows
10660 /// the One Definition Rule) then the type islooked up in that
10661 /// per-corpus type map.  Otherwise, the type is looked-up in each
10662 /// translation unit.
10663 ///
10664 /// @param qualified_name the qualified name of the basic type to look
10665 /// for.
10666 ///
10667 /// @param corp the corpus to look into.
10668 type_decl_sptr
lookup_basic_type(const interned_string & qualified_name,const corpus & corp)10669 lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
10670 {
10671   const istring_type_base_wptrs_map_type& m = corp.get_types().basic_types();
10672   type_decl_sptr result;
10673 
10674   if (!m.empty())
10675     result = lookup_type_in_map<type_decl>(qualified_name, m);
10676   else
10677     result = lookup_basic_type_through_translation_units(qualified_name, corp);
10678 
10679   return result;
10680 }
10681 
10682 /// Lookup a @ref type_decl type from a given corpus, by its location.
10683 ///
10684 /// @param loc the location to consider.
10685 ///
10686 /// @param corp the corpus to consider.
10687 ///
10688 /// @return the resulting basic type, if any.
10689 type_decl_sptr
lookup_basic_type_per_location(const interned_string & loc,const corpus & corp)10690 lookup_basic_type_per_location(const interned_string &loc,
10691 			       const corpus &corp)
10692 {
10693   const istring_type_base_wptrs_map_type& m =
10694     corp.get_type_per_loc_map().basic_types();
10695   type_decl_sptr result;
10696 
10697   result = lookup_type_in_map<type_decl>(loc, m);
10698 
10699   return result;
10700 }
10701 
10702 /// Lookup a @ref type_decl type from a given corpus, by its location.
10703 ///
10704 /// @param loc the location to consider.
10705 ///
10706 /// @param corp the corpus to consider.
10707 ///
10708 /// @return the resulting basic type, if any.
10709 type_decl_sptr
lookup_basic_type_per_location(const string & loc,const corpus & corp)10710 lookup_basic_type_per_location(const string &loc, const corpus &corp)
10711 {
10712   const environment* env = corp.get_environment();
10713   ABG_ASSERT(env);
10714 
10715   return lookup_basic_type_per_location(env->intern(loc), corp);
10716 }
10717 
10718 /// Look into a given corpus to find a basic type which has a given
10719 /// qualified name.
10720 ///
10721 /// If the per-corpus type map is non-empty (because the corpus allows
10722 /// the One Definition Rule) then the type islooked up in that
10723 /// per-corpus type map.  Otherwise, the type is looked-up in each
10724 /// translation unit.
10725 ///
10726 /// @param qualified_name the qualified name of the basic type to look
10727 /// for.
10728 ///
10729 /// @param corp the corpus to look into.
10730 type_decl_sptr
lookup_basic_type(const string & qualified_name,const corpus & corp)10731 lookup_basic_type(const string& qualified_name, const corpus& corp)
10732 {
10733   return lookup_basic_type(corp.get_environment()->intern(qualified_name),
10734 			   corp);
10735 }
10736 
10737 /// Look into a given corpus to find a class type which has the same
10738 /// qualified name as a given type.
10739 ///
10740 /// If the per-corpus type map is non-empty (because the corpus allows
10741 /// the One Definition Rule) then the type islooked up in that
10742 /// per-corpus type map.  Otherwise, the type is looked-up in each
10743 /// translation unit.
10744 ///
10745 /// @param t the class decl type which has the same qualified name as
10746 /// the type we are looking for.
10747 ///
10748 /// @param corp the corpus to look into.
10749 class_decl_sptr
lookup_class_type(const class_decl & t,const corpus & corp)10750 lookup_class_type(const class_decl& t, const corpus& corp)
10751 {
10752   interned_string s = get_type_name(t);
10753   return lookup_class_type(s, corp);
10754 }
10755 
10756 /// Look into a given corpus to find a class type which has a given
10757 /// qualified name.
10758 ///
10759 /// If the per-corpus type map is non-empty (because the corpus allows
10760 /// the One Definition Rule) then the type islooked up in that
10761 /// per-corpus type map.  Otherwise, the type is looked-up in each
10762 /// translation unit.
10763 ///
10764 /// @param qualified_name the qualified name of the type to look for.
10765 ///
10766 /// @param corp the corpus to look into.
10767 class_decl_sptr
lookup_class_type(const string & qualified_name,const corpus & corp)10768 lookup_class_type(const string& qualified_name, const corpus& corp)
10769 {
10770   interned_string s = corp.get_environment()->intern(qualified_name);
10771   return lookup_class_type(s, corp);
10772 }
10773 
10774 /// Look into a given corpus to find a class type which has a given
10775 /// qualified name.
10776 ///
10777 /// If the per-corpus type map is non-empty (because the corpus allows
10778 /// the One Definition Rule) then the type islooked up in that
10779 /// per-corpus type map.  Otherwise, the type is looked-up in each
10780 /// translation unit.
10781 ///
10782 /// @param qualified_name the qualified name of the type to look for.
10783 ///
10784 /// @param corp the corpus to look into.
10785 class_decl_sptr
lookup_class_type(const interned_string & qualified_name,const corpus & corp)10786 lookup_class_type(const interned_string& qualified_name, const corpus& corp)
10787 {
10788   const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
10789 
10790   class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
10791 
10792   return result;
10793 }
10794 
10795 /// Look into a given corpus to find the class type*s* that have a
10796 /// given qualified name.
10797 ///
10798 /// @param qualified_name the qualified name of the type to look for.
10799 ///
10800 /// @param corp the corpus to look into.
10801 ///
10802 /// @return the vector of class types named @p qualified_name.
10803 const type_base_wptrs_type *
lookup_class_types(const interned_string & qualified_name,const corpus & corp)10804 lookup_class_types(const interned_string& qualified_name, const corpus& corp)
10805 {
10806   const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
10807 
10808   return lookup_types_in_map(qualified_name, m);
10809 }
10810 
10811 /// Look into a given corpus to find the class type*s* that have a
10812 /// given qualified name.
10813 ///
10814 /// @param qualified_name the qualified name of the type to look for.
10815 ///
10816 /// @param corp the corpus to look into.
10817 ///
10818 /// @return the vector of class types that which name is @p qualified_name.
10819 const type_base_wptrs_type*
lookup_class_types(const string & qualified_name,const corpus & corp)10820 lookup_class_types(const string& qualified_name, const corpus& corp)
10821 {
10822   interned_string s = corp.get_environment()->intern(qualified_name);
10823   return lookup_class_types(s, corp);
10824 }
10825 
10826 /// Look up a @ref class_decl from a given corpus by its location.
10827 ///
10828 /// @param loc the location to consider.
10829 ///
10830 /// @param corp the corpus to consider.
10831 ///
10832 /// @return the resulting class decl, if any.
10833 class_decl_sptr
lookup_class_type_per_location(const interned_string & loc,const corpus & corp)10834 lookup_class_type_per_location(const interned_string& loc,
10835 			       const corpus& corp)
10836 {
10837   const istring_type_base_wptrs_map_type& m =
10838     corp.get_type_per_loc_map().class_types();
10839   class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
10840 
10841   return result;
10842 }
10843 
10844 /// Look up a @ref class_decl from a given corpus by its location.
10845 ///
10846 /// @param loc the location to consider.
10847 ///
10848 /// @param corp the corpus to consider.
10849 ///
10850 /// @return the resulting class decl, if any.
10851 class_decl_sptr
lookup_class_type_per_location(const string & loc,const corpus & corp)10852 lookup_class_type_per_location(const string &loc, const corpus &corp)
10853 {
10854   const environment* env = corp.get_environment();
10855   ABG_ASSERT(env);
10856 
10857   return lookup_class_type_per_location(env->intern(loc), corp);
10858 }
10859 
10860 /// Look into a given corpus to find a union type which has a given
10861 /// qualified name.
10862 ///
10863 /// If the per-corpus type map is non-empty (because the corpus allows
10864 /// the One Definition Rule) then the type islooked up in that
10865 /// per-corpus type map.  Otherwise, the type is looked-up in each
10866 /// translation unit.
10867 ///
10868 /// @param qualified_name the qualified name of the type to look for.
10869 ///
10870 /// @param corp the corpus to look into.
10871 union_decl_sptr
lookup_union_type(const interned_string & type_name,const corpus & corp)10872 lookup_union_type(const interned_string& type_name, const corpus& corp)
10873 {
10874   const istring_type_base_wptrs_map_type& m = corp.get_types().union_types();
10875 
10876   union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
10877   if (!result)
10878     result = lookup_union_type_through_translation_units(type_name, corp);
10879 
10880   return result;
10881 }
10882 
10883 /// Look into a given corpus to find a union type which has a given
10884 /// qualified name.
10885 ///
10886 /// If the per-corpus type map is non-empty (because the corpus allows
10887 /// the One Definition Rule) then the type islooked up in that
10888 /// per-corpus type map.  Otherwise, the type is looked-up in each
10889 /// translation unit.
10890 ///
10891 /// @param qualified_name the qualified name of the type to look for.
10892 ///
10893 /// @param corp the corpus to look into.
10894 union_decl_sptr
lookup_union_type(const string & type_name,const corpus & corp)10895 lookup_union_type(const string& type_name, const corpus& corp)
10896 {
10897   interned_string s = corp.get_environment()->intern(type_name);
10898   return lookup_union_type(s, corp);
10899 }
10900 
10901 /// Look into a given corpus to find an enum type which has the same
10902 /// qualified name as a given enum type.
10903 ///
10904 /// If the per-corpus type map is non-empty (because the corpus allows
10905 /// the One Definition Rule) then the type islooked up in that
10906 /// per-corpus type map.  Otherwise, the type is looked-up in each
10907 /// translation unit.
10908 ///
10909 /// @param t the enum type which has the same qualified name as the
10910 /// type we are looking for.
10911 ///
10912 /// @param corp the corpus to look into.
10913 enum_type_decl_sptr
lookup_enum_type(const enum_type_decl & t,const corpus & corp)10914 lookup_enum_type(const enum_type_decl& t, const corpus& corp)
10915 {
10916   interned_string s = get_type_name(t);
10917   return lookup_enum_type(s, corp);
10918 }
10919 
10920 /// Look into a given corpus to find an enum type which has a given
10921 /// qualified name.
10922 ///
10923 /// If the per-corpus type map is non-empty (because the corpus allows
10924 /// the One Definition Rule) then the type islooked up in that
10925 /// per-corpus type map.  Otherwise, the type is looked-up in each
10926 /// translation unit.
10927 ///
10928 /// @param qualified_name the qualified name of the enum type to look
10929 /// for.
10930 ///
10931 /// @param corp the corpus to look into.
10932 enum_type_decl_sptr
lookup_enum_type(const string & qualified_name,const corpus & corp)10933 lookup_enum_type(const string& qualified_name, const corpus& corp)
10934 {
10935   interned_string s = corp.get_environment()->intern(qualified_name);
10936   return lookup_enum_type(s, corp);
10937 }
10938 
10939 /// Look into a given corpus to find an enum type which has a given
10940 /// qualified name.
10941 ///
10942 /// If the per-corpus type map is non-empty (because the corpus allows
10943 /// the One Definition Rule) then the type islooked up in that
10944 /// per-corpus type map.  Otherwise, the type is looked-up in each
10945 /// translation unit.
10946 ///
10947 /// @param qualified_name the qualified name of the enum type to look
10948 /// for.
10949 ///
10950 /// @param corp the corpus to look into.
10951 enum_type_decl_sptr
lookup_enum_type(const interned_string & qualified_name,const corpus & corp)10952 lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
10953 {
10954   const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();
10955 
10956   enum_type_decl_sptr result =
10957     lookup_type_in_map<enum_type_decl>(qualified_name, m);
10958   if (!result)
10959     result = lookup_enum_type_through_translation_units(qualified_name, corp);
10960 
10961   return result;
10962 }
10963 
10964 /// Look into a given corpus to find the enum type*s* that have a
10965 /// given qualified name.
10966 ///
10967 /// @param qualified_name the qualified name of the type to look for.
10968 ///
10969 /// @param corp the corpus to look into.
10970 ///
10971 /// @return the vector of enum types that which name is @p qualified_name.
10972 const type_base_wptrs_type *
lookup_enum_types(const interned_string & qualified_name,const corpus & corp)10973 lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
10974 {
10975   const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();
10976 
10977   return lookup_types_in_map(qualified_name, m);
10978 }
10979 
10980 /// Look into a given corpus to find the enum type*s* that have a
10981 /// given qualified name.
10982 ///
10983 /// @param qualified_name the qualified name of the type to look for.
10984 ///
10985 /// @param corp the corpus to look into.
10986 ///
10987 /// @return the vector of enum types that which name is @p qualified_name.
10988 const type_base_wptrs_type*
lookup_enum_types(const string & qualified_name,const corpus & corp)10989 lookup_enum_types(const string& qualified_name, const corpus& corp)
10990 {
10991   interned_string s = corp.get_environment()->intern(qualified_name);
10992   return lookup_enum_types(s, corp);
10993 }
10994 
10995 /// Look up an @ref enum_type_decl from a given corpus, by its location.
10996 ///
10997 /// @param loc the location to consider.
10998 ///
10999 /// @param corp the corpus to look the type from.
11000 ///
11001 /// @return the resulting enum type, if any.
11002 enum_type_decl_sptr
lookup_enum_type_per_location(const interned_string & loc,const corpus & corp)11003 lookup_enum_type_per_location(const interned_string &loc, const corpus& corp)
11004 {
11005   const istring_type_base_wptrs_map_type& m =
11006     corp.get_type_per_loc_map().enum_types();
11007   enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
11008 
11009   return result;
11010 }
11011 
11012 /// Look up an @ref enum_type_decl from a given corpus, by its location.
11013 ///
11014 /// @param loc the location to consider.
11015 ///
11016 /// @param corp the corpus to look the type from.
11017 ///
11018 /// @return the resulting enum type, if any.
11019 enum_type_decl_sptr
lookup_enum_type_per_location(const string & loc,const corpus & corp)11020 lookup_enum_type_per_location(const string &loc, const corpus &corp)
11021 {
11022   const environment* env = corp.get_environment();
11023   ABG_ASSERT(env);
11024 
11025   return lookup_enum_type_per_location(env->intern(loc), corp);
11026 }
11027 
11028 /// Look into a given corpus to find a typedef type which has the
11029 /// same qualified name as a given typedef type.
11030 ///
11031 /// If the per-corpus type map is non-empty (because the corpus allows
11032 /// the One Definition Rule) then the type islooked up in that
11033 /// per-corpus type map.  Otherwise, the type is looked-up in each
11034 /// translation unit.
11035 ///
11036 /// @param t the typedef type which has the same qualified name as the
11037 /// typedef type we are looking for.
11038 ///
11039 /// @param corp the corpus to look into.
11040 typedef_decl_sptr
lookup_typedef_type(const typedef_decl & t,const corpus & corp)11041 lookup_typedef_type(const typedef_decl& t, const corpus& corp)
11042 {
11043   interned_string s = get_type_name(t);
11044   return lookup_typedef_type(s, corp);
11045 }
11046 
11047 /// Look into a given corpus to find a typedef type which has the
11048 /// same qualified name as a given typedef type.
11049 ///
11050 /// If the per-corpus type map is non-empty (because the corpus allows
11051 /// the One Definition Rule) then the type islooked up in that
11052 /// per-corpus type map.  Otherwise, the type is looked-up in each
11053 /// translation unit.
11054 ///
11055 /// @param t the typedef type which has the same qualified name as the
11056 /// typedef type we are looking for.
11057 ///
11058 /// @param corp the corpus to look into.
11059 typedef_decl_sptr
lookup_typedef_type(const string & qualified_name,const corpus & corp)11060 lookup_typedef_type(const string& qualified_name, const corpus& corp)
11061 {
11062   interned_string s = corp.get_environment()->intern(qualified_name);
11063   return lookup_typedef_type(s, corp);
11064 }
11065 
11066 /// Look into a given corpus to find a typedef type which has a
11067 /// given qualified name.
11068 ///
11069 /// If the per-corpus type map is non-empty (because the corpus allows
11070 /// the One Definition Rule) then the type islooked up in that
11071 /// per-corpus type map.  Otherwise, the type is looked-up in each
11072 /// translation unit.
11073 ///
11074 /// @param qualified_name the qualified name of the typedef type to
11075 /// look for.
11076 ///
11077 /// @param corp the corpus to look into.
11078 typedef_decl_sptr
lookup_typedef_type(const interned_string & qualified_name,const corpus & corp)11079 lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
11080 {
11081   const istring_type_base_wptrs_map_type& m = corp.get_types().typedef_types();
11082 
11083   typedef_decl_sptr result =
11084     lookup_type_in_map<typedef_decl>(qualified_name, m);
11085   if (!result)
11086     result = lookup_typedef_type_through_translation_units(qualified_name,
11087 							   corp);
11088 
11089   return result;
11090 }
11091 
11092 /// Lookup a @ref typedef_decl from a corpus, by its location.
11093 ///
11094 /// @param loc the location to consider.
11095 ///
11096 /// @param corp the corpus to consider.
11097 ///
11098 /// @return the typedef_decl found, if any.
11099 typedef_decl_sptr
lookup_typedef_type_per_location(const interned_string & loc,const corpus & corp)11100 lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
11101 {
11102   const istring_type_base_wptrs_map_type& m =
11103     corp.get_type_per_loc_map().typedef_types();
11104   typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
11105 
11106   return result;
11107 }
11108 
11109 /// Lookup a @ref typedef_decl from a corpus, by its location.
11110 ///
11111 /// @param loc the location to consider.
11112 ///
11113 /// @param corp the corpus to consider.
11114 ///
11115 /// @return the typedef_decl found, if any.
11116 typedef_decl_sptr
lookup_typedef_type_per_location(const string & loc,const corpus & corp)11117 lookup_typedef_type_per_location(const string &loc, const corpus &corp)
11118 {
11119   const environment* env = corp.get_environment();
11120   ABG_ASSERT(env);
11121 
11122   return lookup_typedef_type_per_location(env->intern(loc), corp);
11123 }
11124 
11125 /// Look into a corpus to find a class, union or typedef type which
11126 /// has a given qualified name.
11127 ///
11128 /// If the per-corpus type map is non-empty (because the corpus allows
11129 /// the One Definition Rule) then the type islooked up in that
11130 /// per-corpus type map.  Otherwise, the type is looked-up in each
11131 /// translation unit.
11132 ///
11133 /// @param qualified_name the name of the type to find.
11134 ///
11135 /// @param corp the corpus to look into.
11136 ///
11137 /// @return the typedef or class type found.
11138 type_base_sptr
lookup_class_or_typedef_type(const string & qualified_name,const corpus & corp)11139 lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
11140 {
11141   type_base_sptr result = lookup_class_type(qualified_name, corp);
11142   if (!result)
11143     result = lookup_union_type(qualified_name, corp);
11144 
11145   if (!result)
11146     result = lookup_typedef_type(qualified_name, corp);
11147   return result;
11148 }
11149 
11150 /// Look into a corpus to find a class, typedef or enum type which has
11151 /// a given qualified name.
11152 ///
11153 /// If the per-corpus type map is non-empty (because the corpus allows
11154 /// the One Definition Rule) then the type islooked up in that
11155 /// per-corpus type map.  Otherwise, the type is looked-up in each
11156 /// translation unit.
11157 ///
11158 /// @param qualified_name the qualified name of the type to look for.
11159 ///
11160 /// @param corp the corpus to look into.
11161 ///
11162 /// @return the typedef, class or enum type found.
11163 type_base_sptr
lookup_class_typedef_or_enum_type(const string & qualified_name,const corpus & corp)11164 lookup_class_typedef_or_enum_type(const string& qualified_name,
11165 				  const corpus& corp)
11166 {
11167   type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
11168   if (!result)
11169     result = lookup_enum_type(qualified_name, corp);
11170 
11171   return result;
11172 }
11173 
11174 /// Look into a given corpus to find a qualified type which has the
11175 /// same qualified name as a given type.
11176 ///
11177 /// @param t the type which has the same qualified name as the
11178 /// qualified type we are looking for.
11179 ///
11180 /// @param corp the corpus to look into.
11181 ///
11182 /// @return the qualified type found.
11183 qualified_type_def_sptr
lookup_qualified_type(const qualified_type_def & t,const corpus & corp)11184 lookup_qualified_type(const qualified_type_def& t, const corpus& corp)
11185 {
11186   interned_string s = get_type_name(t);
11187   return lookup_qualified_type(s, corp);
11188 }
11189 
11190 /// Look into a given corpus to find a qualified type which has a
11191 /// given qualified name.
11192 ///
11193 /// @param qualified_name the qualified name of the type to look for.
11194 ///
11195 /// @param corp the corpus to look into.
11196 ///
11197 /// @return the type found.
11198 qualified_type_def_sptr
lookup_qualified_type(const interned_string & qualified_name,const corpus & corp)11199 lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
11200 {
11201   const istring_type_base_wptrs_map_type& m =
11202     corp.get_types().qualified_types();
11203 
11204   qualified_type_def_sptr result =
11205     lookup_type_in_map<qualified_type_def>(qualified_name, m);
11206 
11207   if (!result)
11208     result = lookup_qualified_type_through_translation_units(qualified_name,
11209 							     corp);
11210 
11211   return result;
11212 }
11213 
11214 /// Look into a given corpus to find a pointer type which has the same
11215 /// qualified name as a given pointer type.
11216 ///
11217 /// @param t the pointer type which has the same qualified name as the
11218 /// type we are looking for.
11219 ///
11220 /// @param corp the corpus to look into.
11221 ///
11222 /// @return the pointer type found.
11223 pointer_type_def_sptr
lookup_pointer_type(const pointer_type_def & t,const corpus & corp)11224 lookup_pointer_type(const pointer_type_def& t, const corpus& corp)
11225 {
11226   interned_string s = get_type_name(t);
11227   return lookup_pointer_type(s, corp);
11228 }
11229 
11230 /// Look into a given corpus to find a pointer type which has a given
11231 /// qualified name.
11232 ///
11233 /// If the per-corpus type map is non-empty (because the corpus allows
11234 /// the One Definition Rule) then the type islooked up in that
11235 /// per-corpus type map.  Otherwise, the type is looked-up in each
11236 /// translation unit.
11237 ///
11238 /// @param qualified_name the qualified name of the pointer type to
11239 /// look for.
11240 ///
11241 /// @param corp the corpus to look into.
11242 ///
11243 /// @return the pointer type found.
11244 pointer_type_def_sptr
lookup_pointer_type(const interned_string & qualified_name,const corpus & corp)11245 lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
11246 {
11247   const istring_type_base_wptrs_map_type& m = corp.get_types().pointer_types();
11248 
11249   pointer_type_def_sptr result =
11250     lookup_type_in_map<pointer_type_def>(qualified_name, m);
11251   if (!result)
11252     result = lookup_pointer_type_through_translation_units(qualified_name,
11253 							   corp);
11254 
11255   return result;
11256 }
11257 
11258 /// Look into a given corpus to find a reference type which has the
11259 /// same qualified name as a given reference type.
11260 ///
11261 /// If the per-corpus type map is non-empty (because the corpus allows
11262 /// the One Definition Rule) then the type islooked up in that
11263 /// per-corpus type map.  Otherwise, the type is looked-up in each
11264 /// translation unit.
11265 ///
11266 /// @param t the reference type which has the same qualified name as
11267 /// the reference type we are looking for.
11268 ///
11269 /// @param corp the corpus to look into.
11270 ///
11271 /// @return the reference type found.
11272 reference_type_def_sptr
lookup_reference_type(const reference_type_def & t,const corpus & corp)11273 lookup_reference_type(const reference_type_def& t, const corpus& corp)
11274 {
11275   interned_string s = get_type_name(t);
11276   return lookup_reference_type(s, corp);
11277 }
11278 
11279 /// Look into a given corpus to find a reference type which has a
11280 /// given qualified name.
11281 ///
11282 /// If the per-corpus type map is non-empty (because the corpus allows
11283 /// the One Definition Rule) then the type islooked up in that
11284 /// per-corpus type map.  Otherwise, the type is looked-up in each
11285 /// translation unit.
11286 ///
11287 /// @param qualified_name the qualified name of the reference type to
11288 /// look for.
11289 ///
11290 /// @param corp the corpus to look into.
11291 ///
11292 /// @return the reference type found.
11293 reference_type_def_sptr
lookup_reference_type(const interned_string & qualified_name,const corpus & corp)11294 lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
11295 {
11296   const istring_type_base_wptrs_map_type& m =
11297     corp.get_types().reference_types();
11298 
11299   reference_type_def_sptr result =
11300     lookup_type_in_map<reference_type_def>(qualified_name, m);
11301   if (!result)
11302     result = lookup_reference_type_through_translation_units(qualified_name,
11303 							     corp);
11304 
11305   return result;
11306 }
11307 
11308 /// Look into a given corpus to find an array type which has a given
11309 /// qualified name.
11310 ///
11311 /// If the per-corpus type map is non-empty (because the corpus allows
11312 /// the One Definition Rule) then the type islooked up in that
11313 /// per-corpus type map.  Otherwise, the type is looked-up in each
11314 /// translation unit.
11315 ///
11316 /// @param qualified_name the qualified name of the array type to look
11317 /// for.
11318 ///
11319 /// @param corp the corpus to look into.
11320 ///
11321 /// @return the array type found.
11322 array_type_def_sptr
lookup_array_type(const array_type_def & t,const corpus & corp)11323 lookup_array_type(const array_type_def& t, const corpus& corp)
11324 {
11325   interned_string s = get_type_name(t);
11326   return lookup_array_type(s, corp);
11327 }
11328 
11329 /// Look into a given corpus to find an array type which has the same
11330 /// qualified name as a given array type.
11331 ///
11332 /// If the per-corpus type map is non-empty (because the corpus allows
11333 /// the One Definition Rule) then the type islooked up in that
11334 /// per-corpus type map.  Otherwise, the type is looked-up in each
11335 /// translation unit.
11336 ///
11337 /// @param t the type which has the same qualified name as the type we
11338 /// are looking for.
11339 ///
11340 /// @param corp the corpus to look into.
11341 ///
11342 /// @return the type found.
11343 array_type_def_sptr
lookup_array_type(const interned_string & qualified_name,const corpus & corp)11344 lookup_array_type(const interned_string& qualified_name, const corpus& corp)
11345 {
11346   const istring_type_base_wptrs_map_type& m = corp.get_types().array_types();
11347 
11348   array_type_def_sptr result =
11349     lookup_type_in_map<array_type_def>(qualified_name, m);
11350   if (!result)
11351     result = lookup_array_type_through_translation_units(qualified_name, corp);
11352 
11353   return result;
11354 }
11355 
11356 /// Look into a given corpus to find a function type which has the same
11357 /// qualified name as a given function type.
11358 ///
11359 /// If the per-corpus type map is non-empty (because the corpus allows
11360 /// the One Definition Rule) then the type islooked up in that
11361 /// per-corpus type map.  Otherwise, the type is looked-up in each
11362 /// translation unit.
11363 ///
11364 /// @param t the function type which has the same qualified name as
11365 /// the function type we are looking for.
11366 ///
11367 /// @param corp the corpus to look into.
11368 ///
11369 /// @return the function type found.
11370 function_type_sptr
lookup_function_type(const function_type & t,const corpus & corp)11371 lookup_function_type(const function_type&t, const corpus& corp)
11372 {
11373   interned_string type_name = get_type_name(t);
11374   return lookup_function_type(type_name, corp);
11375 }
11376 
11377 /// Look into a given corpus to find a function type which has the same
11378 /// qualified name as a given function type.
11379 ///
11380 /// If the per-corpus type map is non-empty (because the corpus allows
11381 /// the One Definition Rule) then the type islooked up in that
11382 /// per-corpus type map.  Otherwise, the type is looked-up in each
11383 /// translation unit.
11384 ///
11385 /// @param t the function type which has the same qualified name as
11386 /// the function type we are looking for.
11387 ///
11388 /// @param corp the corpus to look into.
11389 ///
11390 /// @return the function type found.
11391 function_type_sptr
lookup_function_type(const function_type_sptr & fn_t,const corpus & corpus)11392 lookup_function_type(const function_type_sptr& fn_t,
11393 		     const corpus& corpus)
11394 {
11395   if (fn_t)
11396     return lookup_function_type(*fn_t, corpus);
11397   return function_type_sptr();
11398 }
11399 
11400 /// Look into a given corpus to find a function type which has a given
11401 /// qualified name.
11402 ///
11403 /// If the per-corpus type map is non-empty (because the corpus allows
11404 /// the One Definition Rule) then the type islooked up in that
11405 /// per-corpus type map.  Otherwise, the type is looked-up in each
11406 /// translation unit.
11407 ///
11408 /// @param qualified_name the qualified name of the function type to
11409 /// look for.
11410 ///
11411 /// @param corp the corpus to look into.
11412 ///
11413 /// @return the function type found.
11414 function_type_sptr
lookup_function_type(const interned_string & qualified_name,const corpus & corp)11415 lookup_function_type(const interned_string& qualified_name, const corpus& corp)
11416 {
11417   const istring_type_base_wptrs_map_type& m = corp.get_types().function_types();
11418 
11419   function_type_sptr result =
11420     lookup_type_in_map<function_type>(qualified_name, m);
11421   if (!result)
11422     result = lookup_function_type_through_translation_units(qualified_name,
11423 							    corp);
11424 
11425   return result;
11426 }
11427 
11428 /// Look into a given corpus to find a type which has a given
11429 /// qualified name.
11430 ///
11431 /// If the per-corpus type map is non-empty (because the corpus allows
11432 /// the One Definition Rule) then the type islooked up in that
11433 /// per-corpus type map.  Otherwise, the type is looked-up in each
11434 /// translation unit.
11435 ///
11436 /// @param qualified_name the qualified name of the function type to
11437 /// look for.
11438 ///
11439 /// @param corp the corpus to look into.
11440 ///
11441 /// @return the function type found.
11442 type_base_sptr
lookup_type(const interned_string & n,const corpus & corp)11443 lookup_type(const interned_string& n, const corpus& corp)
11444 {
11445   type_base_sptr result;
11446 
11447   ((result = lookup_basic_type(n, corp))
11448    || (result = lookup_class_type(n, corp))
11449    || (result = lookup_union_type(n, corp))
11450    || (result = lookup_enum_type(n, corp))
11451    || (result = lookup_typedef_type(n, corp))
11452    || (result = lookup_qualified_type(n, corp))
11453    || (result = lookup_pointer_type(n, corp))
11454    || (result = lookup_reference_type(n, corp))
11455    || (result = lookup_array_type(n, corp))
11456    || (result= lookup_function_type(n, corp)));
11457 
11458   return result;
11459 }
11460 
11461 /// Lookup a type from a corpus, by its location.
11462 ///
11463 /// @param loc the location to consider.
11464 ///
11465 /// @param corp the corpus to look the type from.
11466 ///
11467 /// @return the resulting type, if any found.
11468 type_base_sptr
lookup_type_per_location(const interned_string & loc,const corpus & corp)11469 lookup_type_per_location(const interned_string& loc, const corpus& corp)
11470 {
11471   // TODO: finish this.
11472 
11473   //TODO: when we fully support types indexed by their location, this
11474   //function should return a vector of types because at each location,
11475   //there can be several types that are defined (yay, C and C++,
11476   //*sigh*).
11477 
11478   type_base_sptr result;
11479   ((result = lookup_basic_type_per_location(loc, corp))
11480    || (result = lookup_class_type_per_location(loc, corp))
11481    || (result = lookup_union_type_per_location(loc, corp))
11482    || (result = lookup_enum_type_per_location(loc, corp))
11483    || (result = lookup_typedef_type_per_location(loc, corp)));
11484 
11485   return result;
11486 }
11487 
11488 /// Look into a given corpus to find a type
11489 ///
11490 /// If the per-corpus type map is non-empty (because the corpus allows
11491 /// the One Definition Rule) then the type islooked up in that
11492 /// per-corpus type map.  Otherwise, the type is looked-up in each
11493 /// translation unit.
11494 ///
11495 /// @param qualified_name the qualified name of the function type to
11496 /// look for.
11497 ///
11498 /// @param corp the corpus to look into.
11499 ///
11500 /// @return the function type found.
11501 type_base_sptr
lookup_type(const type_base & t,const corpus & corp)11502 lookup_type(const type_base&t, const corpus& corp)
11503 {
11504   interned_string n = get_type_name(t);
11505   return lookup_type(n, corp);
11506 }
11507 
11508 /// Look into a given corpus to find a type
11509 ///
11510 /// If the per-corpus type map is non-empty (because the corpus allows
11511 /// the One Definition Rule) then the type islooked up in that
11512 /// per-corpus type map.  Otherwise, the type is looked-up in each
11513 /// translation unit.
11514 ///
11515 /// @param qualified_name the qualified name of the function type to
11516 /// look for.
11517 ///
11518 /// @param corp the corpus to look into.
11519 ///
11520 /// @return the function type found.
11521 type_base_sptr
lookup_type(const type_base_sptr & t,const corpus & corp)11522 lookup_type(const type_base_sptr&t, const corpus& corp)
11523 {
11524   if (t)
11525     return lookup_type(*t, corp);
11526   return type_base_sptr();
11527 }
11528 
11529 /// Update the map that associates a fully qualified name of a given
11530 /// type to that type.
11531 ///
11532 ///
11533 /// @param type the type we are considering.
11534 ///
11535 /// @param types_map the map to update.  It's a map that assciates a
11536 /// fully qualified name of a type to the type itself.
11537 ///
11538 /// @param use_type_name_as_key if true, use the name of the type as
11539 /// the key to look it up later.  If false, then use the location of
11540 /// the type as a key to look it up later.
11541 ///
11542 /// @return true iff the type was added to the map.
11543 template<typename TypeKind>
11544 bool
maybe_update_types_lookup_map(const shared_ptr<TypeKind> & type,istring_type_base_wptrs_map_type & types_map,bool use_type_name_as_key=true)11545 maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
11546 			      istring_type_base_wptrs_map_type& types_map,
11547 			      bool use_type_name_as_key = true)
11548 {
11549   interned_string s;
11550 
11551   if (use_type_name_as_key)
11552     s = get_type_name(type);
11553   else if (location l = type->get_location())
11554     {
11555       string str = l.expand();
11556       s = type->get_environment()->intern(str);
11557     }
11558 
11559   istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
11560   bool result = false;
11561 
11562   if (i == types_map.end())
11563     {
11564       types_map[s].push_back(type);
11565       result = true;
11566     }
11567   else
11568     i->second.push_back(type);
11569 
11570   return result;
11571 }
11572 
11573 /// This is the specialization for type @ref class_decl of the
11574 /// function template:
11575 ///
11576 ///    maybe_update_types_lookup_map<T>(scope_decl*,
11577 ///					const shared_ptr<T>&,
11578 ///					istring_type_base_wptrs_map_type&)
11579 ///
11580 /// @param class_type the type to consider.
11581 ///
11582 /// @param types_map the type map to update.
11583 ///
11584 /// @return true iff the type was added to the map.
11585 template<>
11586 bool
maybe_update_types_lookup_map(const class_decl_sptr & class_type,istring_type_base_wptrs_map_type & map,bool use_type_name_as_key)11587 maybe_update_types_lookup_map<class_decl>(const class_decl_sptr& class_type,
11588 					  istring_type_base_wptrs_map_type& map,
11589 					  bool use_type_name_as_key)
11590 {
11591   class_decl_sptr type = class_type;
11592 
11593   bool update_qname_map = true;
11594   if (type->get_is_declaration_only())
11595     {
11596       if (class_decl_sptr def =
11597 	  is_class_type(class_type->get_definition_of_declaration()))
11598 	type = def;
11599       else
11600 	update_qname_map = false;
11601     }
11602 
11603   if (!update_qname_map)
11604     return false;
11605 
11606   interned_string s;
11607   if (use_type_name_as_key)
11608     {
11609       string qname = type->get_qualified_name();
11610       s = type->get_environment()->intern(qname);
11611     }
11612   else if (location l = type->get_location())
11613     {
11614       string str = l.expand();
11615       s = type->get_environment()->intern(str);
11616     }
11617 
11618   bool result = false;
11619   istring_type_base_wptrs_map_type::iterator i = map.find(s);
11620   if (i == map.end())
11621     {
11622       map[s].push_back(type);
11623       result = true;
11624     }
11625   else
11626     i->second.push_back(type);
11627 
11628   return result;
11629 }
11630 
11631 /// This is the specialization for type @ref function_type of the
11632 /// function template:
11633 ///
11634 ///    maybe_update_types_lookup_map<T>(scope_decl*,
11635 ///					const shared_ptr<T>&,
11636 ///					istring_type_base_wptrs_map_type&)
11637 ///
11638 /// @param scope the scope of the type to consider.
11639 ///
11640 /// @param class_type the type to consider.
11641 ///
11642 /// @param types_map the type map to update.
11643 ///
11644 /// @return true iff the type was added to the map.
11645 template<>
11646 bool
maybe_update_types_lookup_map(const function_type_sptr & type,istring_type_base_wptrs_map_type & types_map,bool)11647 maybe_update_types_lookup_map<function_type>
11648 (const function_type_sptr& type,
11649  istring_type_base_wptrs_map_type& types_map,
11650  bool /*use_type_name_as_key*/)
11651 {
11652   bool result = false;
11653   interned_string s = get_type_name(type);
11654   istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
11655   if (i == types_map.end())
11656     {
11657       types_map[s].push_back(type);
11658       result = true;
11659     }
11660   else
11661     i->second.push_back(type);
11662 
11663   return result;
11664 }
11665 
11666 /// Update the map that associates the fully qualified name of a basic
11667 /// type with the type itself.
11668 ///
11669 /// The per-translation unit type map is updated if no type with this
11670 /// name was already existing in that map.
11671 ///
11672 /// If no type with this name did already exist in the per-corpus type
11673 /// map, then that per-corpus type map is updated. Otherwise, that
11674 /// type is erased from that per-corpus map.
11675 ///
11676 /// @param basic_type the basic type to consider.
11677 void
maybe_update_types_lookup_map(const type_decl_sptr & basic_type)11678 maybe_update_types_lookup_map(const type_decl_sptr& basic_type)
11679 {
11680   if (translation_unit *tu = basic_type->get_translation_unit())
11681     maybe_update_types_lookup_map<type_decl>
11682       (basic_type, tu->get_types().basic_types());
11683 
11684   if (corpus *type_corpus = basic_type->get_corpus())
11685     {
11686       maybe_update_types_lookup_map<type_decl>
11687 	(basic_type,
11688 	 type_corpus->priv_->get_types().basic_types());
11689 
11690       maybe_update_types_lookup_map<type_decl>
11691 	(basic_type,
11692 	 type_corpus->get_type_per_loc_map().basic_types(),
11693 	 /*use_type_name_as_key*/false);
11694 
11695       if (corpus *group = type_corpus->get_group())
11696 	{
11697 	  maybe_update_types_lookup_map<type_decl>
11698 	    (basic_type,
11699 	     group->priv_->get_types().basic_types());
11700 
11701 	  maybe_update_types_lookup_map<type_decl>
11702 	    (basic_type,
11703 	     group->get_type_per_loc_map().basic_types(),
11704 	     /*use_type_name_as_key*/false);
11705 	}
11706     }
11707 
11708 }
11709 
11710 /// Update the map that associates the fully qualified name of a class
11711 /// type with the type itself.
11712 ///
11713 /// The per-translation unit type map is updated if no type with this
11714 /// name was already existing in that map.
11715 ///
11716 /// If no type with this name did already exist in the per-corpus type
11717 /// map, then that per-corpus type map is updated. Otherwise, that
11718 /// type is erased from that per-corpus map.
11719 ///
11720 /// @param class_type the class type to consider.
11721 void
maybe_update_types_lookup_map(const class_decl_sptr & class_type)11722 maybe_update_types_lookup_map(const class_decl_sptr& class_type)
11723 {
11724   if (translation_unit *tu = class_type->get_translation_unit())
11725     maybe_update_types_lookup_map<class_decl>
11726       (class_type, tu->get_types().class_types());
11727 
11728   if (corpus *type_corpus = class_type->get_corpus())
11729     {
11730       maybe_update_types_lookup_map<class_decl>
11731 	(class_type,
11732 	 type_corpus->priv_->get_types().class_types());
11733 
11734       maybe_update_types_lookup_map<class_decl>
11735 	(class_type,
11736 	 type_corpus->get_type_per_loc_map().class_types(),
11737 	 /*use_type_name_as_key*/false);
11738 
11739       if (corpus *group = type_corpus->get_group())
11740 	{
11741 	  maybe_update_types_lookup_map<class_decl>
11742 	    (class_type,
11743 	     group->priv_->get_types().class_types());
11744 
11745 	  maybe_update_types_lookup_map<class_decl>
11746 	    (class_type,
11747 	     group->get_type_per_loc_map().class_types(),
11748 	     /*use_type_name_as_key*/false);
11749 	}
11750     }
11751 }
11752 
11753 /// Update the map that associates the fully qualified name of a union
11754 /// type with the type itself.
11755 ///
11756 /// The per-translation unit type map is updated if no type with this
11757 /// name was already existing in that map.
11758 ///
11759 /// If no type with this name did already exist in the per-corpus type
11760 /// map, then that per-corpus type map is updated. Otherwise, that
11761 /// type is erased from that per-corpus map.
11762 ///
11763 /// @param union_type the union type to consider.
11764 void
maybe_update_types_lookup_map(const union_decl_sptr & union_type)11765 maybe_update_types_lookup_map(const union_decl_sptr& union_type)
11766 {
11767   if (translation_unit *tu = union_type->get_translation_unit())
11768     maybe_update_types_lookup_map<union_decl>
11769       (union_type, tu->get_types().union_types());
11770 
11771   if (corpus *type_corpus = union_type->get_corpus())
11772     {
11773       maybe_update_types_lookup_map<union_decl>
11774 	(union_type,
11775 	 type_corpus->priv_->get_types().union_types());
11776 
11777       maybe_update_types_lookup_map<union_decl>
11778 	(union_type,
11779 	 type_corpus->get_type_per_loc_map().union_types(),
11780 	 /*use_type_name_as_key*/false);
11781 
11782       if (corpus *group = type_corpus->get_group())
11783 	{
11784 	  maybe_update_types_lookup_map<union_decl>
11785 	    (union_type,
11786 	     group->priv_->get_types().union_types());
11787 
11788 	  maybe_update_types_lookup_map<union_decl>
11789 	    (union_type,
11790 	     group->get_type_per_loc_map().union_types(),
11791 	     /*use_type_name_as_key*/false);
11792 	}
11793     }
11794 }
11795 
11796 /// Update the map that associates the fully qualified name of an enum
11797 /// type with the type itself.
11798 ///
11799 /// The per-translation unit type map is updated if no type with this
11800 /// name was already existing in that map.
11801 ///
11802 /// If no type with this name did already exist in the per-corpus type
11803 /// map, then that per-corpus type map is updated. Otherwise, that
11804 /// type is erased from that per-corpus map.
11805 ///
11806 /// @param enum_type the type to consider.
11807 void
maybe_update_types_lookup_map(const enum_type_decl_sptr & enum_type)11808 maybe_update_types_lookup_map(const enum_type_decl_sptr& enum_type)
11809 {
11810   if (translation_unit *tu = enum_type->get_translation_unit())
11811     maybe_update_types_lookup_map<enum_type_decl>
11812       (enum_type, tu->get_types().enum_types());
11813 
11814   if (corpus *type_corpus = enum_type->get_corpus())
11815     {
11816       maybe_update_types_lookup_map<enum_type_decl>
11817 	(enum_type,
11818 	 type_corpus->priv_->get_types().enum_types());
11819 
11820       maybe_update_types_lookup_map<enum_type_decl>
11821 	(enum_type,
11822 	 type_corpus->get_type_per_loc_map().enum_types(),
11823 	 /*use_type_name_as_key*/false);
11824 
11825       if (corpus *group = type_corpus->get_group())
11826 	{
11827 	  maybe_update_types_lookup_map<enum_type_decl>
11828 	    (enum_type,
11829 	     group->priv_->get_types().enum_types());
11830 
11831 	  maybe_update_types_lookup_map<enum_type_decl>
11832 	    (enum_type,
11833 	     group->get_type_per_loc_map().enum_types(),
11834 	     /*use_type_name_as_key*/false);
11835 	}
11836     }
11837 
11838 }
11839 
11840 /// Update the map that associates the fully qualified name of a
11841 /// typedef type with the type itself.
11842 ///
11843 /// The per-translation unit type map is updated if no type with this
11844 /// name was already existing in that map.
11845 ///
11846 /// If no type with this name did already exist in the per-corpus type
11847 /// map, then that per-corpus type map is updated. Otherwise, that
11848 /// type is erased from that per-corpus map.
11849 ///
11850 /// @param typedef_type the type to consider.
11851 void
maybe_update_types_lookup_map(const typedef_decl_sptr & typedef_type)11852 maybe_update_types_lookup_map(const typedef_decl_sptr& typedef_type)
11853 {
11854   if (translation_unit *tu = typedef_type->get_translation_unit())
11855     maybe_update_types_lookup_map<typedef_decl>
11856       (typedef_type, tu->get_types().typedef_types());
11857 
11858   if (corpus *type_corpus = typedef_type->get_corpus())
11859     {
11860       maybe_update_types_lookup_map<typedef_decl>
11861 	(typedef_type,
11862 	 type_corpus->priv_->get_types().typedef_types());
11863 
11864       maybe_update_types_lookup_map<typedef_decl>
11865 	(typedef_type,
11866 	 type_corpus->get_type_per_loc_map().typedef_types(),
11867 	 /*use_type_name_as_key*/false);
11868 
11869       if (corpus *group = type_corpus->get_group())
11870 	{
11871 	  maybe_update_types_lookup_map<typedef_decl>
11872 	    (typedef_type,
11873 	     group->priv_->get_types().typedef_types());
11874 
11875 	  maybe_update_types_lookup_map<typedef_decl>
11876 	    (typedef_type,
11877 	     group->get_type_per_loc_map().typedef_types(),
11878 	     /*use_type_name_as_key*/false);
11879 	}
11880     }
11881 }
11882 
11883 /// Update the map that associates the fully qualified name of a
11884 /// qualified type with the type itself.
11885 ///
11886 /// The per-translation unit type map is updated if no type with this
11887 /// name was already existing in that map.
11888 ///
11889 /// If no type with this name did already exist in the per-corpus type
11890 /// map, then that per-corpus type map is updated. Otherwise, that
11891 /// type is erased from that per-corpus map.
11892 ///
11893 /// @param qualified_type the type to consider.
11894 void
maybe_update_types_lookup_map(const qualified_type_def_sptr & qualified_type)11895 maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
11896 {
11897   if (translation_unit *tu = qualified_type->get_translation_unit())
11898     maybe_update_types_lookup_map<qualified_type_def>
11899       (qualified_type, tu->get_types().qualified_types());
11900 
11901   if (corpus *type_corpus = qualified_type->get_corpus())
11902     {
11903       maybe_update_types_lookup_map<qualified_type_def>
11904 	(qualified_type,
11905 	 type_corpus->priv_->get_types().qualified_types());
11906 
11907       if (corpus *group = type_corpus->get_group())
11908 	{
11909 	  maybe_update_types_lookup_map<qualified_type_def>
11910 	    (qualified_type,
11911 	     group->priv_->get_types().qualified_types());
11912 	}
11913     }
11914 }
11915 
11916 /// Update the map that associates the fully qualified name of a
11917 /// pointer type with the type itself.
11918 ///
11919 /// The per-translation unit type map is updated if no type with this
11920 /// name was already existing in that map.
11921 ///
11922 /// If no type with this name did already exist in the per-corpus type
11923 /// map, then that per-corpus type map is updated. Otherwise, that
11924 /// type is erased from that per-corpus map.
11925 ///
11926 /// @param pointer_type the type to consider.
11927 void
maybe_update_types_lookup_map(const pointer_type_def_sptr & pointer_type)11928 maybe_update_types_lookup_map(const pointer_type_def_sptr& pointer_type)
11929 {
11930   if (translation_unit *tu = pointer_type->get_translation_unit())
11931     maybe_update_types_lookup_map<pointer_type_def>
11932       (pointer_type, tu->get_types().pointer_types());
11933 
11934   if (corpus *type_corpus = pointer_type->get_corpus())
11935     {
11936       maybe_update_types_lookup_map<pointer_type_def>
11937 	(pointer_type,
11938 	 type_corpus->priv_->get_types().pointer_types());
11939 
11940       if (corpus *group = type_corpus->get_group())
11941 	{
11942 	  maybe_update_types_lookup_map<pointer_type_def>
11943 	    (pointer_type,
11944 	     group->priv_->get_types().pointer_types());
11945 	}
11946     }
11947 }
11948 
11949 /// Update the map that associates the fully qualified name of a
11950 /// reference type with the type itself.
11951 ///
11952 /// The per-translation unit type map is updated if no type with this
11953 /// name was already existing in that map.
11954 ///
11955 /// If no type with this name did already exist in the per-corpus type
11956 /// map, then that per-corpus type map is updated. Otherwise, that
11957 /// type is erased from that per-corpus map.
11958 ///
11959 /// @param reference_type the type to consider.
11960 void
maybe_update_types_lookup_map(const reference_type_def_sptr & reference_type)11961 maybe_update_types_lookup_map(const reference_type_def_sptr& reference_type)
11962 {
11963   if (translation_unit *tu = reference_type->get_translation_unit())
11964     maybe_update_types_lookup_map<reference_type_def>
11965       (reference_type, tu->get_types().reference_types());
11966 
11967   if (corpus *type_corpus = reference_type->get_corpus())
11968     {
11969       maybe_update_types_lookup_map<reference_type_def>
11970 	(reference_type,
11971 	 type_corpus->priv_->get_types().reference_types());
11972 
11973       if (corpus *group = type_corpus->get_group())
11974 	{
11975 	  maybe_update_types_lookup_map<reference_type_def>
11976 	    (reference_type,
11977 	     group->priv_->get_types().reference_types());
11978 	}
11979     }
11980 }
11981 
11982 /// Update the map that associates the fully qualified name of a type
11983 /// with the type itself.
11984 ///
11985 /// The per-translation unit type map is updated if no type with this
11986 /// name was already existing in that map.
11987 ///
11988 /// If no type with this name did already exist in the per-corpus type
11989 /// map, then that per-corpus type map is updated. Otherwise, that
11990 /// type is erased from that per-corpus map.
11991 ///
11992 /// @param array_type the type to consider.
11993 void
maybe_update_types_lookup_map(const array_type_def_sptr & array_type)11994 maybe_update_types_lookup_map(const array_type_def_sptr& array_type)
11995 {
11996   if (translation_unit *tu = array_type->get_translation_unit())
11997     maybe_update_types_lookup_map<array_type_def>
11998       (array_type, tu->get_types().array_types());
11999 
12000   if (corpus *type_corpus = array_type->get_corpus())
12001     {
12002       maybe_update_types_lookup_map<array_type_def>
12003 	(array_type,
12004 	 type_corpus->priv_->get_types().array_types());
12005 
12006       maybe_update_types_lookup_map<array_type_def>
12007 	(array_type,
12008 	 type_corpus->get_type_per_loc_map().array_types(),
12009 	 /*use_type_name_as_key*/false);
12010 
12011       if (corpus *group = type_corpus->get_group())
12012 	{
12013 	  maybe_update_types_lookup_map<array_type_def>
12014 	    (array_type,
12015 	     group->priv_->get_types().array_types());
12016 
12017 	  maybe_update_types_lookup_map<array_type_def>
12018 	    (array_type,
12019 	     group->get_type_per_loc_map().array_types(),
12020 	     /*use_type_name_as_key*/false);
12021 	}
12022     }
12023 }
12024 
12025 /// Update the map that associates the fully qualified name of a type
12026 /// with the type itself.
12027 ///
12028 /// The per-translation unit type map is updated if no type with this
12029 /// name was already existing in that map.
12030 ///
12031 /// If no type with this name did already exist in the per-corpus type
12032 /// map, then that per-corpus type map is updated. Otherwise, that
12033 /// type is erased from that per-corpus map.
12034 ///
12035 /// @param subrange_type the type to consider.
12036 void
maybe_update_types_lookup_map(const array_type_def::subrange_sptr & subrange_type)12037 maybe_update_types_lookup_map
12038 (const array_type_def::subrange_sptr& subrange_type)
12039 {
12040   if (translation_unit *tu = subrange_type->get_translation_unit())
12041     maybe_update_types_lookup_map<array_type_def::subrange_type>
12042       (subrange_type, tu->get_types().subrange_types());
12043 
12044   if (corpus *type_corpus = subrange_type->get_corpus())
12045     {
12046       maybe_update_types_lookup_map<array_type_def::subrange_type>
12047 	(subrange_type,
12048 	 type_corpus->priv_->get_types().subrange_types());
12049 
12050       maybe_update_types_lookup_map<array_type_def::subrange_type>
12051 	(subrange_type,
12052 	 type_corpus->get_type_per_loc_map().subrange_types(),
12053 	 /*use_type_name_as_key*/false);
12054 
12055       if (corpus *group = subrange_type->get_corpus())
12056 	{
12057 	  maybe_update_types_lookup_map<array_type_def::subrange_type>
12058 	    (subrange_type,
12059 	     group->priv_->get_types().subrange_types());
12060 
12061 	  maybe_update_types_lookup_map<array_type_def::subrange_type>
12062 	    (subrange_type,
12063 	     group->get_type_per_loc_map().subrange_types(),
12064 	     /*use_type_name_as_key*/false);
12065 	}
12066     }
12067 }
12068 
12069 /// Update the map that associates the fully qualified name of a
12070 /// function type with the type itself.
12071 ///
12072 /// The per-translation unit type map is updated if no type with this
12073 /// name was already existing in that map.
12074 ///
12075 /// If no type with this name did already exist in the per-corpus type
12076 /// map, then that per-corpus type map is updated. Otherwise, that
12077 /// type is erased from that per-corpus map.
12078 ///
12079 /// @param scope the scope of the function type.
12080 /// @param fn_type the type to consider.
12081 void
maybe_update_types_lookup_map(const function_type_sptr & fn_type)12082 maybe_update_types_lookup_map(const function_type_sptr& fn_type)
12083 {
12084   if (translation_unit *tu = fn_type->get_translation_unit())
12085     maybe_update_types_lookup_map<function_type>
12086       (fn_type, tu->get_types().function_types());
12087 
12088   if (corpus *type_corpus = fn_type->get_corpus())
12089     {
12090       maybe_update_types_lookup_map<function_type>
12091 	(fn_type,
12092 	 type_corpus->priv_->get_types().function_types());
12093 
12094       if (corpus *group = fn_type->get_corpus())
12095 	{
12096 	  maybe_update_types_lookup_map<function_type>
12097 	    (fn_type,
12098 	     group->priv_->get_types().function_types());
12099 	}
12100     }
12101 }
12102 
12103 /// Update the map that associates the fully qualified name of a type
12104 /// declaration with the type itself.
12105 ///
12106 /// The per-translation unit type map is updated if no type with this
12107 /// name was already existing in that map.
12108 ///
12109 /// If no type with this name did already exist in the per-corpus type
12110 /// map, then that per-corpus type map is updated. Otherwise, that
12111 /// type is erased from that per-corpus map.
12112 ///
12113 /// @param decl the declaration of the type to consider.
12114 void
maybe_update_types_lookup_map(const decl_base_sptr & decl)12115 maybe_update_types_lookup_map(const decl_base_sptr& decl)
12116 {
12117   if (!is_type(decl))
12118     return;
12119 
12120   if (type_decl_sptr basic_type = is_type_decl(decl))
12121     maybe_update_types_lookup_map(basic_type);
12122   else if (class_decl_sptr class_type = is_class_type(decl))
12123     maybe_update_types_lookup_map(class_type);
12124   else if (union_decl_sptr union_type = is_union_type(decl))
12125     maybe_update_types_lookup_map(union_type);
12126   else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
12127     maybe_update_types_lookup_map(enum_type);
12128   else if (typedef_decl_sptr typedef_type = is_typedef(decl))
12129     maybe_update_types_lookup_map(typedef_type);
12130   else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
12131     maybe_update_types_lookup_map(qualified_type);
12132   else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
12133     maybe_update_types_lookup_map(pointer_type);
12134   else if (reference_type_def_sptr reference_type = is_reference_type(decl))
12135     maybe_update_types_lookup_map(reference_type);
12136   else if (array_type_def_sptr array_type = is_array_type(decl))
12137     maybe_update_types_lookup_map(array_type);
12138   else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
12139     maybe_update_types_lookup_map(subrange_type);
12140   else
12141     ABG_ASSERT_NOT_REACHED;
12142 }
12143 
12144 /// Update the map that associates the fully qualified name of a type
12145 /// with the type itself.
12146 ///
12147 /// The per-translation unit type map is updated if no type with this
12148 /// name was already existing in that map.
12149 ///
12150 /// If no type with this name did already exist in the per-corpus type
12151 /// map, then that per-corpus type map is updated. Otherwise, that
12152 /// type is erased from that per-corpus map.
12153 ///
12154 /// @param type the type to consider.
12155 void
maybe_update_types_lookup_map(const type_base_sptr & type)12156 maybe_update_types_lookup_map(const type_base_sptr& type)
12157 {
12158   if (decl_base_sptr decl = get_type_declaration(type))
12159     maybe_update_types_lookup_map(decl);
12160   else
12161     ABG_ASSERT_NOT_REACHED;
12162 }
12163 
12164 //--------------------------------
12165 // </type and decls lookup stuff>
12166 // ------------------------------
12167 
12168 /// In a translation unit, lookup a given type or synthesize it if
12169 /// it's a qualified type.
12170 ///
12171 /// So this function first looks the type up in the translation unit.
12172 /// If it's found, then OK, it's returned.  Otherwise, if it's a
12173 /// qualified, reference or pointer or function type (a composite
12174 /// type), lookup the underlying type, synthesize the type we want
12175 /// from it and return it.
12176 ///
12177 /// If the underlying types is not not found, then give up and return
12178 /// nil.
12179 ///
12180 /// @return the type that was found or the synthesized type.
12181 type_base_sptr
synthesize_type_from_translation_unit(const type_base_sptr & type,translation_unit & tu)12182 synthesize_type_from_translation_unit(const type_base_sptr& type,
12183 				      translation_unit& tu)
12184 {
12185   type_base_sptr result;
12186 
12187    result = lookup_type(type, tu);
12188 
12189   if (!result)
12190     {
12191       if (qualified_type_def_sptr qual = is_qualified_type(type))
12192 	{
12193 	  type_base_sptr underlying_type =
12194 	    synthesize_type_from_translation_unit(qual->get_underlying_type(),
12195 						  tu);
12196 	  if (underlying_type)
12197 	    {
12198 	      result.reset(new qualified_type_def(underlying_type,
12199 						  qual->get_cv_quals(),
12200 						  qual->get_location()));
12201 	    }
12202 	}
12203       else if (pointer_type_def_sptr p = is_pointer_type(type))
12204 	{
12205 	  type_base_sptr pointed_to_type =
12206 	    synthesize_type_from_translation_unit(p->get_pointed_to_type(),
12207 						  tu);
12208 	  if (pointed_to_type)
12209 	    {
12210 	      result.reset(new pointer_type_def(pointed_to_type,
12211 						p->get_size_in_bits(),
12212 						p->get_alignment_in_bits(),
12213 						p->get_location()));
12214 	      result->set_environment(pointed_to_type->get_environment());
12215 	    }
12216 	}
12217       else if (reference_type_def_sptr r = is_reference_type(type))
12218 	{
12219 	  type_base_sptr pointed_to_type =
12220 	    synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
12221 	  if (pointed_to_type)
12222 	    {
12223 	      result.reset(new reference_type_def(pointed_to_type,
12224 						  r->is_lvalue(),
12225 						  r->get_size_in_bits(),
12226 						  r->get_alignment_in_bits(),
12227 						  r->get_location()));
12228 	      result->set_environment(pointed_to_type->get_environment());
12229 	    }
12230 	}
12231       else if (function_type_sptr f = is_function_type(type))
12232 	result = synthesize_function_type_from_translation_unit(*f, tu);
12233 
12234       if (result)
12235 	{
12236 	  add_decl_to_scope(is_decl(result), tu.get_global_scope());
12237 	  canonicalize(result);
12238 	}
12239     }
12240 
12241   if (result)
12242     tu.priv_->synthesized_types_.push_back(result);
12243 
12244   return result;
12245 }
12246 
12247 /// In a translation unit, lookup the sub-types that make up a given
12248 /// function type and if the sub-types are all found, synthesize and
12249 /// return a function_type with them.
12250 ///
12251 /// This function is like lookup_function_type_in_translation_unit()
12252 /// execept that it constructs the function type from the sub-types
12253 /// found in the translation, rather than just looking for the
12254 /// function types held by the translation unit.  This can be useful
12255 /// if the translation unit doesnt hold the function type we are
12256 /// looking for (i.e, lookup_function_type_in_translation_unit()
12257 /// returned NULL) but we still want to see if the sub-types of the
12258 /// function types are present in the translation unit.
12259 ///
12260 /// @param fn_type the function type to consider.
12261 ///
12262 /// @param tu the translation unit to look into.
12263 ///
12264 /// @return the resulting synthesized function type if all its
12265 /// sub-types have been found, NULL otherwise.
12266 function_type_sptr
synthesize_function_type_from_translation_unit(const function_type & fn_type,translation_unit & tu)12267 synthesize_function_type_from_translation_unit(const function_type& fn_type,
12268 					       translation_unit& tu)
12269 {
12270   function_type_sptr nil = function_type_sptr();
12271 
12272   environment* env = tu.get_environment();
12273   ABG_ASSERT(env);
12274 
12275   type_base_sptr return_type = fn_type.get_return_type();
12276   type_base_sptr result_return_type;
12277   if (!return_type || env->is_void_type(return_type))
12278     result_return_type = env->get_void_type();
12279   else
12280     result_return_type = synthesize_type_from_translation_unit(return_type, tu);
12281   if (!result_return_type)
12282     return nil;
12283 
12284   function_type::parameters parms;
12285   type_base_sptr parm_type;
12286   function_decl::parameter_sptr parm;
12287   for (function_type::parameters::const_iterator i =
12288 	 fn_type.get_parameters().begin();
12289        i != fn_type.get_parameters().end();
12290        ++i)
12291     {
12292       type_base_sptr t = (*i)->get_type();
12293       parm_type = synthesize_type_from_translation_unit(t, tu);
12294       if (!parm_type)
12295 	return nil;
12296       parm.reset(new function_decl::parameter(parm_type,
12297 					      (*i)->get_index(),
12298 					      (*i)->get_name(),
12299 					      (*i)->get_location(),
12300 					      (*i)->get_variadic_marker(),
12301 					      (*i)->get_is_artificial()));
12302       parms.push_back(parm);
12303     }
12304 
12305   class_or_union_sptr class_type;
12306   const method_type* method = is_method_type(&fn_type);
12307   if (method)
12308     {
12309       class_type = is_class_or_union_type
12310 	(synthesize_type_from_translation_unit(method->get_class_type(), tu));
12311       ABG_ASSERT(class_type);
12312     }
12313 
12314   function_type_sptr result_fn_type;
12315 
12316   if (class_type)
12317     result_fn_type.reset(new method_type(result_return_type,
12318 					 class_type,
12319 					 parms,
12320 					 method->get_is_const(),
12321 					 fn_type.get_size_in_bits(),
12322 					 fn_type.get_alignment_in_bits()));
12323   else
12324     result_fn_type.reset(new function_type(result_return_type,
12325 					   parms,
12326 					   fn_type.get_size_in_bits(),
12327 					   fn_type.get_alignment_in_bits()));
12328 
12329   tu.priv_->synthesized_types_.push_back(result_fn_type);
12330   // The new synthesized type must be in the same environment as its
12331   // translation unit.
12332   result_fn_type->set_environment(tu.get_environment());
12333   tu.bind_function_type_life_time(result_fn_type);
12334 
12335   canonicalize(result_fn_type);
12336   return result_fn_type;
12337 }
12338 
12339 /// Demangle a C++ mangled name and return the resulting string
12340 ///
12341 /// @param mangled_name the C++ mangled name to demangle.
12342 ///
12343 /// @return the resulting mangled name.
12344 string
demangle_cplus_mangled_name(const string & mangled_name)12345 demangle_cplus_mangled_name(const string& mangled_name)
12346 {
12347   if (mangled_name.empty())
12348     return "";
12349 
12350   size_t l = 0;
12351   int status = 0;
12352   char * str = abi::__cxa_demangle(mangled_name.c_str(),
12353 				   NULL, &l, &status);
12354   string demangled_name = mangled_name;
12355   if (str)
12356     {
12357       ABG_ASSERT(status == 0);
12358       demangled_name = str;
12359       free(str);
12360       str = 0;
12361     }
12362   return demangled_name;
12363 }
12364 
12365 /// Return either the type given in parameter if it's non-null, or the
12366 /// void type.
12367 ///
12368 /// @param t the type to consider.
12369 ///
12370 /// @param env the environment to use.  If NULL, just abort the
12371 /// process.
12372 ///
12373 /// @return either @p t if it is non-null, or the void type.
12374 type_base_sptr
type_or_void(const type_base_sptr t,const environment * env)12375 type_or_void(const type_base_sptr t, const environment* env)
12376 {
12377   type_base_sptr r;
12378 
12379   if (t)
12380     r = t;
12381   else
12382     {
12383       ABG_ASSERT(env);
12384       r = type_base_sptr(env->get_void_type());
12385     }
12386 
12387   return r;
12388 }
12389 
~global_scope()12390 global_scope::~global_scope()
12391 {
12392 }
12393 
12394 // <type_base definitions>
12395 
12396 /// Definition of the private data of @ref type_base.
12397 struct type_base::priv
12398 {
12399   size_t		size_in_bits;
12400   size_t		alignment_in_bits;
12401   type_base_wptr	canonical_type;
12402   // The data member below holds the canonical type that is managed by
12403   // the smart pointer referenced by the canonical_type data member
12404   // above.  We are storing this underlying (naked) pointer here, so
12405   // that users can access it *fast*.  Otherwise, accessing
12406   // canonical_type above implies creating a shared_ptr, and that has
12407   // been measured to be slow for some performance hot spots.
12408   type_base*		naked_canonical_type;
12409   // Computing the representation of a type again and again can be
12410   // costly.  So we cache the internal and non-internal type
12411   // representation strings here.
12412   interned_string	internal_cached_repr_;
12413   interned_string	cached_repr_;
12414 
privabigail::ir::type_base::priv12415   priv()
12416     : size_in_bits(),
12417       alignment_in_bits(),
12418       naked_canonical_type()
12419   {}
12420 
privabigail::ir::type_base::priv12421   priv(size_t s,
12422        size_t a,
12423        type_base_sptr c = type_base_sptr())
12424     : size_in_bits(s),
12425       alignment_in_bits(a),
12426       canonical_type(c),
12427       naked_canonical_type(c.get())
12428   {}
12429 }; // end struct type_base::priv
12430 
12431 static void
12432 maybe_propagate_canonical_type(const type_base& lhs_type,
12433 			       const type_base& rhs_type);
12434 
12435 /// Test if two types are eligible to the "Linux Kernel Fast Type
12436 /// Comparison Optimization", a.k.a LKFTCO.
12437 ///
12438 /// Two types T1 and T2 (who are presumably of the same name and kind)
12439 /// are eligible to the LKFTCO if they fulfill the following criteria/
12440 ///
12441 /// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
12442 /// either class, union or enums.
12443 ///
12444 /// 2/ They are defined in the same translation unit.
12445 ///
12446 /// @param t1 the first type to consider.
12447 ///
12448 /// @param t2 the second type to consider.
12449 ///
12450 /// @return true iff t1 and t2 are eligible to the LKFTCO.
12451 static bool
types_defined_same_linux_kernel_corpus_public(const type_base & t1,const type_base & t2)12452 types_defined_same_linux_kernel_corpus_public(const type_base& t1,
12453 					      const type_base& t2)
12454 {
12455   const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
12456   string t1_file_path, t2_file_path;
12457 
12458   /// If the t1 (and t2) are classes/unions/enums from the same linux
12459   /// kernel corpus, let's move on.  Otherwise bail out.
12460   if (!(t1_corpus && t2_corpus
12461 	&& t1_corpus == t2_corpus
12462 	&& (t1_corpus->get_origin() == corpus::LINUX_KERNEL_BINARY_ORIGIN)
12463 	&& (is_class_or_union_type(&t1)
12464 	    || is_enum_type(&t1))))
12465     return false;
12466 
12467   class_or_union *c1 = 0, *c2 = 0;
12468   c1 = is_class_or_union_type(&t1);
12469   c2 = is_class_or_union_type(&t2);
12470 
12471   // Two anonymous class types with no naming typedefs cannot be
12472   // eligible to this optimization.
12473   if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
12474       || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
12475     return false;
12476 
12477   // Two anonymous enum types cannot be eligible to this optimization.
12478   if (const enum_type_decl *e1 = is_enum_type(&t1))
12479     if (const enum_type_decl *e2 = is_enum_type(&t2))
12480       if (e1->get_is_anonymous() || e2->get_is_anonymous())
12481 	return false;
12482 
12483   // Look through declaration-only types.  That is, get the associated
12484   // definition type.
12485   c1 = look_through_decl_only_class(c1);
12486   c2 = look_through_decl_only_class(c2);
12487 
12488   if (c1 && c2)
12489     {
12490       if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
12491 	{
12492 	  if (c1->get_environment()->decl_only_class_equals_definition())
12493 	    // At least one of classes/union is declaration-only.
12494 	    // Because we are in a context in which a declaration-only
12495 	    // class/union is equal to all definitions of that
12496 	    // class/union, we can assume that the two types are
12497 	    // equal.
12498 	    return true;
12499 	}
12500     }
12501 
12502   if (t1.get_size_in_bits() != t2.get_size_in_bits())
12503     return false;
12504 
12505   // Look at the file names of the locations of t1 and t2.  If they
12506   // are equal, then t1 and t2 are defined in the same file.
12507   {
12508     location l;
12509 
12510     if (c1)
12511       l = c1->get_location();
12512     else
12513       l = dynamic_cast<const decl_base&>(t1).get_location();
12514 
12515     unsigned line = 0, col = 0;
12516     if (l)
12517       l.expand(t1_file_path, line, col);
12518     if (c2)
12519       l = c2->get_location();
12520     else
12521       l = dynamic_cast<const decl_base&>(t2).get_location();
12522     if (l)
12523       l.expand(t2_file_path, line, col);
12524   }
12525 
12526   if (t1_file_path.empty() || t2_file_path.empty())
12527     return false;
12528 
12529   if (t1_file_path == t2_file_path)
12530     return true;
12531 
12532   return false;
12533 }
12534 
12535 /// Compute the canonical type for a given instance of @ref type_base.
12536 ///
12537 /// Consider two types T and T'.  The canonical type of T, denoted
12538 /// C(T) is a type such as T == T' if and only if C(T) == C(T').  Said
12539 /// otherwise, to compare two types, one just needs to compare their
12540 /// canonical types using pointer equality.  That makes type
12541 /// comparison faster than the structural comparison performed by the
12542 /// abigail::ir::equals() overloads.
12543 ///
12544 /// If there is not yet any canonical type for @p t, then @p t is its
12545 /// own canonical type.  Otherwise, this function returns the
12546 /// canonical type of @p t which is the canonical type that has the
12547 /// same hash value as @p t and that structurally equals @p t.  Note
12548 /// that after invoking this function, the life time of the returned
12549 /// canonical time is then equals to the life time of the current
12550 /// process.
12551 ///
12552 /// @param t a smart pointer to instance of @ref type_base we want to
12553 /// compute a canonical type for.
12554 ///
12555 /// @return the canonical type for the current instance of @ref
12556 /// type_base.
12557 type_base_sptr
get_canonical_type_for(type_base_sptr t)12558 type_base::get_canonical_type_for(type_base_sptr t)
12559 {
12560   if (!t)
12561     return t;
12562 
12563   environment* env = t->get_environment();
12564   ABG_ASSERT(env);
12565 
12566   bool decl_only_class_equals_definition =
12567     (odr_is_relevant(*t) || env->decl_only_class_equals_definition());
12568 
12569   class_or_union_sptr class_or_union = is_class_or_union_type(t);
12570 
12571   // Look through declaration-only classes when we are dealing with
12572   // C++ or languages where we assume the "One Definition Rule".  In
12573   // that context, we assume that a declaration-only non-anonymous
12574   // class equals all fully defined classes of the same name.
12575   //
12576   // Otherwise, all classes, including declaration-only classes are
12577   // canonicalized and only canonical comparison is going to be used
12578   // in the system.
12579   if (decl_only_class_equals_definition)
12580     if (class_or_union)
12581       {
12582 	class_or_union = look_through_decl_only_class(class_or_union);
12583 	if (class_or_union->get_is_declaration_only())
12584 	  return type_base_sptr();
12585 	else
12586 	  t = class_or_union;
12587       }
12588 
12589   class_decl_sptr is_class = is_class_type(t);
12590   if (t->get_canonical_type())
12591     return t->get_canonical_type();
12592 
12593   // For classes and union, ensure that an anonymous class doesn't
12594   // have a linkage name.  If it does in the future, then me must be
12595   // mindful that the linkage name respects the type identity
12596   // constraints which states that "if two linkage names are different
12597   // then the two types are different".
12598   ABG_ASSERT(!class_or_union
12599 	     || !class_or_union->get_is_anonymous()
12600 	     || class_or_union->get_linkage_name().empty());
12601 
12602   // We want the pretty representation of the type, but for an
12603   // internal use, not for a user-facing purpose.
12604   //
12605   // If two classe types Foo are declared, one as a class and the
12606   // other as a struct, but are otherwise equivalent, we want their
12607   // pretty representation to be the same.  Hence the 'internal'
12608   // argument of ir::get_pretty_representation() is set to true here.
12609   // So in this case, the pretty representation of Foo is going to be
12610   // "class Foo", regardless of its struct-ness. This also applies to
12611   // composite types which would have "class Foo" as a sub-type.
12612   string repr = t->get_cached_pretty_representation(/*internal=*/true);
12613 
12614   // If 't' already has a canonical type 'inside' its corpus
12615   // (t_corpus), then this variable is going to contain that canonical
12616   // type.
12617   type_base_sptr canonical_type_present_in_corpus;
12618   environment::canonical_types_map_type& types =
12619     env->get_canonical_types_map();
12620 
12621   type_base_sptr result;
12622   environment::canonical_types_map_type::iterator i = types.find(repr);
12623   if (i == types.end())
12624     {
12625       vector<type_base_sptr> v;
12626       v.push_back(t);
12627       types[repr] = v;
12628       result = t;
12629     }
12630   else
12631     {
12632       vector<type_base_sptr> &v = i->second;
12633       // Let's compare 't' structurally (i.e, compare its sub-types
12634       // recursively) against the canonical types of the system. If it
12635       // equals a given canonical type C, then it means C is the
12636       // canonical type of 't'.  Otherwise, if 't' is different from
12637       // all the canonical types of the system, then it means 't' is a
12638       // canonical type itself.
12639       for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
12640 	   it != v.rend();
12641 	   ++it)
12642 	{
12643 	  // Before the "*it == it" comparison below is done, let's
12644 	  // perform on-the-fly-canonicalization.  For C types, let's
12645 	  // consider that an unresolved struct declaration 'struct S'
12646 	  // is different from a definition 'struct S'.  This is
12647 	  // because normally, at this point all the declarations of
12648 	  // struct S that are compatible with the definition of
12649 	  // struct S have already been resolved to that definition,
12650 	  // during the DWARF parsing.  The remaining unresolved
12651 	  // declaration are thus considered different.  With this
12652 	  // setup we can properly handle cases of two *different*
12653 	  // struct S being defined in the same binary (in different
12654 	  // translation units), and a third struct S being only
12655 	  // declared as an opaque type in a third translation unit of
12656 	  // its own, with no definition in there.  In that case, the
12657 	  // declaration-only struct S should be left alone and not
12658 	  // resolved to any of the two definitions of struct S.
12659 	  bool saved_decl_only_class_equals_definition =
12660 	    env->decl_only_class_equals_definition();
12661 	  env->do_on_the_fly_canonicalization(true);
12662 	  // Compare types by considering that decl-only classes don't
12663 	  // equal their definition.
12664 	  env->decl_only_class_equals_definition(false);
12665 	  bool equal = types_defined_same_linux_kernel_corpus_public(**it, *t)
12666 		       || *it == t;
12667 	  // Restore the state of the on-the-fly-canonicalization and
12668 	  // the decl-only-class-being-equal-to-a-matching-definition
12669 	  // flags.
12670 	  env->do_on_the_fly_canonicalization(false);
12671 	  env->decl_only_class_equals_definition
12672 	    (saved_decl_only_class_equals_definition);
12673 	  if (equal)
12674 	    {
12675 	      result = *it;
12676 	      break;
12677 	    }
12678 	}
12679       if (!result)
12680 	{
12681 	  v.push_back(t);
12682 	  result = t;
12683 	}
12684     }
12685 
12686   return result;
12687 }
12688 
12689 /// This method is invoked automatically right after the current
12690 /// instance of @ref class_decl has been canonicalized.
12691 void
on_canonical_type_set()12692 type_base::on_canonical_type_set()
12693 {}
12694 
12695 /// This is a subroutine of the canonicalize() function.
12696 ///
12697 /// When the canonical type C of type T has just been computed, there
12698 /// can be cases where T has member functions that C doesn't have.
12699 ///
12700 /// This is possible because non virtual member functions are not
12701 /// taken in account when comparing two types.
12702 ///
12703 /// In that case, this function updates C so that it contains the
12704 /// member functions.
12705 ///
12706 /// There can also be cases where C has a method M which is not linked
12707 /// to any underlying symbol, whereas in T, M is to link to an
12708 /// underlying symbol.  In that case, this function updates M in C so
12709 /// that it's linked to the same underlying symbol as for M in T.
12710 static void
maybe_adjust_canonical_type(const type_base_sptr & canonical,const type_base_sptr & type)12711 maybe_adjust_canonical_type(const type_base_sptr& canonical,
12712 			    const type_base_sptr& type)
12713 {
12714   if (// If 'type' is *NOT* a newly canonicalized type ...
12715       type->get_naked_canonical_type()
12716       // ... or if 'type' is it's own canonical type, then get out.
12717       || type.get() == canonical.get())
12718     return;
12719 
12720   if (class_decl_sptr cl = is_class_type(type))
12721     {
12722       class_decl_sptr canonical_class = is_class_type(canonical);
12723 
12724       if (canonical_class)
12725 	{
12726 	  // Set symbols of member functions that might be missing
12727 	  // theirs.
12728 	  for (class_decl::member_functions::const_iterator i =
12729 		 cl->get_member_functions().begin();
12730 	       i != cl->get_member_functions().end();
12731 	       ++i)
12732 	    if ((*i)->get_symbol())
12733 	      {
12734 		if (method_decl *m = canonical_class->
12735 		    find_member_function((*i)->get_linkage_name()))
12736 		  {
12737 		    elf_symbol_sptr s1 = (*i)->get_symbol();
12738 		    if (s1 && !m->get_symbol())
12739 		      // Method 'm' in the canonical type is not
12740 		      // linked to the underlying symbol of '*i'.
12741 		      // Let's link it now.  have th
12742 		      m->set_symbol(s1);
12743 		  }
12744 		else
12745 		  // There is a member function defined and publicly
12746 		  // exported in the other class, and the canonical
12747 		  // class doesn't have that member function.  Let's
12748 		  // copy that member function to the canonical class
12749 		  // then.
12750 		  copy_member_function (canonical_class, *i);
12751 	      }
12752 	}
12753     }
12754 }
12755 
12756 /// Compute the canonical type of a given type.
12757 ///
12758 /// It means that after invoking this function, comparing the intance
12759 /// instance @ref type_base and another one (on which
12760 /// type_base::enable_canonical_equality() would have been invoked as
12761 /// well) is performed by just comparing the pointer values of the
12762 /// canonical types of both types.  That equality comparison is
12763 /// supposedly faster than structural comparison of the types.
12764 ///
12765 /// @param t a smart pointer to the instance of @ref type_base for
12766 /// which to compute the canonical type.  After this call,
12767 /// t->get_canonical_type() will return the newly computed canonical
12768 /// type.
12769 ///
12770 /// @return the canonical type computed for @p t.
12771 type_base_sptr
canonicalize(type_base_sptr t)12772 canonicalize(type_base_sptr t)
12773 {
12774   if (!t)
12775     return t;
12776 
12777   if (t->get_canonical_type())
12778     return t->get_canonical_type();
12779 
12780   type_base_sptr canonical = type_base::get_canonical_type_for(t);
12781   maybe_adjust_canonical_type(canonical, t);
12782 
12783   t->priv_->canonical_type = canonical;
12784   t->priv_->naked_canonical_type = canonical.get();
12785 
12786   if (class_decl_sptr cl = is_class_type(t))
12787     if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
12788       if ((canonical = d->get_canonical_type()))
12789 	{
12790 	  d->priv_->canonical_type = canonical;
12791 	  d->priv_->naked_canonical_type = canonical.get();
12792 	}
12793 
12794   if (canonical)
12795     if (decl_base_sptr d = is_decl_slow(canonical))
12796       {
12797 	scope_decl *scope = d->get_scope();
12798 	// Add the canonical type to the set of canonical types
12799 	// belonging to its scope.
12800 	if (scope)
12801 	  scope->get_canonical_types().insert(canonical);
12802 	//else, if the type doesn't have a scope, it's doesn't meant
12803 	// to be emitted.  This can be the case for the result of the
12804 	// function strip_typedef, for instance.
12805       }
12806 
12807   t->on_canonical_type_set();
12808   return canonical;
12809 }
12810 
12811 
12812 /// Set the definition of this declaration-only @ref decl_base.
12813 ///
12814 /// @param d the new definition to set.
12815 void
set_definition_of_declaration(const decl_base_sptr & d)12816 decl_base::set_definition_of_declaration(const decl_base_sptr& d)
12817 {
12818   ABG_ASSERT(get_is_declaration_only());
12819   priv_->definition_of_declaration_ = d;
12820   if (type_base *t = is_type(this))
12821     if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
12822       t->priv_->canonical_type = canonical_type;
12823 
12824   priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
12825 }
12826 
12827 /// The constructor of @ref type_base.
12828 ///
12829 /// @param s the size of the type, in bits.
12830 ///
12831 /// @param a the alignment of the type, in bits.
type_base(const environment * e,size_t s,size_t a)12832 type_base::type_base(const environment* e, size_t s, size_t a)
12833   : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
12834     priv_(new priv(s, a))
12835 {}
12836 
12837 /// Getter of the canonical type of the current instance of @ref
12838 /// type_base.
12839 ///
12840 /// @return a smart pointer to the canonical type of the current
12841 /// intance of @ref type_base, or an empty smart pointer if the
12842 /// current instance of @ref type_base doesn't have any canonical
12843 /// type.
12844 type_base_sptr
get_canonical_type() const12845 type_base::get_canonical_type() const
12846 {return priv_->canonical_type.lock();}
12847 
12848 /// Getter of the canonical type pointer.
12849 ///
12850 /// Note that this function doesn't return a smart pointer, but rather
12851 /// the underlying pointer managed by the smart pointer.  So it's as
12852 /// fast as possible.  This getter is to be used in code paths that
12853 /// are proven to be performance hot spots; especially, when comparing
12854 /// sensitive types like class, function, pointers and reference
12855 /// types.  Those are compared extremely frequently and thus, their
12856 /// accessing the canonical type must be fast.
12857 ///
12858 /// @return the canonical type pointer, not managed by a smart
12859 /// pointer.
12860 type_base*
get_naked_canonical_type() const12861 type_base::get_naked_canonical_type() const
12862 {return priv_->naked_canonical_type;}
12863 
12864 /// Get the pretty representation of the current type.
12865 ///
12866 /// The pretty representation is retrieved from a cache.  If the cache
12867 /// is empty, this function computes the pretty representation, put it
12868 /// in the cache and returns it.
12869 ///
12870 /// Note that if the type is *NOT* canonicalized, the pretty
12871 /// representation is never cached.
12872 ///
12873 /// @param internal if true, then the pretty representation is to be
12874 /// used for purpuses that are internal to the libabigail library
12875 /// itself.  If you don't know what this means, then you probably
12876 /// should set this parameter to "false".
12877 const interned_string&
get_cached_pretty_representation(bool internal) const12878 type_base::get_cached_pretty_representation(bool internal) const
12879 {
12880   if (internal)
12881     {
12882       if (!get_naked_canonical_type() || priv_->internal_cached_repr_.empty())
12883 	{
12884 	  string r = ir::get_pretty_representation(this, internal);
12885 	  priv_->internal_cached_repr_ = get_environment()->intern(r);
12886 	}
12887       return priv_->internal_cached_repr_;
12888     }
12889 
12890   if (!get_naked_canonical_type() || priv_->cached_repr_.empty())
12891     {
12892       string r = ir::get_pretty_representation(this, internal);
12893       priv_->cached_repr_ = get_environment()->intern(r);
12894     }
12895 
12896   return priv_->cached_repr_;
12897 }
12898 
12899 /// Compares two instances of @ref type_base.
12900 ///
12901 /// If the two intances are different, set a bitfield to give some
12902 /// insight about the kind of differences there are.
12903 ///
12904 /// @param l the first artifact of the comparison.
12905 ///
12906 /// @param r the second artifact of the comparison.
12907 ///
12908 /// @param k a pointer to a bitfield that gives information about the
12909 /// kind of changes there are between @p l and @p r.  This one is set
12910 /// iff @p is non-null and if the function returns false.
12911 ///
12912 /// Please note that setting k to a non-null value does have a
12913 /// negative performance impact because even if @p l and @p r are not
12914 /// equal, the function keeps up the comparison in order to determine
12915 /// the different kinds of ways in which they are different.
12916 ///
12917 /// @return true if @p l equals @p r, false otherwise.
12918 bool
equals(const type_base & l,const type_base & r,change_kind * k)12919 equals(const type_base& l, const type_base& r, change_kind* k)
12920 {
12921   bool result = (l.get_size_in_bits() == r.get_size_in_bits()
12922 		 && l.get_alignment_in_bits() == r.get_alignment_in_bits());
12923   if (!result)
12924     if (k)
12925       *k |= LOCAL_TYPE_CHANGE_KIND;
12926   return result;
12927 }
12928 
12929 /// Return true iff both type declarations are equal.
12930 ///
12931 /// Note that this doesn't test if the scopes of both types are equal.
12932 bool
operator ==(const type_base & other) const12933 type_base::operator==(const type_base& other) const
12934 {return equals(*this, other, 0);}
12935 
12936 /// Inequality operator.
12937 ///
12938 ///@param other the instance of @ref type_base to compare the current
12939 /// instance against.
12940 ///
12941 /// @return true iff the current instance is different from @p other.
12942 bool
operator !=(const type_base & other) const12943 type_base::operator!=(const type_base& other) const
12944 {return !operator==(other);}
12945 
12946 /// Setter for the size of the type.
12947 ///
12948 /// @param s the new size -- in bits.
12949 void
set_size_in_bits(size_t s)12950 type_base::set_size_in_bits(size_t s)
12951 {priv_->size_in_bits = s;}
12952 
12953 /// Getter for the size of the type.
12954 ///
12955 /// @return the size in bits of the type.
12956 size_t
get_size_in_bits() const12957 type_base::get_size_in_bits() const
12958 {return priv_->size_in_bits;}
12959 
12960 /// Setter for the alignment of the type.
12961 ///
12962 /// @param a the new alignment -- in bits.
12963 void
set_alignment_in_bits(size_t a)12964 type_base::set_alignment_in_bits(size_t a)
12965 {priv_->alignment_in_bits = a;}
12966 
12967 /// Getter for the alignment of the type.
12968 ///
12969 /// @return the alignment of the type in bits.
12970 size_t
get_alignment_in_bits() const12971 type_base::get_alignment_in_bits() const
12972 {return priv_->alignment_in_bits;}
12973 
12974 /// Default implementation of traversal for types.  This function does
12975 /// nothing.  It must be implemented by every single new type that is
12976 /// written.
12977 ///
12978 /// Please look at e.g, class_decl::traverse() for an example of how
12979 /// to implement this.
12980 ///
12981 /// @param v the visitor used to visit the type.
12982 bool
traverse(ir_node_visitor & v)12983 type_base::traverse(ir_node_visitor& v)
12984 {
12985   if (v.type_node_has_been_visited(this))
12986     return true;
12987 
12988   v.visit_begin(this);
12989   bool result = v.visit_end(this);
12990   v.mark_type_node_as_visited(this);
12991 
12992   return result;
12993 }
12994 
~type_base()12995 type_base::~type_base()
12996 {delete priv_;}
12997 
12998 // </type_base definitions>
12999 
13000 // <integral_type definitions>
13001 
13002 /// Bitwise OR operator for integral_type::modifiers_type.
13003 ///
13004 /// @param l the left-hand side operand.
13005 ///
13006 /// @param r the right-hand side operand.
13007 ///
13008 /// @return the result of the bitwise OR.
13009 integral_type::modifiers_type
operator |(integral_type::modifiers_type l,integral_type::modifiers_type r)13010 operator|(integral_type::modifiers_type l, integral_type::modifiers_type r)
13011 {
13012   return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
13013 						    |static_cast<unsigned>(r));
13014 }
13015 
13016 /// Bitwise AND operator for integral_type::modifiers_type.
13017 ///
13018 /// @param l the left-hand side operand.
13019 ///
13020 /// @param r the right-hand side operand.
13021 ///
13022 /// @return the result of the bitwise AND.
13023 integral_type::modifiers_type
operator &(integral_type::modifiers_type l,integral_type::modifiers_type r)13024 operator&(integral_type::modifiers_type l, integral_type::modifiers_type r)
13025 {
13026   return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
13027 						    &static_cast<unsigned>(r));
13028 }
13029 
13030 /// Bitwise |= operator for integral_type::modifiers_type.
13031 ///
13032 /// @param l the left-hand side operand.
13033 ///
13034 /// @param r the right-hand side operand.
13035 ///
13036 /// @return the result of the bitwise |=.
13037 integral_type::modifiers_type&
operator |=(integral_type::modifiers_type & l,integral_type::modifiers_type r)13038 operator|=(integral_type::modifiers_type& l, integral_type::modifiers_type r)
13039 {
13040   l = l | r;
13041   return l;
13042 }
13043 
13044 /// Parse a word containing one integral type modifier.
13045 ///
13046 /// A word is considered to be a string of characters that doesn't
13047 /// contain any white space.
13048 ///
13049 /// @param word the word to parse.  It is considered to be a string of
13050 /// characters that doesn't contain any white space.
13051 ///
13052 /// @param modifiers out parameter.  It's set by this function to the
13053 /// parsed modifier iff the function returned true.
13054 ///
13055 /// @return true iff @word was successfully parsed.
13056 static bool
parse_integral_type_modifier(const string & word,integral_type::modifiers_type & modifiers)13057 parse_integral_type_modifier(const string& word,
13058 			     integral_type::modifiers_type &modifiers)
13059 {
13060     if (word == "signed")
13061       modifiers |= integral_type::SIGNED_MODIFIER;
13062     else if (word == "unsigned")
13063       modifiers |= integral_type::UNSIGNED_MODIFIER;
13064     else if (word == "short")
13065       modifiers |= integral_type::SHORT_MODIFIER;
13066     else if (word == "long")
13067       modifiers |= integral_type::LONG_MODIFIER;
13068     else if (word == "long long")
13069       modifiers |= integral_type::LONG_LONG_MODIFIER;
13070     else
13071       return false;
13072 
13073     return true;
13074 }
13075 
13076 /// Parse a base type of an integral type from a string.
13077 ///
13078 /// @param type_name the type name to parse.
13079 ///
13080 /// @param base out parameter.  This is set to the resulting base type
13081 /// parsed, iff the function returned true.
13082 ///
13083 /// @return true iff the function could successfully parse the base
13084 /// type.
13085 static bool
parse_base_integral_type(const string & type_name,integral_type::base_type & base)13086 parse_base_integral_type(const string& type_name,
13087 			 integral_type::base_type& base)
13088 {
13089   if (type_name == "int")
13090     base = integral_type::INT_BASE_TYPE;
13091   else if (type_name == "char")
13092     base = integral_type::CHAR_BASE_TYPE;
13093   else if (type_name == "bool" || type_name == "_Bool")
13094     base = integral_type::BOOL_BASE_TYPE;
13095   else if (type_name == "double")
13096     base = integral_type::DOUBLE_BASE_TYPE;
13097   else if (type_name =="float")
13098     base = integral_type::FLOAT_BASE_TYPE;
13099   else if (type_name == "char16_t")
13100     base = integral_type::CHAR16_T_BASE_TYPE;
13101   else if (type_name == "char32_t")
13102     base = integral_type::CHAR32_T_BASE_TYPE;
13103   else if (type_name == "wchar_t")
13104     base = integral_type::WCHAR_T_BASE_TYPE;
13105   else
13106     return false;
13107 
13108   return true;
13109 }
13110 
13111 /// Parse an integral type from a string.
13112 ///
13113 /// @param type_name the string containing the integral type to parse.
13114 ///
13115 /// @param base out parameter.  Is set by this function to the base
13116 /// type of the integral type, iff the function returned true.
13117 ///
13118 /// @param modifiers out parameter  If set by this function to the
13119 /// modifier of the integral type, iff the function returned true.
13120 ///
13121 /// @return true iff the function could parse an integral type from @p
13122 /// type_name.
13123 static bool
parse_integral_type(const string & type_name,integral_type::base_type & base,integral_type::modifiers_type & modifiers)13124 parse_integral_type(const string&			type_name,
13125 		    integral_type::base_type&		base,
13126 		    integral_type::modifiers_type&	modifiers)
13127 {
13128   string input = type_name;
13129   string::size_type len = input.length();
13130   string::size_type cur_pos = 0, prev_pos = 0;
13131   string cur_word, prev_word;
13132   bool ok = false;
13133 
13134   while (cur_pos < len)
13135     {
13136       prev_pos = cur_pos;
13137       cur_pos = input.find(' ', prev_pos);
13138       prev_word = cur_word;
13139       cur_word = input.substr(prev_pos, cur_pos - prev_pos);
13140 
13141       if (cur_pos < len && isspace(input[cur_pos]))
13142 	do
13143 	  ++cur_pos;
13144 	while (cur_pos < len && isspace(input[cur_pos]));
13145 
13146       if (cur_pos < len
13147 	  && cur_word == "long"
13148 	  && prev_word != "long")
13149 	{
13150 	  prev_pos = cur_pos;
13151 	  cur_pos = input.find(' ', prev_pos);
13152 	  string saved_prev_word = prev_word;
13153 	  prev_word = cur_word;
13154 	  cur_word = input.substr(prev_pos, cur_pos - prev_pos);
13155 	  if (cur_word == "long")
13156 	    cur_word = "long long";
13157 	  else
13158 	    {
13159 	      cur_pos = prev_pos;
13160 	      cur_word = prev_word;
13161 	      prev_word = saved_prev_word;
13162 	    }
13163 	}
13164 
13165       if (!parse_integral_type_modifier(cur_word, modifiers))
13166 	{
13167 	  if (!parse_base_integral_type(cur_word, base))
13168 	    return false;
13169 	  else
13170 	    ok = true;
13171 	}
13172       else
13173 	ok = true;
13174     }
13175 
13176   return ok;
13177 }
13178 
13179 /// Parse an integral type from a string.
13180 ///
13181 /// @param str the string containing the integral type to parse.
13182 ///
13183 ///@param type the resulting @ref integral_type.  Is set to the result
13184 ///of the parse, iff the function returns true.
13185 ///
13186 /// @return true iff the function could parse an integral type from @p
13187 /// str.
13188 bool
parse_integral_type(const string & str,integral_type & type)13189 parse_integral_type(const string& str, integral_type& type)
13190 {
13191   integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
13192   integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
13193 
13194   if (!parse_integral_type(str, base_type, modifiers))
13195     return false;
13196 
13197   // So this is an integral type.
13198   integral_type int_type(base_type, modifiers);
13199   type = int_type;
13200   return true;
13201 }
13202 
13203 /// Default constructor of the @ref integral_type.
integral_type()13204 integral_type::integral_type()
13205   : base_(INT_BASE_TYPE),
13206     modifiers_(NO_MODIFIER)
13207 {}
13208 
13209 /// Constructor of the @ref integral_type.
13210 ///
13211 /// @param b the base type of the integral type.
13212 ///
13213 /// @param m the modifiers of the integral type.
integral_type(base_type b,modifiers_type m)13214 integral_type::integral_type(base_type b, modifiers_type m)
13215   : base_(b), modifiers_(m)
13216 {}
13217 
13218 /// Constructor of the @ref integral_type.
13219 ///
13220 /// @param the name of the integral type to parse to initialize the
13221 /// current instance of @ref integral_type.
integral_type(const string & type_name)13222 integral_type::integral_type(const string& type_name)
13223   : base_(INT_BASE_TYPE),
13224     modifiers_(NO_MODIFIER)
13225 {
13226   bool could_parse = parse_integral_type(type_name, base_, modifiers_);
13227   ABG_ASSERT(could_parse);
13228 }
13229 
13230 /// Getter of the base type of the @ref integral_type.
13231 ///
13232 /// @return the base type of the @ref integral_type.
13233 integral_type::base_type
get_base_type() const13234 integral_type::get_base_type() const
13235 {return base_;}
13236 
13237 /// Getter of the modifiers bitmap of the @ref integral_type.
13238 ///
13239 /// @return the modifiers bitmap of the @ref integral_type.
13240 integral_type::modifiers_type
get_modifiers() const13241 integral_type::get_modifiers() const
13242 {return modifiers_;}
13243 
13244 /// Equality operator for the @ref integral_type.
13245 ///
13246 /// @param other the other integral type to compare against.
13247 ///
13248 /// @return true iff @p other equals the current instance of @ref
13249 /// integral_type.
13250 bool
operator ==(const integral_type & other) const13251 integral_type::operator==(const integral_type&other) const
13252 {return base_ == other.base_ && modifiers_ == other.modifiers_;}
13253 
13254 /// Return the string representation of the current instance of @ref
13255 /// integral_type.
13256 ///
13257 /// @return the string representation of the current instance of @ref
13258 /// integral_type.
13259 string
to_string() const13260 integral_type::to_string() const
13261 {
13262   string result;
13263 
13264   // Look at modifiers ...
13265   if (modifiers_ & SIGNED_MODIFIER)
13266     result += "signed ";
13267   if (modifiers_ & UNSIGNED_MODIFIER)
13268     result += "unsigned ";
13269   if (modifiers_ & SHORT_MODIFIER)
13270     result += "short ";
13271   if (modifiers_ & LONG_MODIFIER)
13272     result += "long ";
13273   if (modifiers_ & LONG_LONG_MODIFIER)
13274     result += "long long ";
13275 
13276   // ... and look at base types.
13277   if (base_ == INT_BASE_TYPE)
13278     result += "int";
13279   else if (base_ == CHAR_BASE_TYPE)
13280     result += "char";
13281   else if (base_ == BOOL_BASE_TYPE)
13282     result += "bool";
13283   else if (base_ == DOUBLE_BASE_TYPE)
13284     result += "double";
13285   else if (base_ == FLOAT_BASE_TYPE)
13286     result += "float";
13287   else if (base_ == CHAR16_T_BASE_TYPE)
13288     result += "char16_t";
13289     else if (base_ == CHAR32_T_BASE_TYPE)
13290     result += "char32_t";
13291     else if (base_ == WCHAR_T_BASE_TYPE)
13292     result += "wchar_t";
13293 
13294   return result;
13295 }
13296 
13297 /// Convert the current instance of @ref integral_type into its string
13298 /// representation.
13299 ///
13300 /// @return the string representation of the current instance of @ref
13301 /// integral_type.
operator string() const13302 integral_type::operator string() const
13303 {return to_string();}
13304 
13305 // </integral_type definitions>
13306 
13307 //<type_decl definitions>
13308 
13309 /// Constructor.
13310 ///
13311 /// @param env the environment we are operating from.
13312 ///
13313 /// @param name the name of the type declaration.
13314 ///
13315 /// @param size_in_bits the size of the current type_decl, in bits.
13316 ///
13317 /// @param alignment_in_bits the alignment of the current typ, in
13318 /// bits.
13319 ///
13320 /// @param locus the source location of the current type declaration.
13321 ///
13322 /// @param linkage_name the linkage_name of the current type declaration.
13323 ///
13324 /// @param vis the visibility of the type declaration.
type_decl(const environment * env,const string & name,size_t size_in_bits,size_t alignment_in_bits,const location & locus,const string & linkage_name,visibility vis)13325 type_decl::type_decl(const environment* env,
13326 		     const string&	name,
13327 		     size_t		size_in_bits,
13328 		     size_t		alignment_in_bits,
13329 		     const location&	locus,
13330 		     const string&	linkage_name,
13331 		     visibility	vis)
13332 
13333   : type_or_decl_base(env,
13334 		      BASIC_TYPE
13335 		      | ABSTRACT_TYPE_BASE
13336 		      | ABSTRACT_DECL_BASE),
13337     decl_base(env, name, locus, linkage_name, vis),
13338     type_base(env, size_in_bits, alignment_in_bits)
13339 {
13340   runtime_type_instance(this);
13341 
13342   integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
13343   integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
13344   integral_type int_type(base_type, modifiers);
13345   if (parse_integral_type(name, int_type))
13346     {
13347       // Convert the integral_type into its canonical string
13348       // representation.
13349       string integral_type_name = int_type;
13350 
13351       // Set the name of this type_decl to the canonical string
13352       // representation above
13353       set_name(integral_type_name);
13354       set_qualified_name(get_name());
13355 
13356       if (!get_linkage_name().empty())
13357 	set_linkage_name(integral_type_name);
13358     }
13359 }
13360 
13361 /// Compares two instances of @ref type_decl.
13362 ///
13363 /// If the two intances are different, set a bitfield to give some
13364 /// insight about the kind of differences there are.
13365 ///
13366 /// @param l the first artifact of the comparison.
13367 ///
13368 /// @param r the second artifact of the comparison.
13369 ///
13370 /// @param k a pointer to a bitfield that gives information about the
13371 /// kind of changes there are between @p l and @p r.  This one is set
13372 /// iff @p k is non-null and the function returns false.
13373 ///
13374 /// Please note that setting k to a non-null value does have a
13375 /// negative performance impact because even if @p l and @p r are not
13376 /// equal, the function keeps up the comparison in order to determine
13377 /// the different kinds of ways in which they are different.
13378 ///
13379 /// @return true if @p l equals @p r, false otherwise.
13380 bool
equals(const type_decl & l,const type_decl & r,change_kind * k)13381 equals(const type_decl& l, const type_decl& r, change_kind* k)
13382 {
13383   bool result = equals(static_cast<const decl_base&>(l),
13384 		       static_cast<const decl_base&>(r),
13385 		       k);
13386   if (!k && !result)
13387     return false;
13388 
13389   result &= equals(static_cast<const type_base&>(l),
13390 		   static_cast<const type_base&>(r),
13391 		   k);
13392   return result;
13393 }
13394 
13395 /// Return true if both types equals.
13396 ///
13397 /// This operator re-uses the overload that takes a decl_base.
13398 ///
13399 /// Note that this does not check the scopes of any of the types.
13400 ///
13401 /// @param o the other type_decl to check agains.
13402 bool
operator ==(const type_base & o) const13403 type_decl::operator==(const type_base& o) const
13404 {
13405   const decl_base* other = dynamic_cast<const decl_base*>(&o);
13406   if (!other)
13407     return false;
13408   return *this == *other;
13409 }
13410 
13411 /// Return true if both types equals.
13412 ///
13413 /// Note that this does not check the scopes of any of the types.
13414 ///
13415 /// @param o the other type_decl to check against.
13416 bool
operator ==(const decl_base & o) const13417 type_decl::operator==(const decl_base& o) const
13418 {
13419   const type_decl* other = dynamic_cast<const type_decl*>(&o);
13420   if (!other)
13421     return false;
13422   return try_canonical_compare(this, other);
13423 }
13424 
13425 /// Return true if both types equals.
13426 ///
13427 /// Note that this does not check the scopes of any of the types.
13428 ///
13429 /// @param o the other type_decl to check against.
13430 ///
13431 /// @return true iff the current isntance equals @p o
13432 bool
operator ==(const type_decl & o) const13433 type_decl::operator==(const type_decl& o) const
13434 {
13435   const decl_base& other = o;
13436   return *this == other;
13437 }
13438 
13439 /// Inequality operator.
13440 ///
13441 /// @param o the other type to compare against.
13442 ///
13443 /// @return true iff the current instance is different from @p o.
13444 bool
operator !=(const type_decl & o) const13445 type_decl::operator!=(const type_decl& o) const
13446 {return !operator==(o);}
13447 
13448 /// Equality operator for @ref type_decl_sptr.
13449 ///
13450 /// @param l the first operand to compare.
13451 ///
13452 /// @param r the second operand to compare.
13453 ///
13454 /// @return true iff @p l equals @p r.
13455 bool
operator ==(const type_decl_sptr & l,const type_decl_sptr & r)13456 operator==(const type_decl_sptr& l, const type_decl_sptr& r)
13457 {
13458   if (!!l != !!r)
13459     return false;
13460   if (l.get() == r.get())
13461     return true;
13462   return *l == *r;
13463 }
13464 
13465 /// Inequality operator for @ref type_decl_sptr.
13466 ///
13467 /// @param l the first operand to compare.
13468 ///
13469 /// @param r the second operand to compare.
13470 ///
13471 /// @return true iff @p l is different from @p r.
13472 bool
operator !=(const type_decl_sptr & l,const type_decl_sptr & r)13473 operator!=(const type_decl_sptr& l, const type_decl_sptr& r)
13474 {return !operator==(l, r);}
13475 
13476 /// Get the pretty representation of the current instance of @ref
13477 /// type_decl.
13478 ///
13479 /// @param internal set to true if the call is intended for an
13480 /// internal use (for technical use inside the library itself), false
13481 /// otherwise.  If you don't know what this is for, then set it to
13482 /// false.
13483 ///
13484 /// @param qualified_name if true, names emitted in the pretty
13485 /// representation are fully qualified.
13486 ///
13487 /// @return the pretty representatin of the @ref type_decl.
13488 string
get_pretty_representation(bool internal,bool qualified_name) const13489 type_decl::get_pretty_representation(bool internal,
13490 				     bool qualified_name) const
13491 {
13492   if (qualified_name)
13493     return get_qualified_name(internal);
13494   return get_name();
13495 }
13496 
13497 /// This implements the ir_traversable_base::traverse pure virtual
13498 /// function.
13499 ///
13500 /// @param v the visitor used on the current instance.
13501 ///
13502 /// @return true if the entire IR node tree got traversed, false
13503 /// otherwise.
13504 bool
traverse(ir_node_visitor & v)13505 type_decl::traverse(ir_node_visitor& v)
13506 {
13507   if (v.type_node_has_been_visited(this))
13508     return true;
13509 
13510   v.visit_begin(this);
13511   bool result = v.visit_end(this);
13512   v.mark_type_node_as_visited(this);
13513 
13514   return result;
13515 }
13516 
~type_decl()13517 type_decl::~type_decl()
13518 {}
13519 //</type_decl definitions>
13520 
13521 // <scope_type_decl definitions>
13522 
13523 /// Constructor.
13524 ///
13525 /// @param env the environment we are operating from.
13526 ///
13527 /// @param name the name of the type.
13528 ///
13529 /// @param size_in_bits the size of the type, in bits.
13530 ///
13531 /// @param alignment_in_bits the alignment of the type, in bits.
13532 ///
13533 /// @param locus the source location where the type is defined.
13534 ///
13535 /// @param vis the visibility of the type.
scope_type_decl(const environment * env,const string & name,size_t size_in_bits,size_t alignment_in_bits,const location & locus,visibility vis)13536 scope_type_decl::scope_type_decl(const environment*	env,
13537 				 const string&		name,
13538 				 size_t		size_in_bits,
13539 				 size_t		alignment_in_bits,
13540 				 const location&	locus,
13541 				 visibility		vis)
13542   : type_or_decl_base(env,
13543 		      ABSTRACT_SCOPE_TYPE_DECL
13544 		      | ABSTRACT_TYPE_BASE
13545 		      | ABSTRACT_DECL_BASE),
13546     decl_base(env, name, locus, "", vis),
13547     type_base(env, size_in_bits, alignment_in_bits),
13548     scope_decl(env, name, locus)
13549 {}
13550 
13551 /// Compares two instances of @ref scope_type_decl.
13552 ///
13553 /// If the two intances are different, set a bitfield to give some
13554 /// insight about the kind of differences there are.
13555 ///
13556 /// @param l the first artifact of the comparison.
13557 ///
13558 /// @param r the second artifact of the comparison.
13559 ///
13560 /// @param k a pointer to a bitfield that gives information about the
13561 /// kind of changes there are between @p l and @p r.  This one is set
13562 /// iff @p k is non-null and the function returns false.
13563 ///
13564 /// Please note that setting k to a non-null value does have a
13565 /// negative performance impact because even if @p l and @p r are not
13566 /// equal, the function keeps up the comparison in order to determine
13567 /// the different kinds of ways in which they are different.
13568 ///
13569 /// @return true if @p l equals @p r, false otherwise.
13570 bool
equals(const scope_type_decl & l,const scope_type_decl & r,change_kind * k)13571 equals(const scope_type_decl& l, const scope_type_decl& r, change_kind* k)
13572 {
13573   bool result = equals(static_cast<const scope_decl&>(l),
13574 		  static_cast<const scope_decl&>(r),
13575 		  k);
13576 
13577   if (!k && !result)
13578     return false;
13579 
13580   result &= equals(static_cast<const type_base&>(l),
13581 		   static_cast<const type_base&>(r),
13582 		   k);
13583 
13584   return result;
13585 }
13586 
13587 /// Equality operator between two scope_type_decl.
13588 ///
13589 /// Note that this function does not consider the scope of the scope
13590 /// types themselves.
13591 ///
13592 /// @return true iff both scope types are equal.
13593 bool
operator ==(const decl_base & o) const13594 scope_type_decl::operator==(const decl_base& o) const
13595 {
13596   const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
13597   if (!other)
13598     return false;
13599   return try_canonical_compare(this, other);
13600 }
13601 
13602 /// Equality operator between two scope_type_decl.
13603 ///
13604 /// This re-uses the equality operator that takes a decl_base.
13605 ///
13606 /// @param o the other scope_type_decl to compare against.
13607 ///
13608 /// @return true iff both scope types are equal.
13609 bool
operator ==(const type_base & o) const13610 scope_type_decl::operator==(const type_base& o) const
13611 {
13612   const decl_base* other = dynamic_cast<const decl_base*>(&o);
13613   if (!other)
13614     return false;
13615 
13616   return *this == *other;
13617 }
13618 
13619 /// Traverses an instance of @ref scope_type_decl, visiting all the
13620 /// sub-types and decls that it might contain.
13621 ///
13622 /// @param v the visitor that is used to visit every IR sub-node of
13623 /// the current node.
13624 ///
13625 /// @return true if either
13626 ///  - all the children nodes of the current IR node were traversed
13627 ///    and the calling code should keep going with the traversing.
13628 ///  - or the current IR node is already being traversed.
13629 /// Otherwise, returning false means that the calling code should not
13630 /// keep traversing the tree.
13631 bool
traverse(ir_node_visitor & v)13632 scope_type_decl::traverse(ir_node_visitor& v)
13633 {
13634   if (visiting())
13635     return true;
13636 
13637   if (v.type_node_has_been_visited(this))
13638     return true;
13639 
13640   if (v.visit_begin(this))
13641     {
13642       visiting(true);
13643       for (scope_decl::declarations::const_iterator i =
13644 	     get_member_decls().begin();
13645 	   i != get_member_decls ().end();
13646 	   ++i)
13647 	if (!(*i)->traverse(v))
13648 	  break;
13649       visiting(false);
13650     }
13651 
13652   bool result = v.visit_end(this);
13653   v.mark_type_node_as_visited(this);
13654 
13655   return result;
13656 }
13657 
~scope_type_decl()13658 scope_type_decl::~scope_type_decl()
13659 {}
13660 // </scope_type_decl definitions>
13661 
13662 // <namespace_decl>
13663 
13664 /// Constructor.
13665 ///
13666 /// @param the environment we are operatin from.
13667 ///
13668 /// @param name the name of the namespace.
13669 ///
13670 /// @param locus the source location where the namespace is defined.
13671 ///
13672 /// @param vis the visibility of the namespace.
namespace_decl(const environment * env,const string & name,const location & locus,visibility vis)13673 namespace_decl::namespace_decl(const environment*	env,
13674 			       const string&		name,
13675 			       const location&		locus,
13676 			       visibility		vis)
13677     // We need to call the constructor of decl_base directly here
13678     // because it is virtually inherited by scope_decl.  Note that we
13679     // just implicitely call the default constructor for scope_decl
13680     // here, as what we really want is to initialize the decl_base
13681     // subobject.  Wow, virtual inheritance is		useful, but setting it
13682     // up is ugly.
13683   : type_or_decl_base(env,
13684 		      NAMESPACE_DECL
13685 		      | ABSTRACT_DECL_BASE
13686 		      | ABSTRACT_SCOPE_DECL),
13687     decl_base(env, name, locus, "", vis),
13688     scope_decl(env, name, locus)
13689 {
13690   runtime_type_instance(this);
13691 }
13692 
13693 /// Build and return a copy of the pretty representation of the
13694 /// namespace.
13695 ///
13696 /// @param internal set to true if the call is intended for an
13697 /// internal use (for technical use inside the library itself), false
13698 /// otherwise.  If you don't know what this is for, then set it to
13699 /// false.
13700 ///
13701 /// @param qualified_name if true, names emitted in the pretty
13702 /// representation are fully qualified.
13703 ///
13704 /// @return a copy of the pretty representation of the namespace.
13705 string
get_pretty_representation(bool internal,bool qualified_name) const13706 namespace_decl::get_pretty_representation(bool internal,
13707 					  bool qualified_name) const
13708 {
13709   string r =
13710     "namespace " + scope_decl::get_pretty_representation(internal,
13711 							 qualified_name);
13712   return r;
13713 }
13714 
13715 /// Return true iff both namespaces and their members are equal.
13716 ///
13717 /// Note that this function does not check if the scope of these
13718 /// namespaces are equal.
13719 bool
operator ==(const decl_base & o) const13720 namespace_decl::operator==(const decl_base& o) const
13721 {
13722   const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
13723   if (!other)
13724     return false;
13725   return scope_decl::operator==(*other);
13726 }
13727 
13728 /// Test if the current namespace_decl is empty or contains empty
13729 /// namespaces itself.
13730 ///
13731 /// @return true iff the current namespace_decl is empty or contains
13732 /// empty itself.
13733 bool
is_empty_or_has_empty_sub_namespaces() const13734 namespace_decl::is_empty_or_has_empty_sub_namespaces() const
13735 {
13736   if (is_empty())
13737     return true;
13738 
13739   for (declarations::const_iterator i = get_member_decls().begin();
13740        i != get_member_decls().end();
13741        ++i)
13742     {
13743       if (!is_namespace(*i))
13744 	return false;
13745 
13746       namespace_decl_sptr ns = is_namespace(*i);
13747       ABG_ASSERT(ns);
13748 
13749       if (!ns->is_empty_or_has_empty_sub_namespaces())
13750 	return false;
13751     }
13752 
13753   return true;
13754 }
13755 
13756 /// This implements the ir_traversable_base::traverse pure virtual
13757 /// function.
13758 ///
13759 /// @param v the visitor used on the current instance and on its
13760 /// member nodes.
13761 ///
13762 /// @return true if the entire IR node tree got traversed, false
13763 /// otherwise.
13764 bool
traverse(ir_node_visitor & v)13765 namespace_decl::traverse(ir_node_visitor& v)
13766 {
13767   if (visiting())
13768     return true;
13769 
13770   if (v.visit_begin(this))
13771     {
13772       visiting(true);
13773       scope_decl::declarations::const_iterator i;
13774       for (i = get_member_decls().begin();
13775 	   i != get_member_decls ().end();
13776 	   ++i)
13777 	{
13778 	  ir_traversable_base_sptr t =
13779 	    dynamic_pointer_cast<ir_traversable_base>(*i);
13780 	  if (t)
13781 	    if (!t->traverse (v))
13782 	      break;
13783 	}
13784       visiting(false);
13785     }
13786   return v.visit_end(this);
13787 }
13788 
~namespace_decl()13789 namespace_decl::~namespace_decl()
13790 {
13791 }
13792 
13793 // </namespace_decl>
13794 
13795 // <qualified_type_def>
13796 
13797 /// Type of the private data of qualified_type_def.
13798 class qualified_type_def::priv
13799 {
13800   friend class qualified_type_def;
13801 
13802   qualified_type_def::CV	cv_quals_;
13803   // Before the type is canonicalized, this is used as a temporary
13804   // internal name.
13805   interned_string		temporary_internal_name_;
13806   // Once the type is canonicalized, this is used as the internal
13807   // name.
13808   interned_string		internal_name_;
13809   weak_ptr<type_base>		underlying_type_;
13810 
priv()13811   priv()
13812     : cv_quals_(CV_NONE)
13813   {}
13814 
priv(qualified_type_def::CV quals,type_base_sptr t)13815   priv(qualified_type_def::CV quals,
13816        type_base_sptr t)
13817     : cv_quals_(quals),
13818       underlying_type_(t)
13819   {}
13820 };// end class qualified_type_def::priv
13821 
13822 /// Build the name of the current instance of qualified type.
13823 ///
13824 /// @param fully_qualified if true, build a fully qualified name.
13825 ///
13826 /// @param internal set to true if the call is intended for an
13827 /// internal use (for technical use inside the library itself), false
13828 /// otherwise.  If you don't know what this is for, then set it to
13829 /// false.
13830 ///
13831 /// @return a copy of the newly-built name.
13832 string
build_name(bool fully_qualified,bool internal) const13833 qualified_type_def::build_name(bool fully_qualified, bool internal) const
13834 {
13835   ABG_ASSERT(get_underlying_type());
13836 
13837   return get_name_of_qualified_type(get_underlying_type(),
13838 				    get_cv_quals(),
13839 				    fully_qualified, internal);
13840 }
13841 
13842 /// This function is automatically invoked whenever an instance of
13843 /// this type is canonicalized.
13844 ///
13845 /// It's an overload of the virtual type_base::on_canonical_type_set.
13846 ///
13847 /// We put here what is thus meant to be executed only at the point of
13848 /// type canonicalization.
13849 void
on_canonical_type_set()13850 qualified_type_def::on_canonical_type_set()
13851 {clear_qualified_name();}
13852 
13853 /// Constructor of the qualified_type_def
13854 ///
13855 /// @param type the underlying type
13856 ///
13857 /// @param quals a bitfield representing the const/volatile qualifiers
13858 ///
13859 /// @param locus the location of the qualified type definition
qualified_type_def(type_base_sptr type,CV quals,const location & locus)13860 qualified_type_def::qualified_type_def(type_base_sptr		type,
13861 				       CV			quals,
13862 				       const location&		locus)
13863   : type_or_decl_base(type->get_environment(),
13864 		      QUALIFIED_TYPE
13865 		      | ABSTRACT_TYPE_BASE
13866 		      | ABSTRACT_DECL_BASE),
13867     type_base(type->get_environment(), type->get_size_in_bits(),
13868 	      type->get_alignment_in_bits()),
13869     decl_base(type->get_environment(), "", locus, "",
13870 	      dynamic_pointer_cast<decl_base>(type)->get_visibility()),
13871     priv_(new priv(quals, type))
13872 {
13873   runtime_type_instance(this);
13874   interned_string name = type->get_environment()->intern(build_name(false));
13875   set_name(name);
13876 }
13877 
13878 /// Get the size of the qualified type def.
13879 ///
13880 /// This is an overload for type_base::get_size_in_bits().
13881 ///
13882 /// @return the size of the qualified type.
13883 size_t
get_size_in_bits() const13884 qualified_type_def::get_size_in_bits() const
13885 {
13886   size_t s = get_underlying_type()->get_size_in_bits();
13887   if (s != type_base::get_size_in_bits())
13888     const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
13889   return type_base::get_size_in_bits();
13890 }
13891 
13892 /// Compares two instances of @ref qualified_type_def.
13893 ///
13894 /// If the two intances are different, set a bitfield to give some
13895 /// insight about the kind of differences there are.
13896 ///
13897 /// @param l the first artifact of the comparison.
13898 ///
13899 /// @param r the second artifact of the comparison.
13900 ///
13901 /// @param k a pointer to a bitfield that gives information about the
13902 /// kind of changes there are between @p l and @p r.  This one is set
13903 /// iff @p k is non-null and the function returns false.
13904 ///
13905 /// Please note that setting k to a non-null value does have a
13906 /// negative performance impact because even if @p l and @p r are not
13907 /// equal, the function keeps up the comparison in order to determine
13908 /// the different kinds of ways in which they are different.
13909 ///
13910 /// @return true if @p l equals @p r, false otherwise.
13911 bool
equals(const qualified_type_def & l,const qualified_type_def & r,change_kind * k)13912 equals(const qualified_type_def& l, const qualified_type_def& r, change_kind* k)
13913 {
13914   bool result = true;
13915   if (l.get_cv_quals() != r.get_cv_quals())
13916     {
13917       result = false;
13918       if (k)
13919 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
13920       else
13921 	return false;
13922     }
13923 
13924   if (l.get_underlying_type() != r.get_underlying_type())
13925     {
13926       result = false;
13927       if (k)
13928 	{
13929 	  if (!types_have_similar_structure(l.get_underlying_type().get(),
13930 					    r.get_underlying_type().get()))
13931 	    // Underlying type changes in which the structure of the
13932 	    // type changed are considered local changes to the
13933 	    // qualified type.
13934 	    *k |= LOCAL_TYPE_CHANGE_KIND;
13935 	  else
13936 	    *k |= SUBTYPE_CHANGE_KIND;
13937 	}
13938       else
13939 	// okay strictly speaking this is not necessary, but I am
13940 	// putting it here to maintenance; that is, so that adding
13941 	// subsequent clauses needed to compare two qualified types
13942 	// later still works.
13943 	return false;
13944     }
13945 
13946   return result;
13947 }
13948 
13949 /// Equality operator for qualified types.
13950 ///
13951 /// Note that this function does not check for equality of the scopes.
13952 ///
13953 ///@param o the other qualified type to compare against.
13954 ///
13955 /// @return true iff both qualified types are equal.
13956 bool
operator ==(const decl_base & o) const13957 qualified_type_def::operator==(const decl_base& o) const
13958 {
13959   const qualified_type_def* other =
13960     dynamic_cast<const qualified_type_def*>(&o);
13961   if (!other)
13962     return false;
13963   return try_canonical_compare(this, other);
13964 }
13965 
13966 /// Equality operator for qualified types.
13967 ///
13968 /// Note that this function does not check for equality of the scopes.
13969 /// Also, this re-uses the equality operator above that takes a
13970 /// decl_base.
13971 ///
13972 ///@param o the other qualified type to compare against.
13973 ///
13974 /// @return true iff both qualified types are equal.
13975 bool
operator ==(const type_base & o) const13976 qualified_type_def::operator==(const type_base& o) const
13977 {
13978   const decl_base* other = dynamic_cast<const decl_base*>(&o);
13979   if (!other)
13980     return false;
13981   return *this == *other;
13982 }
13983 
13984 /// Equality operator for qualified types.
13985 ///
13986 /// Note that this function does not check for equality of the scopes.
13987 /// Also, this re-uses the equality operator above that takes a
13988 /// decl_base.
13989 ///
13990 ///@param o the other qualified type to compare against.
13991 ///
13992 /// @return true iff both qualified types are equal.
13993 bool
operator ==(const qualified_type_def & o) const13994 qualified_type_def::operator==(const qualified_type_def& o) const
13995 {
13996   const decl_base* other = dynamic_cast<const decl_base*>(&o);
13997   if (!other)
13998     return false;
13999   return *this == *other;
14000 }
14001 
14002 /// Implementation for the virtual qualified name builder for @ref
14003 /// qualified_type_def.
14004 ///
14005 /// @param qualified_name the output parameter to hold the resulting
14006 /// qualified name.
14007 ///
14008 /// @param internal set to true if the call is intended for an
14009 /// internal use (for technical use inside the library itself), false
14010 /// otherwise.  If you don't know what this is for, then set it to
14011 /// false.
14012 void
get_qualified_name(interned_string & qualified_name,bool internal) const14013 qualified_type_def::get_qualified_name(interned_string& qualified_name,
14014 				       bool internal) const
14015 {qualified_name = get_qualified_name(internal);}
14016 
14017 /// Implementation of the virtual qualified name builder/getter.
14018 ///
14019 /// @param internal set to true if the call is intended for an
14020 /// internal use (for technical use inside the library itself), false
14021 /// otherwise.  If you don't know what this is for, then set it to
14022 /// false.
14023 ///
14024 /// @return the resulting qualified name.
14025 const interned_string&
get_qualified_name(bool internal) const14026 qualified_type_def::get_qualified_name(bool internal) const
14027 {
14028   const environment* env = get_environment();
14029   ABG_ASSERT(env);
14030 
14031   if (!get_canonical_type())
14032     {
14033       // The type hasn't been canonicalized yet. We want to return a
14034       // temporary name that is not cached because the structure of
14035       // this type (and so its name) can change until its
14036       // canonicalized.
14037       if (internal)
14038 	{
14039 	  // We are asked to return a temporary *internal* name.
14040 	  // Lets compute it and return a reference to where it's
14041 	  // stored.
14042 	  priv_->temporary_internal_name_ =
14043 	      env->intern(build_name(true, /*internal=*/true));
14044 	  return priv_->temporary_internal_name_;
14045 	}
14046       else
14047 	{
14048 	  // We are asked to return a temporary non-internal name.
14049 	    set_temporary_qualified_name
14050 	      (env->intern(build_name(true, /*internal=*/false)));
14051 	  return peek_temporary_qualified_name();
14052 	}
14053     }
14054   else
14055     {
14056       // The type has already been canonicalized. We want to return
14057       // the definitive name and cache it.
14058       if (internal)
14059 	{
14060 	  if (priv_->internal_name_.empty())
14061 	    priv_->internal_name_ =
14062 	      env->intern(build_name(/*qualified=*/true,
14063 				     /*internal=*/true));
14064 	  return priv_->internal_name_;
14065 	}
14066       else
14067 	{
14068 	  if (peek_qualified_name().empty())
14069 	    set_qualified_name
14070 	      (env->intern(build_name(/*qualified=*/true,
14071 				      /*internal=*/false)));
14072 	  return peek_qualified_name();
14073 	}
14074     }
14075 }
14076 
14077 /// This implements the ir_traversable_base::traverse pure virtual
14078 /// function.
14079 ///
14080 /// @param v the visitor used on the current instance.
14081 ///
14082 /// @return true if the entire IR node tree got traversed, false
14083 /// otherwise.
14084 bool
traverse(ir_node_visitor & v)14085 qualified_type_def::traverse(ir_node_visitor& v)
14086 {
14087   if (v.type_node_has_been_visited(this))
14088     return true;
14089 
14090   if (visiting())
14091     return true;
14092 
14093   if (v.visit_begin(this))
14094     {
14095       visiting(true);
14096       if (type_base_sptr t = get_underlying_type())
14097 	t->traverse(v);
14098       visiting(false);
14099     }
14100   bool result = v.visit_end(this);
14101   v.mark_type_node_as_visited(this);
14102   return result;
14103 }
14104 
~qualified_type_def()14105 qualified_type_def::~qualified_type_def()
14106 {
14107 }
14108 
14109 /// Getter of the const/volatile qualifier bit field
14110 qualified_type_def::CV
get_cv_quals() const14111 qualified_type_def::get_cv_quals() const
14112 {return priv_->cv_quals_;}
14113 
14114 /// Setter of the const/value qualifiers bit field
14115 void
set_cv_quals(CV cv_quals)14116 qualified_type_def::set_cv_quals(CV cv_quals)
14117 {priv_->cv_quals_ = cv_quals;}
14118 
14119 /// Compute and return the string prefix or suffix representing the
14120 /// qualifiers hold by the current instance of @ref
14121 /// qualified_type_def.
14122 ///
14123 /// @return the newly-built cv string.
14124 string
get_cv_quals_string_prefix() const14125 qualified_type_def::get_cv_quals_string_prefix() const
14126 {return get_string_representation_of_cv_quals(priv_->cv_quals_);}
14127 
14128 /// Getter of the underlying type
14129 type_base_sptr
get_underlying_type() const14130 qualified_type_def::get_underlying_type() const
14131 {return priv_->underlying_type_.lock();}
14132 
14133 /// Setter of the underlying type.
14134 ///
14135 /// @param t the new underlying type.
14136 void
set_underlying_type(const type_base_sptr & t)14137 qualified_type_def::set_underlying_type(const type_base_sptr& t)
14138 {priv_->underlying_type_ = t;}
14139 
14140 /// Non-member equality operator for @ref qualified_type_def
14141 ///
14142 /// @param l the left-hand side of the equality operator
14143 ///
14144 /// @param r the right-hand side of the equality operator
14145 ///
14146 /// @return true iff @p l and @p r equals.
14147 bool
operator ==(const qualified_type_def_sptr & l,const qualified_type_def_sptr & r)14148 operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
14149 {
14150   if (l.get() == r.get())
14151     return true;
14152   if (!!l != !!r)
14153     return false;
14154 
14155   return *l == *r;
14156 }
14157 
14158 /// Non-member inequality operator for @ref qualified_type_def
14159 ///
14160 /// @param l the left-hand side of the equality operator
14161 ///
14162 /// @param r the right-hand side of the equality operator
14163 ///
14164 /// @return true iff @p l and @p r equals.
14165 bool
operator !=(const qualified_type_def_sptr & l,const qualified_type_def_sptr & r)14166 operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
14167 {return ! operator==(l, r);}
14168 
14169 /// Overloaded bitwise OR operator for cv qualifiers.
14170 qualified_type_def::CV
operator |(qualified_type_def::CV lhs,qualified_type_def::CV rhs)14171 operator|(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
14172 {
14173   return static_cast<qualified_type_def::CV>
14174     (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
14175 }
14176 
14177 /// Overloaded bitwise |= operator for cv qualifiers.
14178 qualified_type_def::CV&
operator |=(qualified_type_def::CV & l,qualified_type_def::CV r)14179 operator|=(qualified_type_def::CV& l, qualified_type_def::CV r)
14180 {
14181   l = l | r;
14182   return l;
14183 }
14184 
14185 /// Overloaded bitwise AND operator for CV qualifiers.
14186 qualified_type_def::CV
operator &(qualified_type_def::CV lhs,qualified_type_def::CV rhs)14187 operator&(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
14188 {
14189     return static_cast<qualified_type_def::CV>
14190     (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
14191 }
14192 
14193 /// Overloaded bitwise inverting operator for CV qualifiers.
14194 qualified_type_def::CV
operator ~(qualified_type_def::CV q)14195 operator~(qualified_type_def::CV q)
14196 {return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
14197 
14198 /// Streaming operator for qualified_type_decl::CV
14199 ///
14200 /// @param o the output stream to serialize the cv qualifier to.
14201 ///
14202 /// @param cv the cv qualifier to serialize.
14203 ///
14204 /// @return the output stream used.
14205 std::ostream&
operator <<(std::ostream & o,qualified_type_def::CV cv)14206 operator<<(std::ostream& o, qualified_type_def::CV cv)
14207 {
14208   string str;
14209 
14210   switch (cv)
14211     {
14212     case qualified_type_def::CV_NONE:
14213       str = "none";
14214       break;
14215     case qualified_type_def::CV_CONST:
14216       str = "const";
14217       break;
14218     case qualified_type_def::CV_VOLATILE:
14219       str = "volatile";
14220       break;
14221     case qualified_type_def::CV_RESTRICT:
14222       str = "restrict";
14223       break;
14224     }
14225 
14226   o << str;
14227   return o;
14228 }
14229 
14230 // </qualified_type_def>
14231 
14232 //<pointer_type_def definitions>
14233 
14234 /// Private data structure of the @ref pointer_type_def.
14235 struct pointer_type_def::priv
14236 {
14237   type_base_wptr pointed_to_type_;
14238   type_base* naked_pointed_to_type_;
14239   interned_string internal_qualified_name_;
14240   interned_string temp_internal_qualified_name_;
14241 
privabigail::ir::pointer_type_def::priv14242   priv(const type_base_sptr& t)
14243     : pointed_to_type_(type_or_void(t, 0)),
14244       naked_pointed_to_type_(t.get())
14245   {}
14246 
privabigail::ir::pointer_type_def::priv14247   priv()
14248     : naked_pointed_to_type_()
14249   {}
14250 }; //end struct pointer_type_def
14251 
14252 /// This function is automatically invoked whenever an instance of
14253 /// this type is canonicalized.
14254 ///
14255 /// It's an overload of the virtual type_base::on_canonical_type_set.
14256 ///
14257 /// We put here what is thus meant to be executed only at the point of
14258 /// type canonicalization.
14259 void
on_canonical_type_set()14260 pointer_type_def::on_canonical_type_set()
14261 {clear_qualified_name();}
14262 
pointer_type_def(const type_base_sptr & pointed_to,size_t size_in_bits,size_t align_in_bits,const location & locus)14263 pointer_type_def::pointer_type_def(const type_base_sptr&	pointed_to,
14264 				   size_t			size_in_bits,
14265 				   size_t			align_in_bits,
14266 				   const location&		locus)
14267   : type_or_decl_base(pointed_to->get_environment(),
14268 		      POINTER_TYPE
14269 		      | ABSTRACT_TYPE_BASE
14270 		      | ABSTRACT_DECL_BASE),
14271     type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
14272     decl_base(pointed_to->get_environment(), "", locus, ""),
14273     priv_(new priv(pointed_to))
14274 {
14275   runtime_type_instance(this);
14276   try
14277     {
14278       ABG_ASSERT(pointed_to);
14279       const environment* env = pointed_to->get_environment();
14280       decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
14281       string name = (pto ? pto->get_name() : string("void")) + "*";
14282       set_name(env->intern(name));
14283       if (pto)
14284 	set_visibility(pto->get_visibility());
14285     }
14286   catch (...)
14287     {}
14288 }
14289 
14290 /// Compares two instances of @ref pointer_type_def.
14291 ///
14292 /// If the two intances are different, set a bitfield to give some
14293 /// insight about the kind of differences there are.
14294 ///
14295 /// @param l the first artifact of the comparison.
14296 ///
14297 /// @param r the second artifact of the comparison.
14298 ///
14299 /// @param k a pointer to a bitfield that gives information about the
14300 /// kind of changes there are between @p l and @p r.  This one is set
14301 /// iff @p k is non-null and the function returns false.
14302 ///
14303 /// Please note that setting k to a non-null value does have a
14304 /// negative performance impact because even if @p l and @p r are not
14305 /// equal, the function keeps up the comparison in order to determine
14306 /// the different kinds of ways in which they are different.
14307 ///
14308 /// @return true if @p l equals @p r, false otherwise.
14309 bool
equals(const pointer_type_def & l,const pointer_type_def & r,change_kind * k)14310 equals(const pointer_type_def& l, const pointer_type_def& r, change_kind* k)
14311 {
14312   // Compare the pointed-to-types modulo the typedefs they might have
14313   bool result = (peel_typedef_type(l.get_pointed_to_type())
14314 		 == peel_typedef_type(r.get_pointed_to_type()));
14315   if (!result)
14316     if (k)
14317       {
14318 	if (!types_have_similar_structure(&l, &r))
14319 	  // pointed-to type changes in which the structure of the
14320 	  // type changed are considered local changes to the pointer
14321 	  // type.
14322 	  *k |= LOCAL_TYPE_CHANGE_KIND;
14323 	*k |= SUBTYPE_CHANGE_KIND;
14324       }
14325 
14326   return result;
14327 }
14328 
14329 /// Return true iff both instances of pointer_type_def are equal.
14330 ///
14331 /// Note that this function does not check for the scopes of the this
14332 /// types.
14333 bool
operator ==(const decl_base & o) const14334 pointer_type_def::operator==(const decl_base& o) const
14335 {
14336   const pointer_type_def* other = is_pointer_type(&o);
14337   if (!other)
14338     return false;
14339   return try_canonical_compare(this, other);
14340 }
14341 
14342 /// Return true iff both instances of pointer_type_def are equal.
14343 ///
14344 /// Note that this function does not check for the scopes of the
14345 /// types.
14346 ///
14347 /// @param other the other type to compare against.
14348 ///
14349 /// @return true iff @p other equals the current instance.
14350 bool
operator ==(const type_base & other) const14351 pointer_type_def::operator==(const type_base& other) const
14352 {
14353   const decl_base* o = is_decl(&other);
14354   if (!o)
14355     return false;
14356   return *this == *o;
14357 }
14358 
14359 /// Return true iff both instances of pointer_type_def are equal.
14360 ///
14361 /// Note that this function does not check for the scopes of the
14362 /// types.
14363 ///
14364 /// @param other the other type to compare against.
14365 ///
14366 /// @return true iff @p other equals the current instance.
14367 bool
operator ==(const pointer_type_def & other) const14368 pointer_type_def::operator==(const pointer_type_def& other) const
14369 {
14370   const decl_base& o = other;
14371   return *this == o;
14372 }
14373 
14374 /// Getter of the pointed-to type.
14375 ///
14376 /// @return the pointed-to type.
14377 const type_base_sptr
get_pointed_to_type() const14378 pointer_type_def::get_pointed_to_type() const
14379 {return priv_->pointed_to_type_.lock();}
14380 
14381 /// Getter of a naked pointer to the pointed-to type.
14382 ///
14383 /// @return a naked pointed to the pointed-to type.
14384 type_base*
get_naked_pointed_to_type() const14385 pointer_type_def::get_naked_pointed_to_type() const
14386 {return priv_->naked_pointed_to_type_;}
14387 
14388 /// Build and return the qualified name of the current instance of
14389 /// @ref pointer_type_def.
14390 ///
14391 /// @param qn output parameter.  The resulting qualified name.
14392 ///
14393 /// @param internal set to true if the call is intended for an
14394 /// internal use (for technical use inside the library itself), false
14395 /// otherwise.  If you don't know what this is for, then set it to
14396 /// false.
14397 void
get_qualified_name(interned_string & qn,bool internal) const14398 pointer_type_def::get_qualified_name(interned_string& qn, bool internal) const
14399 {qn = get_qualified_name(internal);}
14400 
14401 /// Build, cache and return the qualified name of the current instance
14402 /// of @ref pointer_type_def.  Subsequent invocations of this function
14403 /// return the cached value.
14404 ///
14405 /// @param internal set to true if the call is intended for an
14406 /// internal use (for technical use inside the library itself), false
14407 /// otherwise.  If you don't know what this is for, then set it to
14408 /// false.
14409 ///
14410 /// @return the resulting qualified name.
14411 const interned_string&
get_qualified_name(bool internal) const14412 pointer_type_def::get_qualified_name(bool internal) const
14413 {
14414   type_base* pointed_to_type = get_naked_pointed_to_type();
14415 
14416   if (internal)
14417     {
14418       if (get_canonical_type())
14419 	{
14420 	  if (priv_->internal_qualified_name_.empty())
14421 	    priv_->internal_qualified_name_ =
14422 	      get_name_of_pointer_to_type(*pointed_to_type,
14423 					  /*qualified_name=*/true,
14424 					  /*internal=*/true);
14425 	  return priv_->internal_qualified_name_;
14426 	}
14427       else
14428 	{
14429 	  // As the type hasn't yet been canonicalized, its structure
14430 	  // (and so its name) can change.  So let's invalidate the
14431 	  // cache where we store its name at each invocation of this
14432 	  // function.
14433 	  priv_->temp_internal_qualified_name_ =
14434 	    get_name_of_pointer_to_type(*pointed_to_type,
14435 					/*qualified_name=*/true,
14436 					/*internal=*/true);
14437 	  return priv_->temp_internal_qualified_name_;
14438 	}
14439     }
14440   else
14441     {
14442       if (get_naked_canonical_type())
14443 	{
14444 	  if (decl_base::peek_qualified_name().empty())
14445 	    set_qualified_name
14446 	      (get_name_of_pointer_to_type(*pointed_to_type,
14447 					   /*qualified_name=*/true,
14448 					   /*internal=*/false));
14449 	  return decl_base::peek_qualified_name();
14450 	}
14451       else
14452 	{
14453 	  // As the type hasn't yet been canonicalized, its structure
14454 	  // (and so its name) can change.  So let's invalidate the
14455 	  // cache where we store its name at each invocation of this
14456 	  // function.
14457 	  set_qualified_name
14458 	    (get_name_of_pointer_to_type(*pointed_to_type,
14459 					 /*qualified_name=*/true,
14460 					 /*internal=*/false));
14461 	  return decl_base::peek_qualified_name();
14462 	}
14463     }
14464 }
14465 
14466 /// This implements the ir_traversable_base::traverse pure virtual
14467 /// function.
14468 ///
14469 /// @param v the visitor used on the current instance.
14470 ///
14471 /// @return true if the entire IR node tree got traversed, false
14472 /// otherwise.
14473 bool
traverse(ir_node_visitor & v)14474 pointer_type_def::traverse(ir_node_visitor& v)
14475 {
14476   if (v.type_node_has_been_visited(this))
14477     return true;
14478 
14479   if (visiting())
14480     return true;
14481 
14482   if (v.visit_begin(this))
14483     {
14484       visiting(true);
14485       if (type_base_sptr t = get_pointed_to_type())
14486 	t->traverse(v);
14487       visiting(false);
14488     }
14489 
14490   bool result = v.visit_end(this);
14491   v.mark_type_node_as_visited(this);
14492   return result;
14493 }
14494 
~pointer_type_def()14495 pointer_type_def::~pointer_type_def()
14496 {}
14497 
14498 /// Turn equality of shared_ptr of @ref pointer_type_def into a deep
14499 /// equality; that is, make it compare the pointed to objects too.
14500 ///
14501 /// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
14502 /// of the equality.
14503 ///
14504 /// @param r the shared_ptr of @ref pointer_type_def on
14505 /// right-hand-side of the equality.
14506 ///
14507 /// @return true if the @ref pointer_type_def pointed to by the
14508 /// shared_ptrs are equal, false otherwise.
14509 bool
operator ==(const pointer_type_def_sptr & l,const pointer_type_def_sptr & r)14510 operator==(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
14511 {
14512   if (l.get() == r.get())
14513     return true;
14514   if (!!l != !!r)
14515     return false;
14516 
14517   return *l == *r;
14518 }
14519 
14520 /// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
14521 /// equality; that is, make it compare the pointed to objects too.
14522 ///
14523 /// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
14524 /// of the equality.
14525 ///
14526 /// @param r the shared_ptr of @ref pointer_type_def on
14527 /// right-hand-side of the equality.
14528 ///
14529 /// @return true iff the @ref pointer_type_def pointed to by the
14530 /// shared_ptrs are different.
14531 bool
operator !=(const pointer_type_def_sptr & l,const pointer_type_def_sptr & r)14532 operator!=(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
14533 {return !operator==(l, r);}
14534 
14535 // </pointer_type_def definitions>
14536 
14537 // <reference_type_def definitions>
14538 
14539 /// This function is automatically invoked whenever an instance of
14540 /// this type is canonicalized.
14541 ///
14542 /// It's an overload of the virtual type_base::on_canonical_type_set.
14543 ///
14544 /// We put here what is thus meant to be executed only at the point of
14545 /// type canonicalization.
14546 void
on_canonical_type_set()14547 reference_type_def::on_canonical_type_set()
14548 {clear_qualified_name();}
14549 
reference_type_def(const type_base_sptr pointed_to,bool lvalue,size_t size_in_bits,size_t align_in_bits,const location & locus)14550 reference_type_def::reference_type_def(const type_base_sptr	pointed_to,
14551 				       bool			lvalue,
14552 				       size_t			size_in_bits,
14553 				       size_t			align_in_bits,
14554 				       const location&		locus)
14555   : type_or_decl_base(pointed_to->get_environment(),
14556 		      REFERENCE_TYPE
14557 		      | ABSTRACT_TYPE_BASE
14558 		      | ABSTRACT_DECL_BASE),
14559     type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
14560     decl_base(pointed_to->get_environment(), "", locus, ""),
14561     is_lvalue_(lvalue)
14562 {
14563   runtime_type_instance(this);
14564 
14565   try
14566     {
14567       decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
14568       string name;
14569       if (pto)
14570 	{
14571 	  set_visibility(pto->get_visibility());
14572 	  name = string(pto->get_name()) + "&";
14573 	}
14574       else
14575 	name = string(get_type_name(is_function_type(pointed_to),
14576 				    /*qualified_name=*/true)) + "&";
14577 
14578       if (!is_lvalue())
14579 	name += "&";
14580       environment* env = pointed_to->get_environment();
14581       ABG_ASSERT(env);
14582       set_name(env->intern(name));
14583 
14584       pointed_to_type_ = type_base_wptr(type_or_void(pointed_to, 0));
14585     }
14586   catch (...)
14587     {}
14588 }
14589 
14590 /// Compares two instances of @ref reference_type_def.
14591 ///
14592 /// If the two intances are different, set a bitfield to give some
14593 /// insight about the kind of differences there are.
14594 ///
14595 /// @param l the first artifact of the comparison.
14596 ///
14597 /// @param r the second artifact of the comparison.
14598 ///
14599 /// @param k a pointer to a bitfield that gives information about the
14600 /// kind of changes there are between @p l and @p r.  This one is set
14601 /// iff @p k is non-null and the function returns false.
14602 ///
14603 /// Please note that setting k to a non-null value does have a
14604 /// negative performance impact because even if @p l and @p r are not
14605 /// equal, the function keeps up the comparison in order to determine
14606 /// the different kinds of ways in which they are different.
14607 ///
14608 /// @return true if @p l equals @p r, false otherwise.
14609 bool
equals(const reference_type_def & l,const reference_type_def & r,change_kind * k)14610 equals(const reference_type_def& l, const reference_type_def& r, change_kind* k)
14611 {
14612   if (l.is_lvalue() != r.is_lvalue())
14613     {
14614       if (k)
14615 	*k |= LOCAL_TYPE_CHANGE_KIND;
14616       return false;
14617     }
14618 
14619   // Compare the pointed-to-types modulo the typedefs they might have
14620   bool result = (peel_typedef_type(l.get_pointed_to_type())
14621 		 == (peel_typedef_type(r.get_pointed_to_type())));
14622   if (!result)
14623     if (k)
14624       {
14625 	if (!types_have_similar_structure(&l, &r))
14626 	  *k |= LOCAL_TYPE_CHANGE_KIND;
14627 	*k |= SUBTYPE_CHANGE_KIND;
14628       }
14629   return result;
14630 }
14631 
14632 /// Equality operator of the @ref reference_type_def type.
14633 ///
14634 /// @param o the other instance of @ref reference_type_def to compare
14635 /// against.
14636 ///
14637 /// @return true iff the two instances are equal.
14638 bool
operator ==(const decl_base & o) const14639 reference_type_def::operator==(const decl_base& o) const
14640 {
14641   const reference_type_def* other =
14642     dynamic_cast<const reference_type_def*>(&o);
14643   if (!other)
14644     return false;
14645   return try_canonical_compare(this, other);
14646 }
14647 
14648 /// Equality operator of the @ref reference_type_def type.
14649 ///
14650 /// @param o the other instance of @ref reference_type_def to compare
14651 /// against.
14652 ///
14653 /// @return true iff the two instances are equal.
14654 bool
operator ==(const type_base & o) const14655 reference_type_def::operator==(const type_base& o) const
14656 {
14657   const decl_base* other = dynamic_cast<const decl_base*>(&o);
14658   if (!other)
14659     return false;
14660   return *this == *other;
14661 }
14662 
14663 /// Equality operator of the @ref reference_type_def type.
14664 ///
14665 /// @param o the other instance of @ref reference_type_def to compare
14666 /// against.
14667 ///
14668 /// @return true iff the two instances are equal.
14669 bool
operator ==(const reference_type_def & o) const14670 reference_type_def::operator==(const reference_type_def& o) const
14671 {
14672   const decl_base* other = dynamic_cast<const decl_base*>(&o);
14673   if (!other)
14674     return false;
14675   return *this == *other;
14676 }
14677 
14678 type_base_sptr
get_pointed_to_type() const14679 reference_type_def::get_pointed_to_type() const
14680 {return pointed_to_type_.lock();}
14681 
14682 bool
is_lvalue() const14683 reference_type_def::is_lvalue() const
14684 {return is_lvalue_;}
14685 
14686 /// Build and return the qualified name of the current instance of the
14687 /// @ref reference_type_def.
14688 ///
14689 /// @param qn output parameter.  Is set to the newly-built qualified
14690 /// name of the current instance of @ref reference_type_def.
14691 ///
14692 /// @param internal set to true if the call is intended for an
14693 /// internal use (for technical use inside the library itself), false
14694 /// otherwise.  If you don't know what this is for, then set it to
14695 /// false.
14696 void
get_qualified_name(interned_string & qn,bool internal) const14697 reference_type_def::get_qualified_name(interned_string& qn, bool internal) const
14698 {qn = get_qualified_name(internal);}
14699 
14700 /// Build, cache and return the qualified name of the current instance
14701 /// of the @ref reference_type_def.  Subsequent invocations of this
14702 /// function return the cached value.
14703 ///
14704 /// @param internal set to true if the call is intended for an
14705 /// internal use (for technical use inside the library itself), false
14706 /// otherwise.  If you don't know what this is for, then set it to
14707 /// false.
14708 ///
14709 /// @return the newly-built qualified name of the current instance of
14710 /// @ref reference_type_def.
14711 const interned_string&
get_qualified_name(bool internal) const14712 reference_type_def::get_qualified_name(bool internal) const
14713 {
14714   if (peek_qualified_name().empty()
14715       || !get_canonical_type())
14716     set_qualified_name(get_name_of_reference_to_type(*get_pointed_to_type(),
14717 						     is_lvalue(),
14718 						     /*qualified_name=*/true,
14719 						     internal));
14720   return peek_qualified_name();
14721 }
14722 
14723 /// This implements the ir_traversable_base::traverse pure virtual
14724 /// function.
14725 ///
14726 /// @param v the visitor used on the current instance.
14727 ///
14728 /// @return true if the entire IR node tree got traversed, false
14729 /// otherwise.
14730 bool
traverse(ir_node_visitor & v)14731 reference_type_def::traverse(ir_node_visitor& v)
14732 {
14733   if (v.type_node_has_been_visited(this))
14734     return true;
14735 
14736   if (visiting())
14737     return true;
14738 
14739   if (v.visit_begin(this))
14740     {
14741       visiting(true);
14742       if (type_base_sptr t = get_pointed_to_type())
14743 	t->traverse(v);
14744       visiting(false);
14745     }
14746 
14747   bool result = v.visit_end(this);
14748   v.mark_type_node_as_visited(this);
14749   return result;
14750 }
14751 
~reference_type_def()14752 reference_type_def::~reference_type_def()
14753 {}
14754 
14755 /// Turn equality of shared_ptr of @ref reference_type_def into a deep
14756 /// equality; that is, make it compare the pointed to objects too.
14757 ///
14758 /// @param l the shared_ptr of @ref reference_type_def on left-hand-side
14759 /// of the equality.
14760 ///
14761 /// @param r the shared_ptr of @ref reference_type_def on
14762 /// right-hand-side of the equality.
14763 ///
14764 /// @return true if the @ref reference_type_def pointed to by the
14765 /// shared_ptrs are equal, false otherwise.
14766 bool
operator ==(const reference_type_def_sptr & l,const reference_type_def_sptr & r)14767 operator==(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
14768 {
14769   if (l.get() == r.get())
14770     return true;
14771   if (!!l != !!r)
14772     return false;
14773 
14774   return *l == *r;
14775 }
14776 
14777 /// Turn inequality of shared_ptr of @ref reference_type_def into a deep
14778 /// equality; that is, make it compare the pointed to objects too.
14779 ///
14780 /// @param l the shared_ptr of @ref reference_type_def on left-hand-side
14781 /// of the equality.
14782 ///
14783 /// @param r the shared_ptr of @ref reference_type_def on
14784 /// right-hand-side of the equality.
14785 ///
14786 /// @return true iff the @ref reference_type_def pointed to by the
14787 /// shared_ptrs are different.
14788 bool
operator !=(const reference_type_def_sptr & l,const reference_type_def_sptr & r)14789 operator!=(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
14790 {return !operator==(l, r);}
14791 
14792 // </reference_type_def definitions>
14793 
14794 // <array_type_def definitions>
14795 
14796 // <array_type_def::subrange_type>
14797 
14798 // <array_type_def::subrante_type::bound_value>
14799 
14800 /// Default constructor of the @ref
14801 /// array_type_def::subrange_type::bound_value class.
14802 ///
14803 /// Constructs an unsigned bound_value of value zero.
bound_value()14804 array_type_def::subrange_type::bound_value::bound_value()
14805   : s_(UNSIGNED_SIGNEDNESS)
14806 {
14807   v_.unsigned_ = 0;
14808 }
14809 
14810 /// Initialize an unsigned bound_value with a given value.
14811 ///
14812 /// @param v the initial bound value.
bound_value(uint64_t v)14813 array_type_def::subrange_type::bound_value::bound_value(uint64_t v)
14814   : s_(UNSIGNED_SIGNEDNESS)
14815 {
14816   v_.unsigned_ = v;
14817 }
14818 
14819 /// Initialize a signed bound_value with a given value.
14820 ///
14821 /// @param v the initial bound value.
bound_value(int64_t v)14822 array_type_def::subrange_type::bound_value::bound_value(int64_t v)
14823   : s_(SIGNED_SIGNEDNESS)
14824 {
14825   v_.signed_ = v;
14826 }
14827 
14828 /// Getter of the signedness (unsigned VS signed) of the bound value.
14829 ///
14830 /// @return the signedness of the bound value.
14831 enum array_type_def::subrange_type::bound_value::signedness
get_signedness() const14832 array_type_def::subrange_type::bound_value::get_signedness() const
14833 {return s_;}
14834 
14835 /// Setter of the signedness (unsigned VS signed) of the bound value.
14836 ///
14837 /// @param s the new signedness of the bound value.
14838 void
set_signedness(enum signedness s)14839 array_type_def::subrange_type::bound_value::set_signedness(enum signedness s)
14840 { s_ = s;}
14841 
14842 /// Getter of the bound value as a signed value.
14843 ///
14844 /// @return the bound value as signed.
14845 int64_t
get_signed_value() const14846 array_type_def::subrange_type::bound_value::get_signed_value() const
14847 {return v_.signed_;
14848 }
14849 
14850 /// Getter of the bound value as an unsigned value.
14851 ///
14852 /// @return the bound value as unsigned.
14853 uint64_t
get_unsigned_value()14854 array_type_def::subrange_type::bound_value::get_unsigned_value()
14855 {return v_.unsigned_;}
14856 
14857 /// Setter of the bound value as unsigned.
14858 ///
14859 /// @param v the new unsigned value.
14860 void
set_unsigned(uint64_t v)14861 array_type_def::subrange_type::bound_value::set_unsigned(uint64_t v)
14862 {
14863     s_ = UNSIGNED_SIGNEDNESS;
14864   v_.unsigned_ = v;
14865 }
14866 
14867 /// Setter of the bound value as signed.
14868 ///
14869 /// @param v the new signed value.
14870 void
set_signed(int64_t v)14871 array_type_def::subrange_type::bound_value::set_signed(int64_t v)
14872 {
14873   s_ = SIGNED_SIGNEDNESS;
14874   v_.signed_ = v;
14875 }
14876 
14877 /// Equality operator of the bound value.
14878 ///
14879 /// @param v the other bound value to compare with.
14880 ///
14881 /// @return true iff the current bound value equals @p v.
14882 bool
operator ==(const bound_value & v) const14883 array_type_def::subrange_type::bound_value::operator==(const bound_value& v) const
14884 {
14885   return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
14886 }
14887 
14888 // </array_type_def::subrante_type::bound_value>
14889 
14890 struct array_type_def::subrange_type::priv
14891 {
14892   bound_value		lower_bound_;
14893   bound_value		upper_bound_;
14894   type_base_wptr	underlying_type_;
14895   translation_unit::language language_;
14896   bool			infinite_;
14897 
privabigail::ir::array_type_def::subrange_type::priv14898   priv(bound_value ub,
14899        translation_unit::language l = translation_unit::LANG_C11)
14900     : upper_bound_(ub), language_(l), infinite_(false)
14901   {}
14902 
privabigail::ir::array_type_def::subrange_type::priv14903   priv(bound_value lb, bound_value ub,
14904        translation_unit::language l = translation_unit::LANG_C11)
14905     : lower_bound_(lb), upper_bound_(ub),
14906       language_(l), infinite_(false)
14907   {}
14908 
privabigail::ir::array_type_def::subrange_type::priv14909   priv(bound_value lb, bound_value ub, const type_base_sptr &u,
14910        translation_unit::language l = translation_unit::LANG_C11)
14911     : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
14912       language_(l), infinite_(false)
14913   {}
14914 };
14915 
14916 /// Constructor of an array_type_def::subrange_type type.
14917 ///
14918 /// @param env the environment this type was created from.
14919 ///
14920 /// @param name the name of the subrange type.
14921 ///
14922 /// @param lower_bound the lower bound of the array.  This is
14923 /// generally zero (at least for C and C++).
14924 ///
14925 /// @param upper_bound the upper bound of the array.
14926 ///
14927 /// @param underlying_type the underlying type of the subrange type.
14928 ///
14929 /// @param loc the source location where the type is defined.
subrange_type(const environment * env,const string & name,bound_value lower_bound,bound_value upper_bound,const type_base_sptr & utype,const location & loc,translation_unit::language l)14930 array_type_def::subrange_type::subrange_type(const environment* env,
14931 					     const string&	name,
14932 					     bound_value	lower_bound,
14933 					     bound_value	upper_bound,
14934 					     const type_base_sptr& utype,
14935 					     const location&	loc,
14936 					     translation_unit::language l)
14937   : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
14938     type_base(env,
14939 	      upper_bound.get_unsigned_value()
14940 	      - lower_bound.get_unsigned_value(),
14941 	      0),
14942     decl_base(env, name, loc, ""),
14943     priv_(new priv(lower_bound, upper_bound, utype, l))
14944 {
14945   runtime_type_instance(this);
14946 }
14947 
14948 /// Constructor of the array_type_def::subrange_type type.
14949 ///
14950 /// @param env the environment this type is being created in.
14951 ///
14952 /// @param name the name of the subrange type.
14953 ///
14954 /// @param lower_bound the lower bound of the array.  This is
14955 /// generally zero (at least for C and C++).
14956 ///
14957 /// @param upper_bound the upper bound of the array.
14958 ///
14959 /// @param loc the source location where the type is defined.
14960 ///
14961 /// @param l the language that generated this subrange.
subrange_type(const environment * env,const string & name,bound_value lower_bound,bound_value upper_bound,const location & loc,translation_unit::language l)14962 array_type_def::subrange_type::subrange_type(const environment* env,
14963 					     const string&	name,
14964 					     bound_value	lower_bound,
14965 					     bound_value	upper_bound,
14966 					     const location&	loc,
14967 					     translation_unit::language l)
14968   : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
14969     type_base(env,
14970 	      upper_bound.get_unsigned_value()
14971 	      - lower_bound.get_unsigned_value(), 0),
14972     decl_base(env, name, loc, ""),
14973     priv_(new priv(lower_bound, upper_bound, l))
14974 {
14975   runtime_type_instance(this);
14976 }
14977 
14978 /// Constructor of the array_type_def::subrange_type type.
14979 ///
14980 /// @param env the environment this type is being created from.
14981 ///
14982 /// @param name of the name of type.
14983 ///
14984 /// @param upper_bound the upper bound of the array.  The lower bound
14985 /// is considered to be zero.
14986 ///
14987 /// @param loc the source location of the type.
14988 ///
14989 /// @param the language that generated this type.
subrange_type(const environment * env,const string & name,bound_value upper_bound,const location & loc,translation_unit::language l)14990 array_type_def::subrange_type::subrange_type(const environment* env,
14991 					     const string&	name,
14992 					     bound_value	upper_bound,
14993 					     const location&	loc,
14994 					     translation_unit::language l)
14995   : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
14996     type_base(env, upper_bound.get_unsigned_value(), 0),
14997     decl_base(env, name, loc, ""),
14998     priv_(new priv(upper_bound, l))
14999 {
15000   runtime_type_instance(this);
15001 }
15002 
15003 /// Getter of the underlying type of the subrange, that is, the type
15004 /// that defines the range.
15005 ///
15006 /// @return the underlying type.
15007 type_base_sptr
get_underlying_type() const15008 array_type_def::subrange_type::get_underlying_type() const
15009 {return priv_->underlying_type_.lock();}
15010 
15011 /// Setter of the underlying type of the subrange, that is, the type
15012 /// that defines the range.
15013 ///
15014 /// @param u the new underlying type.
15015 void
set_underlying_type(const type_base_sptr & u)15016 array_type_def::subrange_type::set_underlying_type(const type_base_sptr &u)
15017 {
15018   ABG_ASSERT(priv_->underlying_type_.expired());
15019   priv_->underlying_type_ = u;
15020 }
15021 
15022 /// Getter of the upper bound of the subrange type.
15023 ///
15024 /// @return the upper bound of the subrange type.
15025 int64_t
get_upper_bound() const15026 array_type_def::subrange_type::get_upper_bound() const
15027 {return priv_->upper_bound_.get_signed_value();}
15028 
15029 /// Getter of the lower bound of the subrange type.
15030 ///
15031 /// @return the lower bound of the subrange type.
15032 int64_t
get_lower_bound() const15033 array_type_def::subrange_type::get_lower_bound() const
15034 {return priv_->lower_bound_.get_signed_value();}
15035 
15036 /// Setter of the upper bound of the subrange type.
15037 ///
15038 /// @param ub the new value of the upper bound.
15039 void
set_upper_bound(int64_t ub)15040 array_type_def::subrange_type::set_upper_bound(int64_t ub)
15041 {priv_->upper_bound_ = ub;}
15042 
15043 /// Setter of the lower bound.
15044 ///
15045 /// @param lb the new value of the lower bound.
15046 void
set_lower_bound(int64_t lb)15047 array_type_def::subrange_type::set_lower_bound(int64_t lb)
15048 {priv_->lower_bound_ = lb;}
15049 
15050 /// Getter of the length of the subrange type.
15051 ///
15052 /// Note that a length of zero means the array has an infinite (or
15053 /// rather a non-known) size.
15054 ///
15055 /// @return the length of the subrange type.
15056 uint64_t
get_length() const15057 array_type_def::subrange_type::get_length() const
15058 {
15059   if (is_infinite())
15060     return 0;
15061 
15062   ABG_ASSERT(get_upper_bound() >= get_lower_bound());
15063   return get_upper_bound() - get_lower_bound() + 1;
15064 }
15065 
15066 /// Test if the length of the subrange type is infinite.
15067 ///
15068 /// @return true iff the length of the subrange type is infinite.
15069 bool
is_infinite() const15070 array_type_def::subrange_type::is_infinite() const
15071 {return priv_->infinite_;}
15072 
15073 /// Set the infinite-ness status of the subrange type.
15074 ///
15075 /// @param f true iff the length of the subrange type should be set to
15076 /// being infinite.
15077 void
is_infinite(bool f)15078 array_type_def::subrange_type::is_infinite(bool f)
15079 {priv_->infinite_ = f;}
15080 
15081 /// Getter of the language that generated this type.
15082 ///
15083 /// @return the language of this type.
15084 translation_unit::language
get_language() const15085 array_type_def::subrange_type::get_language() const
15086 {return priv_->language_;}
15087 
15088 /// Return a string representation of the sub range.
15089 ///
15090 /// @return the string representation of the sub range.
15091 string
as_string() const15092 array_type_def::subrange_type::as_string() const
15093 {
15094   std::ostringstream o;
15095 
15096   if (is_ada_language(get_language()))
15097     {
15098       type_base_sptr underlying_type = get_underlying_type();
15099       if (underlying_type)
15100 	o << ir::get_pretty_representation(underlying_type, false) << " ";
15101       o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
15102     }
15103   else if (is_infinite())
15104     o << "[]";
15105   else
15106     o << "["  << get_length() << "]";
15107 
15108   return o.str();
15109 }
15110 
15111 /// Return a string representation of a vector of subranges
15112 ///
15113 /// @return the string representation of a vector of sub ranges.
15114 string
vector_as_string(const vector<subrange_sptr> & v)15115 array_type_def::subrange_type::vector_as_string(const vector<subrange_sptr>& v)
15116 {
15117   if (v.empty())
15118     return "[]";
15119 
15120   string r;
15121   for (vector<subrange_sptr>::const_iterator i = v.begin();
15122        i != v.end();
15123        ++i)
15124     r += (*i)->as_string();
15125 
15126   return r;
15127 }
15128 
15129 /// Compares two isntances of @ref array_type_def::subrange_type.
15130 ///
15131 /// If the two intances are different, set a bitfield to give some
15132 /// insight about the kind of differences there are.
15133 ///
15134 /// @param l the first artifact of the comparison.
15135 ///
15136 /// @param r the second artifact of the comparison.
15137 ///
15138 /// @param k a pointer to a bitfield that gives information about the
15139 /// kind of changes there are between @p l and @p r.  This one is set
15140 /// iff @p k is non-null and the function returns false.
15141 ///
15142 /// Please note that setting k to a non-null value does have a
15143 /// negative performance impact because even if @p l and @p r are not
15144 /// equal, the function keeps up the comparison in order to determine
15145 /// the different kinds of ways in which they are different.
15146 ///
15147 /// @return true if @p l equals @p r, false otherwise.
15148 bool
equals(const array_type_def::subrange_type & l,const array_type_def::subrange_type & r,change_kind * k)15149 equals(const array_type_def::subrange_type& l,
15150        const array_type_def::subrange_type& r,
15151        change_kind* k)
15152 {
15153   bool result = true;
15154 
15155   if (l.get_lower_bound() != r.get_lower_bound()
15156       || l.get_upper_bound() != r.get_upper_bound()
15157       || l.get_name() != r.get_name())
15158     {
15159       result = false;
15160       if (k)
15161 	*k |= LOCAL_TYPE_CHANGE_KIND;
15162       else
15163 	return result;
15164     }
15165 
15166 #if 0
15167   // If we enable this, we need to update the reporting code too, to
15168   // report changes about range underlying types too.
15169   if (l.get_underlying_type() != r.get_underlying_type())
15170     {
15171       result = false;
15172       if (k)
15173 	{
15174 	  if (!types_have_similar_structure(l.get_underlying_type().get(),
15175 					    r.get_underlying_type().get()))
15176 	    *k |= LOCAL_TYPE_CHANGE_KIND;
15177 	  else
15178 	    *k |= SUBTYPE_CHANGE_KIND;
15179 	}
15180       else
15181 	return result;
15182     }
15183 #endif
15184   return result;
15185 }
15186 
15187 /// Equality operator.
15188 ///
15189 /// @param o the other subrange to test against.
15190 ///
15191 /// @return true iff @p o equals the current instance of
15192 /// array_type_def::subrange_type.
15193 bool
operator ==(const decl_base & o) const15194 array_type_def::subrange_type::operator==(const decl_base& o) const
15195 {
15196   const subrange_type* other =
15197     dynamic_cast<const subrange_type*>(&o);
15198   if (!other)
15199     return false;
15200   return try_canonical_compare(this, other);
15201 }
15202 
15203 /// Equality operator.
15204 ///
15205 /// @param o the other subrange to test against.
15206 ///
15207 /// @return true iff @p o equals the current instance of
15208 /// array_type_def::subrange_type.
15209 bool
operator ==(const type_base & o) const15210 array_type_def::subrange_type::operator==(const type_base& o) const
15211 {
15212   const decl_base* other = dynamic_cast<const decl_base*>(&o);
15213   if (!other)
15214     return false;
15215   return *this == *other;
15216 }
15217 
15218 /// Equality operator.
15219 ///
15220 /// @param o the other subrange to test against.
15221 ///
15222 /// @return true iff @p o equals the current instance of
15223 /// array_type_def::subrange_type.
15224 bool
operator ==(const subrange_type & o) const15225 array_type_def::subrange_type::operator==(const subrange_type& o) const
15226 {
15227   const type_base &t = o;
15228   return operator==(t);
15229 }
15230 
15231 /// Inequality operator.
15232 ///
15233 /// @param o the other subrange to test against.
15234 ///
15235 /// @return true iff @p o is different from the current instance of
15236 /// array_type_def::subrange_type.
15237 bool
operator !=(const subrange_type & o) const15238 array_type_def::subrange_type::operator!=(const subrange_type& o) const
15239 {return !operator==(o);}
15240 
15241 /// Build a pretty representation for an
15242 /// array_type_def::subrange_type.
15243 ///
15244 /// @param internal set to true if the call is intended for an
15245 /// internal use (for technical use inside the library itself), false
15246 /// otherwise.  If you don't know what this is for, then set it to
15247 /// false.
15248 ///
15249 /// @return a copy of the pretty representation of the current
15250 /// instance of typedef_decl.
15251 string
get_pretty_representation(bool,bool) const15252 array_type_def::subrange_type::get_pretty_representation(bool, bool) const
15253 {
15254   string name = get_name();
15255   string repr;
15256 
15257   if (name.empty())
15258     repr += "<anonymous range>";
15259   else
15260     repr += "<range " + get_name() + ">";
15261   repr += as_string();
15262 
15263   return repr;
15264 }
15265 
15266 /// This implements the ir_traversable_base::traverse pure virtual
15267 /// function.
15268 ///
15269 /// @param v the visitor used on the current instance.
15270 ///
15271 /// @return true if the entire IR node tree got traversed, false
15272 /// otherwise.
15273 bool
traverse(ir_node_visitor & v)15274 array_type_def::subrange_type::traverse(ir_node_visitor& v)
15275 {
15276   if (v.type_node_has_been_visited(this))
15277     return true;
15278 
15279   if (v.visit_begin(this))
15280     {
15281       visiting(true);
15282       if (type_base_sptr u = get_underlying_type())
15283 	u->traverse(v);
15284       visiting(false);
15285     }
15286 
15287   bool result = v.visit_end(this);
15288   v.mark_type_node_as_visited(this);
15289   return result;
15290 }
15291 
15292 // </array_type_def::subrange_type>
15293 
15294 struct array_type_def::priv
15295 {
15296   type_base_wptr	element_type_;
15297   subranges_type	subranges_;
15298   interned_string	temp_internal_qualified_name_;
15299   interned_string	internal_qualified_name_;
15300 
privabigail::ir::array_type_def::priv15301   priv(type_base_sptr t)
15302     : element_type_(t) {}
privabigail::ir::array_type_def::priv15303   priv(type_base_sptr t, subranges_type subs)
15304     : element_type_(t), subranges_(subs) {}
15305 };
15306 
15307 /// Constructor for the type array_type_def
15308 ///
15309 /// Note how the constructor expects a vector of subrange
15310 /// objects. Parsing of the array information always entails
15311 /// parsing the subrange info as well, thus the class subrange_type
15312 /// is defined inside class array_type_def and also parsed
15313 /// simultaneously.
15314 ///
15315 /// @param e_type the type of the elements contained in the array
15316 ///
15317 /// @param subs a vector of the array's subranges(dimensions)
15318 ///
15319 /// @param locus the source location of the array type definition.
array_type_def(const type_base_sptr e_type,const std::vector<subrange_sptr> & subs,const location & locus)15320 array_type_def::array_type_def(const type_base_sptr			e_type,
15321 			       const std::vector<subrange_sptr>&	subs,
15322 			       const location&				locus)
15323   : type_or_decl_base(e_type->get_environment(),
15324 		      ARRAY_TYPE
15325 		      | ABSTRACT_TYPE_BASE
15326 		      | ABSTRACT_DECL_BASE),
15327     type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
15328     decl_base(e_type->get_environment(), locus),
15329     priv_(new priv(e_type))
15330 {
15331   runtime_type_instance(this);
15332   append_subranges(subs);
15333 }
15334 
15335 string
get_subrange_representation() const15336 array_type_def::get_subrange_representation() const
15337 {
15338   string r = subrange_type::vector_as_string(get_subranges());
15339   return r;
15340 }
15341 
15342 /// Get the string representation of an @ref array_type_def.
15343 ///
15344 /// @param a the array type to consider.
15345 ///
15346 /// @param internal set to true if the call is intended for an
15347 /// internal use (for technical use inside the library itself), false
15348 /// otherwise.  If you don't know what this is for, then set it to
15349 /// false.
15350 static string
get_type_representation(const array_type_def & a,bool internal)15351 get_type_representation(const array_type_def& a, bool internal)
15352 {
15353   type_base_sptr e_type = a.get_element_type();
15354   decl_base_sptr d = get_type_declaration(e_type);
15355   string r;
15356 
15357   if (is_ada_language(a.get_language()))
15358     {
15359       std::ostringstream o;
15360       o << "array ("
15361 	<< a.get_subrange_representation()
15362 	<< ") of "
15363 	<<  e_type->get_pretty_representation(internal);
15364     }
15365   else
15366     {
15367       if (internal)
15368 	r = get_type_name(e_type, /*qualified=*/true, /*internal=*/true)
15369 	  + a.get_subrange_representation();
15370       else
15371 	r = get_type_name(e_type, /*qualified=*/false, /*internal=*/false)
15372 	  + a.get_subrange_representation();
15373     }
15374 
15375   return r;
15376 }
15377 
15378 /// Get the pretty representation of the current instance of @ref
15379 /// array_type_def.
15380 ///
15381 /// @param internal set to true if the call is intended for an
15382 /// internal use (for technical use inside the library itself), false
15383 /// otherwise.  If you don't know what this is for, then set it to
15384 /// false.
15385 string
get_pretty_representation(bool internal,bool) const15386 array_type_def::get_pretty_representation(bool internal,
15387 					  bool /*qualified_name*/) const
15388 {return get_type_representation(*this, internal);}
15389 
15390 /// Compares two instances of @ref array_type_def.
15391 ///
15392 /// If the two intances are different, set a bitfield to give some
15393 /// insight about the kind of differences there are.
15394 ///
15395 /// @param l the first artifact of the comparison.
15396 ///
15397 /// @param r the second artifact of the comparison.
15398 ///
15399 /// @param k a pointer to a bitfield that gives information about the
15400 /// kind of changes there are between @p l and @p r.  This one is set
15401 /// iff @p k is non-null and the function returns false.
15402 ///
15403 /// Please note that setting k to a non-null value does have a
15404 /// negative performance impact because even if @p l and @p r are not
15405 /// equal, the function keeps up the comparison in order to determine
15406 /// the different kinds of ways in which they are different.
15407 ///
15408 /// @return true if @p l equals @p r, false otherwise.
15409 bool
equals(const array_type_def & l,const array_type_def & r,change_kind * k)15410 equals(const array_type_def& l, const array_type_def& r, change_kind* k)
15411 {
15412   std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
15413   std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
15414 
15415   bool result = true;
15416   if (this_subs.size() != other_subs.size())
15417     {
15418       result = false;
15419       if (k)
15420 	*k |= LOCAL_TYPE_CHANGE_KIND;
15421       else
15422 	return false;
15423     }
15424 
15425   std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
15426   for (i = this_subs.begin(), j = other_subs.begin();
15427        i != this_subs.end() && j != other_subs.end();
15428        ++i, ++j)
15429     if (**i != **j)
15430       {
15431 	result = false;
15432 	if (k)
15433 	  {
15434 	    *k |= LOCAL_TYPE_CHANGE_KIND;
15435 	    break;
15436 	  }
15437 	else
15438 	  return false;
15439       }
15440 
15441   // Compare the element types modulo the typedefs they might have
15442   if (peel_typedef_type(l.get_element_type())
15443       != peel_typedef_type(r.get_element_type()))
15444     {
15445       result = false;
15446       if (k)
15447 	*k |= SUBTYPE_CHANGE_KIND;
15448       else
15449 	return false;
15450     }
15451 
15452   return result;
15453 }
15454 
15455 /// Test if two variables are equals modulo CV qualifiers.
15456 ///
15457 /// @param l the first array of the comparison.
15458 ///
15459 /// @param r the second array of the comparison.
15460 ///
15461 /// @return true iff @p l equals @p r or, if they are different, the
15462 /// difference between the too is just a matter of CV qualifiers.
15463 bool
equals_modulo_cv_qualifier(const array_type_def * l,const array_type_def * r)15464 equals_modulo_cv_qualifier(const array_type_def* l, const array_type_def* r)
15465 {
15466   if (l == r)
15467     return true;
15468 
15469   if (!l || !r)
15470     return false;
15471 
15472   l = is_array_type(peel_qualified_or_typedef_type(l));
15473   r = is_array_type(peel_qualified_or_typedef_type(r));
15474 
15475   std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
15476   std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
15477 
15478   if (this_subs.size() != other_subs.size())
15479     return false;
15480 
15481   std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
15482   for (i = this_subs.begin(), j = other_subs.begin();
15483        i != this_subs.end() && j != other_subs.end();
15484        ++i, ++j)
15485     if (**i != **j)
15486       return false;
15487 
15488   type_base *first_element_type =
15489     peel_qualified_or_typedef_type(l->get_element_type().get());
15490   type_base *second_element_type =
15491     peel_qualified_or_typedef_type(r->get_element_type().get());
15492 
15493   if (*first_element_type != *second_element_type)
15494     return false;
15495 
15496   return true;
15497 }
15498 
15499 /// Get the language of the array.
15500 ///
15501 /// @return the language of the array.
15502 translation_unit::language
get_language() const15503 array_type_def::get_language() const
15504 {
15505   const std::vector<subrange_sptr>& subranges =
15506     get_subranges();
15507 
15508   if (subranges.empty())
15509     return translation_unit::LANG_C11;
15510   return subranges.front()->get_language();
15511 }
15512 
15513 bool
operator ==(const decl_base & o) const15514 array_type_def::operator==(const decl_base& o) const
15515 {
15516   const array_type_def* other =
15517     dynamic_cast<const array_type_def*>(&o);
15518   if (!other)
15519     return false;
15520   return try_canonical_compare(this, other);
15521 }
15522 
15523 bool
operator ==(const type_base & o) const15524 array_type_def::operator==(const type_base& o) const
15525 {
15526   const decl_base* other = dynamic_cast<const decl_base*>(&o);
15527   if (!other)
15528     return false;
15529   return *this == *other;
15530 }
15531 
15532 /// Getter of the type of an array element.
15533 ///
15534 /// @return the type of an array element.
15535 const type_base_sptr
get_element_type() const15536 array_type_def::get_element_type() const
15537 {return priv_->element_type_.lock();}
15538 
15539 /// Setter of the type of array element.
15540 ///
15541 /// Beware that after using this function, one might want to
15542 /// re-compute the canonical type of the array, if one has already
15543 /// been computed.
15544 ///
15545 /// The intended use of this method is to permit in-place adjustment
15546 /// of the element type's qualifiers. In particular, the size of the
15547 /// element type should not be changed.
15548 ///
15549 /// @param element_type the new element type to set.
15550 void
set_element_type(const type_base_sptr & element_type)15551 array_type_def::set_element_type(const type_base_sptr& element_type)
15552 {
15553   priv_->element_type_ = element_type;
15554 }
15555 
15556 /// Append subranges from the vector @param subs to the current
15557 /// vector of subranges.
15558 void
append_subranges(const std::vector<subrange_sptr> & subs)15559 array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
15560 {
15561   size_t s = get_element_type()->get_size_in_bits();
15562 
15563   for (std::vector<shared_ptr<subrange_type> >::const_iterator i = subs.begin();
15564        i != subs.end();
15565        ++i)
15566     {
15567       priv_->subranges_.push_back(*i);
15568       s *= (*i)->get_length();
15569     }
15570 
15571   const environment* env = get_environment();
15572   ABG_ASSERT(env);
15573   set_name(env->intern(get_pretty_representation()));
15574   set_size_in_bits(s);
15575 }
15576 
15577 /// @return true if one of the sub-ranges of the array is infinite, or
15578 /// if the array has no sub-range at all, also meaning that the size
15579 /// of the array is infinite.
15580 bool
is_infinite() const15581 array_type_def::is_infinite() const
15582 {
15583   if (priv_->subranges_.empty())
15584     return true;
15585 
15586   for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
15587 	 priv_->subranges_.begin();
15588        i != priv_->subranges_.end();
15589        ++i)
15590     if ((*i)->is_infinite())
15591       return true;
15592 
15593   return false;
15594 }
15595 
15596 int
get_dimension_count() const15597 array_type_def::get_dimension_count() const
15598 {return priv_->subranges_.size();}
15599 
15600 /// Build and return the qualified name of the current instance of the
15601 /// @ref array_type_def.
15602 ///
15603 /// @param qn output parameter.  Is set to the newly-built qualified
15604 /// name of the current instance of @ref array_type_def.
15605 ///
15606 /// @param internal set to true if the call is intended for an
15607 /// internal use (for technical use inside the library itself), false
15608 /// otherwise.  If you don't know what this is for, then set it to
15609 /// false.
15610 void
get_qualified_name(interned_string & qn,bool internal) const15611 array_type_def::get_qualified_name(interned_string& qn, bool internal) const
15612 {qn = get_qualified_name(internal);}
15613 
15614 /// Compute the qualified name of the array.
15615 ///
15616 /// @param internal set to true if the call is intended for an
15617 /// internal use (for technical use inside the library itself), false
15618 /// otherwise.  If you don't know what this is for, then set it to
15619 /// false.
15620 ///
15621 /// @return the resulting qualified name.
15622 const interned_string&
get_qualified_name(bool internal) const15623 array_type_def::get_qualified_name(bool internal) const
15624 {
15625   const environment* env = get_environment();
15626   ABG_ASSERT(env);
15627 
15628   if (internal)
15629     {
15630       if (get_canonical_type())
15631 	{
15632 	  if (priv_->internal_qualified_name_.empty())
15633 	    priv_->internal_qualified_name_ =
15634 	      env->intern(get_type_representation(*this, /*internal=*/true));
15635 	  return priv_->internal_qualified_name_;
15636 	}
15637       else
15638 	{
15639 	  priv_->temp_internal_qualified_name_ =
15640 	    env->intern(get_type_representation(*this, /*internal=*/true));
15641 	  return priv_->temp_internal_qualified_name_;
15642 	}
15643     }
15644   else
15645     {
15646       if (get_canonical_type())
15647 	{
15648 	  if (decl_base::peek_qualified_name().empty())
15649 	    set_qualified_name(env->intern(get_type_representation
15650 					   (*this, /*internal=*/false)));
15651 	  return decl_base::peek_qualified_name();
15652 	}
15653       else
15654 	{
15655 	  set_qualified_name(env->intern(get_type_representation
15656 					 (*this, /*internal=*/false)));
15657 	  return decl_base::peek_qualified_name();
15658 	}
15659     }
15660 }
15661 
15662 /// This implements the ir_traversable_base::traverse pure virtual
15663 /// function.
15664 ///
15665 /// @param v the visitor used on the current instance.
15666 ///
15667 /// @return true if the entire IR node tree got traversed, false
15668 /// otherwise.
15669 bool
traverse(ir_node_visitor & v)15670 array_type_def::traverse(ir_node_visitor& v)
15671 {
15672   if (v.type_node_has_been_visited(this))
15673     return true;
15674 
15675   if (visiting())
15676     return true;
15677 
15678   if (v.visit_begin(this))
15679     {
15680       visiting(true);
15681       if (type_base_sptr t = get_element_type())
15682 	t->traverse(v);
15683       visiting(false);
15684     }
15685 
15686   bool result = v.visit_end(this);
15687   v.mark_type_node_as_visited(this);
15688   return result;
15689 }
15690 
15691 const location&
get_location() const15692 array_type_def::get_location() const
15693 {return decl_base::get_location();}
15694 
15695 /// Get the array's subranges
15696 const std::vector<array_type_def::subrange_sptr>&
get_subranges() const15697 array_type_def::get_subranges() const
15698 {return priv_->subranges_;}
15699 
~array_type_def()15700 array_type_def::~array_type_def()
15701 {}
15702 
15703 // </array_type_def definitions>
15704 
15705 // <enum_type_decl definitions>
15706 
15707 class enum_type_decl::priv
15708 {
15709   type_base_sptr	underlying_type_;
15710   enumerators		enumerators_;
15711 
15712   friend class enum_type_decl;
15713 
15714   priv();
15715 
15716 public:
priv(type_base_sptr underlying_type,enumerators & enumerators)15717   priv(type_base_sptr underlying_type,
15718        enumerators& enumerators)
15719     : underlying_type_(underlying_type),
15720       enumerators_(enumerators)
15721   {}
15722 }; // end class enum_type_decl::priv
15723 
15724 /// Constructor.
15725 ///
15726 /// @param name the name of the type declaration.
15727 ///
15728 /// @param locus the source location where the type was defined.
15729 ///
15730 /// @param underlying_type the underlying type of the enum.
15731 ///
15732 /// @param enums the enumerators of this enum type.
15733 ///
15734 /// @param linkage_name the linkage name of the enum.
15735 ///
15736 /// @param vis the visibility of the enum type.
enum_type_decl(const string & name,const location & locus,type_base_sptr underlying_type,enumerators & enums,const string & linkage_name,visibility vis)15737 enum_type_decl::enum_type_decl(const string&	name,
15738 			       const location&	locus,
15739 			       type_base_sptr	underlying_type,
15740 			       enumerators&	enums,
15741 			       const string&	linkage_name,
15742 			       visibility	vis)
15743   : type_or_decl_base(underlying_type->get_environment(),
15744 		      ENUM_TYPE
15745 		      | ABSTRACT_TYPE_BASE
15746 		      | ABSTRACT_DECL_BASE),
15747     type_base(underlying_type->get_environment(),
15748 	      underlying_type->get_size_in_bits(),
15749 	      underlying_type->get_alignment_in_bits()),
15750     decl_base(underlying_type->get_environment(),
15751 	      name, locus, linkage_name, vis),
15752     priv_(new priv(underlying_type, enums))
15753 {
15754   runtime_type_instance(this);
15755   for (enumerators::iterator e = get_enumerators().begin();
15756        e != get_enumerators().end();
15757        ++e)
15758     e->set_enum_type(this);
15759 }
15760 
15761 /// Return the underlying type of the enum.
15762 type_base_sptr
get_underlying_type() const15763 enum_type_decl::get_underlying_type() const
15764 {return priv_->underlying_type_;}
15765 
15766 /// @return the list of enumerators of the enum.
15767 const enum_type_decl::enumerators&
get_enumerators() const15768 enum_type_decl::get_enumerators() const
15769 {return priv_->enumerators_;}
15770 
15771 /// @return the list of enumerators of the enum.
15772 enum_type_decl::enumerators&
get_enumerators()15773 enum_type_decl::get_enumerators()
15774 {return priv_->enumerators_;}
15775 
15776 /// Get the pretty representation of the current instance of @ref
15777 /// enum_type_decl.
15778 ///
15779 /// @param internal set to true if the call is intended for an
15780 /// internal use (for technical use inside the library itself), false
15781 /// otherwise.  If you don't know what this is for, then set it to
15782 /// false.
15783 ///
15784 /// @param qualified_name if true, names emitted in the pretty
15785 /// representation are fully qualified.
15786 ///
15787 /// @return the pretty representation of the enum type.
15788 string
get_pretty_representation(bool internal,bool qualified_name) const15789 enum_type_decl::get_pretty_representation(bool internal,
15790 					  bool qualified_name) const
15791 {
15792   string r = "enum " + decl_base::get_pretty_representation(internal,
15793 							    qualified_name);
15794   return r;
15795 }
15796 
15797 /// This implements the ir_traversable_base::traverse pure virtual
15798 /// function.
15799 ///
15800 /// @param v the visitor used on the current instance.
15801 ///
15802 /// @return true if the entire IR node tree got traversed, false
15803 /// otherwise.
15804 bool
traverse(ir_node_visitor & v)15805 enum_type_decl::traverse(ir_node_visitor &v)
15806 {
15807   if (v.type_node_has_been_visited(this))
15808     return true;
15809 
15810   if (visiting())
15811     return true;
15812 
15813   if (v.visit_begin(this))
15814     {
15815       visiting(true);
15816       if (type_base_sptr t = get_underlying_type())
15817 	t->traverse(v);
15818       visiting(false);
15819     }
15820 
15821   bool result = v.visit_end(this);
15822   v.mark_type_node_as_visited(this);
15823   return result;
15824 }
15825 
15826 /// Destructor for the enum type declaration.
~enum_type_decl()15827 enum_type_decl::~enum_type_decl()
15828 {}
15829 
15830 /// Test if two enums differ, but not by a name change.
15831 ///
15832 /// @param l the first enum to consider.
15833 ///
15834 /// @param r the second enum to consider.
15835 ///
15836 /// @return true iff @p l differs from @p r by anything but a name
15837 /// change.
15838 bool
enum_has_non_name_change(const enum_type_decl & l,const enum_type_decl & r,change_kind * k)15839 enum_has_non_name_change(const enum_type_decl& l,
15840 			 const enum_type_decl& r,
15841 			 change_kind* k)
15842 {
15843   bool result = false;
15844   if (*l.get_underlying_type() != *r.get_underlying_type())
15845     {
15846       result = true;
15847       if (k)
15848 	*k |= SUBTYPE_CHANGE_KIND;
15849       else
15850 	return true;
15851     }
15852 
15853   enum_type_decl::enumerators::const_iterator i, j;
15854   for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
15855        i != l.get_enumerators().end() && j != r.get_enumerators().end();
15856        ++i, ++j)
15857     if (*i != *j)
15858       {
15859 	result = true;
15860 	if (k)
15861 	  {
15862 	    *k |= LOCAL_TYPE_CHANGE_KIND;
15863 	    break;
15864 	  }
15865 	else
15866 	  return true;
15867       }
15868 
15869   if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
15870     {
15871       result = true;
15872       if (k)
15873 	*k |= LOCAL_TYPE_CHANGE_KIND;
15874       else
15875 	return true;
15876     }
15877 
15878   enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
15879   interned_string qn_r = l.get_environment()->intern(r.get_qualified_name());
15880   interned_string qn_l = l.get_environment()->intern(l.get_qualified_name());
15881   string n_l = l.get_name();
15882   string n_r = r.get_name();
15883   local_r.set_qualified_name(qn_l);
15884   local_r.set_name(n_l);
15885 
15886   if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
15887     {
15888       result = true;
15889       if (k)
15890 	{
15891 	  if (!l.decl_base::operator==(r))
15892 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
15893 	  if (!l.type_base::operator==(r))
15894 	    *k |= LOCAL_TYPE_CHANGE_KIND;
15895 	}
15896       else
15897 	{
15898 	  local_r.set_name(n_r);
15899 	  local_r.set_qualified_name(qn_r);
15900 	  return true;
15901 	}
15902     }
15903   local_r.set_qualified_name(qn_r);
15904   local_r.set_name(n_r);
15905 
15906   return result;
15907 }
15908 
15909 /// Compares two instances of @ref enum_type_decl.
15910 ///
15911 /// If the two intances are different, set a bitfield to give some
15912 /// insight about the kind of differences there are.
15913 ///
15914 /// @param l the first artifact of the comparison.
15915 ///
15916 /// @param r the second artifact of the comparison.
15917 ///
15918 /// @param k a pointer to a bitfield that gives information about the
15919 /// kind of changes there are between @p l and @p r.  This one is set
15920 /// iff @p k is non-null and the function returns false.
15921 ///
15922 /// Please note that setting k to a non-null value does have a
15923 /// negative performance impact because even if @p l and @p r are not
15924 /// equal, the function keeps up the comparison in order to determine
15925 /// the different kinds of ways in which they are different.
15926 ///
15927 /// @return true if @p l equals @p r, false otherwise.
15928 bool
equals(const enum_type_decl & l,const enum_type_decl & r,change_kind * k)15929 equals(const enum_type_decl& l, const enum_type_decl& r, change_kind* k)
15930 {
15931   bool result = true;
15932   if (*l.get_underlying_type() != *r.get_underlying_type())
15933     {
15934       result = false;
15935       if (k)
15936 	*k |= SUBTYPE_CHANGE_KIND;
15937       else
15938 	return false;
15939     }
15940 
15941   enum_type_decl::enumerators::const_iterator i, j;
15942   for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
15943        i != l.get_enumerators().end() && j != r.get_enumerators().end();
15944        ++i, ++j)
15945     if (*i != *j)
15946       {
15947 	result = false;
15948 	if (k)
15949 	  {
15950 	    *k |= LOCAL_TYPE_CHANGE_KIND;
15951 	    break;
15952 	  }
15953 	else
15954 	  return false;
15955       }
15956 
15957   if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
15958     {
15959       result = false;
15960       if (k)
15961 	*k |= LOCAL_TYPE_CHANGE_KIND;
15962       else
15963 	return false;
15964     }
15965 
15966   if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
15967     {
15968       result = false;
15969       if (k)
15970 	{
15971 	  if (!l.decl_base::operator==(r))
15972 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
15973 	  if (!l.type_base::operator==(r))
15974 	    *k |= LOCAL_TYPE_CHANGE_KIND;
15975 	}
15976       else
15977 	return false;
15978     }
15979 
15980   return result;
15981 }
15982 
15983 /// Equality operator.
15984 ///
15985 /// @param o the other enum to test against.
15986 ///
15987 /// @return true iff @p o equals the current instance of enum type
15988 /// decl.
15989 bool
operator ==(const decl_base & o) const15990 enum_type_decl::operator==(const decl_base& o) const
15991 {
15992   const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
15993   if (!op)
15994     return false;
15995   return try_canonical_compare(this, op);
15996 }
15997 
15998 /// Equality operator.
15999 ///
16000 /// @param o the other enum to test against.
16001 ///
16002 /// @return true iff @p o is equals the current instance of enum type
16003 /// decl.
16004 bool
operator ==(const type_base & o) const16005 enum_type_decl::operator==(const type_base& o) const
16006 {
16007   const decl_base* other = dynamic_cast<const decl_base*>(&o);
16008   if (!other)
16009     return false;
16010   return *this == *other;
16011 }
16012 
16013 /// Equality operator for @ref enum_type_decl_sptr.
16014 ///
16015 /// @param l the first operand to compare.
16016 ///
16017 /// @param r the second operand to compare.
16018 ///
16019 /// @return true iff @p l equals @p r.
16020 bool
operator ==(const enum_type_decl_sptr & l,const enum_type_decl_sptr & r)16021 operator==(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
16022 {
16023   if (!!l != !!r)
16024     return false;
16025   if (l.get() == r.get())
16026     return true;
16027   decl_base_sptr o = r;
16028   return *l == *o;
16029 }
16030 
16031 /// Inequality operator for @ref enum_type_decl_sptr.
16032 ///
16033 /// @param l the first operand to compare.
16034 ///
16035 /// @param r the second operand to compare.
16036 ///
16037 /// @return true iff @p l equals @p r.
16038 bool
operator !=(const enum_type_decl_sptr & l,const enum_type_decl_sptr & r)16039 operator!=(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
16040 {return !operator==(l, r);}
16041 
16042 /// The type of the private data of an @ref
16043 /// enum_type_decl::enumerator.
16044 class enum_type_decl::enumerator::priv
16045 {
16046   const environment*	env_;
16047   interned_string	name_;
16048   int64_t		value_;
16049   interned_string	qualified_name_;
16050   enum_type_decl*	enum_type_;
16051 
16052   friend class	enum_type_decl::enumerator;
16053 
16054 public:
16055 
priv()16056   priv()
16057     : env_(),
16058       enum_type_()
16059   {}
16060 
priv(const environment * env,const string & name,int64_t value,enum_type_decl * e=0)16061   priv(const environment* env,
16062        const string& name,
16063        int64_t value,
16064        enum_type_decl* e = 0)
16065     : env_(env),
16066       name_(env ? env->intern(name) : interned_string()),
16067       value_(value),
16068       enum_type_(e)
16069   {}
16070 }; // end class enum_type_def::enumerator::priv
16071 
16072 /// Default constructor of the @ref enum_type_decl::enumerator type.
enumerator()16073 enum_type_decl::enumerator::enumerator()
16074   : priv_(new priv)
16075 {}
16076 
16077 /// Constructor of the @ref enum_type_decl::enumerator type.
16078 ///
16079 /// @param env the environment we are operating from.
16080 ///
16081 /// @param name the name of the enumerator.
16082 ///
16083 /// @param value the value of the enumerator.
enumerator(const environment * env,const string & name,int64_t value)16084 enum_type_decl::enumerator::enumerator(const environment* env,
16085 				       const string& name,
16086 				       int64_t value)
16087   : priv_(new priv(env, name, value))
16088 {}
16089 
16090 /// Copy constructor of the @ref enum_type_decl::enumerator type.
16091 ///
16092 /// @param other enumerator to copy.
enumerator(const enumerator & other)16093 enum_type_decl::enumerator::enumerator(const enumerator& other)
16094   : priv_(new priv(other.get_environment(),
16095 		   other.get_name(),
16096 		   other.get_value(),
16097 		   other.get_enum_type()))
16098 {}
16099 
16100 /// Assignment operator of the @ref enum_type_decl::enumerator type.
16101 ///
16102 /// @param o
16103 enum_type_decl::enumerator&
operator =(const enumerator & o)16104 enum_type_decl::enumerator::operator=(const enumerator& o)
16105 {
16106   priv_->env_ = o.get_environment();
16107   priv_->name_ = o.get_name();
16108   priv_->value_ = o.get_value();
16109   priv_->enum_type_ = o.get_enum_type();
16110   return *this;
16111 }
16112 /// Equality operator
16113 ///
16114 /// @param other the enumerator to compare to the current instance of
16115 /// enum_type_decl::enumerator.
16116 ///
16117 /// @return true if @p other equals the current instance of
16118 /// enum_type_decl::enumerator.
16119 bool
operator ==(const enumerator & other) const16120 enum_type_decl::enumerator::operator==(const enumerator& other) const
16121 {return (get_name() == other.get_name()
16122 	 && get_value() == other.get_value());}
16123 
16124 /// Inequality operator.
16125 ///
16126 /// @param other the other instance to compare against.
16127 ///
16128 /// @return true iff @p other is different from the current instance.
16129 bool
operator !=(const enumerator & other) const16130 enum_type_decl::enumerator::operator!=(const enumerator& other) const
16131 {return !operator==(other);}
16132 
16133 /// Getter of the environment of this enumerator.
16134 ///
16135 /// @return the environment of this enumerator.
16136 const environment*
get_environment() const16137 enum_type_decl::enumerator::get_environment() const
16138 {return priv_->env_;}
16139 
16140 /// Getter for the name of the current instance of
16141 /// enum_type_decl::enumerator.
16142 ///
16143 /// @return a reference to the name of the current instance of
16144 /// enum_type_decl::enumerator.
16145 const interned_string&
get_name() const16146 enum_type_decl::enumerator::get_name() const
16147 {return priv_->name_;}
16148 
16149 /// Getter for the qualified name of the current instance of
16150 /// enum_type_decl::enumerator.  The first invocation of the method
16151 /// builds the qualified name, caches it and return a reference to the
16152 /// cached qualified name.  Subsequent invocations just return the
16153 /// cached value.
16154 ///
16155 /// @param internal set to true if the call is intended for an
16156 /// internal use (for technical use inside the library itself), false
16157 /// otherwise.  If you don't know what this is for, then set it to
16158 /// false.
16159 ///
16160 /// @return the qualified name of the current instance of
16161 /// enum_type_decl::enumerator.
16162 const interned_string&
get_qualified_name(bool internal) const16163 enum_type_decl::enumerator::get_qualified_name(bool internal) const
16164 {
16165   if (priv_->qualified_name_.empty())
16166     {
16167       const environment* env = priv_->enum_type_->get_environment();
16168       ABG_ASSERT(env);
16169       priv_->qualified_name_ =
16170 	env->intern(get_enum_type()->get_qualified_name(internal)
16171 		    + "::"
16172 		    + get_name());
16173     }
16174   return priv_->qualified_name_;
16175 }
16176 
16177 /// Setter for the name of @ref enum_type_decl::enumerator.
16178 ///
16179 /// @param n the new name.
16180 void
set_name(const string & n)16181 enum_type_decl::enumerator::set_name(const string& n)
16182 {
16183   const environment* env = get_environment();
16184   ABG_ASSERT(env);
16185   priv_->name_ = env->intern(n);
16186 }
16187 
16188 /// Getter for the value of @ref enum_type_decl::enumerator.
16189 ///
16190 /// @return the value of the current instance of
16191 /// enum_type_decl::enumerator.
16192 int64_t
get_value() const16193 enum_type_decl::enumerator::get_value() const
16194 {return priv_->value_;}
16195 
16196 /// Setter for the value of @ref enum_type_decl::enumerator.
16197 ///
16198 /// @param v the new value of the enum_type_decl::enumerator.
16199 void
set_value(int64_t v)16200 enum_type_decl::enumerator::set_value(int64_t v)
16201 {priv_->value_= v;}
16202 
16203 /// Getter for the enum type that this enumerator is for.
16204 ///
16205 /// @return the enum type that this enumerator is for.
16206 enum_type_decl*
get_enum_type() const16207 enum_type_decl::enumerator::get_enum_type() const
16208 {return priv_->enum_type_;}
16209 
16210 /// Setter for the enum type that this enumerator is for.
16211 ///
16212 /// @param e the new enum type.
16213 void
set_enum_type(enum_type_decl * e)16214 enum_type_decl::enumerator::set_enum_type(enum_type_decl* e)
16215 {priv_->enum_type_ = e;}
16216 // </enum_type_decl definitions>
16217 
16218 // <typedef_decl definitions>
16219 
16220 /// Private data structure of the @ref typedef_decl.
16221 struct typedef_decl::priv
16222 {
16223   type_base_wptr	underlying_type_;
16224   string		internal_qualified_name_;
16225   string		temp_internal_qualified_name_;
16226 
privabigail::ir::typedef_decl::priv16227   priv(const type_base_sptr& t)
16228     : underlying_type_(t)
16229   {}
16230 }; // end struct typedef_decl::priv
16231 
16232 /// Constructor of the typedef_decl type.
16233 ///
16234 /// @param name the name of the typedef.
16235 ///
16236 /// @param underlying_type the underlying type of the typedef.
16237 ///
16238 /// @param locus the source location of the typedef declaration.
16239 ///
16240 /// @param linkage_name the mangled name of the typedef.
16241 ///
16242 /// @param vis the visibility of the typedef type.
typedef_decl(const string & name,const type_base_sptr underlying_type,const location & locus,const string & linkage_name,visibility vis)16243 typedef_decl::typedef_decl(const string&		name,
16244 			   const type_base_sptr	underlying_type,
16245 			   const location&		locus,
16246 			   const string&		linkage_name,
16247 			   visibility vis)
16248   : type_or_decl_base(underlying_type->get_environment(),
16249 		      TYPEDEF_TYPE
16250 		      | ABSTRACT_TYPE_BASE
16251 		      | ABSTRACT_DECL_BASE),
16252     type_base(underlying_type->get_environment(),
16253 	      underlying_type->get_size_in_bits(),
16254 	      underlying_type->get_alignment_in_bits()),
16255     decl_base(underlying_type->get_environment(),
16256 	      name, locus, linkage_name, vis),
16257     priv_(new priv(underlying_type))
16258 {
16259   runtime_type_instance(this);
16260 }
16261 
16262 /// Return the size of the typedef.
16263 ///
16264 /// This function looks at the size of the underlying type and ensures
16265 /// that it's the same as the size of the typedef.
16266 ///
16267 /// @return the size of the typedef.
16268 size_t
get_size_in_bits() const16269 typedef_decl::get_size_in_bits() const
16270 {
16271   size_t s = get_underlying_type()->get_size_in_bits();
16272   if (s != type_base::get_size_in_bits())
16273     const_cast<typedef_decl*>(this)->set_size_in_bits(s);
16274   return type_base::get_size_in_bits();
16275 }
16276 
16277 /// Return the alignment of the typedef.
16278 ///
16279 /// This function looks at the alignment of the underlying type and
16280 /// ensures that it's the same as the alignment of the typedef.
16281 ///
16282 /// @return the size of the typedef.
16283 size_t
get_alignment_in_bits() const16284 typedef_decl::get_alignment_in_bits() const
16285 {
16286     size_t s = get_underlying_type()->get_alignment_in_bits();
16287   if (s != type_base::get_alignment_in_bits())
16288     const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
16289   return type_base::get_alignment_in_bits();
16290 }
16291 
16292 /// Compares two instances of @ref typedef_decl.
16293 ///
16294 /// If the two intances are different, set a bitfield to give some
16295 /// insight about the kind of differences there are.
16296 ///
16297 /// @param l the first artifact of the comparison.
16298 ///
16299 /// @param r the second artifact of the comparison.
16300 ///
16301 /// @param k a pointer to a bitfield that gives information about the
16302 /// kind of changes there are between @p l and @p r.  This one is set
16303 /// iff @p k is non-null and the function returns false.
16304 ///
16305 /// Please note that setting k to a non-null value does have a
16306 /// negative performance impact because even if @p l and @p r are not
16307 /// equal, the function keeps up the comparison in order to determine
16308 /// the different kinds of ways in which they are different.
16309 ///
16310 /// @return true if @p l equals @p r, false otherwise.
16311 bool
equals(const typedef_decl & l,const typedef_decl & r,change_kind * k)16312 equals(const typedef_decl& l, const typedef_decl& r, change_kind* k)
16313 {
16314   bool result = true;
16315   // Compare the properties of the 'is-a-member-decl" relation of this
16316   // decl.  For typedefs of a C program, this always return true as
16317   // there is no "member typedef type" in C.
16318   //
16319   // In other words, in C, Only the underlying types of typedefs are
16320   // compared.  In C++ however, the properties of the
16321   // 'is-a-member-decl' relation of the typedef are compared.
16322   if (!maybe_compare_as_member_decls(l, r, k))
16323     {
16324       result = false;
16325       if (k)
16326 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
16327       else
16328 	return false;
16329     }
16330 
16331   if (*l.get_underlying_type() != *r.get_underlying_type())
16332     {
16333       // Changes to the underlying type of a typedef are considered
16334       // local, a bit like for pointers.
16335       result = false;
16336       if (k)
16337 	*k |= LOCAL_TYPE_CHANGE_KIND;
16338       else
16339 	return false;
16340     }
16341 
16342   return result;
16343 }
16344 
16345 /// Equality operator
16346 ///
16347 /// @param o the other typedef_decl to test against.
16348 bool
operator ==(const decl_base & o) const16349 typedef_decl::operator==(const decl_base& o) const
16350 {
16351   const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
16352   if (!other)
16353     return false;
16354   return try_canonical_compare(this, other);
16355 }
16356 
16357 /// Equality operator
16358 ///
16359 /// @param o the other typedef_decl to test against.
16360 ///
16361 /// @return true if the current instance of @ref typedef_decl equals
16362 /// @p o.
16363 bool
operator ==(const type_base & o) const16364 typedef_decl::operator==(const type_base& o) const
16365 {
16366   const decl_base* other = dynamic_cast<const decl_base*>(&o);
16367   if (!other)
16368     return false;
16369   return *this == *other;
16370 }
16371 
16372 /// Build a pretty representation for a typedef_decl.
16373 ///
16374 /// @param internal set to true if the call is intended for an
16375 /// internal use (for technical use inside the library itself), false
16376 /// otherwise.  If you don't know what this is for, then set it to
16377 /// false.
16378 ///
16379 /// @param qualified_name if true, names emitted in the pretty
16380 /// representation are fully qualified.
16381 ///
16382 /// @return a copy of the pretty representation of the current
16383 /// instance of typedef_decl.
16384 string
get_pretty_representation(bool internal,bool qualified_name) const16385 typedef_decl::get_pretty_representation(bool internal,
16386 					bool qualified_name) const
16387 {
16388 
16389   string result = "typedef ";
16390   if (qualified_name)
16391     result += get_qualified_name(internal);
16392   else
16393     result += get_name();
16394 
16395   return result;
16396 }
16397 
16398 /// Getter of the underlying type of the typedef.
16399 ///
16400 /// @return the underlying_type.
16401 type_base_sptr
get_underlying_type() const16402 typedef_decl::get_underlying_type() const
16403 {return priv_->underlying_type_.lock();}
16404 
16405 /// Setter ofthe underlying type of the typedef.
16406 ///
16407 /// @param t the new underlying type of the typedef.
16408 void
set_underlying_type(const type_base_sptr & t)16409 typedef_decl::set_underlying_type(const type_base_sptr& t)
16410 {priv_->underlying_type_ = t;}
16411 
16412 /// This implements the ir_traversable_base::traverse pure virtual
16413 /// function.
16414 ///
16415 /// @param v the visitor used on the current instance.
16416 ///
16417 /// @return true if the entire IR node tree got traversed, false
16418 /// otherwise.
16419 bool
traverse(ir_node_visitor & v)16420 typedef_decl::traverse(ir_node_visitor& v)
16421 {
16422   if (v.type_node_has_been_visited(this))
16423     return true;
16424 
16425   if (visiting())
16426     return true;
16427 
16428   if (v.visit_begin(this))
16429     {
16430       visiting(true);
16431       if (type_base_sptr t = get_underlying_type())
16432 	t->traverse(v);
16433       visiting(false);
16434     }
16435 
16436   bool result = v.visit_end(this);
16437   v.mark_type_node_as_visited(this);
16438   return result;
16439 }
16440 
~typedef_decl()16441 typedef_decl::~typedef_decl()
16442 {}
16443 // </typedef_decl definitions>
16444 
16445 // <var_decl definitions>
16446 
16447 struct var_decl::priv
16448 {
16449   type_base_wptr	type_;
16450   type_base*		naked_type_;
16451   decl_base::binding	binding_;
16452   elf_symbol_sptr	symbol_;
16453   interned_string	id_;
16454 
privabigail::ir::var_decl::priv16455   priv()
16456     : naked_type_(),
16457     binding_(decl_base::BINDING_GLOBAL)
16458   {}
16459 
privabigail::ir::var_decl::priv16460   priv(type_base_sptr t,
16461        decl_base::binding b)
16462     : type_(t),
16463       naked_type_(t.get()),
16464       binding_(b)
16465   {}
16466 }; // end struct var_decl::priv
16467 
16468 /// Constructor
16469 ///
16470 /// @param name the name of the variable declaration
16471 ///
16472 /// @param name the type of the variable declaration
16473 ///
16474 /// @param locus the source location where the variable was defined.
16475 ///
16476 /// @param linkage_name the linkage name of the variable.
16477 ///
16478 /// @param vis the visibility of of the variable.
16479 ///
16480 /// @param bind the binding kind of the variable.
var_decl(const string & name,type_base_sptr type,const location & locus,const string & linkage_name,visibility vis,binding bind)16481 var_decl::var_decl(const string&	name,
16482 		   type_base_sptr	type,
16483 		   const location&	locus,
16484 		   const string&	linkage_name,
16485 		   visibility		vis,
16486 		   binding		bind)
16487   : type_or_decl_base(type->get_environment(),
16488 		      VAR_DECL | ABSTRACT_DECL_BASE),
16489     decl_base(type->get_environment(), name, locus, linkage_name, vis),
16490     priv_(new priv(type, bind))
16491 {
16492   runtime_type_instance(this);
16493 }
16494 
16495 /// Getter of the type of the variable.
16496 ///
16497 /// @return the type of the variable.
16498 const type_base_sptr
get_type() const16499 var_decl::get_type() const
16500 {return priv_->type_.lock();}
16501 
16502 /// Getter of the type of the variable.
16503 ///
16504 /// This getter returns a bare pointer, as opposed to a smart pointer.
16505 /// It's to be used on performance sensitive code paths identified by
16506 /// careful profiling.
16507 ///
16508 /// @return the type of the variable, as a bare pointer.
16509 const type_base*
get_naked_type() const16510 var_decl::get_naked_type() const
16511 {return priv_->naked_type_;}
16512 
16513 /// Getter of the binding of the variable.
16514 ///
16515 /// @return the biding of the variable.
16516 decl_base::binding
get_binding() const16517 var_decl::get_binding() const
16518 {return priv_->binding_;}
16519 
16520 /// Setter of the binding of the variable.
16521 ///
16522 /// @param b the new binding value.
16523 void
set_binding(decl_base::binding b)16524 var_decl::set_binding(decl_base::binding b)
16525 {priv_->binding_ = b;}
16526 
16527 /// Sets the underlying ELF symbol for the current variable.
16528 ///
16529 /// And underlyin$g ELF symbol for the current variable might exist
16530 /// only if the corpus that this variable originates from was
16531 /// constructed from an ELF binary file.
16532 ///
16533 /// Note that comparing two variables that have underlying ELF symbols
16534 /// involves comparing their underlying elf symbols.  The decl name
16535 /// for the variable thus becomes irrelevant in the comparison.
16536 ///
16537 /// @param sym the new ELF symbol for this variable decl.
16538 void
set_symbol(const elf_symbol_sptr & sym)16539 var_decl::set_symbol(const elf_symbol_sptr& sym)
16540 {
16541   priv_->symbol_ = sym;
16542   // The variable id cache that depends on the symbol must be
16543   // invalidated because the symbol changed.
16544   priv_->id_ = get_environment()->intern("");
16545 }
16546 
16547 /// Gets the the underlying ELF symbol for the current variable,
16548 /// that was set using var_decl::set_symbol().  Please read the
16549 /// documentation for that member function for more information about
16550 /// "underlying ELF symbols".
16551 ///
16552 /// @return sym the underlying ELF symbol for this variable decl, if
16553 /// one exists.
16554 const elf_symbol_sptr&
get_symbol() const16555 var_decl::get_symbol() const
16556 {return priv_->symbol_;}
16557 
16558 /// Create a new var_decl that is a clone of the current one.
16559 ///
16560 /// @return the cloned var_decl.
16561 var_decl_sptr
clone() const16562 var_decl::clone() const
16563 {
16564   var_decl_sptr v(new var_decl(get_name(),
16565 			       get_type(),
16566 			       get_location(),
16567 			       get_linkage_name(),
16568 			       get_visibility(),
16569 			       get_binding()));
16570 
16571   v->set_symbol(get_symbol());
16572 
16573   if (is_member_decl(*this))
16574     {
16575       class_decl* scope = dynamic_cast<class_decl*>(get_scope());
16576       scope->add_data_member(v, get_member_access_specifier(*this),
16577 			     get_data_member_is_laid_out(*this),
16578 			     get_member_is_static(*this),
16579 			     get_data_member_offset(*this));
16580     }
16581   else
16582     add_decl_to_scope(v, get_scope());
16583 
16584   return v;
16585 }
16586 /// Setter of the scope of the current var_decl.
16587 ///
16588 /// Note that the decl won't hold a reference on the scope.  It's
16589 /// rather the scope that holds a reference on its members.
16590 ///
16591 /// @param scope the new scope.
16592 void
set_scope(scope_decl * scope)16593 var_decl::set_scope(scope_decl* scope)
16594 {
16595   if (!get_context_rel())
16596     set_context_rel(new dm_context_rel(scope));
16597   else
16598     get_context_rel()->set_scope(scope);
16599 }
16600 
16601 /// Compares two instances of @ref var_decl.
16602 ///
16603 /// If the two intances are different, set a bitfield to give some
16604 /// insight about the kind of differences there are.
16605 ///
16606 /// @param l the first artifact of the comparison.
16607 ///
16608 /// @param r the second artifact of the comparison.
16609 ///
16610 /// @param k a pointer to a bitfield that gives information about the
16611 /// kind of changes there are between @p l and @p r.  This one is set
16612 /// iff @p k is non-null and the function returns false.
16613 ///
16614 /// Please note that setting k to a non-null value does have a
16615 /// negative performance impact because even if @p l and @p r are not
16616 /// equal, the function keeps up the comparison in order to determine
16617 /// the different kinds of ways in which they are different.
16618 ///
16619 /// @return true if @p l equals @p r, false otherwise.
16620 bool
equals(const var_decl & l,const var_decl & r,change_kind * k)16621 equals(const var_decl& l, const var_decl& r, change_kind* k)
16622 {
16623   bool result = true;
16624 
16625   // First test types of variables.  This should be fast because in
16626   // the general case, most types should be canonicalized.
16627   if (*l.get_naked_type() != *r.get_naked_type())
16628     {
16629       result = false;
16630       if (k)
16631 	{
16632 	  if (!types_have_similar_structure(l.get_naked_type(),
16633 					   r.get_naked_type()))
16634 	    *k |= (LOCAL_TYPE_CHANGE_KIND);
16635 	  else
16636 	    *k |= SUBTYPE_CHANGE_KIND;
16637 	}
16638       else
16639 	return false;
16640     }
16641 
16642   // If there are underlying elf symbols for these variables,
16643   // compare them.  And then compare the other parts.
16644   const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
16645   if (!!s0 != !!s1)
16646     {
16647       result = false;
16648       if (k)
16649 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
16650       else
16651 	return false;
16652     }
16653   else if (s0 && s0 != s1)
16654     {
16655       result = false;
16656       if (k)
16657 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
16658       else
16659 	return false;
16660     }
16661   bool symbols_are_equal = (s0 && s1 && result);
16662 
16663   if (symbols_are_equal)
16664     {
16665       // The variables have underlying elf symbols that are equal, so
16666       // now, let's compare the decl_base part of the variables w/o
16667       // considering their decl names.
16668       const interned_string &n1 = l.get_name(), &n2 = r.get_name();
16669       const_cast<var_decl&>(l).set_name("");
16670       const_cast<var_decl&>(r).set_name("");
16671       bool decl_bases_different = !l.decl_base::operator==(r);
16672       const_cast<var_decl&>(l).set_name(n1);
16673       const_cast<var_decl&>(r).set_name(n2);
16674 
16675       if (decl_bases_different)
16676 	{
16677 	  result = false;
16678 	  if (k)
16679 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
16680 	  else
16681 	    return false;
16682 	}
16683     }
16684   else
16685     if (!l.decl_base::operator==(r))
16686       {
16687 	result = false;
16688 	if (k)
16689 	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
16690 	else
16691 	  return false;
16692       }
16693 
16694   const dm_context_rel* c0 =
16695     dynamic_cast<const dm_context_rel*>(l.get_context_rel());
16696   const dm_context_rel* c1 =
16697     dynamic_cast<const dm_context_rel*>(r.get_context_rel());
16698   ABG_ASSERT(c0 && c1);
16699 
16700   if (*c0 != *c1)
16701     {
16702       result = false;
16703       if (k)
16704 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
16705       else
16706 	return false;
16707     }
16708 
16709   return result;
16710 }
16711 
16712 /// Comparison operator of @ref var_decl.
16713 ///
16714 /// @param o the instance of @ref var_decl to compare against.
16715 ///
16716 /// @return true iff the current instance of @ref var_decl equals @p o.
16717 bool
operator ==(const decl_base & o) const16718 var_decl::operator==(const decl_base& o) const
16719 {
16720   const var_decl* other = dynamic_cast<const var_decl*>(&o);
16721   if (!other)
16722     return false;
16723 
16724   return equals(*this, *other, 0);
16725 }
16726 
16727 /// Return an ID that tries to uniquely identify the variable inside a
16728 /// program or a library.
16729 ///
16730 /// So if the variable has an underlying elf symbol, the ID is the
16731 /// concatenation of the symbol name and its version.  Otherwise, the
16732 /// ID is the linkage name if its non-null.  Otherwise, it's the
16733 /// pretty representation of the variable.
16734 ///
16735 /// @return the ID.
16736 interned_string
get_id() const16737 var_decl::get_id() const
16738 {
16739   if (priv_->id_.empty())
16740     {
16741       string repr = get_name();
16742       string sym_str;
16743       if (elf_symbol_sptr s = get_symbol())
16744 	sym_str = s->get_id_string();
16745       else if (!get_linkage_name().empty())
16746 	sym_str = get_linkage_name();
16747       const environment* env = get_type()->get_environment();
16748       ABG_ASSERT(env);
16749       priv_->id_ = env->intern(repr);
16750       if (!sym_str.empty())
16751 	priv_->id_ = env->intern(priv_->id_ + "{" + sym_str + "}");
16752     }
16753   return priv_->id_;
16754 }
16755 
16756 /// Return the hash value for the current instance.
16757 ///
16758 /// @return the hash value.
16759 size_t
get_hash() const16760 var_decl::get_hash() const
16761 {
16762   var_decl::hash hash_var;
16763   return hash_var(this);
16764 }
16765 
16766 /// Get the qualified name of a given variable or data member.
16767 ///
16768 ///
16769 /// Note that if the current instance of @ref var_decl is an anonymous
16770 /// data member, then the qualified name is actually the flat
16771 /// representation (the definition) of the type of the anonymous data
16772 /// member.  We chose the flat representation because otherwise, the
16773 /// name of an *anonymous* data member is empty, by construction, e.g:
16774 ///
16775 ///   struct foo {
16776 ///     int a;
16777 ///     union {
16778 ///       char b;
16779 ///       char c;
16780 ///     }; // <---- this data member is anonymous.
16781 ///     int d;
16782 ///   }
16783 ///
16784 ///   The string returned for the anonymous member here is going to be:
16785 ///
16786 ///     "union {char b; char c}"
16787 ///
16788 /// @param internal if true then this is for a purpose to the library,
16789 /// otherwise, it's for being displayed to users.
16790 ///
16791 /// @return the resulting qualified name.
16792 const interned_string&
get_qualified_name(bool internal) const16793 var_decl::get_qualified_name(bool internal) const
16794 {
16795   if (is_anonymous_data_member(this)
16796       && decl_base::get_qualified_name().empty())
16797     {
16798       // Display the anonymous data member in a way that makes sense.
16799       string r = get_pretty_representation(internal);
16800       set_qualified_name(get_environment()->intern(r));
16801     }
16802 
16803     return decl_base::get_qualified_name(internal);
16804 }
16805 
16806 /// Build and return the pretty representation of this variable.
16807 ///
16808 /// @param internal set to true if the call is intended for an
16809 /// internal use (for technical use inside the library itself), false
16810 /// otherwise.  If you don't know what this is for, then set it to
16811 /// false.
16812 ///
16813 /// @param qualified_name if true, names emitted in the pretty
16814 /// representation are fully qualified.
16815 ///
16816 /// @return a copy of the pretty representation of this variable.
16817 string
get_pretty_representation(bool internal,bool qualified_name) const16818 var_decl::get_pretty_representation(bool internal, bool qualified_name) const
16819 {
16820   string result;
16821 
16822   if (is_member_decl(this) && get_member_is_static(this))
16823     result = "static ";
16824 
16825   // Detect if the current instance of var_decl is a member of
16826   // an anonymous class or union.
16827   bool member_of_anonymous_class = false;
16828   if (class_or_union* scope = is_at_class_scope(this))
16829     if (scope->get_is_anonymous())
16830       member_of_anonymous_class = true;
16831 
16832   if (array_type_def_sptr t = is_array_type(get_type()))
16833     {
16834       string name;
16835       if (member_of_anonymous_class || !qualified_name)
16836 	name = get_name();
16837       else
16838 	name = get_qualified_name(internal);
16839 
16840       result +=
16841 	get_type_declaration(t->get_element_type())->get_qualified_name(internal)
16842 	+ " " + name + t->get_subrange_representation();
16843     }
16844   else
16845     {
16846       if (/*The current var_decl is to be used as an anonymous data
16847 	    member.  */
16848 	  get_name().empty())
16849 	{
16850 	  // Display the anonymous data member in a way that
16851 	  // makes sense.
16852 	  result +=
16853 	    get_class_or_union_flat_representation
16854 	    (is_class_or_union_type(get_type()),
16855 	     "", /*one_line=*/true, internal);
16856 	}
16857       else if (data_member_has_anonymous_type(this))
16858 	{
16859 	  result += get_class_or_union_flat_representation
16860 	    (is_class_or_union_type(get_type()),
16861 	     "", /*one_line=*/true, internal);
16862 	  result += " ";
16863 	  if (member_of_anonymous_class || !qualified_name)
16864 	    // It doesn't make sense to name the member of an
16865 	    // anonymous class or union like:
16866 	    // "__anonymous__::data_member_name".  So let's just use
16867 	    // its non-qualified name.
16868 	    result += get_name();
16869 	  else
16870 	    result += get_qualified_name(internal);
16871 	}
16872       else
16873 	{
16874 	  result +=
16875 	    get_type_declaration(get_type())->get_qualified_name(internal)
16876 	    + " ";
16877 
16878 	  if (member_of_anonymous_class || !qualified_name)
16879 	    // It doesn't make sense to name the member of an
16880 	    // anonymous class or union like:
16881 	    // "__anonymous__::data_member_name".  So let's just use
16882 	    // its non-qualified name.
16883 	    result += get_name();
16884 	  else
16885 	    result += get_qualified_name(internal);
16886 	}
16887     }
16888   return result;
16889 }
16890 
16891 /// Get a name that is valid even for an anonymous data member.
16892 ///
16893 /// If the current @ref var_decl is an anonymous data member, then
16894 /// return its pretty representation. As of now, that pretty
16895 /// representation is actually its flat representation as returned by
16896 /// get_class_or_union_flat_representation().
16897 ///
16898 /// Otherwise, just return the name of the current @ref var_decl.
16899 ///
16900 /// @param qualified if true, return the qualified name.  This doesn't
16901 /// have an effet if the current @ref var_decl represents an anonymous
16902 /// data member.
16903 string
get_anon_dm_reliable_name(bool qualified) const16904 var_decl::get_anon_dm_reliable_name(bool qualified) const
16905 {
16906   string name;
16907   if (is_anonymous_data_member(this))
16908     name = get_pretty_representation(true, qualified);
16909   else
16910     name = get_name();
16911 
16912   return name;
16913 }
16914 
16915 /// This implements the ir_traversable_base::traverse pure virtual
16916 /// function.
16917 ///
16918 /// @param v the visitor used on the current instance.
16919 ///
16920 /// @return true if the entire IR node tree got traversed, false
16921 /// otherwise.
16922 bool
traverse(ir_node_visitor & v)16923 var_decl::traverse(ir_node_visitor& v)
16924 {
16925   if (visiting())
16926     return true;
16927 
16928   if (v.visit_begin(this))
16929     {
16930       visiting(true);
16931       if (type_base_sptr t = get_type())
16932 	t->traverse(v);
16933       visiting(false);
16934     }
16935   return v.visit_end(this);
16936 }
16937 
~var_decl()16938 var_decl::~var_decl()
16939 {}
16940 
16941 // </var_decl definitions>
16942 
16943 // <function_type>
16944 
16945 /// The type of the private data of the @ref function_type type.
16946 struct function_type::priv
16947 {
16948   parameters parms_;
16949   type_base_wptr return_type_;
16950   interned_string cached_name_;
16951   interned_string internal_cached_name_;
16952 
privabigail::ir::function_type::priv16953   priv()
16954   {}
16955 
privabigail::ir::function_type::priv16956   priv(const parameters&	parms,
16957        type_base_sptr		return_type)
16958     : parms_(parms),
16959       return_type_(return_type)
16960   {}
16961 
privabigail::ir::function_type::priv16962   priv(type_base_sptr return_type)
16963     : return_type_(return_type)
16964   {}
16965 
16966   /// Mark a given @ref function_type as being compared.
16967   ///
16968   /// @param type the @ref function_type to mark as being compared.
16969   void
mark_as_being_comparedabigail::ir::function_type::priv16970   mark_as_being_compared(const function_type& type) const
16971   {
16972     const environment* env = type.get_environment();
16973     ABG_ASSERT(env);
16974     env->priv_->fn_types_being_compared_.insert(&type);
16975   }
16976 
16977   /// If a given @ref function_type was marked as being compared, this
16978   /// function unmarks it.
16979   ///
16980   /// @param type the @ref function_type to mark as *NOT* being
16981   /// compared.
16982   void
unmark_as_being_comparedabigail::ir::function_type::priv16983   unmark_as_being_compared(const function_type& type) const
16984   {
16985     const environment* env = type.get_environment();
16986     ABG_ASSERT(env);
16987     env->priv_->fn_types_being_compared_.erase(&type);
16988   }
16989 
16990   /// Tests if a @ref function_type is currently being compared.
16991   ///
16992   /// @param type the function type to take into account.
16993   ///
16994   /// @return true if @p type is being compared.
16995   bool
comparison_startedabigail::ir::function_type::priv16996   comparison_started(const function_type& type) const
16997   {
16998     const environment* env = type.get_environment();
16999     ABG_ASSERT(env);
17000     return env->priv_->fn_types_being_compared_.count(&type);
17001   }
17002 };// end struc function_type::priv
17003 
17004 /// This function is automatically invoked whenever an instance of
17005 /// this type is canonicalized.
17006 ///
17007 /// It's an overload of the virtual type_base::on_canonical_type_set.
17008 ///
17009 /// We put here what is thus meant to be executed only at the point of
17010 /// type canonicalization.
17011 void
on_canonical_type_set()17012 function_type::on_canonical_type_set()
17013 {
17014   priv_->cached_name_.clear();
17015   priv_->internal_cached_name_.clear();
17016 }
17017 
17018 /// The most straightforward constructor for the function_type class.
17019 ///
17020 /// @param return_type the return type of the function type.
17021 ///
17022 /// @param parms the list of parameters of the function type.
17023 /// Stricto sensu, we just need a list of types; we are using a list
17024 /// of parameters (where each parameter also carries the name of the
17025 /// parameter and its source location) to try and provide better
17026 /// diagnostics whenever it makes sense.  If it appears that this
17027 /// wasts too many resources, we can fall back to taking just a
17028 /// vector of types here.
17029 ///
17030 /// @param size_in_bits the size of this type, in bits.
17031 ///
17032 /// @param alignment_in_bits the alignment of this type, in bits.
17033 ///
17034 /// @param size_in_bits the size of this type.
function_type(type_base_sptr return_type,const parameters & parms,size_t size_in_bits,size_t alignment_in_bits)17035 function_type::function_type(type_base_sptr	return_type,
17036 			     const parameters&	parms,
17037 			     size_t		size_in_bits,
17038 			     size_t		alignment_in_bits)
17039   : type_or_decl_base(return_type->get_environment(),
17040 		      FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
17041     type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
17042     priv_(new priv(parms, return_type))
17043 {
17044   runtime_type_instance(this);
17045 
17046   for (parameters::size_type i = 0, j = 1;
17047        i < priv_->parms_.size();
17048        ++i, ++j)
17049     {
17050       if (i == 0 && priv_->parms_[i]->get_is_artificial())
17051 	// If the first parameter is artificial, then it certainly
17052 	// means that this is a member function, and the first
17053 	// parameter is the implicit this pointer.  In that case, set
17054 	// the index of that implicit parameter to zero.  Otherwise,
17055 	// the index of the first parameter starts at one.
17056 	j = 0;
17057       priv_->parms_[i]->set_index(j);
17058     }
17059 }
17060 
17061 /// A constructor for a function_type that takes no parameters.
17062 ///
17063 /// @param return_type the return type of this function_type.
17064 ///
17065 /// @param size_in_bits the size of this type, in bits.
17066 ///
17067 /// @param alignment_in_bits the alignment of this type, in bits.
function_type(type_base_sptr return_type,size_t size_in_bits,size_t alignment_in_bits)17068 function_type::function_type(type_base_sptr return_type,
17069 			     size_t size_in_bits, size_t alignment_in_bits)
17070   : type_or_decl_base(return_type->get_environment(),
17071 		      FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
17072     type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
17073     priv_(new priv(return_type))
17074 {
17075   runtime_type_instance(this);
17076 }
17077 
17078 /// A constructor for a function_type that takes no parameter and
17079 /// that has no return_type yet.  These missing parts can (and must)
17080 /// be added later.
17081 ///
17082 /// @param env the environment we are operating from.
17083 ///
17084 /// @param size_in_bits the size of this type, in bits.
17085 ///
17086 /// @param alignment_in_bits the alignment of this type, in bits.
function_type(const environment * env,size_t size_in_bits,size_t alignment_in_bits)17087 function_type::function_type(const environment* env,
17088 			     size_t		size_in_bits,
17089 			     size_t		alignment_in_bits)
17090   : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
17091     type_base(env, size_in_bits, alignment_in_bits),
17092     priv_(new priv)
17093 {
17094   runtime_type_instance(this);
17095 }
17096 
17097 /// Getter for the return type of the current instance of @ref
17098 /// function_type.
17099 ///
17100 /// @return the return type.
17101 type_base_sptr
get_return_type() const17102 function_type::get_return_type() const
17103 {return priv_->return_type_.lock();}
17104 
17105 /// Setter of the return type of the current instance of @ref
17106 /// function_type.
17107 ///
17108 /// @param t the new return type to set.
17109 void
set_return_type(type_base_sptr t)17110 function_type::set_return_type(type_base_sptr t)
17111 {priv_->return_type_ = t;}
17112 
17113 /// Getter for the set of parameters of the current intance of @ref
17114 /// function_type.
17115 ///
17116 /// @return the parameters of the current instance of @ref
17117 /// function_type.
17118 const function_decl::parameters&
get_parameters() const17119 function_type::get_parameters() const
17120 {return priv_->parms_;}
17121 
17122 /// Get the Ith parameter of the vector of parameters of the current
17123 /// instance of @ref function_type.
17124 ///
17125 /// Note that the first parameter is at index 0.  That parameter is
17126 /// the first parameter that comes after the possible implicit "this"
17127 /// parameter, when the current instance @ref function_type is for a
17128 /// member function.  Otherwise, if the current instance of @ref
17129 /// function_type is for a non-member function, the parameter at index
17130 /// 0 is the first parameter of the function.
17131 ///
17132 ///
17133 /// @param i the index of the parameter to return.  If i is greater
17134 /// than the index of the last parameter, then this function returns
17135 /// an empty parameter (smart) pointer.
17136 ///
17137 /// @return the @p i th parameter that is not implicit.
17138 const function_decl::parameter_sptr
get_parm_at_index_from_first_non_implicit_parm(size_t i) const17139 function_type::get_parm_at_index_from_first_non_implicit_parm(size_t i) const
17140 {
17141   parameter_sptr result;
17142   if (dynamic_cast<const method_type*>(this))
17143     {
17144       if (i + 1 < get_parameters().size())
17145 	result = get_parameters()[i + 1];
17146     }
17147   else
17148     {
17149       if (i < get_parameters().size())
17150 	result = get_parameters()[i];
17151     }
17152   return result;
17153 }
17154 
17155 /// Setter for the parameters of the current instance of @ref
17156 /// function_type.
17157 ///
17158 /// @param p the new vector of parameters to set.
17159 void
set_parameters(const parameters & p)17160 function_type::set_parameters(const parameters &p)
17161 {
17162   priv_->parms_ = p;
17163   for (parameters::size_type i = 0, j = 1;
17164        i < priv_->parms_.size();
17165        ++i, ++j)
17166     {
17167       if (i == 0 && priv_->parms_[i]->get_is_artificial())
17168 	// If the first parameter is artificial, then it certainly
17169 	// means that this is a member function, and the first
17170 	// parameter is the implicit this pointer.  In that case, set
17171 	// the index of that implicit parameter to zero.  Otherwise,
17172 	// the index of the first parameter starts at one.
17173 	j = 0;
17174       priv_->parms_[i]->set_index(j);
17175     }
17176 }
17177 
17178 /// Append a new parameter to the vector of parameters of the current
17179 /// instance of @ref function_type.
17180 ///
17181 /// @param parm the parameter to append.
17182 void
append_parameter(parameter_sptr parm)17183 function_type::append_parameter(parameter_sptr parm)
17184 {
17185   parm->set_index(priv_->parms_.size());
17186   priv_->parms_.push_back(parm);
17187 }
17188 
17189 /// Test if the current instance of @ref function_type is for a
17190 /// variadic function.
17191 ///
17192 /// A variadic function is a function that takes a variable number of
17193 /// arguments.
17194 ///
17195 /// @return true iff the current instance of @ref function_type is for
17196 /// a variadic function.
17197 bool
is_variadic() const17198 function_type::is_variadic() const
17199 {
17200   return (!priv_->parms_.empty()
17201 	 && priv_->parms_.back()->get_variadic_marker());
17202 }
17203 
17204 /// Compare two function types.
17205 ///
17206 /// In case these function types are actually method types, this
17207 /// function avoids comparing two parameters (of the function types)
17208 /// if the types of the parameters are actually the types of the
17209 /// classes of the method types.  This prevents infinite recursion
17210 /// during the comparison of two classes that are structurally
17211 /// identical.
17212 ///
17213 /// This is a subroutine of the equality operator of function_type.
17214 ///
17215 /// @param lhs the first function type to consider
17216 ///
17217 /// @param rhs the second function type to consider
17218 ///
17219 /// @param k a pointer to a bitfield set by the function to give
17220 /// information about the kind of changes carried by @p lhs and @p
17221 /// rhs.  It is set iff @p k is non-null and the function returns
17222 /// false.
17223 ///
17224 /// Please note that setting k to a non-null value does have a
17225 /// negative performance impact because even if @p l and @p r are not
17226 /// equal, the function keeps up the comparison in order to determine
17227 /// the different kinds of ways in which they are different.
17228 ///
17229 ///@return true if lhs == rhs, false otherwise.
17230 bool
equals(const function_type & lhs,const function_type & rhs,change_kind * k)17231 equals(const function_type& lhs,
17232        const function_type& rhs,
17233        change_kind* k)
17234 {
17235 #define RETURN(value)				\
17236   do {						\
17237     lhs.priv_->unmark_as_being_compared(lhs);	\
17238     lhs.priv_->unmark_as_being_compared(rhs);	\
17239     if (value == true)				\
17240       maybe_propagate_canonical_type(lhs, rhs); \
17241     return value;				\
17242   } while(0)
17243 
17244   if (lhs.priv_->comparison_started(lhs)
17245       || lhs.priv_->comparison_started(rhs))
17246     return true;
17247 
17248   lhs.priv_->mark_as_being_compared(lhs);
17249   lhs.priv_->mark_as_being_compared(rhs);
17250 
17251   bool result = true;
17252 
17253   if (!lhs.type_base::operator==(rhs))
17254     {
17255       result = false;
17256       if (k)
17257 	*k |= LOCAL_TYPE_CHANGE_KIND;
17258       else
17259 	RETURN(result);
17260     }
17261 
17262   class_or_union* lhs_class = 0, *rhs_class = 0;
17263   if (const method_type* m = dynamic_cast<const method_type*>(&lhs))
17264     lhs_class = m->get_class_type().get();
17265 
17266   if (const method_type* m = dynamic_cast<const method_type*>(&rhs))
17267     rhs_class = m->get_class_type().get();
17268 
17269   // Compare the names of the class of the method
17270 
17271   if (!!lhs_class != !!rhs_class)
17272     {
17273       result = false;
17274       if (k)
17275 	*k |= LOCAL_TYPE_CHANGE_KIND;
17276       else
17277 	RETURN(result);
17278     }
17279   else if (lhs_class
17280 	   && (lhs_class->get_qualified_name()
17281 	       != rhs_class->get_qualified_name()))
17282     {
17283       result = false;
17284       if (k)
17285 	*k |= LOCAL_TYPE_CHANGE_KIND;
17286       else
17287 	RETURN(result);
17288     }
17289 
17290   // Then compare the return type; Beware if it's t's a class type
17291   // that is the same as the method class name; we can recurse for
17292   // ever in that case.
17293 
17294   decl_base* lhs_return_type_decl =
17295     get_type_declaration(lhs.get_return_type()).get();
17296   decl_base* rhs_return_type_decl =
17297     get_type_declaration(rhs.get_return_type()).get();
17298   bool compare_result_types = true;
17299   string lhs_rt_name = lhs_return_type_decl
17300     ? lhs_return_type_decl->get_qualified_name()
17301     : string();
17302   string rhs_rt_name = rhs_return_type_decl
17303     ? rhs_return_type_decl->get_qualified_name()
17304     : string();
17305 
17306   if ((lhs_class && (lhs_class->get_qualified_name() == lhs_rt_name))
17307       ||
17308       (rhs_class && (rhs_class->get_qualified_name() == rhs_rt_name)))
17309     compare_result_types = false;
17310 
17311   if (compare_result_types)
17312     {
17313       if (lhs.get_return_type() != rhs.get_return_type())
17314 	{
17315 	  result = false;
17316 	  if (k)
17317 	    {
17318 	      if (!types_have_similar_structure(lhs.get_return_type(),
17319 						rhs.get_return_type()))
17320 		*k |= LOCAL_TYPE_CHANGE_KIND;
17321 	      else
17322 		*k |= SUBTYPE_CHANGE_KIND;
17323 	    }
17324 	  else
17325 	    RETURN(result);
17326 	}
17327     }
17328   else
17329     if (lhs_rt_name != rhs_rt_name)
17330       {
17331 	result = false;
17332 	if (k)
17333 	  *k |= SUBTYPE_CHANGE_KIND;
17334 	else
17335 	  RETURN(result);
17336       }
17337 
17338   vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
17339   for (i = lhs.get_first_parm(), j = rhs.get_first_parm();
17340        i != lhs.get_parameters().end() && j != rhs.get_parameters().end();
17341        ++i, ++j)
17342     {
17343       if (**i != **j)
17344 	{
17345 	  result = false;
17346 	  if (k)
17347 	    {
17348 	      if (!types_have_similar_structure((*i)->get_type(),
17349 						(*j)->get_type()))
17350 		*k |= LOCAL_TYPE_CHANGE_KIND;
17351 	      else
17352 		*k |= SUBTYPE_CHANGE_KIND;
17353 	    }
17354 	  else
17355 	    RETURN(result);
17356 	}
17357     }
17358 
17359   if ((i != lhs.get_parameters().end()
17360        || j != rhs.get_parameters().end()))
17361     {
17362       result = false;
17363       if (k)
17364 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
17365       else
17366 	RETURN(result);
17367     }
17368 
17369   RETURN(result);
17370 #undef RETURN
17371 }
17372 
17373 /// Get the first parameter of the function.
17374 ///
17375 /// If the function is a non-static member function, the parameter
17376 /// returned is the first one following the implicit 'this' parameter.
17377 ///
17378 /// @return the first non implicit parameter of the function.
17379 function_type::parameters::const_iterator
get_first_non_implicit_parm() const17380 function_type::get_first_non_implicit_parm() const
17381 {
17382   if (get_parameters().empty())
17383     return get_parameters().end();
17384 
17385   bool is_method = dynamic_cast<const method_type*>(this);
17386 
17387   parameters::const_iterator i = get_parameters().begin();
17388 
17389   if (is_method)
17390     ++i;
17391 
17392   return i;
17393 }
17394 
17395 /// Get the first parameter of the function.
17396 ///
17397 /// Note that if the function is a non-static member function, the
17398 /// parameter returned is the implicit 'this' parameter.
17399 ///
17400 /// @return the first parameter of the function.
17401 function_type::parameters::const_iterator
get_first_parm() const17402 function_type::get_first_parm() const
17403 {return get_parameters().begin();}
17404 
17405 /// Get the name of the current @ref function_type.
17406 ///
17407 /// The name is retrieved from a cache.  If the cache is empty, this
17408 /// function computes the name of the type, stores it in the cache and
17409 /// returns it.  Subsequent invocation of the function are going to
17410 /// just hit the cache.
17411 ///
17412 /// Note that if the type is *NOT* canonicalized then function type
17413 /// name is never cached.
17414 ///
17415 /// @param internal if true then it means the function type name is
17416 /// going to be used for purposes that are internal to libabigail
17417 /// itself.  If you don't know what this is then you probably should
17418 /// set this parameter to 'false'.
17419 ///
17420 /// @return the name of the function type.
17421 const interned_string&
get_cached_name(bool internal) const17422 function_type::get_cached_name(bool internal) const
17423 {
17424   if (internal)
17425     {
17426       if (!get_naked_canonical_type() || priv_->internal_cached_name_.empty())
17427 	priv_->internal_cached_name_ = get_function_type_name(this, internal);
17428 
17429       return priv_->internal_cached_name_;
17430     }
17431 
17432   if (!get_naked_canonical_type() || priv_->cached_name_.empty())
17433     priv_->cached_name_ = get_function_type_name(this, internal);
17434 
17435   return priv_->cached_name_;
17436 }
17437 
17438 /// Equality operator for function_type.
17439 ///
17440 /// @param o the other function_type to compare against.
17441 ///
17442 /// @return true iff the two function_type are equal.
17443 bool
operator ==(const type_base & other) const17444 function_type::operator==(const type_base& other) const
17445 {
17446   const function_type* o = dynamic_cast<const function_type*>(&other);
17447   if (!o)
17448     return false;
17449   return try_canonical_compare(this, o);
17450 }
17451 
17452 /// Return a copy of the pretty representation of the current @ref
17453 /// function_type.
17454 ///
17455 /// @param internal set to true if the call is intended for an
17456 /// internal use (for technical use inside the library itself), false
17457 /// otherwise.  If you don't know what this is for, then set it to
17458 /// false.
17459 ///
17460 /// @return a copy of the pretty representation of the current @ref
17461 /// function_type.
17462 string
get_pretty_representation(bool internal,bool) const17463 function_type::get_pretty_representation(bool internal,
17464 					 bool /*qualified_name*/) const
17465 {return ir::get_pretty_representation(this, internal);}
17466 
17467 /// Traverses an instance of @ref function_type, visiting all the
17468 /// sub-types and decls that it might contain.
17469 ///
17470 /// @param v the visitor that is used to visit every IR sub-node of
17471 /// the current node.
17472 ///
17473 /// @return true if either
17474 ///  - all the children nodes of the current IR node were traversed
17475 ///    and the calling code should keep going with the traversing.
17476 ///  - or the current IR node is already being traversed.
17477 /// Otherwise, returning false means that the calling code should not
17478 /// keep traversing the tree.
17479 bool
traverse(ir_node_visitor & v)17480 function_type::traverse(ir_node_visitor& v)
17481 {
17482   // TODO: should we allow the walker to avoid visiting function type
17483   // twice?  I think that if we do, then ir_node_visitor needs an
17484   // option to specifically disallow this feature for function types.
17485 
17486   if (visiting())
17487     return true;
17488 
17489   if (v.visit_begin(this))
17490     {
17491       visiting(true);
17492       bool keep_going = true;
17493 
17494       if (type_base_sptr t = get_return_type())
17495 	{
17496 	  if (!t->traverse(v))
17497 	    keep_going = false;
17498 	}
17499 
17500       if (keep_going)
17501 	for (parameters::const_iterator i = get_parameters().begin();
17502 	     i != get_parameters().end();
17503 	     ++i)
17504 	  if (type_base_sptr parm_type = (*i)->get_type())
17505 	    if (!parm_type->traverse(v))
17506 	      break;
17507 
17508       visiting(false);
17509     }
17510   return v.visit_end(this);
17511 }
17512 
~function_type()17513 function_type::~function_type()
17514 {}
17515 // </function_type>
17516 
17517 // <method_type>
17518 
17519 struct method_type::priv
17520 {
17521   class_or_union_wptr class_type_;
17522   bool is_const;
17523 
privabigail::ir::method_type::priv17524   priv()
17525     : is_const()
17526   {}
17527 }; // end struct method_type::priv
17528 
17529 /// Constructor for instances of method_type.
17530 ///
17531 /// Instances of method_decl must be of type method_type.
17532 ///
17533 /// @param return_type the type of the return value of the method.
17534 ///
17535 /// @param class_type the base type of the method type.  That is, the
17536 /// type of the class the method belongs to.
17537 ///
17538 /// @param p the vector of the parameters of the method.
17539 ///
17540 /// @param is_const whether this method type is for a const method.
17541 /// Note that const-ness is a property of the method *type* and of the
17542 /// relationship between a method *declaration* and its scope.
17543 ///
17544 /// @param size_in_bits the size of an instance of method_type,
17545 /// expressed in bits.
17546 ///
17547 /// @param alignment_in_bits the alignment of an instance of
17548 /// method_type, expressed in bits.
method_type(type_base_sptr return_type,class_or_union_sptr class_type,const std::vector<function_decl::parameter_sptr> & p,bool is_const,size_t size_in_bits,size_t alignment_in_bits)17549 method_type::method_type (type_base_sptr return_type,
17550 			  class_or_union_sptr class_type,
17551 			  const std::vector<function_decl::parameter_sptr>& p,
17552 			  bool is_const,
17553 			  size_t size_in_bits,
17554 			  size_t alignment_in_bits)
17555   : type_or_decl_base(class_type->get_environment(),
17556 		      METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
17557     type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
17558     function_type(return_type, p, size_in_bits, alignment_in_bits),
17559     priv_(new priv)
17560 {
17561   runtime_type_instance(this);
17562   set_class_type(class_type);
17563   set_is_const(is_const);
17564 }
17565 
17566 /// Constructor of instances of method_type.
17567 ///
17568 ///Instances of method_decl must be of type method_type.
17569 ///
17570 /// @param return_type the type of the return value of the method.
17571 ///
17572 /// @param class_type the type of the class the method belongs to.
17573 /// The actual (dynamic) type of class_type must be a pointer
17574 /// class_type.  We are setting it to pointer to type_base here to
17575 /// help client code that is compiled without rtti and thus cannot
17576 /// perform dynamic casts.
17577 ///
17578 /// @param p the vector of the parameters of the method type.
17579 ///
17580 /// @param is_const whether this method type is for a const method.
17581 /// Note that const-ness is a property of the method *type* and of the
17582 /// relationship between a method *declaration* and its scope.
17583 ///
17584 /// @param size_in_bits the size of an instance of method_type,
17585 /// expressed in bits.
17586 ///
17587 /// @param alignment_in_bits the alignment of an instance of
17588 /// method_type, expressed in bits.
method_type(type_base_sptr return_type,type_base_sptr class_type,const std::vector<function_decl::parameter_sptr> & p,bool is_const,size_t size_in_bits,size_t alignment_in_bits)17589 method_type::method_type(type_base_sptr return_type,
17590 			 type_base_sptr class_type,
17591 			 const std::vector<function_decl::parameter_sptr>& p,
17592 			 bool is_const,
17593 			 size_t size_in_bits,
17594 			 size_t alignment_in_bits)
17595   : type_or_decl_base(class_type->get_environment(),
17596 		      METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
17597     type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
17598     function_type(return_type, p, size_in_bits, alignment_in_bits),
17599     priv_(new priv)
17600 {
17601   runtime_type_instance(this);
17602   set_class_type(is_class_type(class_type));
17603   set_is_const(is_const);
17604 }
17605 
17606 /// Constructor of the qualified_type_def
17607 ///
17608 /// @param env the environment we are operating from.
17609 ///
17610 /// @param size_in_bits the size of the type, expressed in bits.
17611 ///
17612 /// @param alignment_in_bits the alignment of the type, expressed in bits
method_type(const environment * env,size_t size_in_bits,size_t alignment_in_bits)17613 method_type::method_type(const environment*	env,
17614 			 size_t		size_in_bits,
17615 			 size_t		alignment_in_bits)
17616   : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
17617     type_base(env, size_in_bits, alignment_in_bits),
17618     function_type(env, size_in_bits, alignment_in_bits),
17619     priv_(new priv)
17620 {
17621   runtime_type_instance(this);
17622 }
17623 
17624 /// Constructor of instances of method_type.
17625 ///
17626 /// When constructed with this constructor, and instane of method_type
17627 /// must set a return type using method_type::set_return_type
17628 ///
17629 /// @param class_typ the base type of the method type.  That is, the
17630 /// type of the class (or union) the method belongs to.
17631 ///
17632 /// @param size_in_bits the size of an instance of method_type,
17633 /// expressed in bits.
17634 ///
17635 /// @param alignment_in_bits the alignment of an instance of
17636 /// method_type, expressed in bits.
method_type(class_or_union_sptr class_type,bool is_const,size_t size_in_bits,size_t alignment_in_bits)17637 method_type::method_type(class_or_union_sptr class_type,
17638 			 bool is_const,
17639 			 size_t size_in_bits,
17640 			 size_t alignment_in_bits)
17641   : type_or_decl_base(class_type->get_environment(),
17642 		      METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
17643     type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
17644     function_type(class_type->get_environment(),
17645 		  size_in_bits,
17646 		  alignment_in_bits),
17647     priv_(new priv)
17648 {
17649   runtime_type_instance(this);
17650   set_class_type(class_type);
17651   set_is_const(is_const);
17652 }
17653 
17654 /// Get the class type this method belongs to.
17655 ///
17656 /// @return the class type.
17657 class_or_union_sptr
get_class_type() const17658 method_type::get_class_type() const
17659 {return class_or_union_sptr(priv_->class_type_);}
17660 
17661 /// Sets the class type of the current instance of method_type.
17662 ///
17663 /// The class type is the type of the class the method belongs to.
17664 ///
17665 /// @param t the new class type to set.
17666 void
set_class_type(const class_or_union_sptr & t)17667 method_type::set_class_type(const class_or_union_sptr& t)
17668 {
17669   if (!t)
17670     return;
17671 
17672   priv_->class_type_ = t;
17673 }
17674 
17675 /// Return a copy of the pretty representation of the current @ref
17676 /// method_type.
17677 ///
17678 /// @param internal set to true if the call is intended for an
17679 /// internal use (for technical use inside the library itself), false
17680 /// otherwise.  If you don't know what this is for, then set it to
17681 /// false.
17682 ///
17683 /// @return a copy of the pretty representation of the current @ref
17684 /// method_type.
17685 string
get_pretty_representation(bool internal,bool) const17686 method_type::get_pretty_representation(bool internal,
17687 				       bool /*qualified_name*/) const
17688 {return ir::get_pretty_representation(*this, internal);}
17689 
17690 /// Setter of the "is-const" property of @ref method_type.
17691 ///
17692 /// @param the new value of the "is-const" property.
17693 void
set_is_const(bool f)17694 method_type::set_is_const(bool f)
17695 {priv_->is_const = f;}
17696 
17697 /// Getter of the "is-const" property of @ref method_type.
17698 ///
17699 /// @return true iff the "is-const" property was set.
17700 bool
get_is_const() const17701 method_type::get_is_const() const
17702 {return priv_->is_const;}
17703 
17704 /// The destructor of method_type
~method_type()17705 method_type::~method_type()
17706 {}
17707 
17708 // </method_type>
17709 
17710 // <function_decl definitions>
17711 
17712 struct function_decl::priv
17713 {
17714   bool			declared_inline_;
17715   decl_base::binding	binding_;
17716   function_type_wptr	type_;
17717   function_type*	naked_type_;
17718   elf_symbol_sptr	symbol_;
17719   interned_string id_;
17720 
privabigail::ir::function_decl::priv17721   priv()
17722     : declared_inline_(false),
17723       binding_(decl_base::BINDING_GLOBAL),
17724       naked_type_()
17725   {}
17726 
privabigail::ir::function_decl::priv17727   priv(function_type_sptr t,
17728        bool declared_inline,
17729        decl_base::binding binding)
17730     : declared_inline_(declared_inline),
17731       binding_(binding),
17732       type_(t),
17733       naked_type_(t.get())
17734   {}
17735 
privabigail::ir::function_decl::priv17736   priv(function_type_sptr t,
17737        bool declared_inline,
17738        decl_base::binding binding,
17739        elf_symbol_sptr s)
17740     : declared_inline_(declared_inline),
17741       binding_(binding),
17742       type_(t),
17743       naked_type_(t.get()),
17744       symbol_(s)
17745   {}
17746 }; // end sruct function_decl::priv
17747 
function_decl(const string & name,function_type_sptr function_type,bool declared_inline,const location & locus,const string & mangled_name,visibility vis,binding bind)17748 function_decl::function_decl(const string& name,
17749 			     function_type_sptr function_type,
17750 			     bool declared_inline,
17751 			     const location& locus,
17752 			     const string& mangled_name,
17753 			     visibility vis,
17754 			     binding bind)
17755   : type_or_decl_base(function_type->get_environment(),
17756 		      FUNCTION_DECL | ABSTRACT_DECL_BASE),
17757     decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
17758     priv_(new priv(function_type, declared_inline, bind))
17759 {
17760   runtime_type_instance(this);
17761 }
17762 
17763 /// Constructor of the function_decl type.
17764 ///
17765 /// This flavour of constructor is for when the pointer to the
17766 /// instance of function_type that the client code has is presented as
17767 /// a pointer to type_base.  In that case, this constructor saves the
17768 /// client code from doing a dynamic_cast to get the function_type
17769 /// pointer.
17770 ///
17771 /// @param name the name of the function declaration.
17772 ///
17773 /// @param fn_type the type of the function declaration.  The dynamic
17774 /// type of this parameter should be 'pointer to function_type'
17775 ///
17776 /// @param declared_inline whether this function was declared inline
17777 ///
17778 /// @param locus the source location of the function declaration.
17779 ///
17780 /// @param linkage_name the mangled name of the function declaration.
17781 ///
17782 /// @param vis the visibility of the function declaration.
17783 ///
17784 /// @param bind  the kind of the binding of the function
17785 /// declaration.
function_decl(const string & name,type_base_sptr fn_type,bool declared_inline,const location & locus,const string & linkage_name,visibility vis,binding bind)17786 function_decl::function_decl(const string&	name,
17787 			     type_base_sptr	fn_type,
17788 			     bool		declared_inline,
17789 			     const location&	locus,
17790 			     const string&	linkage_name,
17791 			     visibility	vis,
17792 			     binding		bind)
17793   : type_or_decl_base(fn_type->get_environment(),
17794 		      FUNCTION_DECL | ABSTRACT_DECL_BASE),
17795     decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
17796     priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
17797 		   declared_inline,
17798 		   bind))
17799 {
17800   runtime_type_instance(this);
17801 }
17802 
17803 /// Get the pretty representation of the current instance of @ref function_decl.
17804 ///
17805 /// @param internal set to true if the call is intended for an
17806 /// internal use (for technical use inside the library itself), false
17807 /// otherwise.  If you don't know what this is for, then set it to
17808 /// false.
17809 ///
17810 /// @return the pretty representation for a function.
17811 string
get_pretty_representation(bool internal,bool) const17812 function_decl::get_pretty_representation(bool internal,
17813 					 bool /*qualified_name*/) const
17814 {
17815   const method_decl* mem_fn =
17816     dynamic_cast<const method_decl*>(this);
17817 
17818   string result = mem_fn ? "method ": "function ";
17819 
17820   if (mem_fn
17821       && is_member_function(mem_fn)
17822       && get_member_function_is_virtual(mem_fn))
17823     result += "virtual ";
17824 
17825   decl_base_sptr type;
17826   if ((mem_fn
17827        && is_member_function(mem_fn)
17828        && (get_member_function_is_dtor(*mem_fn)
17829 	   || get_member_function_is_ctor(*mem_fn))))
17830     /*cdtors do not have return types.  */;
17831   else
17832     type = mem_fn
17833       ? get_type_declaration(mem_fn->get_type()->get_return_type())
17834       : get_type_declaration(get_type()->get_return_type());
17835 
17836   if (type)
17837     result += type->get_qualified_name(internal) + " ";
17838 
17839   result += get_pretty_representation_of_declarator(internal);
17840 
17841   return result;
17842 }
17843 
17844 /// Compute and return the pretty representation for the part of the
17845 /// function declaration that starts at the declarator.  That is, the
17846 /// return type and the other specifiers of the beginning of the
17847 /// function's declaration ar omitted.
17848 ///
17849 /// @param internal set to true if the call is intended for an
17850 /// internal use (for technical use inside the library itself), false
17851 /// otherwise.  If you don't know what this is for, then set it to
17852 /// false.
17853 ///
17854 /// @return the pretty representation for the part of the function
17855 /// declaration that starts at the declarator.
17856 string
get_pretty_representation_of_declarator(bool internal) const17857 function_decl::get_pretty_representation_of_declarator (bool internal) const
17858 {
17859   const method_decl* mem_fn =
17860     dynamic_cast<const method_decl*>(this);
17861 
17862   string result;
17863 
17864   if (mem_fn)
17865     {
17866       result += mem_fn->get_type()->get_class_type()->get_qualified_name()
17867 	+ "::" + mem_fn->get_name();
17868     }
17869   else
17870     result += get_qualified_name();
17871 
17872   result += "(";
17873 
17874   parameters::const_iterator i = get_parameters().begin(),
17875     end = get_parameters().end();
17876 
17877   // Skip the first parameter if this is a method.
17878   if (mem_fn && i != end)
17879     ++i;
17880   parameter_sptr parm;
17881   parameter_sptr first_parm;
17882   if (i != end)
17883     first_parm = *i;
17884   for (; i != end; ++i)
17885     {
17886       parm = *i;
17887       if (parm.get() != first_parm.get())
17888 	result += ", ";
17889       if (parm->get_variadic_marker()
17890 	  || get_environment()->is_variadic_parameter_type(parm->get_type()))
17891 	result += "...";
17892       else
17893 	{
17894 	  decl_base_sptr type_decl = get_type_declaration(parm->get_type());
17895 	  result += type_decl->get_qualified_name(internal);
17896 	}
17897     }
17898   result += ")";
17899 
17900   if (mem_fn
17901       &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
17902 	 || is_method_type(mem_fn->get_type())->get_is_const()))
17903     result += " const";
17904 
17905   return result;
17906 }
17907 
17908 /// Getter for the first non-implicit parameter of a function decl.
17909 ///
17910 /// If the function is a non-static member function, the parameter
17911 /// returned is the first one following the implicit 'this' parameter.
17912 ///
17913 /// @return the first non implicit parm.
17914 function_decl::parameters::const_iterator
get_first_non_implicit_parm() const17915 function_decl::get_first_non_implicit_parm() const
17916 {
17917   if (get_parameters().empty())
17918     return get_parameters().end();
17919 
17920   bool is_method = dynamic_cast<const method_decl*>(this);
17921 
17922   parameters::const_iterator i = get_parameters().begin();
17923   if (is_method)
17924     ++i;
17925 
17926   return i;
17927 }
17928 
17929 /// Return the type of the current instance of @ref function_decl.
17930 ///
17931 /// It's either a function_type or method_type.
17932 /// @return the type of the current instance of @ref function_decl.
17933 const shared_ptr<function_type>
get_type() const17934 function_decl::get_type() const
17935 {return priv_->type_.lock();}
17936 
17937 /// Fast getter of the type of the current instance of @ref function_decl.
17938 ///
17939 /// Note that this function returns the underlying pointer managed by
17940 /// the smart pointer returned by function_decl::get_type().  It's
17941 /// faster than function_decl::get_type().  This getter is to be used
17942 /// in code paths that are proven to be performance hot spots;
17943 /// especially (for instance) when comparing function types.  Those
17944 /// are compared extremely frequently when libabigail is used to
17945 /// handle huge binaries with a lot of functions.
17946 ///
17947 /// @return the type of the current instance of @ref function_decl.
17948 const function_type*
get_naked_type() const17949 function_decl::get_naked_type() const
17950 {return priv_->naked_type_;}
17951 
17952 void
set_type(const function_type_sptr & fn_type)17953 function_decl::set_type(const function_type_sptr& fn_type)
17954 {
17955   priv_->type_ = fn_type;
17956   priv_->naked_type_ = fn_type.get();
17957 }
17958 
17959 /// This sets the underlying ELF symbol for the current function decl.
17960 ///
17961 /// And underlyin$g ELF symbol for the current function decl might
17962 /// exist only if the corpus that this function decl originates from
17963 /// was constructed from an ELF binary file.
17964 ///
17965 /// Note that comparing two function decls that have underlying ELF
17966 /// symbols involves comparing their underlying elf symbols.  The decl
17967 /// name for the function thus becomes irrelevant in the comparison.
17968 ///
17969 /// @param sym the new ELF symbol for this function decl.
17970 void
set_symbol(const elf_symbol_sptr & sym)17971 function_decl::set_symbol(const elf_symbol_sptr& sym)
17972 {
17973   priv_->symbol_ = sym;
17974   // The function id cache that depends on the symbol must be
17975   // invalidated because the symbol changed.
17976   priv_->id_ = get_environment()->intern("");
17977 }
17978 
17979 /// Gets the the underlying ELF symbol for the current variable,
17980 /// that was set using function_decl::set_symbol().  Please read the
17981 /// documentation for that member function for more information about
17982 /// "underlying ELF symbols".
17983 ///
17984 /// @return sym the underlying ELF symbol for this function decl, if
17985 /// one exists.
17986 const elf_symbol_sptr&
get_symbol() const17987 function_decl::get_symbol() const
17988 {return priv_->symbol_;}
17989 
17990 bool
is_declared_inline() const17991 function_decl::is_declared_inline() const
17992 {return priv_->declared_inline_;}
17993 
17994 decl_base::binding
get_binding() const17995 function_decl::get_binding() const
17996 {return priv_->binding_;}
17997 
17998 /// @return the return type of the current instance of function_decl.
17999 const shared_ptr<type_base>
get_return_type() const18000 function_decl::get_return_type() const
18001 {return get_type()->get_return_type();}
18002 
18003 /// @return the parameters of the function.
18004 const std::vector<shared_ptr<function_decl::parameter> >&
get_parameters() const18005 function_decl::get_parameters() const
18006 {return get_type()->get_parameters();}
18007 
18008 /// Append a parameter to the type of this function.
18009 ///
18010 /// @param parm the parameter to append.
18011 void
append_parameter(shared_ptr<parameter> parm)18012 function_decl::append_parameter(shared_ptr<parameter> parm)
18013 {get_type()->append_parameter(parm);}
18014 
18015 /// Append a vector of parameters to the type of this function.
18016 ///
18017 /// @param parms the vector of parameters to append.
18018 void
append_parameters(std::vector<shared_ptr<parameter>> & parms)18019 function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
18020 {
18021   for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
18022        i != parms.end();
18023        ++i)
18024     get_type()->append_parameter(*i);
18025 }
18026 
18027 /// Create a new instance of function_decl that is a clone of the
18028 /// current one.
18029 ///
18030 /// @return the new clone.
18031 function_decl_sptr
clone() const18032 function_decl::clone() const
18033 {
18034   function_decl_sptr f;
18035   if (is_member_function(*this))
18036     {
18037       method_decl_sptr
18038 	m(new method_decl(get_name(),
18039 				      get_type(),
18040 				      is_declared_inline(),
18041 				      get_location(),
18042 				      get_linkage_name(),
18043 				      get_visibility(),
18044 				      get_binding()));
18045       class_or_union* scope = is_class_or_union_type(get_scope());
18046       ABG_ASSERT(scope);
18047       scope->add_member_function(m, get_member_access_specifier(*this),
18048 				 get_member_function_is_virtual(*this),
18049 				 get_member_function_vtable_offset(*this),
18050 				 get_member_is_static(*this),
18051 				 get_member_function_is_ctor(*this),
18052 				 get_member_function_is_dtor(*this),
18053 				 get_member_function_is_const(*this));
18054       f = m;
18055     }
18056   else
18057     {
18058       f.reset(new function_decl(get_name(),
18059 				get_type(),
18060 				is_declared_inline(),
18061 				get_location(),
18062 				get_linkage_name(),
18063 				get_visibility(),
18064 				get_binding()));
18065       add_decl_to_scope(f, get_scope());
18066     }
18067   f->set_symbol(get_symbol());
18068 
18069   return f;
18070 }
18071 
18072 /// Compares two instances of @ref function_decl.
18073 ///
18074 /// If the two intances are different, set a bitfield to give some
18075 /// insight about the kind of differences there are.
18076 ///
18077 /// @param l the first artifact of the comparison.
18078 ///
18079 /// @param r the second artifact of the comparison.
18080 ///
18081 /// @param k a pointer to a bitfield that gives information about the
18082 /// kind of changes there are between @p l and @p r.  This one is set
18083 /// iff @p k is non-null and the function returns false.
18084 ///
18085 /// Please note that setting k to a non-null value does have a
18086 /// negative performance impact because even if @p l and @p r are not
18087 /// equal, the function keeps up the comparison in order to determine
18088 /// the different kinds of ways in which they are different.
18089 ///
18090 /// @return true if @p l equals @p r, false otherwise.
18091 bool
equals(const function_decl & l,const function_decl & r,change_kind * k)18092 equals(const function_decl& l, const function_decl& r, change_kind* k)
18093 {
18094   bool result = true;
18095 
18096   // Compare function types
18097   const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
18098   if (t0 == t1 || *t0 == *t1)
18099     ; // the types are equal, let's move on to compare the other
18100       // properties of the functions.
18101   else
18102     {
18103       result = false;
18104       if (k)
18105 	{
18106 	  if (!types_have_similar_structure(t0, t1))
18107 	    *k |= LOCAL_TYPE_CHANGE_KIND;
18108 	  else
18109 	    *k |= SUBTYPE_CHANGE_KIND;
18110 	}
18111       else
18112 	return false;
18113     }
18114 
18115   const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
18116   if (!!s0 != !!s1)
18117     {
18118       result = false;
18119       if (k)
18120 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
18121       else
18122 	return false;
18123     }
18124   else if (s0 && s0 != s1)
18125     {
18126       if (!elf_symbols_alias(s0, s1))
18127 	{
18128 	  result = false;
18129 	  if (k)
18130 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18131 	  else
18132 	    return false;
18133 	}
18134     }
18135   bool symbols_are_equal = (s0 && s1 && result);
18136 
18137   if (symbols_are_equal)
18138     {
18139       // The functions have underlying elf symbols that are equal,
18140       // so now, let's compare the decl_base part of the functions
18141       // w/o considering their decl names.
18142       interned_string n1 = l.get_name(), n2 = r.get_name();
18143       interned_string ln1 = l.get_linkage_name(), ln2 = r.get_linkage_name();
18144       const_cast<function_decl&>(l).set_name("");
18145       const_cast<function_decl&>(l).set_linkage_name("");
18146       const_cast<function_decl&>(r).set_name("");
18147       const_cast<function_decl&>(r).set_linkage_name("");
18148 
18149       bool decl_bases_different = !l.decl_base::operator==(r);
18150 
18151       const_cast<function_decl&>(l).set_name(n1);
18152       const_cast<function_decl&>(l).set_linkage_name(ln1);
18153       const_cast<function_decl&>(r).set_name(n2);
18154       const_cast<function_decl&>(r).set_linkage_name(ln2);
18155 
18156       if (decl_bases_different)
18157 	{
18158 	  result = false;
18159 	  if (k)
18160 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18161 	  else
18162 	    return false;
18163 	}
18164     }
18165   else
18166     if (!l.decl_base::operator==(r))
18167       {
18168 	result = false;
18169 	if (k)
18170 	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18171 	else
18172 	  return false;
18173       }
18174 
18175   // Compare the remaining properties
18176   if (l.is_declared_inline() != r.is_declared_inline()
18177       || l.get_binding() != r.get_binding())
18178     {
18179       result = false;
18180       if (k)
18181 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
18182       else
18183 	return false;
18184     }
18185 
18186   if (is_member_function(l) != is_member_function(r))
18187     {
18188       result = false;
18189       if (k)
18190 	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18191       else
18192 	return false;
18193     }
18194 
18195   if (is_member_function(l) && is_member_function(r))
18196     {
18197       if (!((get_member_function_is_ctor(l)
18198 	     == get_member_function_is_ctor(r))
18199 	    && (get_member_function_is_dtor(l)
18200 		== get_member_function_is_dtor(r))
18201 	    && (get_member_is_static(l)
18202 		== get_member_is_static(r))
18203 	    && (get_member_function_is_const(l)
18204 		== get_member_function_is_const(r))
18205 	    && (get_member_function_is_virtual(l)
18206 		== get_member_function_is_virtual(r))
18207 	    && (get_member_function_vtable_offset(l)
18208 		== get_member_function_vtable_offset(r))))
18209 	{
18210 	  result = false;
18211 	  if (k)
18212 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18213 	  else
18214 	    return false;
18215 	}
18216     }
18217 
18218   return result;
18219 }
18220 
18221 /// Comparison operator for @ref function_decl.
18222 ///
18223 /// @param other the other instance of @ref function_decl to compare
18224 /// against.
18225 ///
18226 /// @return true iff the current instance of @ref function_decl equals
18227 /// @p other.
18228 bool
operator ==(const decl_base & other) const18229 function_decl::operator==(const decl_base& other) const
18230 {
18231   const function_decl* o = dynamic_cast<const function_decl*>(&other);
18232   if (!o)
18233     return false;
18234   return equals(*this, *o, 0);
18235 }
18236 
18237 /// Return true iff the function takes a variable number of
18238 /// parameters.
18239 ///
18240 /// @return true if the function taks a variable number
18241 /// of parameters.
18242 bool
is_variadic() const18243 function_decl::is_variadic() const
18244 {
18245   return (!get_parameters().empty()
18246 	  && get_parameters().back()->get_variadic_marker());
18247 }
18248 
18249 /// The virtual implementation of 'get_hash' for a function_decl.
18250 ///
18251 /// This allows decl_base::get_hash to work for function_decls.
18252 ///
18253 /// @return the hash value for function decl.
18254 size_t
get_hash() const18255 function_decl::get_hash() const
18256 {
18257   function_decl::hash hash_fn;
18258   return hash_fn(*this);
18259 }
18260 
18261 /// Return an ID that tries to uniquely identify the function inside a
18262 /// program or a library.
18263 ///
18264 /// So if the function has an underlying elf symbol, the ID is the
18265 /// concatenation of the symbol name and its version.  Otherwise, the
18266 /// ID is the linkage name if its non-null.  Otherwise, it's the
18267 /// pretty representation of the function.
18268 ///
18269 /// @return the ID.
18270 interned_string
get_id() const18271 function_decl::get_id() const
18272 {
18273   if (priv_->id_.empty())
18274     {
18275       const environment* env = get_type()->get_environment();
18276       if (elf_symbol_sptr s = get_symbol())
18277 	{
18278 	  if (s->has_aliases())
18279 	    // The symbol has several aliases, so let's use a scheme
18280 	    // that allows all aliased functions to have different
18281 	    // IDs.
18282 	    priv_->id_ = env->intern(get_name() + "/" + s->get_id_string());
18283 	  else
18284 	    // Let's use the full symbol name with its version as ID.
18285 	    priv_->id_ = env->intern(s->get_id_string());
18286 	}
18287       else if (!get_linkage_name().empty())
18288 	priv_->id_= env->intern(get_linkage_name());
18289       else
18290 	priv_->id_ = env->intern(get_pretty_representation());
18291     }
18292   return priv_->id_;
18293 }
18294 
18295 /// Test if two function declarations are aliases.
18296 ///
18297 /// Two functions declarations are aliases if their symbols are
18298 /// aliases, in the ELF sense.
18299 ///
18300 /// @param f1 the first function to consider.
18301 ///
18302 /// @param f2 the second function to consider.
18303 ///
18304 /// @return true iff @p f1 is an alias of @p f2
18305 bool
function_decls_alias(const function_decl & f1,const function_decl & f2)18306 function_decls_alias(const function_decl& f1, const function_decl& f2)
18307 {
18308   elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
18309 
18310   if (!s1 || !s2)
18311     return false;
18312 
18313   return elf_symbols_alias(s1, s2);
18314 }
18315 
18316 /// This implements the ir_traversable_base::traverse pure virtual
18317 /// function.
18318 ///
18319 /// @param v the visitor used on the current instance.
18320 ///
18321 /// @return true if the entire IR node tree got traversed, false
18322 /// otherwise.
18323 bool
traverse(ir_node_visitor & v)18324 function_decl::traverse(ir_node_visitor& v)
18325 {
18326   if (visiting())
18327     return true;
18328 
18329   if (v.visit_begin(this))
18330     {
18331       visiting(true);
18332       if (type_base_sptr t = get_type())
18333 	t->traverse(v);
18334       visiting(false);
18335     }
18336   return v.visit_end(this);
18337 }
18338 
18339 /// Destructor of the @ref function_decl type.
~function_decl()18340 function_decl::~function_decl()
18341 {delete priv_;}
18342 
18343 /// A deep comparison operator for a shared pointer to @ref function_decl
18344 ///
18345 /// This function compares to shared pointers to @ref function_decl by
18346 /// looking at the pointed-to instances of @ref function_dec
18347 /// comparing them too.  If the two pointed-to objects are equal then
18348 /// this function returns true.
18349 ///
18350 /// @param l the left-hand side argument of the equality operator.
18351 ///
18352 /// @param r the right-hand side argument of the equality operator.
18353 ///
18354 /// @return true iff @p l equals @p r.
18355 bool
operator ==(const function_decl_sptr & l,const function_decl_sptr & r)18356 operator==(const function_decl_sptr& l, const function_decl_sptr& r)
18357 {
18358   if (l.get() == r.get())
18359     return true;
18360   if (!!l != !!r)
18361     return false;
18362 
18363   return *l == *r;
18364 }
18365 
18366 /// A deep inequality operator for smart pointers to functions.
18367 ///
18368 /// @param l the left-hand side argument of the inequality operator.
18369 ///
18370 /// @pram r the right-hand side argument of the inequality operator.
18371 ///
18372 /// @return true iff @p is not equal to @p r.
18373 bool
operator !=(const function_decl_sptr & l,const function_decl_sptr & r)18374 operator!=(const function_decl_sptr& l, const function_decl_sptr& r)
18375 {return !operator==(l, r);}
18376 
18377 // <function_decl definitions>
18378 
18379 // <function_decl::parameter definitions>
18380 
18381 struct function_decl::parameter::priv
18382 {
18383   type_base_wptr	type_;
18384   unsigned		index_;
18385   bool			variadic_marker_;
18386 
privabigail::ir::function_decl::parameter::priv18387   priv()
18388     : index_(),
18389       variadic_marker_()
18390   {}
18391 
privabigail::ir::function_decl::parameter::priv18392   priv(type_base_sptr type,
18393        unsigned index,
18394        bool variadic_marker)
18395     : type_(type),
18396       index_(index),
18397       variadic_marker_(variadic_marker)
18398   {}
18399 };// end struct function_decl::parameter::priv
18400 
parameter(const type_base_sptr type,unsigned index,const string & name,const location & loc,bool is_variadic)18401 function_decl::parameter::parameter(const type_base_sptr	type,
18402 				    unsigned			index,
18403 				    const string&		name,
18404 				    const location&		loc,
18405 				    bool			is_variadic)
18406   : type_or_decl_base(type->get_environment(),
18407 		      FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
18408     decl_base(type->get_environment(), name, loc),
18409     priv_(new priv(type, index, is_variadic))
18410 {
18411   runtime_type_instance(this);
18412 }
18413 
parameter(const type_base_sptr type,unsigned index,const string & name,const location & loc,bool is_variadic,bool is_artificial)18414 function_decl::parameter::parameter(const type_base_sptr	type,
18415 				    unsigned			index,
18416 				    const string&		name,
18417 				    const location&		loc,
18418 				    bool			is_variadic,
18419 				    bool			is_artificial)
18420   : type_or_decl_base(type->get_environment(),
18421 		      FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
18422     decl_base(type->get_environment(), name, loc),
18423     priv_(new priv(type, index, is_variadic))
18424 {
18425   runtime_type_instance(this);
18426   set_is_artificial(is_artificial);
18427 }
18428 
parameter(const type_base_sptr type,const string & name,const location & loc,bool is_variadic,bool is_artificial)18429 function_decl::parameter::parameter(const type_base_sptr	type,
18430 				    const string&		name,
18431 				    const location&		loc,
18432 				    bool			is_variadic,
18433 				    bool			is_artificial)
18434   : type_or_decl_base(type->get_environment(),
18435 		      FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
18436     decl_base(type->get_environment(), name, loc),
18437     priv_(new priv(type, 0, is_variadic))
18438 {
18439   runtime_type_instance(this);
18440   set_is_artificial(is_artificial);
18441 }
18442 
parameter(const type_base_sptr type,unsigned index,bool variad)18443 function_decl::parameter::parameter(const type_base_sptr	type,
18444 				    unsigned			index,
18445 				    bool			variad)
18446   : type_or_decl_base(type->get_environment(),
18447 		      FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
18448     decl_base(type->get_environment(), "", location()),
18449     priv_(new priv(type, index, variad))
18450 {
18451   runtime_type_instance(this);
18452 }
18453 
18454 const type_base_sptr
get_type() const18455 function_decl::parameter::get_type()const
18456 {return priv_->type_.lock();}
18457 
18458 /// @return a copy of the type name of the parameter.
18459 interned_string
get_type_name() const18460 function_decl::parameter::get_type_name() const
18461 {
18462   const environment* env = get_environment();
18463   ABG_ASSERT(env);
18464 
18465   type_base_sptr t = get_type();
18466   string str;
18467   if (get_variadic_marker() || env->is_variadic_parameter_type(t))
18468     str = "...";
18469   else
18470     {
18471 	ABG_ASSERT(t);
18472 	str = abigail::ir::get_type_name(t);
18473     }
18474   return env->intern(str);
18475 }
18476 
18477 /// @return a copy of the pretty representation of the type of the
18478 /// parameter.
18479 const string
get_type_pretty_representation() const18480 function_decl::parameter::get_type_pretty_representation() const
18481 {
18482   type_base_sptr t = get_type();
18483   string str;
18484   if (get_variadic_marker()
18485       || get_environment()->is_variadic_parameter_type(t))
18486     str = "...";
18487   else
18488     {
18489 	ABG_ASSERT(t);
18490 	str += get_type_declaration(t)->get_pretty_representation();
18491     }
18492   return str;
18493 }
18494 
18495 /// Get a name uniquely identifying the parameter in the function.
18496 ///
18497 ///@return the unique parm name id.
18498 interned_string
get_name_id() const18499 function_decl::parameter::get_name_id() const
18500 {
18501   const environment* env = get_environment();
18502   ABG_ASSERT(env);
18503 
18504   std::ostringstream o;
18505   o << "parameter-" << get_index();
18506 
18507   return env->intern(o.str());
18508 }
18509 
18510 unsigned
get_index() const18511 function_decl::parameter::get_index() const
18512 {return priv_->index_;}
18513 
18514 void
set_index(unsigned i)18515 function_decl::parameter::set_index(unsigned i)
18516 {priv_->index_ = i;}
18517 
18518 
18519 bool
get_variadic_marker() const18520 function_decl::parameter::get_variadic_marker() const
18521 {return priv_->variadic_marker_;}
18522 
18523 /// Compares two instances of @ref function_decl::parameter.
18524 ///
18525 /// If the two intances are different, set a bitfield to give some
18526 /// insight about the kind of differences there are.
18527 ///
18528 /// @param l the first artifact of the comparison.
18529 ///
18530 /// @param r the second artifact of the comparison.
18531 ///
18532 /// @param k a pointer to a bitfield that gives information about the
18533 /// kind of changes there are between @p l and @p r.  This one is set
18534 /// iff @p k is non-null and the function returns false.
18535 ///
18536 /// Please note that setting k to a non-null value does have a
18537 /// negative performance impact because even if @p l and @p r are not
18538 /// equal, the function keeps up the comparison in order to determine
18539 /// the different kinds of ways in which they are different.
18540 ///
18541 /// @return true if @p l equals @p r, false otherwise.
18542 bool
equals(const function_decl::parameter & l,const function_decl::parameter & r,change_kind * k)18543 equals(const function_decl::parameter& l,
18544        const function_decl::parameter& r,
18545        change_kind* k)
18546 {
18547   bool result = true;
18548 
18549   if ((l.get_variadic_marker() != r.get_variadic_marker())
18550       || (l.get_index() != r.get_index())
18551       || (!!l.get_type() != !!r.get_type()))
18552     {
18553       result = false;
18554       if (k)
18555 	{
18556 	  if (l.get_index() != r.get_index())
18557 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18558 	  if (l.get_variadic_marker() != r.get_variadic_marker()
18559 	      || !!l.get_type() != !!r.get_type())
18560 	    *k |= LOCAL_TYPE_CHANGE_KIND;
18561 	}
18562       else
18563 	return false;
18564     }
18565 
18566 
18567   // Sometimes, function parameters can be wrapped into a no-op
18568   // qualifier.  Let's strip that qualifier out.
18569   type_base_sptr l_type = look_through_no_op_qualified_type(l.get_type());
18570   type_base_sptr r_type = look_through_no_op_qualified_type(r.get_type());
18571   if (l_type != r_type)
18572     {
18573       result = false;
18574       if (k)
18575 	{
18576 	  if (!types_have_similar_structure(l_type, r_type))
18577 	    *k |= LOCAL_TYPE_CHANGE_KIND;
18578 	  else
18579 	    *k |= SUBTYPE_CHANGE_KIND;
18580 	}
18581       else
18582 	return false;
18583     }
18584 
18585   return result;
18586 }
18587 
18588 bool
operator ==(const parameter & o) const18589 function_decl::parameter::operator==(const parameter& o) const
18590 {return equals(*this, o, 0);}
18591 
18592 bool
operator ==(const decl_base & o) const18593 function_decl::parameter::operator==(const decl_base& o) const
18594 {
18595   const function_decl::parameter* p =
18596     dynamic_cast<const function_decl::parameter*>(&o);
18597   if (!p)
18598     return false;
18599   return function_decl::parameter::operator==(*p);
18600 }
18601 
18602 /// Non-member equality operator for @ref function_decl::parameter.
18603 ///
18604 /// @param l the left-hand side of the equality operator
18605 ///
18606 /// @param r the right-hand side of the equality operator
18607 ///
18608 /// @return true iff @p l and @p r equals.
18609 bool
operator ==(const function_decl::parameter_sptr & l,const function_decl::parameter_sptr & r)18610 operator==(const function_decl::parameter_sptr& l,
18611 	   const function_decl::parameter_sptr& r)
18612 {
18613   if (!!l != !!r)
18614     return false;
18615   if (!l)
18616     return true;
18617   return *l == *r;
18618 }
18619 
18620 /// Non-member inequality operator for @ref function_decl::parameter.
18621 ///
18622 /// @param l the left-hand side of the equality operator
18623 ///
18624 /// @param r the right-hand side of the equality operator
18625 ///
18626 /// @return true iff @p l and @p r different.
18627 bool
operator !=(const function_decl::parameter_sptr & l,const function_decl::parameter_sptr & r)18628 operator!=(const function_decl::parameter_sptr& l,
18629 	   const function_decl::parameter_sptr& r)
18630 {return !operator==(l, r);}
18631 
18632 /// Traverse the diff sub-tree under the current instance
18633 /// function_decl.
18634 ///
18635 /// @param v the visitor to invoke on each diff node of the sub-tree.
18636 ///
18637 /// @return true if the traversing has to keep going on, false
18638 /// otherwise.
18639 bool
traverse(ir_node_visitor & v)18640 function_decl::parameter::traverse(ir_node_visitor& v)
18641 {
18642   if (visiting())
18643     return true;
18644 
18645   if (v.visit_begin(this))
18646     {
18647       visiting(true);
18648       if (type_base_sptr t = get_type())
18649 	t->traverse(v);
18650       visiting(false);
18651     }
18652   return v.visit_end(this);
18653 }
18654 
18655 /// Get the hash of a decl.  If the hash hasn't been computed yet,
18656 /// compute it ans store its value; otherwise, just return the hash.
18657 ///
18658 /// @return the hash of the decl.
18659 size_t
get_hash() const18660 function_decl::parameter::get_hash() const
18661 {
18662   function_decl::parameter::hash hash_fn_parm;
18663   return hash_fn_parm(this);
18664 }
18665 
18666 /// Compute the qualified name of the parameter.
18667 ///
18668 /// @param internal set to true if the call is intended for an
18669 /// internal use (for technical use inside the library itself), false
18670 /// otherwise.  If you don't know what this is for, then set it to
18671 /// false.
18672 ///
18673 /// @param qn the resulting qualified name.
18674 void
get_qualified_name(interned_string & qualified_name,bool) const18675 function_decl::parameter::get_qualified_name(interned_string& qualified_name,
18676 					     bool /*internal*/) const
18677 {qualified_name = get_name();}
18678 
18679 /// Compute and return a copy of the pretty representation of the
18680 /// current function parameter.
18681 ///
18682 /// @param internal set to true if the call is intended for an
18683 /// internal use (for technical use inside the library itself), false
18684 /// otherwise.  If you don't know what this is for, then set it to
18685 /// false.
18686 ///
18687 /// @return a copy of the textual representation of the current
18688 /// function parameter.
18689 string
get_pretty_representation(bool internal,bool) const18690 function_decl::parameter::get_pretty_representation(bool internal,
18691 						    bool /*qualified_name*/) const
18692 {
18693   const environment* env = get_environment();
18694   ABG_ASSERT(env);
18695 
18696   string type_repr;
18697   type_base_sptr t = get_type();
18698   if (!t)
18699     type_repr = "void";
18700   else if (env->is_variadic_parameter_type(t))
18701     type_repr = "...";
18702   else
18703     type_repr = ir::get_pretty_representation(t, internal);
18704 
18705   string result = type_repr;
18706   string parm_name = get_name_id();
18707 
18708   if (!parm_name.empty())
18709     result += " " + parm_name;
18710 
18711   return result;
18712 }
18713 
18714 // </function_decl::parameter definitions>
18715 
18716 // <class_or_union definitions>
18717 struct class_or_union::priv
18718 {
18719   typedef_decl_wptr		naming_typedef_;
18720   member_types			member_types_;
18721   data_members			data_members_;
18722   data_members			non_static_data_members_;
18723   member_functions		member_functions_;
18724   // A map that associates a linkage name to a member function.
18725   string_mem_fn_sptr_map_type	mem_fns_map_;
18726   // A map that associates function signature strings to member
18727   // function.
18728   string_mem_fn_ptr_map_type	signature_2_mem_fn_map_;
18729   member_function_templates	member_function_templates_;
18730   member_class_templates	member_class_templates_;
18731 
privabigail::ir::class_or_union::priv18732   priv()
18733   {}
18734 
privabigail::ir::class_or_union::priv18735   priv(class_or_union::member_types& mbr_types,
18736        class_or_union::data_members& data_mbrs,
18737        class_or_union::member_functions& mbr_fns)
18738     : member_types_(mbr_types),
18739       data_members_(data_mbrs),
18740       member_functions_(mbr_fns)
18741   {
18742     for (data_members::const_iterator i = data_members_.begin();
18743 	 i != data_members_.end();
18744 	 ++i)
18745       if (!get_member_is_static(*i))
18746 	non_static_data_members_.push_back(*i);
18747   }
18748 
18749   /// Mark a class or union or union as being currently compared using
18750   /// the class_or_union== operator.
18751   ///
18752   /// Note that is marking business is to avoid infinite loop when
18753   /// comparing a class or union or union. If via the comparison of a
18754   /// data member or a member function a recursive re-comparison of
18755   /// the class or union is attempted, the marking business help to
18756   /// detect that infinite loop possibility and avoid it.
18757   ///
18758   /// @param klass the class or union or union to mark as being
18759   /// currently compared.
18760   void
mark_as_being_comparedabigail::ir::class_or_union::priv18761   mark_as_being_compared(const class_or_union& klass) const
18762   {
18763     const environment* env = klass.get_environment();
18764     ABG_ASSERT(env);
18765     env->priv_->classes_being_compared_.insert(&klass);
18766   }
18767 
18768   /// Mark a class or union as being currently compared using the
18769   /// class_or_union== operator.
18770   ///
18771   /// Note that is marking business is to avoid infinite loop when
18772   /// comparing a class or union. If via the comparison of a data
18773   /// member or a member function a recursive re-comparison of the
18774   /// class or union is attempted, the marking business help to detect
18775   /// that infinite loop possibility and avoid it.
18776   ///
18777   /// @param klass the class or union to mark as being currently
18778   /// compared.
18779   void
mark_as_being_comparedabigail::ir::class_or_union::priv18780   mark_as_being_compared(const class_or_union* klass) const
18781   {mark_as_being_compared(*klass);}
18782 
18783   /// Mark a class or union as being currently compared using the
18784   /// class_or_union== operator.
18785   ///
18786   /// Note that is marking business is to avoid infinite loop when
18787   /// comparing a class or union. If via the comparison of a data
18788   /// member or a member function a recursive re-comparison of the
18789   /// class or union is attempted, the marking business help to detect
18790   /// that infinite loop possibility and avoid it.
18791   ///
18792   /// @param klass the class or union to mark as being currently
18793   /// compared.
18794   void
mark_as_being_comparedabigail::ir::class_or_union::priv18795   mark_as_being_compared(const class_or_union_sptr& klass) const
18796   {mark_as_being_compared(*klass);}
18797 
18798   /// If the instance of class_or_union has been previously marked as
18799   /// being compared -- via an invocation of mark_as_being_compared()
18800   /// this method unmarks it.  Otherwise is has no effect.
18801   ///
18802   /// This method is not thread safe because it uses the static data
18803   /// member classes_being_compared_.  If you wish to use it in a
18804   /// multi-threaded environment you should probably protect the
18805   /// access to that static data member with a mutex or somesuch.
18806   ///
18807   /// @param klass the instance of class_or_union to unmark.
18808   void
unmark_as_being_comparedabigail::ir::class_or_union::priv18809   unmark_as_being_compared(const class_or_union& klass) const
18810   {
18811     const environment* env = klass.get_environment();
18812     ABG_ASSERT(env);
18813     env->priv_->classes_being_compared_.erase(&klass);
18814   }
18815 
18816   /// If the instance of class_or_union has been previously marked as
18817   /// being compared -- via an invocation of mark_as_being_compared()
18818   /// this method unmarks it.  Otherwise is has no effect.
18819   ///
18820   /// @param klass the instance of class_or_union to unmark.
18821   void
unmark_as_being_comparedabigail::ir::class_or_union::priv18822   unmark_as_being_compared(const class_or_union* klass) const
18823   {
18824     if (klass)
18825       return unmark_as_being_compared(*klass);
18826   }
18827 
18828   /// Test if a given instance of class_or_union is being currently
18829   /// compared.
18830   ///
18831   ///@param klass the class or union to test.
18832   ///
18833   /// @return true if @p klass is being compared, false otherwise.
18834   bool
comparison_startedabigail::ir::class_or_union::priv18835   comparison_started(const class_or_union& klass) const
18836   {
18837     const environment* env = klass.get_environment();
18838     ABG_ASSERT(env);
18839     return env->priv_->classes_being_compared_.count(&klass);
18840   }
18841 
18842   /// Test if a given instance of class_or_union is being currently
18843   /// compared.
18844   ///
18845   ///@param klass the class or union to test.
18846   ///
18847   /// @return true if @p klass is being compared, false otherwise.
18848   bool
comparison_startedabigail::ir::class_or_union::priv18849   comparison_started(const class_or_union* klass) const
18850   {
18851     if (klass)
18852       return comparison_started(*klass);
18853     return false;
18854   }
18855 }; // end struct class_or_union::priv
18856 
18857 /// A Constructor for instances of @ref class_or_union
18858 ///
18859 /// @param env the environment we are operating from.
18860 ///
18861 /// @param name the identifier of the class.
18862 ///
18863 /// @param size_in_bits the size of an instance of @ref
18864 /// class_or_union, expressed in bits
18865 ///
18866 /// @param align_in_bits the alignment of an instance of @ref class_or_union,
18867 /// expressed in bits.
18868 ///
18869 /// @param locus the source location of declaration point this class.
18870 ///
18871 /// @param vis the visibility of instances of @ref class_or_union.
18872 ///
18873 /// @param mem_types the vector of member types of this instance of
18874 /// @ref class_or_union.
18875 ///
18876 /// @param data_members the vector of data members of this instance of
18877 /// @ref class_or_union.
18878 ///
18879 /// @param member_fns the vector of member functions of this instance
18880 /// of @ref class_or_union.
class_or_union(const environment * env,const string & name,size_t size_in_bits,size_t align_in_bits,const location & locus,visibility vis,member_types & mem_types,data_members & data_members,member_functions & member_fns)18881 class_or_union::class_or_union(const environment* env, const string& name,
18882 			       size_t size_in_bits, size_t align_in_bits,
18883 			       const location& locus, visibility vis,
18884 			       member_types& mem_types,
18885 			       data_members& data_members,
18886 			       member_functions& member_fns)
18887   : type_or_decl_base(env,
18888 		      ABSTRACT_TYPE_BASE
18889 		      | ABSTRACT_DECL_BASE
18890 		      | ABSTRACT_SCOPE_TYPE_DECL
18891 		      | ABSTRACT_SCOPE_DECL),
18892     decl_base(env, name, locus, name, vis),
18893     type_base(env, size_in_bits, align_in_bits),
18894     scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
18895     priv_(new priv(mem_types, data_members, member_fns))
18896 {
18897   for (member_types::iterator i = mem_types.begin();
18898        i != mem_types.end();
18899        ++i)
18900     if (!has_scope(get_type_declaration(*i)))
18901       add_decl_to_scope(get_type_declaration(*i), this);
18902 
18903   for (data_members::iterator i = data_members.begin();
18904        i != data_members.end();
18905        ++i)
18906     if (!has_scope(*i))
18907       add_decl_to_scope(*i, this);
18908 
18909   for (member_functions::iterator i = member_fns.begin();
18910        i != member_fns.end();
18911        ++i)
18912     if (!has_scope(static_pointer_cast<decl_base>(*i)))
18913       add_decl_to_scope(*i, this);
18914 }
18915 
18916 /// A constructor for instances of @ref class_or_union.
18917 ///
18918 /// @param env the environment we are operating from.
18919 ///
18920 /// @param name the name of the class.
18921 ///
18922 /// @param size_in_bits the size of an instance of @ref
18923 /// class_or_union, expressed in bits
18924 ///
18925 /// @param align_in_bits the alignment of an instance of @ref class_or_union,
18926 /// expressed in bits.
18927 ///
18928 /// @param locus the source location of declaration point this class.
18929 ///
18930 /// @param vis the visibility of instances of @ref class_or_union.
class_or_union(const environment * env,const string & name,size_t size_in_bits,size_t align_in_bits,const location & locus,visibility vis)18931 class_or_union::class_or_union(const environment* env, const string& name,
18932 			       size_t size_in_bits, size_t align_in_bits,
18933 			       const location& locus, visibility vis)
18934   : type_or_decl_base(env,
18935 		      ABSTRACT_TYPE_BASE
18936 		      | ABSTRACT_DECL_BASE
18937 		      | ABSTRACT_SCOPE_TYPE_DECL
18938 		      | ABSTRACT_SCOPE_DECL),
18939     decl_base(env, name, locus, name, vis),
18940     type_base(env, size_in_bits, align_in_bits),
18941     scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
18942     priv_(new priv)
18943 {}
18944 
18945 /// Constructor of the @ref class_or_union type.
18946 ///
18947 /// @param env the @ref environment we are operating from.
18948 ///
18949 /// @param name the name of the @ref class_or_union.
18950 ///
18951 /// @param is_declaration_only a boolean saying whether the instance
18952 /// represents a declaration only, or not.
class_or_union(const environment * env,const string & name,bool is_declaration_only)18953 class_or_union::class_or_union(const environment* env, const string& name,
18954 			       bool is_declaration_only)
18955   : type_or_decl_base(env,
18956 		      ABSTRACT_TYPE_BASE
18957 		      | ABSTRACT_DECL_BASE
18958 		      | ABSTRACT_SCOPE_TYPE_DECL
18959 		      | ABSTRACT_SCOPE_DECL),
18960     decl_base(env, name, location(), name),
18961     type_base(env, 0, 0),
18962     scope_type_decl(env, name, 0, 0, location()),
18963     priv_(new priv)
18964 {
18965   set_is_declaration_only(is_declaration_only);
18966 }
18967 
18968 /// This implements the ir_traversable_base::traverse pure virtual
18969 /// function.
18970 ///
18971 /// @param v the visitor used on the member nodes of the translation
18972 /// unit during the traversal.
18973 ///
18974 /// @return true if the entire IR node tree got traversed, false
18975 /// otherwise.
18976 bool
traverse(ir_node_visitor & v)18977 class_or_union::traverse(ir_node_visitor& v)
18978 {
18979   if (v.type_node_has_been_visited(this))
18980     return true;
18981 
18982   if (visiting())
18983     return true;
18984 
18985   if (v.visit_begin(this))
18986     {
18987       visiting(true);
18988       bool stop = false;
18989 
18990       if (!stop)
18991 	for (data_members::const_iterator i = get_data_members().begin();
18992 	     i != get_data_members().end();
18993 	     ++i)
18994 	  if (!(*i)->traverse(v))
18995 	    {
18996 	      stop = true;
18997 	      break;
18998 	    }
18999 
19000       if (!stop)
19001 	for (member_functions::const_iterator i= get_member_functions().begin();
19002 	     i != get_member_functions().end();
19003 	     ++i)
19004 	  if (!(*i)->traverse(v))
19005 	    {
19006 	      stop = true;
19007 	      break;
19008 	    }
19009 
19010       if (!stop)
19011 	for (member_types::const_iterator i = get_member_types().begin();
19012 	     i != get_member_types().end();
19013 	     ++i)
19014 	  if (!(*i)->traverse(v))
19015 	    {
19016 	      stop = true;
19017 	      break;
19018 	    }
19019 
19020       if (!stop)
19021 	for (member_function_templates::const_iterator i =
19022 	       get_member_function_templates().begin();
19023 	     i != get_member_function_templates().end();
19024 	     ++i)
19025 	  if (!(*i)->traverse(v))
19026 	    {
19027 	      stop = true;
19028 	      break;
19029 	    }
19030 
19031       if (!stop)
19032 	for (member_class_templates::const_iterator i =
19033 	       get_member_class_templates().begin();
19034 	     i != get_member_class_templates().end();
19035 	     ++i)
19036 	  if (!(*i)->traverse(v))
19037 	    {
19038 	      stop = true;
19039 	      break;
19040 	    }
19041       visiting(false);
19042     }
19043 
19044   bool result = v.visit_end(this);
19045   v.mark_type_node_as_visited(this);
19046   return result;
19047 }
19048 
19049 /// Destrcutor of the @ref class_or_union type.
~class_or_union()19050 class_or_union::~class_or_union()
19051 {delete priv_;}
19052 
19053 /// Add a member declaration to the current instance of class_or_union.
19054 /// The member declaration can be either a member type, data member,
19055 /// member function, or member template.
19056 ///
19057 /// @param d the member declaration to add.
19058 decl_base_sptr
add_member_decl(const decl_base_sptr & d)19059 class_or_union::add_member_decl(const decl_base_sptr& d)
19060 {return insert_member_decl(d, get_member_decls().end());}
19061 
19062 /// Remove a given decl from the current @ref class_or_union scope.
19063 ///
19064 /// Note that only type declarations are supported by this method for
19065 /// now.  Support for the other kinds of declaration is left as an
19066 /// exercise for the interested reader of the code.
19067 ///
19068 /// @param decl the declaration to remove from this @ref
19069 /// class_or_union scope.
19070 void
remove_member_decl(decl_base_sptr decl)19071 class_or_union::remove_member_decl(decl_base_sptr decl)
19072 {
19073   type_base_sptr t = is_type(decl);
19074 
19075   // For now we want to support just removing types from classes.  For
19076   // other kinds of IR node, we need more work.
19077   ABG_ASSERT(t);
19078 
19079   remove_member_type(t);
19080 }
19081 
19082 /// Fixup the members of the type of an anonymous data member.
19083 ///
19084 /// Walk all data members of (the type of) a given anonymous data
19085 /// member and set a particular property of the relationship between
19086 /// each data member and its containing type.
19087 ///
19088 /// That property records the fact that the data member belongs to the
19089 /// anonymous data member we consider.
19090 ///
19091 /// In the future, if there are other properties of this relationship
19092 /// to set in this manner, they ought to be added here.
19093 ///
19094 /// @param anon_dm the anonymous data member to consider.
19095 void
maybe_fixup_members_of_anon_data_member(var_decl_sptr & anon_dm)19096 class_or_union::maybe_fixup_members_of_anon_data_member(var_decl_sptr& anon_dm)
19097 {
19098   class_or_union * anon_dm_type =
19099     anonymous_data_member_to_class_or_union(anon_dm.get());
19100   if (!anon_dm_type)
19101     return;
19102 
19103   for (class_or_union::data_members::const_iterator it =
19104 	 anon_dm_type->get_non_static_data_members().begin();
19105        it != anon_dm_type->get_non_static_data_members().end();
19106        ++it)
19107     {
19108       dm_context_rel *rel =
19109 	dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
19110       ABG_ASSERT(rel);
19111       rel->set_anonymous_data_member(anon_dm.get());
19112     }
19113 }
19114 
19115 /// Insert a member type.
19116 ///
19117 /// @param t the type to insert in the @ref class_or_union type.
19118 ///
19119 /// @param an iterator right before which @p t has to be inserted.
19120 void
insert_member_type(type_base_sptr t,declarations::iterator before)19121 class_or_union::insert_member_type(type_base_sptr t,
19122 				   declarations::iterator before)
19123 {
19124   decl_base_sptr d = get_type_declaration(t);
19125   ABG_ASSERT(d);
19126   ABG_ASSERT(!has_scope(d));
19127 
19128   priv_->member_types_.push_back(t);
19129   scope_decl::insert_member_decl(d, before);
19130 }
19131 
19132 /// Add a member type to the current instance of class_or_union.
19133 ///
19134 /// @param t the member type to add.  It must not have been added to a
19135 /// scope, otherwise this will violate an ABG_ASSERTion.
19136 void
add_member_type(type_base_sptr t)19137 class_or_union::add_member_type(type_base_sptr t)
19138 {insert_member_type(t, get_member_decls().end());}
19139 
19140 /// Add a member type to the current instance of class_or_union.
19141 ///
19142 /// @param t the type to be added as a member type to the current
19143 /// instance of class_or_union.  An instance of class_or_union::member_type
19144 /// will be created out of @p t and and added to the the class.
19145 ///
19146 /// @param a the access specifier for the member type to be created.
19147 type_base_sptr
add_member_type(type_base_sptr t,access_specifier a)19148 class_or_union::add_member_type(type_base_sptr t, access_specifier a)
19149 {
19150   decl_base_sptr d = get_type_declaration(t);
19151   ABG_ASSERT(d);
19152   ABG_ASSERT(!is_member_decl(d));
19153   add_member_type(t);
19154   set_member_access_specifier(d, a);
19155   return t;
19156 }
19157 
19158 /// Remove a member type from the current @ref class_or_union scope.
19159 ///
19160 /// @param t the type to remove.
19161 void
remove_member_type(type_base_sptr t)19162 class_or_union::remove_member_type(type_base_sptr t)
19163 {
19164   for (member_types::iterator i = priv_->member_types_.begin();
19165        i != priv_->member_types_.end();
19166        ++i)
19167     {
19168       if (*((*i)) == *t)
19169 	{
19170 	  priv_->member_types_.erase(i);
19171 	  return;
19172 	}
19173     }
19174 }
19175 
19176 /// Getter of the alignment of the @ref class_or_union type.
19177 ///
19178 /// If this @ref class_or_union is a declaration of a definition that
19179 /// is elsewhere, then the size of the definition is returned.
19180 ///
19181 /// @return the alignment of the @ref class_or_union type.
19182 size_t
get_alignment_in_bits() const19183 class_or_union::get_alignment_in_bits() const
19184 {
19185   if (get_is_declaration_only() && get_definition_of_declaration())
19186     return is_class_or_union_type
19187       (get_definition_of_declaration())->get_alignment_in_bits();
19188 
19189    return type_base::get_alignment_in_bits();
19190 }
19191 
19192 /// Setter of the alignment of the class type.
19193 ///
19194 /// If this class is a declaration of a definition that is elsewhere,
19195 /// then the new alignment is set to the definition.
19196 ///
19197 /// @param s the new alignment.
19198 void
set_alignment_in_bits(size_t a)19199 class_or_union::set_alignment_in_bits(size_t a)
19200 {
19201   if (get_is_declaration_only() && get_definition_of_declaration())
19202     is_class_or_union_type
19203       (get_definition_of_declaration()) ->set_alignment_in_bits(a);
19204   else
19205     type_base::set_alignment_in_bits(a);
19206 }
19207 
19208 /// Setter of the size of the @ref class_or_union type.
19209 ///
19210 /// If this @ref class_or_union is a declaration of a definition that
19211 /// is elsewhere, then the new size is set to the definition.
19212 ///
19213 /// @param s the new size.
19214 void
set_size_in_bits(size_t s)19215 class_or_union::set_size_in_bits(size_t s)
19216 {
19217   if (get_is_declaration_only() && get_definition_of_declaration())
19218     is_class_or_union_type
19219       (get_definition_of_declaration())->set_size_in_bits(s);
19220   else
19221     type_base::set_size_in_bits(s);
19222 }
19223 
19224 /// Getter of the size of the @ref class_or_union type.
19225 ///
19226 /// If this @ref class_or_union is a declaration of a definition that
19227 /// is elsewhere, then the size of the definition is returned.
19228 ///
19229 /// @return the size of the @ref class_or_union type.
19230 size_t
get_size_in_bits() const19231 class_or_union::get_size_in_bits() const
19232 {
19233   if (get_is_declaration_only() && get_definition_of_declaration())
19234     return is_class_or_union_type
19235       (get_definition_of_declaration())->get_size_in_bits();
19236 
19237   return type_base::get_size_in_bits();
19238 }
19239 
19240 
19241 /// Getter for the naming typedef of the current class.
19242 ///
19243 /// Consider the C idiom:
19244 ///
19245 ///    typedef struct {int member;} foo_type;
19246 ///
19247 /// In that idiom, foo_type is the naming typedef of the anonymous
19248 /// struct that is declared.
19249 ///
19250 /// @return the naming typedef, if any.  Otherwise, returns nil.
19251 typedef_decl_sptr
get_naming_typedef() const19252 class_or_union::get_naming_typedef() const
19253 {return priv_->naming_typedef_.lock();}
19254 
19255 /// Set the naming typedef of the current instance of @ref class_decl.
19256 ///
19257 /// Consider the C idiom:
19258 ///
19259 ///    typedef struct {int member;} foo_type;
19260 ///
19261 /// In that idiom, foo_type is the naming typedef of the anonymous
19262 /// struct that is declared.
19263 ///
19264 /// @param typedef_type the new naming typedef.
19265 void
set_naming_typedef(const typedef_decl_sptr & typedef_type)19266 class_or_union::set_naming_typedef(const typedef_decl_sptr& typedef_type)
19267 {
19268   priv_->naming_typedef_ = typedef_type;
19269 }
19270 
19271 /// Get the member types of this @ref class_or_union.
19272 ///
19273 /// @return a vector of the member types of this ref class_or_union.
19274 const class_or_union::member_types&
get_member_types() const19275 class_or_union::get_member_types() const
19276 {return priv_->member_types_;}
19277 
19278 /// Get the number of anonymous member classes contained in this
19279 /// class.
19280 ///
19281 /// @return the number of anonymous member classes contained in this
19282 /// class.
19283 size_t
get_num_anonymous_member_classes() const19284 class_or_union::get_num_anonymous_member_classes() const
19285 {
19286   int result = 0;
19287   for (member_types::const_iterator it = get_member_types().begin();
19288        it != get_member_types().end();
19289        ++it)
19290     if (class_decl_sptr t = is_class_type(*it))
19291       if (t->get_is_anonymous())
19292 	++result;
19293 
19294   return result;
19295 }
19296 
19297 /// Get the number of anonymous member unions contained in this class.
19298 ///
19299 /// @return the number of anonymous member unions contained in this
19300 /// class.
19301 size_t
get_num_anonymous_member_unions() const19302 class_or_union::get_num_anonymous_member_unions() const
19303 {
19304   int result = 0;
19305   for (member_types::const_iterator it = get_member_types().begin();
19306        it != get_member_types().end();
19307        ++it)
19308     if (union_decl_sptr t = is_union_type(*it))
19309       if (t->get_is_anonymous())
19310 	++result;
19311 
19312   return result;
19313 }
19314 
19315 /// Get the number of anonymous member enums contained in this class.
19316 ///
19317 /// @return the number of anonymous member enums contained in this
19318 /// class.
19319 size_t
get_num_anonymous_member_enums() const19320 class_or_union::get_num_anonymous_member_enums() const
19321 {
19322   int result = 0;
19323   for (member_types::const_iterator it = get_member_types().begin();
19324        it != get_member_types().end();
19325        ++it)
19326     if (enum_type_decl_sptr t = is_enum_type(*it))
19327       if (t->get_is_anonymous())
19328 	++result;
19329 
19330   return result;
19331 }
19332 
19333 /// Find a member type of a given name, inside the current @ref
19334 /// class_or_union.
19335 ///
19336 /// @param name the name of the member type to look for.
19337 ///
19338 /// @return a pointer to the @ref type_base that represents the member
19339 /// type of name @p name, for the current class.
19340 type_base_sptr
find_member_type(const string & name) const19341 class_or_union::find_member_type(const string& name) const
19342 {
19343   for (member_types::const_iterator i = get_member_types().begin();
19344        i != get_member_types().end();
19345        ++i)
19346     if (get_type_name(*i, /*qualified*/false) == name)
19347       return *i;
19348   return type_base_sptr();
19349 }
19350 
19351 /// Add a data member to the current instance of class_or_union.
19352 ///
19353 /// @param v a var_decl to add as a data member.  A proper
19354 /// class_or_union::data_member is created from @p v and added to the
19355 /// class_or_union.  This var_decl should not have been already added
19356 /// to a scope.
19357 ///
19358 /// @param access the access specifier for the data member.
19359 ///
19360 /// @param is_laid_out whether the data member was laid out.  That is,
19361 /// if its offset has been computed.  In the pattern of a class
19362 /// template for instance, this would be set to false.
19363 ///
19364 /// @param is_static whether the data memer is static.
19365 ///
19366 /// @param offset_in_bits if @p is_laid_out is true, this is the
19367 /// offset of the data member, expressed (oh, surprise) in bits.
19368 void
add_data_member(var_decl_sptr v,access_specifier access,bool is_laid_out,bool is_static,size_t offset_in_bits)19369 class_or_union::add_data_member(var_decl_sptr v, access_specifier access,
19370 				bool is_laid_out, bool is_static,
19371 				size_t offset_in_bits)
19372 {
19373   ABG_ASSERT(!has_scope(v));
19374 
19375   priv_->data_members_.push_back(v);
19376   scope_decl::add_member_decl(v);
19377   set_data_member_is_laid_out(v, is_laid_out);
19378   set_data_member_offset(v, offset_in_bits);
19379   set_member_access_specifier(v, access);
19380   set_member_is_static(v, is_static);
19381 
19382   if (!is_static)
19383     {
19384       // If this is a non-static variable, add it to the set of
19385       // non-static variables, if it's not only in there.
19386       bool is_already_in = false;
19387       for (data_members::const_iterator i =
19388 	     priv_->non_static_data_members_.begin();
19389 	   i != priv_->non_static_data_members_.end();
19390 	   ++i)
19391 	if (*i == v)
19392 	  {
19393 	    is_already_in = true;
19394 	    break;
19395 	  }
19396       if (!is_already_in)
19397 	priv_->non_static_data_members_.push_back(v);
19398     }
19399 
19400   // If v is an anonymous data member, then fixup its data members.
19401   // For now, the only thing the fixup does is to make the data
19402   // members of the anonymous data member be aware of their containing
19403   // anonymous data member.  That is helpful to compute the absolute
19404   // bit offset of each of the members of the anonymous data member.
19405   maybe_fixup_members_of_anon_data_member(v);
19406 }
19407 
19408 /// Get the data members of this @ref class_or_union.
19409 ///
19410 /// @return a vector of the data members of this @ref class_or_union.
19411 const class_or_union::data_members&
get_data_members() const19412 class_or_union::get_data_members() const
19413 {return priv_->data_members_;}
19414 
19415 /// Find a data member of a given name in the current @ref class_or_union.
19416 ///
19417 /// @param name the name of the data member to find in the current
19418 /// @ref class_or_union.
19419 ///
19420 /// @return a pointer to the @ref var_decl that represents the data
19421 /// member to find inside the current @ref class_or_union.
19422 const var_decl_sptr
find_data_member(const string & name) const19423 class_or_union::find_data_member(const string& name) const
19424 {
19425   for (data_members::const_iterator i = get_data_members().begin();
19426        i != get_data_members().end();
19427        ++i)
19428     if ((*i)->get_name() == name)
19429       return *i;
19430 
19431   // We haven't found a data member with the name 'name'.  Let's look
19432   // closer again, this time in our anonymous data members.
19433   for (data_members::const_iterator i = get_data_members().begin();
19434        i != get_data_members().end();
19435        ++i)
19436     if (is_anonymous_data_member(*i))
19437       {
19438 	class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
19439 	ABG_ASSERT(type);
19440 	if (var_decl_sptr data_member = type->find_data_member(name))
19441 	  return data_member;
19442       }
19443 
19444   return var_decl_sptr();
19445 }
19446 
19447 /// Find an anonymous data member in the class.
19448 ///
19449 /// @param v the anonymous data member to find.
19450 ///
19451 /// @return the anonymous data member found, or nil if none was found.
19452 const var_decl_sptr
find_anonymous_data_member(const var_decl_sptr & v) const19453 class_or_union::find_anonymous_data_member(const var_decl_sptr& v) const
19454 {
19455   if (!v->get_name().empty())
19456     return var_decl_sptr();
19457 
19458   for (data_members::const_iterator it = get_non_static_data_members().begin();
19459        it != get_non_static_data_members().end();
19460        ++it)
19461     {
19462       if (is_anonymous_data_member(*it))
19463 	if ((*it)->get_pretty_representation(true, true)
19464 	    == v->get_pretty_representation(true, true))
19465 	  return *it;
19466     }
19467 
19468   return var_decl_sptr();
19469 }
19470 
19471 /// Find a given data member.
19472 ///
19473 /// This function takes a @ref var_decl as an argument.  If it has a
19474 /// non-empty name, then it tries to find a data member which has the
19475 /// same name as the argument.
19476 ///
19477 /// If it has an empty name, then the @ref var_decl is considered as
19478 /// an anonymous data member.  In that case, this function tries to
19479 /// find an anonymous data member which type equals that of the @ref
19480 /// var_decl argument.
19481 ///
19482 /// @param v this carries either the name of the data member we need
19483 /// to look for, or the type of the anonymous data member we are
19484 /// looking for.
19485 const var_decl_sptr
find_data_member(const var_decl_sptr & v) const19486 class_or_union::find_data_member(const var_decl_sptr& v) const
19487 {
19488   if (!v)
19489     return var_decl_sptr();
19490 
19491   if (v->get_name().empty())
19492     return find_anonymous_data_member(v);
19493 
19494   return find_data_member(v->get_name());
19495 }
19496 
19497 
19498 /// Get the non-static data memebers of this @ref class_or_union.
19499 ///
19500 /// @return a vector of the non-static data members of this @ref
19501 /// class_or_union.
19502 const class_or_union::data_members&
get_non_static_data_members() const19503 class_or_union::get_non_static_data_members() const
19504 {return priv_->non_static_data_members_;}
19505 
19506 /// Add a member function.
19507 ///
19508 /// @param f the new member function to add.
19509 ///
19510 /// @param a the access specifier to use for the new member function.
19511 ///
19512 /// @param is_static whether the new member function is static.
19513 ///
19514 /// @param is_ctor whether the new member function is a constructor.
19515 ///
19516 /// @param is_dtor whether the new member function is a destructor.
19517 ///
19518 /// @param is_const whether the new member function is const.
19519 void
add_member_function(method_decl_sptr f,access_specifier a,bool is_static,bool is_ctor,bool is_dtor,bool is_const)19520 class_or_union::add_member_function(method_decl_sptr f,
19521 				    access_specifier a,
19522 				    bool is_static, bool is_ctor,
19523 				    bool is_dtor, bool is_const)
19524 {
19525   ABG_ASSERT(!has_scope(f));
19526 
19527   scope_decl::add_member_decl(f);
19528 
19529   set_member_function_is_ctor(f, is_ctor);
19530   set_member_function_is_dtor(f, is_dtor);
19531   set_member_access_specifier(f, a);
19532   set_member_is_static(f, is_static);
19533   set_member_function_is_const(f, is_const);
19534 
19535   priv_->member_functions_.push_back(f);
19536 
19537   // Update the map of linkage name -> member functions.  It's useful,
19538   // so that class_or_union::find_member_function() can function.
19539   if (!f->get_linkage_name().empty())
19540     priv_->mem_fns_map_[f->get_linkage_name()] = f;
19541 }
19542 
19543 /// Get the member functions of this @ref class_or_union.
19544 ///
19545 /// @return a vector of the member functions of this @ref
19546 /// class_or_union.
19547 const class_or_union::member_functions&
get_member_functions() const19548 class_or_union::get_member_functions() const
19549 {return priv_->member_functions_;}
19550 
19551 /// Find a method, using its linkage name as a key.
19552 ///
19553 /// @param linkage_name the linkage name of the method to find.
19554 ///
19555 /// @return the method found, or nil if none was found.
19556 const method_decl*
find_member_function(const string & linkage_name) const19557 class_or_union::find_member_function(const string& linkage_name) const
19558 {
19559   return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
19560 }
19561 
19562 /// Find a method, using its linkage name as a key.
19563 ///
19564 /// @param linkage_name the linkage name of the method to find.
19565 ///
19566 /// @return the method found, or nil if none was found.
19567 method_decl*
find_member_function(const string & linkage_name)19568 class_or_union::find_member_function(const string& linkage_name)
19569 {
19570   string_mem_fn_sptr_map_type::const_iterator i =
19571     priv_->mem_fns_map_.find(linkage_name);
19572   if (i == priv_->mem_fns_map_.end())
19573     return 0;
19574   return i->second.get();
19575 }
19576 
19577 /// Find a method, using its linkage name as a key.
19578 ///
19579 /// @param linkage_name the linkage name of the method to find.
19580 ///
19581 /// @return the method found, or nil if none was found.
19582 method_decl_sptr
find_member_function_sptr(const string & linkage_name)19583 class_or_union::find_member_function_sptr(const string& linkage_name)
19584 {
19585   string_mem_fn_sptr_map_type::const_iterator i =
19586     priv_->mem_fns_map_.find(linkage_name);
19587   if (i == priv_->mem_fns_map_.end())
19588     return 0;
19589   return i->second;
19590 }
19591 
19592 /// Find a method (member function) using its signature (pretty
19593 /// representation) as a key.
19594 ///
19595 /// @param s the signature of the method.
19596 ///
19597 /// @return the method found, or nil if none was found.
19598 const method_decl*
find_member_function_from_signature(const string & s) const19599 class_or_union::find_member_function_from_signature(const string& s) const
19600 {
19601   return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
19602 }
19603 
19604 /// Find a method (member function) using its signature (pretty
19605 /// representation) as a key.
19606 ///
19607 /// @param s the signature of the method.
19608 ///
19609 /// @return the method found, or nil if none was found.
19610 method_decl*
find_member_function_from_signature(const string & s)19611 class_or_union::find_member_function_from_signature(const string& s)
19612 {
19613   string_mem_fn_ptr_map_type::const_iterator i =
19614     priv_->signature_2_mem_fn_map_.find(s);
19615   if (i == priv_->signature_2_mem_fn_map_.end())
19616     return 0;
19617   return i->second;
19618 }
19619 
19620 /// Get the member function templates of this class.
19621 ///
19622 /// @return a vector of the member function templates of this class.
19623 const member_function_templates&
get_member_function_templates() const19624 class_or_union::get_member_function_templates() const
19625 {return priv_->member_function_templates_;}
19626 
19627 /// Get the member class templates of this class.
19628 ///
19629 /// @return a vector of the member class templates of this class.
19630 const member_class_templates&
get_member_class_templates() const19631 class_or_union::get_member_class_templates() const
19632 {return priv_->member_class_templates_;}
19633 
19634 /// Append a member function template to the @ref class_or_union.
19635 ///
19636 /// @param m the member function template to append.
19637 void
add_member_function_template(member_function_template_sptr m)19638 class_or_union::add_member_function_template(member_function_template_sptr m)
19639 {
19640   decl_base* c = m->as_function_tdecl()->get_scope();
19641   /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
19642   /// error message or something like a structured error.
19643   priv_->member_function_templates_.push_back(m);
19644   if (!c)
19645     scope_decl::add_member_decl(m->as_function_tdecl());
19646 }
19647 
19648 /// Append a member class template to the @ref class_or_union.
19649 ///
19650 /// @param m the member function template to append.
19651 void
add_member_class_template(member_class_template_sptr m)19652 class_or_union::add_member_class_template(member_class_template_sptr m)
19653 {
19654   decl_base* c = m->as_class_tdecl()->get_scope();
19655   /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
19656   /// error message or something like a structured error.
19657   m->set_scope(this);
19658   priv_->member_class_templates_.push_back(m);
19659   if (!c)
19660     scope_decl::add_member_decl(m->as_class_tdecl());
19661 }
19662 
19663 ///@return true iff the current instance has no member.
19664 bool
has_no_member() const19665 class_or_union::has_no_member() const
19666 {
19667   return (priv_->member_types_.empty()
19668 	  && priv_->data_members_.empty()
19669 	  && priv_->member_functions_.empty()
19670 	  && priv_->member_function_templates_.empty()
19671 	  && priv_->member_class_templates_.empty());
19672 }
19673 
19674 /// Insert a data member to this @ref class_or_union type.
19675 ///
19676 /// @param d the data member to insert.
19677 ///
19678 /// @param before an iterator to the point before which to insert the
19679 /// the data member, in the coontainer that contains all the data
19680 /// members.
19681 decl_base_sptr
insert_member_decl(decl_base_sptr d,declarations::iterator before)19682 class_or_union::insert_member_decl(decl_base_sptr d,
19683 				   declarations::iterator before)
19684 {
19685   if (type_base_sptr t = dynamic_pointer_cast<type_base>(d))
19686     insert_member_type(t, before);
19687   else if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
19688     {
19689       add_data_member(v, public_access,
19690 		      /*is_laid_out=*/false,
19691 		      /*is_static=*/true,
19692 		      /*offset_in_bits=*/0);
19693       d = v;
19694     }
19695   else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
19696     add_member_function(f, public_access,
19697 			/*is_static=*/false,
19698 			/*is_ctor=*/false,
19699 			/*is_dtor=*/false,
19700 			/*is_const=*/false);
19701   else if (member_function_template_sptr f =
19702 	   dynamic_pointer_cast<member_function_template>(d))
19703     add_member_function_template(f);
19704   else if (member_class_template_sptr c =
19705 	   dynamic_pointer_cast<member_class_template>(d))
19706     add_member_class_template(c);
19707   else
19708     scope_decl::add_member_decl(d);
19709 
19710   return d;
19711 }
19712 
19713 /// Equality operator.
19714 ///
19715 /// @param other the other @ref class_or_union to compare against.
19716 ///
19717 /// @return true iff @p other equals the current @ref class_or_union.
19718 bool
operator ==(const decl_base & other) const19719 class_or_union::operator==(const decl_base& other) const
19720 {
19721   const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
19722   if (!op)
19723     return false;
19724 
19725   // If this is a decl-only type (and thus with no canonical type),
19726   // use the canonical type of the definition, if any.
19727   const class_or_union *l = 0;
19728   if (get_is_declaration_only())
19729     l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
19730   if (l == 0)
19731     l = this;
19732 
19733   // Likewise for the other class.
19734   const class_or_union *r = 0;
19735   if (op->get_is_declaration_only())
19736     r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
19737   if (r == 0)
19738     r = op;
19739 
19740   return try_canonical_compare(l, r);
19741 }
19742 
19743 /// Equality operator.
19744 ///
19745 /// @param other the other @ref class_or_union to compare against.
19746 ///
19747 /// @return true iff @p other equals the current @ref class_or_union.
19748 bool
operator ==(const type_base & other) const19749 class_or_union::operator==(const type_base& other) const
19750 {
19751   const decl_base* o = dynamic_cast<const decl_base*>(&other);
19752   if (!o)
19753     return false;
19754   return *this == *o;
19755 }
19756 
19757 /// Equality operator.
19758 ///
19759 /// @param other the other @ref class_or_union to compare against.
19760 ///
19761 /// @return true iff @p other equals the current @ref class_or_union.
19762 bool
operator ==(const class_or_union & other) const19763 class_or_union::operator==(const class_or_union& other) const
19764 {
19765   const decl_base& o = other;
19766   return class_or_union::operator==(o);
19767 }
19768 
19769 /// Compares two instances of @ref class_or_union.
19770 ///
19771 /// If the two intances are different, set a bitfield to give some
19772 /// insight about the kind of differences there are.
19773 ///
19774 /// @param l the first artifact of the comparison.
19775 ///
19776 /// @param r the second artifact of the comparison.
19777 ///
19778 /// @param k a pointer to a bitfield that gives information about the
19779 /// kind of changes there are between @p l and @p r.  This one is set
19780 /// iff it's non-null and if the function returns false.
19781 ///
19782 /// Please note that setting k to a non-null value does have a
19783 /// negative performance impact because even if @p l and @p r are not
19784 /// equal, the function keeps up the comparison in order to determine
19785 /// the different kinds of ways in which they are different.
19786 ///
19787 /// @return true if @p l equals @p r, false otherwise.
19788 bool
equals(const class_or_union & l,const class_or_union & r,change_kind * k)19789 equals(const class_or_union& l, const class_or_union& r, change_kind* k)
19790 {
19791 #define RETURN(value)				\
19792   do {						\
19793     l.priv_->unmark_as_being_compared(l);	\
19794     l.priv_->unmark_as_being_compared(r);	\
19795     return value;				\
19796   } while(0)
19797 
19798   // if one of the classes is declaration-only, look through it to
19799   // get its definition.
19800   bool l_is_decl_only = l.get_is_declaration_only();
19801   bool r_is_decl_only = r.get_is_declaration_only();
19802   if (l_is_decl_only || r_is_decl_only)
19803     {
19804       const class_or_union* def1 = l_is_decl_only
19805 	? is_class_or_union_type(l.get_naked_definition_of_declaration())
19806 	: &l;
19807 
19808       const class_or_union* def2 = r_is_decl_only
19809 	? is_class_or_union_type(r.get_naked_definition_of_declaration())
19810 	: &r;
19811 
19812       if (!def1 || !def2)
19813 	{
19814 	  if (!l.get_is_anonymous()
19815 	      && !r.get_is_anonymous()
19816 	      && l_is_decl_only && r_is_decl_only
19817 	      && comparison::filtering::is_decl_only_class_with_size_change(l, r))
19818 	    // The two decl-only classes differ from their size.  A
19819 	    // true decl-only class should not have a size property to
19820 	    // begin with.  This comes from a DWARF oddity and can
19821 	    // results in a false positive, so let's not consider that
19822 	    // change.
19823 	    return true;
19824 
19825 	  if (l.get_environment()->decl_only_class_equals_definition()
19826 	      && !l.get_is_anonymous()
19827 	      && !r.get_is_anonymous())
19828 	    {
19829 	      const interned_string& q1 = l.get_scoped_name();
19830 	      const interned_string& q2 = r.get_scoped_name();
19831 	      if (q1 == q2)
19832 		// Not using RETURN(true) here, because that causes
19833 		// performance issues.  We don't need to do
19834 		// l.priv_->unmark_as_being_compared({l,r}) here because
19835 		// we haven't marked l or r as being compared yet, and
19836 		// doing so has a peformance cost that shows up on
19837 		// performance profiles for *big* libraries.
19838 		return true;
19839 	      else
19840 		{
19841 		  if (k)
19842 		    *k |= LOCAL_TYPE_CHANGE_KIND;
19843 		  // Not using RETURN(true) here, because that causes
19844 		  // performance issues.  We don't need to do
19845 		  // l.priv_->unmark_as_being_compared({l,r}) here because
19846 		  // we haven't marked l or r as being compared yet, and
19847 		  // doing so has a peformance cost that shows up on
19848 		  // performance profiles for *big* libraries.
19849 		  return false;
19850 		}
19851 	    }
19852 	  else // A decl-only class is considered different from a
19853 	       // class definition of the same name.
19854 	    {
19855 	      if (!!def1 != !!def2)
19856 		{
19857 		  if (k)
19858 		    *k |= LOCAL_TYPE_CHANGE_KIND;
19859 		  return false;
19860 		}
19861 
19862 	      // both definitions are empty
19863 	      if (!(l.decl_base::operator==(r)
19864 		       && l.type_base::operator==(r)))
19865 		{
19866 		  if (k)
19867 		    *k |= LOCAL_TYPE_CHANGE_KIND;
19868 		  return false;
19869 		}
19870 
19871 	      return true;
19872 	    }
19873 	}
19874 
19875       if (l.priv_->comparison_started(l)
19876 	  || l.priv_->comparison_started(r))
19877 	return true;
19878 
19879       l.priv_->mark_as_being_compared(l);
19880       l.priv_->mark_as_being_compared(r);
19881 
19882       bool val = *def1 == *def2;
19883       if (!val)
19884 	if (k)
19885 	  *k |= LOCAL_TYPE_CHANGE_KIND;
19886       RETURN(val);
19887     }
19888 
19889   // No need to go further if the classes have different names or
19890   // different size / alignment.
19891   if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
19892     {
19893       if (k)
19894 	*k |= LOCAL_TYPE_CHANGE_KIND;
19895       return false;
19896     }
19897 
19898   if (types_defined_same_linux_kernel_corpus_public(l, r))
19899     return true;
19900 
19901   if (l.priv_->comparison_started(l)
19902       || l.priv_->comparison_started(r))
19903     return true;
19904 
19905   l.priv_->mark_as_being_compared(l);
19906   l.priv_->mark_as_being_compared(r);
19907 
19908   bool result = true;
19909 
19910   //compare data_members
19911   {
19912     if (l.get_non_static_data_members().size()
19913 	!= r.get_non_static_data_members().size())
19914       {
19915 	result = false;
19916 	if (k)
19917 	  *k |= LOCAL_TYPE_CHANGE_KIND;
19918 	else
19919 	  RETURN(result);
19920       }
19921 
19922     for (class_or_union::data_members::const_iterator
19923 	   d0 = l.get_non_static_data_members().begin(),
19924 	   d1 = r.get_non_static_data_members().begin();
19925 	 (d0 != l.get_non_static_data_members().end()
19926 	  && d1 != r.get_non_static_data_members().end());
19927 	 ++d0, ++d1)
19928       if (**d0 != **d1)
19929 	{
19930 	  result = false;
19931 	  if (k)
19932 	    {
19933 	      // Report any representation change as being local.
19934 	      if (!types_have_similar_structure((*d0)->get_type(),
19935 						(*d1)->get_type())
19936 		  || (*d0)->get_type() == (*d1)->get_type())
19937 		*k |= LOCAL_TYPE_CHANGE_KIND;
19938 	      else
19939 		*k |= SUBTYPE_CHANGE_KIND;
19940 	    }
19941 	  else
19942 	    RETURN(result);
19943 	}
19944   }
19945 
19946   // Do not compare member functions.  DWARF does not necessarily
19947   // all the member functions, be they virtual or not, in all
19948   // translation units.  So we cannot have a clear view of them, per
19949   // class
19950 
19951   // compare member function templates
19952   {
19953     if (l.get_member_function_templates().size()
19954 	!= r.get_member_function_templates().size())
19955       {
19956 	result = false;
19957 	if (k)
19958 	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19959 	else
19960 	  RETURN(result);
19961       }
19962 
19963     for (member_function_templates::const_iterator
19964 	   fn_tmpl_it0 = l.get_member_function_templates().begin(),
19965 	   fn_tmpl_it1 = r.get_member_function_templates().begin();
19966 	 fn_tmpl_it0 != l.get_member_function_templates().end()
19967 	   &&  fn_tmpl_it1 != r.get_member_function_templates().end();
19968 	 ++fn_tmpl_it0, ++fn_tmpl_it1)
19969       if (**fn_tmpl_it0 != **fn_tmpl_it1)
19970 	{
19971 	  result = false;
19972 	  if (k)
19973 	    {
19974 	      *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19975 	      break;
19976 	    }
19977 	  else
19978 	    RETURN(result);
19979 	}
19980   }
19981 
19982   // compare member class templates
19983   {
19984     if (l.get_member_class_templates().size()
19985 	!= r.get_member_class_templates().size())
19986       {
19987 	result = false;
19988 	if (k)
19989 	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19990 	else
19991 	  RETURN(result);
19992       }
19993 
19994     for (member_class_templates::const_iterator
19995 	   cl_tmpl_it0 = l.get_member_class_templates().begin(),
19996 	   cl_tmpl_it1 = r.get_member_class_templates().begin();
19997 	 cl_tmpl_it0 != l.get_member_class_templates().end()
19998 	   &&  cl_tmpl_it1 != r.get_member_class_templates().end();
19999 	 ++cl_tmpl_it0, ++cl_tmpl_it1)
20000       if (**cl_tmpl_it0 != **cl_tmpl_it1)
20001 	{
20002 	  result = false;
20003 	  if (k)
20004 	    {
20005 	      *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20006 	      break;
20007 	    }
20008 	  else
20009 	    RETURN(result);
20010 	}
20011   }
20012 
20013   RETURN(result);
20014 #undef RETURN
20015 }
20016 
20017 
20018 /// Copy a method of a @ref class_or_union into a new @ref
20019 /// class_or_union.
20020 ///
20021 /// @param t the @ref class_or_union into which the method is to be copied.
20022 ///
20023 /// @param method the method to copy into @p t.
20024 ///
20025 /// @return the resulting newly copied method.
20026 method_decl_sptr
copy_member_function(const class_or_union_sptr & t,const method_decl_sptr & method)20027 copy_member_function(const class_or_union_sptr& t,
20028 		     const method_decl_sptr& method)
20029 {return copy_member_function(t, method.get());}
20030 
20031 
20032 /// Copy a method of a @ref class_or_union into a new @ref
20033 /// class_or_union.
20034 ///
20035 /// @param t the @ref class_or_union into which the method is to be copied.
20036 ///
20037 /// @param method the method to copy into @p t.
20038 ///
20039 /// @return the resulting newly copied method.
20040 method_decl_sptr
copy_member_function(const class_or_union_sptr & t,const method_decl * method)20041 copy_member_function(const class_or_union_sptr& t, const method_decl* method)
20042 {
20043   ABG_ASSERT(t);
20044   ABG_ASSERT(method);
20045 
20046   method_type_sptr old_type = method->get_type();
20047   ABG_ASSERT(old_type);
20048   method_type_sptr new_type(new method_type(old_type->get_return_type(),
20049 					    t,
20050 					    old_type->get_parameters(),
20051 					    old_type->get_is_const(),
20052 					    old_type->get_size_in_bits(),
20053 					    old_type->get_alignment_in_bits()));
20054   new_type->set_environment(t->get_environment());
20055   keep_type_alive(new_type);
20056 
20057   method_decl_sptr
20058     new_method(new method_decl(method->get_name(),
20059 			       new_type,
20060 			       method->is_declared_inline(),
20061 			       method->get_location(),
20062 			       method->get_linkage_name(),
20063 			       method->get_visibility(),
20064 			       method->get_binding()));
20065   new_method->set_symbol(method->get_symbol());
20066 
20067   if (class_decl_sptr class_type = is_class_type(t))
20068     class_type->add_member_function(new_method,
20069 				    get_member_access_specifier(*method),
20070 				    get_member_function_is_virtual(*method),
20071 				    get_member_function_vtable_offset(*method),
20072 				    get_member_is_static(*method),
20073 				    get_member_function_is_ctor(*method),
20074 				    get_member_function_is_dtor(*method),
20075 				    get_member_function_is_const(*method));
20076   else
20077     t->add_member_function(new_method,
20078 			   get_member_access_specifier(*method),
20079 			   get_member_is_static(*method),
20080 			   get_member_function_is_ctor(*method),
20081 			   get_member_function_is_dtor(*method),
20082 			   get_member_function_is_const(*method));
20083   return new_method;
20084 }
20085 
20086 // </class_or_union definitions>
20087 
20088 /// Test if two @ref class_decl or @ref function_type are already
20089 /// being compared.
20090 ///
20091 /// @param lhs_type the first type that would be involved in a
20092 /// potential comparison.
20093 ///
20094 /// @param rhs_type the second type that would involved in a potential
20095 /// comparison.
20096 ///
20097 /// @return true iff @p lhs_type and @p rhs_type are being compared.
20098 static bool
types_are_being_compared(const type_base & lhs_type,const type_base & rhs_type)20099 types_are_being_compared(const type_base& lhs_type,
20100 			 const type_base& rhs_type)
20101 {
20102   type_base *l = &const_cast<type_base&>(lhs_type);
20103   type_base *r = &const_cast<type_base&>(rhs_type);
20104 
20105   if (class_or_union *l_cou = is_class_or_union_type(l))
20106     if (class_or_union *r_cou = is_class_or_union_type(r))
20107       return (l_cou->priv_->comparison_started(*l_cou)
20108 	      || l_cou->priv_->comparison_started(*r_cou));
20109 
20110   if (function_type *l_fn_type = is_function_type(l))
20111     if (function_type *r_fn_type = is_function_type(r))
20112       return (l_fn_type->priv_->comparison_started(*l_fn_type)
20113 	      || l_fn_type->priv_->comparison_started(*r_fn_type));
20114 
20115   return false;
20116 }
20117 
20118 /// @defgroup OnTheFlyCanonicalization On-the-fly Canonicalization
20119 /// @{
20120 ///
20121 /// During the canonicalization of a type T (which doesn't yet have a
20122 /// canonical type), T is compared structurally (member-wise) against
20123 /// a type C which already has a canonical type.  The comparison
20124 /// expression is C == T.
20125 ///
20126 /// During that structural comparison, if a subtype of C (which also
20127 /// already has a canonical type) is structurally compared to a
20128 /// subtype of T (which doesn't yet have a canonical type) and if they
20129 /// are equal, then we can deduce that the canonical type of the
20130 /// subtype of C is the canonical type of the subtype of C.
20131 ///
20132 /// Thus, we can canonicalize the sub-type of the T, during the
20133 /// canonicalization of T itself.  That canonicalization of the
20134 /// sub-type of T is what we call the "on-the-fly canonicalization".
20135 /// It's on the fly because it happens during a comparison -- which
20136 /// itself happens during the canonicalization of T.
20137 ///
20138 /// For now this on-the-fly canonicalization only happens when
20139 /// comparing @ref class_decl and @ref function_type.
20140 ///
20141 /// @}
20142 
20143 
20144 /// If on-the-fly canonicalization is turned on, then this function
20145 /// sets the canonical type of its second parameter to the canonical
20146 /// type of the first parameter.
20147 ///
20148 /// @param lhs_type the type which canonical type to propagate.
20149 ///
20150 /// @param rhs_type the type which canonical type to set.
20151 static void
maybe_propagate_canonical_type(const type_base & lhs_type,const type_base & rhs_type)20152 maybe_propagate_canonical_type(const type_base& lhs_type,
20153 			       const type_base& rhs_type)
20154 {
20155 
20156   if (const environment *env = lhs_type.get_environment())
20157     if (env->do_on_the_fly_canonicalization())
20158       if (type_base_sptr canonical_type = lhs_type.get_canonical_type())
20159 	if (!rhs_type.get_canonical_type()
20160 	    && !types_are_being_compared(lhs_type, rhs_type))
20161 	  {
20162 	    const_cast<type_base&>(rhs_type).priv_->canonical_type =
20163 	      canonical_type;
20164 	    const_cast<type_base&>(rhs_type).priv_->naked_canonical_type =
20165 	      canonical_type.get();
20166 	  }
20167 }
20168 
20169 // <class_decl definitions>
20170 
20171 static void
20172 sort_virtual_member_functions(class_decl::member_functions& mem_fns);
20173 
20174 /// The private data for the class_decl type.
20175 struct class_decl::priv
20176 {
20177   base_specs					bases_;
20178   unordered_map<string, base_spec_sptr>	bases_map_;
20179   member_functions				virtual_mem_fns_;
20180   virtual_mem_fn_map_type			virtual_mem_fns_map_;
20181   bool						is_struct_;
20182 
privabigail::ir::class_decl::priv20183   priv()
20184     : is_struct_(false)
20185   {}
20186 
privabigail::ir::class_decl::priv20187   priv(bool is_struct, class_decl::base_specs& bases)
20188     : bases_(bases),
20189       is_struct_(is_struct)
20190   {
20191   }
20192 
privabigail::ir::class_decl::priv20193   priv(bool is_struct)
20194     : is_struct_(is_struct)
20195   {}
20196 };// end struct class_decl::priv
20197 
20198 /// A Constructor for instances of \ref class_decl
20199 ///
20200 /// @param env the environment we are operating from.
20201 ///
20202 /// @param name the identifier of the class.
20203 ///
20204 /// @param size_in_bits the size of an instance of class_decl, expressed
20205 /// in bits
20206 ///
20207 /// @param align_in_bits the alignment of an instance of class_decl,
20208 /// expressed in bits.
20209 ///
20210 /// @param locus the source location of declaration point this class.
20211 ///
20212 /// @param vis the visibility of instances of class_decl.
20213 ///
20214 /// @param bases the vector of base classes for this instance of class_decl.
20215 ///
20216 /// @param mbrs the vector of member types of this instance of
20217 /// class_decl.
20218 ///
20219 /// @param data_mbrs the vector of data members of this instance of
20220 /// class_decl.
20221 ///
20222 /// @param mbr_fns the vector of member functions of this instance of
20223 /// class_decl.
class_decl(const environment * env,const string & name,size_t size_in_bits,size_t align_in_bits,bool is_struct,const location & locus,visibility vis,base_specs & bases,member_types & mbr_types,data_members & data_mbrs,member_functions & mbr_fns)20224 class_decl::class_decl(const environment* env, const string& name,
20225 		       size_t size_in_bits, size_t align_in_bits,
20226 		       bool is_struct, const location& locus,
20227 		       visibility vis, base_specs& bases,
20228 		       member_types& mbr_types,
20229 		       data_members& data_mbrs,
20230 		       member_functions& mbr_fns)
20231   : type_or_decl_base(env,
20232 		      CLASS_TYPE
20233 		      | ABSTRACT_TYPE_BASE
20234 		      | ABSTRACT_DECL_BASE
20235 		      | ABSTRACT_SCOPE_TYPE_DECL
20236 		      | ABSTRACT_SCOPE_DECL),
20237     decl_base(env, name, locus, name, vis),
20238     type_base(env, size_in_bits, align_in_bits),
20239     class_or_union(env, name, size_in_bits, align_in_bits,
20240 		   locus, vis, mbr_types, data_mbrs, mbr_fns),
20241     priv_(new priv(is_struct, bases))
20242 {
20243   runtime_type_instance(this);
20244 }
20245 
20246 /// A Constructor for instances of @ref class_decl
20247 ///
20248 /// @param env the environment we are operating from.
20249 ///
20250 /// @param name the identifier of the class.
20251 ///
20252 /// @param size_in_bits the size of an instance of class_decl, expressed
20253 /// in bits
20254 ///
20255 /// @param align_in_bits the alignment of an instance of class_decl,
20256 /// expressed in bits.
20257 ///
20258 /// @param locus the source location of declaration point this class.
20259 ///
20260 /// @param vis the visibility of instances of class_decl.
20261 ///
20262 /// @param bases the vector of base classes for this instance of class_decl.
20263 ///
20264 /// @param mbrs the vector of member types of this instance of
20265 /// class_decl.
20266 ///
20267 /// @param data_mbrs the vector of data members of this instance of
20268 /// class_decl.
20269 ///
20270 /// @param mbr_fns the vector of member functions of this instance of
20271 /// class_decl.
20272 ///
20273 /// @param is_anonymous whether the newly created instance is
20274 /// anonymous.
class_decl(const environment * env,const string & name,size_t size_in_bits,size_t align_in_bits,bool is_struct,const location & locus,visibility vis,base_specs & bases,member_types & mbr_types,data_members & data_mbrs,member_functions & mbr_fns,bool is_anonymous)20275 class_decl::class_decl(const environment* env, const string& name,
20276 		       size_t size_in_bits, size_t align_in_bits,
20277 		       bool is_struct, const location& locus,
20278 		       visibility vis, base_specs& bases,
20279 		       member_types& mbr_types, data_members& data_mbrs,
20280 		       member_functions& mbr_fns, bool is_anonymous)
20281   : type_or_decl_base(env,
20282 		      CLASS_TYPE
20283 		      | ABSTRACT_TYPE_BASE
20284 		      | ABSTRACT_DECL_BASE
20285 		      | ABSTRACT_SCOPE_TYPE_DECL
20286 		      | ABSTRACT_SCOPE_DECL),
20287     decl_base(env, name, locus,
20288 	      // If the class is anonymous then by default it won't
20289 	      // have a linkage name.  Also, the anonymous class does
20290 	      // have an internal-only unique name that is generally
20291 	      // not taken into account when comparing classes; such a
20292 	      // unique internal-only name, when used as a linkage
20293 	      // name might introduce spurious comparison false
20294 	      // negatives.
20295 	      /*linkage_name=*/is_anonymous ? string() : name,
20296 	      vis),
20297     type_base(env, size_in_bits, align_in_bits),
20298     class_or_union(env, name, size_in_bits, align_in_bits,
20299 		   locus, vis, mbr_types, data_mbrs, mbr_fns),
20300     priv_(new priv(is_struct, bases))
20301 {
20302   runtime_type_instance(this);
20303   set_is_anonymous(is_anonymous);
20304 }
20305 
20306 /// A constructor for instances of class_decl.
20307 ///
20308 /// @param env the environment we are operating from.
20309 ///
20310 /// @param name the name of the class.
20311 ///
20312 /// @param size_in_bits the size of an instance of class_decl, expressed
20313 /// in bits
20314 ///
20315 /// @param align_in_bits the alignment of an instance of class_decl,
20316 /// expressed in bits.
20317 ///
20318 /// @param locus the source location of declaration point this class.
20319 ///
20320 /// @param vis the visibility of instances of class_decl.
class_decl(const environment * env,const string & name,size_t size_in_bits,size_t align_in_bits,bool is_struct,const location & locus,visibility vis)20321 class_decl::class_decl(const environment* env, const string& name,
20322 		       size_t size_in_bits, size_t align_in_bits,
20323 		       bool is_struct, const location& locus,
20324 		       visibility vis)
20325   : type_or_decl_base(env,
20326 		      CLASS_TYPE
20327 		      | ABSTRACT_TYPE_BASE
20328 		      | ABSTRACT_DECL_BASE
20329 		      | ABSTRACT_SCOPE_TYPE_DECL
20330 		      | ABSTRACT_SCOPE_DECL),
20331     decl_base(env, name, locus, name, vis),
20332     type_base(env, size_in_bits, align_in_bits),
20333     class_or_union(env, name, size_in_bits, align_in_bits,
20334 		   locus, vis),
20335     priv_(new priv(is_struct))
20336 {
20337   runtime_type_instance(this);
20338 }
20339 
20340 /// A constructor for instances of @ref class_decl.
20341 ///
20342 /// @param env the environment we are operating from.
20343 ///
20344 /// @param name the name of the class.
20345 ///
20346 /// @param size_in_bits the size of an instance of class_decl, expressed
20347 /// in bits
20348 ///
20349 /// @param align_in_bits the alignment of an instance of class_decl,
20350 /// expressed in bits.
20351 ///
20352 /// @param locus the source location of declaration point this class.
20353 ///
20354 /// @param vis the visibility of instances of class_decl.
20355 ///
20356 /// @param is_anonymous whether the newly created instance is
20357 /// anonymous.
class_decl(const environment * env,const string & name,size_t size_in_bits,size_t align_in_bits,bool is_struct,const location & locus,visibility vis,bool is_anonymous)20358 class_decl:: class_decl(const environment* env, const string& name,
20359 			size_t size_in_bits, size_t align_in_bits,
20360 			bool is_struct, const location& locus,
20361 			visibility vis, bool is_anonymous)
20362   : type_or_decl_base(env,
20363 		      CLASS_TYPE
20364 		      | ABSTRACT_TYPE_BASE
20365 		      | ABSTRACT_DECL_BASE
20366 		      | ABSTRACT_SCOPE_TYPE_DECL
20367 		      | ABSTRACT_SCOPE_DECL),
20368     decl_base(env, name, locus,
20369 	      // If the class is anonymous then by default it won't
20370 	      // have a linkage name.  Also, the anonymous class does
20371 	      // have an internal-only unique name that is generally
20372 	      // not taken into account when comparing classes; such a
20373 	      // unique internal-only name, when used as a linkage
20374 	      // name might introduce spurious comparison false
20375 	      // negatives.
20376 	      /*linkage_name=*/ is_anonymous ? string() : name,
20377 	      vis),
20378     type_base(env, size_in_bits, align_in_bits),
20379     class_or_union(env, name, size_in_bits, align_in_bits,
20380 		   locus, vis),
20381   priv_(new priv(is_struct))
20382 {
20383   runtime_type_instance(this);
20384   set_is_anonymous(is_anonymous);
20385 }
20386 
20387 /// A constuctor for instances of class_decl that represent a
20388 /// declaration without definition.
20389 ///
20390 /// @param env the environment we are operating from.
20391 ///
20392 /// @param name the name of the class.
20393 ///
20394 /// @param is_declaration_only a boolean saying whether the instance
20395 /// represents a declaration only, or not.
class_decl(const environment * env,const string & name,bool is_struct,bool is_declaration_only)20396 class_decl::class_decl(const environment* env, const string& name,
20397 		       bool is_struct, bool is_declaration_only)
20398   : type_or_decl_base(env,
20399 		      CLASS_TYPE
20400 		      | ABSTRACT_TYPE_BASE
20401 		      | ABSTRACT_DECL_BASE
20402 		      | ABSTRACT_SCOPE_TYPE_DECL
20403 		      | ABSTRACT_SCOPE_DECL),
20404     decl_base(env, name, location(), name),
20405     type_base(env, 0, 0),
20406     class_or_union(env, name, is_declaration_only),
20407     priv_(new priv(is_struct))
20408 {
20409   runtime_type_instance(this);
20410 }
20411 
20412 /// This method is invoked automatically right after the current
20413 /// instance of @ref class_decl has been canonicalized.
20414 ///
20415 /// Currently, the only thing it does is to sort the virtual member
20416 /// functions vector.
20417 void
on_canonical_type_set()20418 class_decl::on_canonical_type_set()
20419 {
20420   sort_virtual_mem_fns();
20421 
20422   for (class_decl::virtual_mem_fn_map_type::iterator i =
20423 	 priv_->virtual_mem_fns_map_.begin();
20424        i != priv_->virtual_mem_fns_map_.end();
20425        ++i)
20426     sort_virtual_member_functions(i->second);
20427 }
20428 
20429 /// Set the "is-struct" flag of the class.
20430 ///
20431 /// @param f the new value of the flag.
20432 void
is_struct(bool f)20433 class_decl::is_struct(bool f)
20434 {priv_->is_struct_ = f;}
20435 
20436 /// Test if the class is a struct.
20437 ///
20438 /// @return true iff the class is a struct.
20439 bool
is_struct() const20440 class_decl::is_struct() const
20441 {return priv_->is_struct_;}
20442 
20443 /// Add a base specifier to this class.
20444 ///
20445 /// @param b the new base specifier.
20446 void
add_base_specifier(base_spec_sptr b)20447 class_decl::add_base_specifier(base_spec_sptr b)
20448 {
20449   ABG_ASSERT(get_environment());
20450   ABG_ASSERT(b->get_environment() == get_environment());
20451   priv_->bases_.push_back(b);
20452   priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
20453   if (const environment* env = get_environment())
20454     b->set_environment(env);
20455 }
20456 
20457 /// Get the base specifiers for this class.
20458 ///
20459 /// @return a vector of the base specifiers.
20460 const class_decl::base_specs&
get_base_specifiers() const20461 class_decl::get_base_specifiers() const
20462 {return priv_->bases_;}
20463 
20464 /// Find a base class of a given qualified name for the current class.
20465 ///
20466 /// @param qualified_name the qualified name of the base class to look for.
20467 ///
20468 /// @return a pointer to the @ref class_decl that represents the base
20469 /// class of name @p qualified_name, if found.
20470 class_decl_sptr
find_base_class(const string & qualified_name) const20471 class_decl::find_base_class(const string& qualified_name) const
20472 {
20473   unordered_map<string, base_spec_sptr>::iterator i =
20474     priv_->bases_map_.find(qualified_name);
20475 
20476   if (i != priv_->bases_map_.end())
20477     return i->second->get_base_class();
20478 
20479   return class_decl_sptr();
20480 }
20481 
20482 /// Get the virtual member functions of this class.
20483 ///
20484 /// @param return a vector of the virtual member functions of this
20485 /// class.
20486 const class_decl::member_functions&
get_virtual_mem_fns() const20487 class_decl::get_virtual_mem_fns() const
20488 {return priv_->virtual_mem_fns_;}
20489 
20490 /// Get the map that associates a virtual table offset to the virtual
20491 /// member functions with that virtual table offset.
20492 ///
20493 /// Usually, there should be a 1:1 mapping between a given vtable
20494 /// offset and virtual member functions of that vtable offset.  But
20495 /// because of some implementation details, there can be several C++
20496 /// destructor functions that are *generated* by compilers, for a
20497 /// given destructor that is defined in the source code.  If the
20498 /// destructor is virtual then those generated functions have some
20499 /// DWARF attributes in common with the constructor that the user
20500 /// actually defined in its source code.  Among those attributes are
20501 /// the vtable offset of the destructor.
20502 ///
20503 /// @return the map that associates a virtual table offset to the
20504 /// virtual member functions with that virtual table offset.
20505 const class_decl::virtual_mem_fn_map_type&
get_virtual_mem_fns_map() const20506 class_decl::get_virtual_mem_fns_map() const
20507 {return priv_->virtual_mem_fns_map_;}
20508 
20509 /// Sort the virtual member functions by their virtual index.
20510 void
sort_virtual_mem_fns()20511 class_decl::sort_virtual_mem_fns()
20512 {sort_virtual_member_functions(priv_->virtual_mem_fns_);}
20513 
20514 /// Getter of the pretty representation of the current instance of
20515 /// @ref class_decl.
20516 ///
20517 /// @param internal set to true if the call is intended for an
20518 /// internal use (for technical use inside the library itself), false
20519 /// otherwise.  If you don't know what this is for, then set it to
20520 /// false.
20521 ///
20522 /// @param qualified_name if true, names emitted in the pretty
20523 /// representation are fully qualified.
20524 ///
20525 /// @return the pretty representaion for a class_decl.
20526 string
get_pretty_representation(bool internal,bool qualified_name) const20527 class_decl::get_pretty_representation(bool internal,
20528 				      bool qualified_name) const
20529 {
20530   string cl = "class ";
20531   if (!internal && is_struct())
20532     cl = "struct ";
20533 
20534   // When computing the pretty representation for internal purposes,
20535   // if an anonymous class is named by a typedef, then consider that
20536   // it has a name, which is the typedef name.
20537   if (get_is_anonymous())
20538     return get_class_or_union_flat_representation(this, "",
20539 						  /*one_line=*/true,
20540 						  internal);
20541 
20542   string result = cl;
20543   if (qualified_name)
20544     result += get_qualified_name(internal);
20545   else
20546     result += get_name();
20547 
20548   return result;
20549 }
20550 
20551 decl_base_sptr
insert_member_decl(decl_base_sptr d,declarations::iterator before)20552 class_decl::insert_member_decl(decl_base_sptr d,
20553 			       declarations::iterator before)
20554 {
20555   if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
20556     add_member_function(f, public_access,
20557 			/*is_virtual=*/false,
20558 			/*vtable_offset=*/0,
20559 			/*is_static=*/false,
20560 			/*is_ctor=*/false,
20561 			/*is_dtor=*/false,
20562 			/*is_const=*/false);
20563   else
20564     d = class_or_union::insert_member_decl(d, before);
20565 
20566   return d;
20567 }
20568 
20569 /// The private data structure of class_decl::base_spec.
20570 struct class_decl::base_spec::priv
20571 {
20572   class_decl_wptr	base_class_;
20573   long			offset_in_bits_;
20574   bool			is_virtual_;
20575 
privabigail::ir::class_decl::base_spec::priv20576   priv(const class_decl_sptr& cl,
20577        long offset_in_bits,
20578        bool is_virtual)
20579     : base_class_(cl),
20580       offset_in_bits_(offset_in_bits),
20581       is_virtual_(is_virtual)
20582   {}
20583 };
20584 
20585 /// Constructor for base_spec instances.
20586 ///
20587 /// @param base the base class to consider
20588 ///
20589 /// @param a the access specifier of the base class.
20590 ///
20591 /// @param offset_in_bits if positive or null, represents the offset
20592 /// of the base in the layout of its containing type..  If negative,
20593 /// means that the current base is not laid out in its containing type.
20594 ///
20595 /// @param is_virtual if true, means that the current base class is
20596 /// virtual in it's containing type.
base_spec(const class_decl_sptr & base,access_specifier a,long offset_in_bits,bool is_virtual)20597 class_decl::base_spec::base_spec(const class_decl_sptr& base,
20598 				 access_specifier a,
20599 				 long offset_in_bits,
20600 				 bool is_virtual)
20601   : type_or_decl_base(base->get_environment(),
20602 		      ABSTRACT_DECL_BASE),
20603     decl_base(base->get_environment(), base->get_name(), base->get_location(),
20604 	      base->get_linkage_name(), base->get_visibility()),
20605     member_base(a),
20606     priv_(new priv(base, offset_in_bits, is_virtual))
20607 {
20608   runtime_type_instance(this);
20609 }
20610 
20611 /// Get the base class referred to by the current base class
20612 /// specifier.
20613 ///
20614 /// @return the base class.
20615 class_decl_sptr
get_base_class() const20616 class_decl::base_spec::get_base_class() const
20617 {return priv_->base_class_.lock();}
20618 
20619 /// Getter of the "is-virtual" proprerty of the base class specifier.
20620 ///
20621 /// @return true iff this specifies a virtual base class.
20622 bool
get_is_virtual() const20623 class_decl::base_spec::get_is_virtual() const
20624 {return priv_->is_virtual_;}
20625 
20626 /// Getter of the offset of the base.
20627 ///
20628 /// @return the offset of the base.
20629 long
get_offset_in_bits() const20630 class_decl::base_spec::get_offset_in_bits() const
20631 {return priv_->offset_in_bits_;}
20632 
20633 /// Calculate the hash value for a class_decl::base_spec.
20634 ///
20635 /// @return the hash value.
20636 size_t
get_hash() const20637 class_decl::base_spec::get_hash() const
20638 {
20639   base_spec::hash h;
20640   return h(*this);
20641 }
20642 
20643 /// Traverses an instance of @ref class_decl::base_spec, visiting all
20644 /// the sub-types and decls that it might contain.
20645 ///
20646 /// @param v the visitor that is used to visit every IR sub-node of
20647 /// the current node.
20648 ///
20649 /// @return true if either
20650 ///  - all the children nodes of the current IR node were traversed
20651 ///    and the calling code should keep going with the traversing.
20652 ///  - or the current IR node is already being traversed.
20653 /// Otherwise, returning false means that the calling code should not
20654 /// keep traversing the tree.
20655 bool
traverse(ir_node_visitor & v)20656 class_decl::base_spec::traverse(ir_node_visitor& v)
20657 {
20658   if (visiting())
20659     return true;
20660 
20661   if (v.visit_begin(this))
20662     {
20663       visiting(true);
20664       get_base_class()->traverse(v);
20665       visiting(false);
20666     }
20667 
20668   return v.visit_end(this);
20669 }
20670 
20671 /// Constructor for base_spec instances.
20672 ///
20673 /// Note that this constructor is for clients that don't support RTTI
20674 /// and that have a base class of type_base, but of dynamic type
20675 /// class_decl.
20676 ///
20677 /// @param base the base class to consider.  Must be a pointer to an
20678 /// instance of class_decl
20679 ///
20680 /// @param a the access specifier of the base class.
20681 ///
20682 /// @param offset_in_bits if positive or null, represents the offset
20683 /// of the base in the layout of its containing type..  If negative,
20684 /// means that the current base is not laid out in its containing type.
20685 ///
20686 /// @param is_virtual if true, means that the current base class is
20687 /// virtual in it's containing type.
base_spec(const type_base_sptr & base,access_specifier a,long offset_in_bits,bool is_virtual)20688 class_decl::base_spec::base_spec(const type_base_sptr& base,
20689 				 access_specifier a,
20690 				 long offset_in_bits,
20691 				 bool is_virtual)
20692   : type_or_decl_base(base->get_environment(),
20693 		      ABSTRACT_DECL_BASE),
20694     decl_base(base->get_environment(), get_type_declaration(base)->get_name(),
20695 	      get_type_declaration(base)->get_location(),
20696 	      get_type_declaration(base)->get_linkage_name(),
20697 	      get_type_declaration(base)->get_visibility()),
20698     member_base(a),
20699     priv_(new priv(dynamic_pointer_cast<class_decl>(base),
20700 		   offset_in_bits,
20701 		   is_virtual))
20702 {
20703   runtime_type_instance(this);
20704 }
20705 
20706 /// Compares two instances of @ref class_decl::base_spec.
20707 ///
20708 /// If the two intances are different, set a bitfield to give some
20709 /// insight about the kind of differences there are.
20710 ///
20711 /// @param l the first artifact of the comparison.
20712 ///
20713 /// @param r the second artifact of the comparison.
20714 ///
20715 /// @param k a pointer to a bitfield that gives information about the
20716 /// kind of changes there are between @p l and @p r.  This one is set
20717 /// iff @p k is non-null and the function returns false.
20718 ///
20719 /// Please note that setting k to a non-null value does have a
20720 /// negative performance impact because even if @p l and @p r are not
20721 /// equal, the function keeps up the comparison in order to determine
20722 /// the different kinds of ways in which they are different.
20723 ///
20724 /// @return true if @p l equals @p r, false otherwise.
20725 bool
equals(const class_decl::base_spec & l,const class_decl::base_spec & r,change_kind * k)20726 equals(const class_decl::base_spec& l,
20727        const class_decl::base_spec& r,
20728        change_kind* k)
20729 {
20730   if (!l.member_base::operator==(r))
20731     {
20732       if (k)
20733 	*k |= LOCAL_TYPE_CHANGE_KIND;
20734       return false;
20735     }
20736 
20737   return (*l.get_base_class() == *r.get_base_class());
20738 }
20739 
20740 /// Comparison operator for @ref class_decl::base_spec.
20741 ///
20742 /// @param other the instance of @ref class_decl::base_spec to compare
20743 /// against.
20744 ///
20745 /// @return true if the current instance of @ref class_decl::base_spec
20746 /// equals @p other.
20747 bool
operator ==(const decl_base & other) const20748 class_decl::base_spec::operator==(const decl_base& other) const
20749 {
20750   const class_decl::base_spec* o =
20751     dynamic_cast<const class_decl::base_spec*>(&other);
20752 
20753   if (!o)
20754     return false;
20755 
20756   return equals(*this, *o, 0);
20757 }
20758 
20759 /// Comparison operator for @ref class_decl::base_spec.
20760 ///
20761 /// @param other the instance of @ref class_decl::base_spec to compare
20762 /// against.
20763 ///
20764 /// @return true if the current instance of @ref class_decl::base_spec
20765 /// equals @p other.
20766 bool
operator ==(const member_base & other) const20767 class_decl::base_spec::operator==(const member_base& other) const
20768 {
20769   const class_decl::base_spec* o =
20770     dynamic_cast<const class_decl::base_spec*>(&other);
20771   if (!o)
20772     return false;
20773 
20774   return operator==(static_cast<const decl_base&>(*o));
20775 }
20776 
~mem_fn_context_rel()20777 mem_fn_context_rel::~mem_fn_context_rel()
20778 {
20779 }
20780 
20781 /// A constructor for instances of method_decl.
20782 ///
20783 /// @param name the name of the method.
20784 ///
20785 /// @param type the type of the method.
20786 ///
20787 /// @param declared_inline whether the method was
20788 /// declared inline or not.
20789 ///
20790 /// @param locus the source location of the method.
20791 ///
20792 /// @param linkage_name the mangled name of the method.
20793 ///
20794 /// @param vis the visibility of the method.
20795 ///
20796 /// @param bind the binding of the method.
method_decl(const string & name,method_type_sptr type,bool declared_inline,const location & locus,const string & linkage_name,visibility vis,binding bind)20797 method_decl::method_decl(const string&		name,
20798 			 method_type_sptr	type,
20799 			 bool			declared_inline,
20800 			 const location&	locus,
20801 			 const string&		linkage_name,
20802 			 visibility		vis,
20803 			 binding		bind)
20804   : type_or_decl_base(type->get_environment(),
20805 		      METHOD_DECL
20806 		      | ABSTRACT_DECL_BASE
20807 		      |FUNCTION_DECL),
20808     decl_base(type->get_environment(), name, locus, linkage_name, vis),
20809     function_decl(name, static_pointer_cast<function_type>(type),
20810 		  declared_inline, locus, linkage_name, vis, bind)
20811 {
20812   runtime_type_instance(this);
20813   set_context_rel(new mem_fn_context_rel(0));
20814   set_member_function_is_const(*this, type->get_is_const());
20815 }
20816 
20817 /// A constructor for instances of method_decl.
20818 ///
20819 /// @param name the name of the method.
20820 ///
20821 /// @param type the type of the method.  Must be an instance of
20822 /// method_type.
20823 ///
20824 /// @param declared_inline whether the method was
20825 /// declared inline or not.
20826 ///
20827 /// @param locus the source location of the method.
20828 ///
20829 /// @param linkage_name the mangled name of the method.
20830 ///
20831 /// @param vis the visibility of the method.
20832 ///
20833 /// @param bind the binding of the method.
method_decl(const string & name,function_type_sptr type,bool declared_inline,const location & locus,const string & linkage_name,visibility vis,binding bind)20834 method_decl::method_decl(const string&		name,
20835 			 function_type_sptr	type,
20836 			 bool			declared_inline,
20837 			 const location&	locus,
20838 			 const string&		linkage_name,
20839 			 visibility		vis,
20840 			 binding		bind)
20841   : type_or_decl_base(type->get_environment(),
20842 		      METHOD_DECL
20843 		      | ABSTRACT_DECL_BASE
20844 		      | FUNCTION_DECL),
20845     decl_base(type->get_environment(), name, locus, linkage_name, vis),
20846     function_decl(name, static_pointer_cast<function_type>
20847 		  (dynamic_pointer_cast<method_type>(type)),
20848 		  declared_inline, locus, linkage_name, vis, bind)
20849 {
20850   runtime_type_instance(this);
20851   set_context_rel(new mem_fn_context_rel(0));
20852 }
20853 
20854 /// A constructor for instances of method_decl.
20855 ///
20856 /// @param name the name of the method.
20857 ///
20858 /// @param type the type of the method.  Must be an instance of
20859 /// method_type.
20860 ///
20861 /// @param declared_inline whether the method was
20862 /// declared inline or not.
20863 ///
20864 /// @param locus the source location of the method.
20865 ///
20866 /// @param linkage_name the mangled name of the method.
20867 ///
20868 /// @param vis the visibility of the method.
20869 ///
20870 /// @param bind the binding of the method.
method_decl(const string & name,type_base_sptr type,bool declared_inline,const location & locus,const string & linkage_name,visibility vis,binding bind)20871 method_decl::method_decl(const string&		name,
20872 			 type_base_sptr	type,
20873 			 bool			declared_inline,
20874 			 const location&	locus,
20875 			 const string&		linkage_name,
20876 			 visibility		vis,
20877 			 binding		bind)
20878   : type_or_decl_base(type->get_environment(),
20879 		      METHOD_DECL
20880 		      | ABSTRACT_DECL_BASE
20881 		      | FUNCTION_DECL),
20882     decl_base(type->get_environment(), name, locus, linkage_name, vis),
20883     function_decl(name, static_pointer_cast<function_type>
20884 		  (dynamic_pointer_cast<method_type>(type)),
20885 		  declared_inline, locus, linkage_name, vis, bind)
20886 {
20887   runtime_type_instance(this);
20888   set_context_rel(new mem_fn_context_rel(0));
20889 }
20890 
20891 /// Set the linkage name of the method.
20892 ///
20893 /// @param l the new linkage name of the method.
20894 void
set_linkage_name(const string & l)20895 method_decl::set_linkage_name(const string& l)
20896 {
20897   decl_base::set_linkage_name(l);
20898   // Update the linkage_name -> member function map of the containing
20899   // class declaration.
20900   if (!l.empty())
20901     {
20902       method_type_sptr t = get_type();
20903       class_or_union_sptr cl = t->get_class_type();
20904       method_decl_sptr m(this, sptr_utils::noop_deleter());
20905       cl->priv_->mem_fns_map_[l] = m;
20906     }
20907 }
20908 
~method_decl()20909 method_decl::~method_decl()
20910 {}
20911 
20912 const method_type_sptr
get_type() const20913 method_decl::get_type() const
20914 {
20915   method_type_sptr result;
20916   if (function_decl::get_type())
20917     result = dynamic_pointer_cast<method_type>(function_decl::get_type());
20918   return result;
20919 }
20920 
20921 /// Set the containing class of a method_decl.
20922 ///
20923 /// @param scope the new containing class_decl.
20924 void
set_scope(scope_decl * scope)20925 method_decl::set_scope(scope_decl* scope)
20926 {
20927   if (!get_context_rel())
20928     set_context_rel(new mem_fn_context_rel(scope));
20929   else
20930     get_context_rel()->set_scope(scope);
20931 }
20932 
20933 /// Equality operator for @ref method_decl_sptr.
20934 ///
20935 /// This is a deep equality operator, as it compares the @ref
20936 /// method_decl that is pointed-to by the smart pointer.
20937 ///
20938 /// @param l the left-hand side argument of the equality operator.
20939 ///
20940 /// @param r the righ-hand side argument of the equality operator.
20941 ///
20942 /// @return true iff @p l equals @p r.
20943 bool
operator ==(const method_decl_sptr & l,const method_decl_sptr & r)20944 operator==(const method_decl_sptr& l, const method_decl_sptr& r)
20945 {
20946   if (l.get() == r.get())
20947     return true;
20948   if (!!l != !!r)
20949     return false;
20950 
20951   return *l == *r;
20952 }
20953 
20954 /// Inequality operator for @ref method_decl_sptr.
20955 ///
20956 /// This is a deep equality operator, as it compares the @ref
20957 /// method_decl that is pointed-to by the smart pointer.
20958 ///
20959 /// @param l the left-hand side argument of the equality operator.
20960 ///
20961 /// @param r the righ-hand side argument of the equality operator.
20962 ///
20963 /// @return true iff @p l differs from @p r.
20964 bool
operator !=(const method_decl_sptr & l,const method_decl_sptr & r)20965 operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
20966 {return !operator==(l, r);}
20967 
20968 /// Test if a function_decl is actually a method_decl.
20969 ///
20970 ///@param d the @ref function_decl to consider.
20971 ///
20972 /// @return the method_decl sub-object of @p d if inherits
20973 /// a method_decl type.
20974 method_decl*
is_method_decl(const type_or_decl_base * d)20975 is_method_decl(const type_or_decl_base *d)
20976 {
20977   return dynamic_cast<method_decl*>
20978     (const_cast<type_or_decl_base*>(d));
20979 }
20980 
20981 /// Test if a function_decl is actually a method_decl.
20982 ///
20983 ///@param d the @ref function_decl to consider.
20984 ///
20985 /// @return the method_decl sub-object of @p d if inherits
20986 /// a method_decl type.
20987 method_decl*
is_method_decl(const type_or_decl_base & d)20988 is_method_decl(const type_or_decl_base&d)
20989 {return is_method_decl(&d);}
20990 
20991 /// Test if a function_decl is actually a method_decl.
20992 ///
20993 ///@param d the @ref function_decl to consider.
20994 ///
20995 /// @return the method_decl sub-object of @p d if inherits
20996 /// a method_decl type.
20997 method_decl_sptr
is_method_decl(const type_or_decl_base_sptr & d)20998 is_method_decl(const type_or_decl_base_sptr& d)
20999 {return dynamic_pointer_cast<method_decl>(d);}
21000 
21001 /// A "less than" functor to sort a vector of instances of
21002 /// method_decl that are virtual.
21003 struct virtual_member_function_less_than
21004 {
21005   /// The less than operator.  First, it sorts the methods by their
21006   /// vtable index.  If they have the same vtable index, it sorts them
21007   /// by the name of their ELF symbol.  If they don't have elf
21008   /// symbols, it sorts them by considering their pretty
21009   /// representation.
21010   ///
21011   ///  Note that this method expects virtual methods.
21012   ///
21013   /// @param f the first method to consider.
21014   ///
21015   /// @param s the second method to consider.
21016   ///
21017   /// @return true if method @p is less than method @s.
21018   bool
operator ()abigail::ir::virtual_member_function_less_than21019   operator()(const method_decl& f,
21020 	     const method_decl& s)
21021   {
21022     ABG_ASSERT(get_member_function_is_virtual(f));
21023     ABG_ASSERT(get_member_function_is_virtual(s));
21024 
21025     ssize_t f_offset = get_member_function_vtable_offset(f);
21026     ssize_t s_offset = get_member_function_vtable_offset(s);
21027     if (f_offset != s_offset) return f_offset < s_offset;
21028 
21029     string fn, sn;
21030 
21031     // If the functions have symbols, then compare their symbol-id
21032     // string.
21033     elf_symbol_sptr f_sym = f.get_symbol();
21034     elf_symbol_sptr s_sym = s.get_symbol();
21035     if ((!f_sym) != (!s_sym)) return !f_sym;
21036     if (f_sym && s_sym)
21037       {
21038 	fn = f_sym->get_id_string();
21039 	sn = s_sym->get_id_string();
21040 	if (fn != sn) return fn < sn;
21041       }
21042 
21043     // Try the linkage names (important for destructors).
21044     fn = f.get_linkage_name();
21045     sn = s.get_linkage_name();
21046     if (fn != sn) return fn < sn;
21047 
21048     // None of the functions have symbols or linkage names that
21049     // distinguish them, so compare their pretty representation.
21050     fn = f.get_pretty_representation();
21051     sn = s.get_pretty_representation();
21052     if (fn != sn) return fn < sn;
21053 
21054     /// If it's just the file paths that are different then sort them
21055     /// too.
21056     string fn_filepath, sn_filepath;
21057     unsigned line = 0, column = 0;
21058     location fn_loc = f.get_location(), sn_loc = s.get_location();
21059     if (fn_loc)
21060       fn_loc.expand(fn_filepath, line, column);
21061     if (sn_loc)
21062       sn_loc.expand(sn_filepath, line, column);
21063     return fn_filepath < sn_filepath;
21064   }
21065 
21066   /// The less than operator.  First, it sorts the methods by their
21067   /// vtable index.  If they have the same vtable index, it sorts them
21068   /// by the name of their ELF symbol.  If they don't have elf
21069   /// symbols, it sorts them by considering their pretty
21070   /// representation.
21071   ///
21072   ///  Note that this method expects to take virtual methods.
21073   ///
21074   /// @param f the first method to consider.
21075   ///
21076   /// @param s the second method to consider.
21077   bool
operator ()abigail::ir::virtual_member_function_less_than21078   operator()(const method_decl_sptr f,
21079 	     const method_decl_sptr s)
21080   {return operator()(*f, *s);}
21081 }; // end struct virtual_member_function_less_than
21082 
21083 /// Sort a vector of instances of virtual member functions.
21084 ///
21085 /// @param mem_fns the vector of member functions to sort.
21086 static void
sort_virtual_member_functions(class_decl::member_functions & mem_fns)21087 sort_virtual_member_functions(class_decl::member_functions& mem_fns)
21088 {
21089   virtual_member_function_less_than lt;
21090   std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
21091 }
21092 
21093 /// Add a member function to the current instance of @ref class_or_union.
21094 ///
21095 /// @param f a method_decl to add to the current class.  This function
21096 /// should not have been already added to a scope.
21097 ///
21098 /// @param access the access specifier for the member function to add.
21099 ///
21100 /// @param is_virtual if this is true then it means the function @p f
21101 /// is a virtual function.  That also means that the current instance
21102 /// of @ref class_or_union is actually an instance of @ref class_decl.
21103 ///
21104 /// @param vtable_offset the offset of the member function in the
21105 /// virtual table.  This parameter is taken into account only if @p
21106 /// is_virtual is true.
21107 ///
21108 /// @param is_static whether the member function is static.
21109 ///
21110 /// @param is_ctor whether the member function is a constructor.
21111 ///
21112 /// @param is_dtor whether the member function is a destructor.
21113 ///
21114 /// @param is_const whether the member function is const.
21115 void
add_member_function(method_decl_sptr f,access_specifier a,bool is_virtual,size_t vtable_offset,bool is_static,bool is_ctor,bool is_dtor,bool is_const)21116 class_or_union::add_member_function(method_decl_sptr f,
21117 				    access_specifier a,
21118 				    bool is_virtual,
21119 				    size_t vtable_offset,
21120 				    bool is_static, bool is_ctor,
21121 				    bool is_dtor, bool is_const)
21122 {
21123   add_member_function(f, a, is_static, is_ctor,
21124 		      is_dtor, is_const);
21125 
21126   if (class_decl* klass = is_class_type(this))
21127     {
21128       set_member_function_is_virtual(f, is_virtual);
21129       if (is_virtual)
21130 	{
21131 	  set_member_function_vtable_offset(f, vtable_offset);
21132 	  sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
21133 	}
21134     }
21135 }
21136 
21137 /// When a virtual member function has seen its virtualness set by
21138 /// set_member_function_is_virtual(), this function ensures that the
21139 /// member function is added to the specific vectors and maps of
21140 /// virtual member function of its class.
21141 ///
21142 /// @param method the method to fixup.
21143 void
fixup_virtual_member_function(method_decl_sptr method)21144 fixup_virtual_member_function(method_decl_sptr method)
21145 {
21146   if (!method || !get_member_function_is_virtual(method))
21147     return;
21148 
21149   class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
21150 
21151   class_decl::member_functions::const_iterator m;
21152   for (m = klass->priv_->virtual_mem_fns_.begin();
21153        m != klass->priv_->virtual_mem_fns_.end();
21154        ++m)
21155     if (m->get() == method.get())
21156       break;
21157   if (m == klass->priv_->virtual_mem_fns_.end())
21158     klass->priv_->virtual_mem_fns_.push_back(method);
21159 
21160   // Build or udpate the map that associates a vtable offset to the
21161   // number of virtual member functions that "point" to it.
21162   ssize_t voffset = get_member_function_vtable_offset(method);
21163   if (voffset == -1)
21164     return;
21165 
21166   class_decl::virtual_mem_fn_map_type::iterator i =
21167     klass->priv_->virtual_mem_fns_map_.find(voffset);
21168   if (i == klass->priv_->virtual_mem_fns_map_.end())
21169     {
21170       class_decl::member_functions virtual_mem_fns_at_voffset;
21171       virtual_mem_fns_at_voffset.push_back(method);
21172       klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
21173     }
21174   else
21175     {
21176       for (m = i->second.begin() ; m != i->second.end(); ++m)
21177 	if (m->get() == method.get())
21178 	  break;
21179       if (m == i->second.end())
21180 	i->second.push_back(method);
21181     }
21182 }
21183 
21184 /// Return true iff the class has no entity in its scope.
21185 bool
has_no_base_nor_member() const21186 class_decl::has_no_base_nor_member() const
21187 {return priv_->bases_.empty() && has_no_member();}
21188 
21189 /// Test if the current instance of @ref class_decl has virtual member
21190 /// functions.
21191 ///
21192 /// @return true iff the current instance of @ref class_decl has
21193 /// virtual member functions.
21194 bool
has_virtual_member_functions() const21195 class_decl::has_virtual_member_functions() const
21196 {return !get_virtual_mem_fns().empty();}
21197 
21198 /// Test if the current instance of @ref class_decl has at least one
21199 /// virtual base.
21200 ///
21201 /// @return true iff the current instance of @ref class_decl has a
21202 /// virtual member function.
21203 bool
has_virtual_bases() const21204 class_decl::has_virtual_bases() const
21205 {
21206   for (base_specs::const_iterator b = get_base_specifiers().begin();
21207        b != get_base_specifiers().end();
21208        ++b)
21209     if ((*b)->get_is_virtual()
21210 	|| (*b)->get_base_class()->has_virtual_bases())
21211       return true;
21212 
21213   return false;
21214 }
21215 
21216 /// Test if the current instance has a vtable.
21217 ///
21218 /// This is only valid for a C++ program.
21219 ///
21220 /// Basically this function checks if the class has either virtual
21221 /// functions, or virtual bases.
21222 bool
has_vtable() const21223 class_decl::has_vtable() const
21224 {
21225   if (has_virtual_member_functions()
21226       || has_virtual_bases())
21227     return true;
21228   return false;
21229 }
21230 
21231 /// Get the highest vtable offset of all the virtual methods of the
21232 /// class.
21233 ///
21234 /// @return the highest vtable offset of all the virtual methods of
21235 /// the class.
21236 ssize_t
get_biggest_vtable_offset() const21237 class_decl::get_biggest_vtable_offset() const
21238 {
21239   ssize_t offset = -1;
21240   for (class_decl::virtual_mem_fn_map_type::const_iterator e =
21241 	 get_virtual_mem_fns_map().begin();
21242        e != get_virtual_mem_fns_map().end();
21243        ++e)
21244     if (e->first > offset)
21245       offset = e->first;
21246 
21247   return offset;
21248 }
21249 
21250 /// Return the hash value for the current instance.
21251 ///
21252 /// @return the hash value.
21253 size_t
get_hash() const21254 class_decl::get_hash() const
21255 {
21256   class_decl::hash hash_class;
21257   return hash_class(this);
21258 }
21259 
21260 /// Test if two methods are equal without taking their symbol or
21261 /// linkage name into account.
21262 ///
21263 /// @param f the first method.
21264 ///
21265 /// @param s the second method.
21266 ///
21267 /// @return true iff @p f equals @p s without taking their linkage
21268 /// name or symbol into account.
21269 static bool
methods_equal_modulo_elf_symbol(const method_decl_sptr & f,const method_decl_sptr & s)21270 methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
21271 				const method_decl_sptr& s)
21272 {
21273   method_decl_sptr first = f, second = s;
21274   elf_symbol_sptr saved_first_elf_symbol =
21275     first->get_symbol();
21276   elf_symbol_sptr saved_second_elf_symbol =
21277     second->get_symbol();
21278   interned_string saved_first_linkage_name =
21279     first->get_linkage_name();
21280   interned_string saved_second_linkage_name =
21281     second->get_linkage_name();
21282 
21283   first->set_symbol(elf_symbol_sptr());
21284   first->set_linkage_name("");
21285   second->set_symbol(elf_symbol_sptr());
21286   second->set_linkage_name("");
21287 
21288   bool equal = *first == *second;
21289 
21290   first->set_symbol(saved_first_elf_symbol);
21291   first->set_linkage_name(saved_first_linkage_name);
21292   second->set_symbol(saved_second_elf_symbol);
21293   second->set_linkage_name(saved_second_linkage_name);
21294 
21295   return equal;
21296 }
21297 
21298 /// Test if a given method is equivalent to at least of other method
21299 /// that is in a vector of methods.
21300 ///
21301 /// Note that "equivalent" here means being equal without taking the
21302 /// linkage name or the symbol of the methods into account.
21303 ///
21304 /// This is a sub-routine of the 'equals' function that compares @ref
21305 /// class_decl.
21306 ///
21307 /// @param method the method to compare.
21308 ///
21309 /// @param fns the vector of functions to compare @p method against.
21310 ///
21311 /// @return true iff @p is equivalent to at least one method in @p
21312 /// fns.
21313 static bool
method_matches_at_least_one_in_vector(const method_decl_sptr & method,const class_decl::member_functions & fns)21314 method_matches_at_least_one_in_vector(const method_decl_sptr& method,
21315 				      const class_decl::member_functions& fns)
21316 {
21317   for (class_decl::member_functions::const_iterator i = fns.begin();
21318        i != fns.end();
21319        ++i)
21320     if (methods_equal_modulo_elf_symbol(*i, method))
21321       return true;
21322 
21323   return false;
21324 }
21325 
21326 /// Compares two instances of @ref class_decl.
21327 ///
21328 /// If the two intances are different, set a bitfield to give some
21329 /// insight about the kind of differences there are.
21330 ///
21331 /// @param l the first artifact of the comparison.
21332 ///
21333 /// @param r the second artifact of the comparison.
21334 ///
21335 /// @param k a pointer to a bitfield that gives information about the
21336 /// kind of changes there are between @p l and @p r.  This one is set
21337 /// iff @p k is non-null and the function returns false.
21338 ///
21339 /// Please note that setting k to a non-null value does have a
21340 /// negative performance impact because even if @p l and @p r are not
21341 /// equal, the function keeps up the comparison in order to determine
21342 /// the different kinds of ways in which they are different.
21343 ///
21344 /// @return true if @p l equals @p r, false otherwise.
21345 bool
equals(const class_decl & l,const class_decl & r,change_kind * k)21346 equals(const class_decl& l, const class_decl& r, change_kind* k)
21347 {
21348   // if one of the classes is declaration-only then we take a fast
21349   // path here.
21350   if (l.get_is_declaration_only() || r.get_is_declaration_only())
21351     return equals(static_cast<const class_or_union&>(l),
21352 		  static_cast<const class_or_union&>(r),
21353 		  k);
21354 
21355   if (l.class_or_union::priv_->comparison_started(l)
21356       || l.class_or_union::priv_->comparison_started(r))
21357     return true;
21358 
21359   bool result = true;
21360   if (!equals(static_cast<const class_or_union&>(l),
21361 	      static_cast<const class_or_union&>(r),
21362 	      k))
21363     {
21364       result = false;
21365       if (!k)
21366 	return result;
21367     }
21368 
21369   l.class_or_union::priv_->mark_as_being_compared(l);
21370   l.class_or_union::priv_->mark_as_being_compared(r);
21371 
21372 #define RETURN(value)						\
21373   do {								\
21374     l.class_or_union::priv_->unmark_as_being_compared(l);	\
21375     l.class_or_union::priv_->unmark_as_being_compared(r);	\
21376     if (value == true)						\
21377       maybe_propagate_canonical_type(l, r);			\
21378     return value;						\
21379   } while(0)
21380 
21381   // Compare bases.
21382     if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
21383       {
21384 	result = false;
21385 	if (k)
21386 	  *k |= LOCAL_TYPE_CHANGE_KIND;
21387 	else
21388 	  RETURN(result);
21389       }
21390 
21391     for (class_decl::base_specs::const_iterator
21392 	   b0 = l.get_base_specifiers().begin(),
21393 	   b1 = r.get_base_specifiers().begin();
21394 	 (b0 != l.get_base_specifiers().end()
21395 	 && b1 != r.get_base_specifiers().end());
21396 	 ++b0, ++b1)
21397       if (*b0 != *b1)
21398 	{
21399 	  result = false;
21400 	  if (k)
21401 	    {
21402 	      if (!types_have_similar_structure((*b0)->get_base_class().get(),
21403 						(*b1)->get_base_class().get()))
21404 		*k |= LOCAL_TYPE_CHANGE_KIND;
21405 	      else
21406 		*k |= SUBTYPE_CHANGE_KIND;
21407 	      break;
21408 	    }
21409 	  RETURN(result);
21410 	}
21411 
21412     // Compare virtual member functions
21413 
21414     // We look at the map that associates a given vtable offset to a
21415     // vector of virtual member functions that point to that offset.
21416     //
21417     // This is because there are cases where several functions can
21418     // point to the same virtual table offset.
21419     //
21420     // This is usually the case for virtual destructors.  Even though
21421     // there can be only one virtual destructor declared in source
21422     // code, there are actually potentially up to three generated
21423     // functions for that destructor.  Some of these generated
21424     // functions can be clones of other functions that are among those
21425     // generated ones.  In any cases, they all have the same
21426     // properties, including the vtable offset property.
21427 
21428     // So, there should be the same number of different vtable
21429     // offsets, the size of two maps must be equals.
21430     if (l.get_virtual_mem_fns_map().size()
21431 	!= r.get_virtual_mem_fns_map().size())
21432       {
21433 	result = false;
21434 	if (k)
21435 	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21436 	else
21437 	  RETURN(result);
21438       }
21439 
21440     // Then, each virtual member function of a given vtable offset in
21441     // the first class type, must match an equivalent virtual member
21442     // function of a the same vtable offset in the second class type.
21443     //
21444     // By "match", I mean that the two virtual member function should
21445     // be equal if we don't take into account their symbol name or
21446     // their linkage name.  This is because two destructor functions
21447     // clones (for instance) might have different linkage name, but
21448     // are still equivalent if their other properties are the same.
21449     for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
21450 	   l.get_virtual_mem_fns_map().begin();
21451 	 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
21452 	 ++first_v_fn_entry)
21453       {
21454 	unsigned voffset = first_v_fn_entry->first;
21455 	const class_decl::member_functions& first_vfns =
21456 	  first_v_fn_entry->second;
21457 
21458 	const class_decl::virtual_mem_fn_map_type::const_iterator
21459 	  second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
21460 
21461 	if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
21462 	  {
21463 	    result = false;
21464 	    if (k)
21465 	      *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21466 	    RETURN(result);
21467 	  }
21468 
21469 	const class_decl::member_functions& second_vfns =
21470 	  second_v_fn_entry->second;
21471 
21472 	bool matches = false;
21473 	for (class_decl::member_functions::const_iterator i =
21474 	       first_vfns.begin();
21475 	     i != first_vfns.end();
21476 	     ++i)
21477 	  if (method_matches_at_least_one_in_vector(*i, second_vfns))
21478 	    {
21479 	      matches = true;
21480 	      break;
21481 	    }
21482 
21483 	if (!matches)
21484 	  {
21485 	    result = false;
21486 	    if (k)
21487 	      *k |= SUBTYPE_CHANGE_KIND;
21488 	    else
21489 	      RETURN(result);
21490 	  }
21491       }
21492 
21493   RETURN(result);
21494 #undef RETURN
21495 }
21496 
21497 /// Copy a method of a class into a new class.
21498 ///
21499 /// @param klass the class into which the method is to be copied.
21500 ///
21501 /// @param method the method to copy into @p klass.
21502 ///
21503 /// @return the resulting newly copied method.
21504 method_decl_sptr
copy_member_function(const class_decl_sptr & clazz,const method_decl_sptr & f)21505 copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
21506 {return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
21507 
21508 /// Copy a method of a class into a new class.
21509 ///
21510 /// @param klass the class into which the method is to be copied.
21511 ///
21512 /// @param method the method to copy into @p klass.
21513 ///
21514 /// @return the resulting newly copied method.
21515 method_decl_sptr
copy_member_function(const class_decl_sptr & clazz,const method_decl * f)21516 copy_member_function(const class_decl_sptr& clazz, const method_decl* f)
21517 {return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
21518 
21519 /// Comparison operator for @ref class_decl.
21520 ///
21521 /// @param other the instance of @ref class_decl to compare against.
21522 ///
21523 /// @return true iff the current instance of @ref class_decl equals @p
21524 /// other.
21525 bool
operator ==(const decl_base & other) const21526 class_decl::operator==(const decl_base& other) const
21527 {
21528   const class_decl* op = is_class_type(&other);
21529   if (!op)
21530     return false;
21531 
21532   // If this is a decl-only type (and thus with no canonical type),
21533   // use the canonical type of the definition, if any.
21534   const class_decl *l = 0;
21535   if (get_is_declaration_only())
21536     l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
21537   if (l == 0)
21538     l = this;
21539 
21540   ABG_ASSERT(l);
21541 
21542   // Likewise for the other type.
21543   const class_decl *r = 0;
21544   if (op->get_is_declaration_only())
21545     r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
21546   if (r == 0)
21547     r = op;
21548 
21549   ABG_ASSERT(r);
21550 
21551   return try_canonical_compare(l, r);
21552 }
21553 
21554 /// Equality operator for class_decl.
21555 ///
21556 /// Re-uses the equality operator that takes a decl_base.
21557 ///
21558 /// @param other the other class_decl to compare against.
21559 ///
21560 /// @return true iff the current instance equals the other one.
21561 bool
operator ==(const type_base & other) const21562 class_decl::operator==(const type_base& other) const
21563 {
21564   const decl_base* o = is_decl(&other);
21565   if (!o)
21566     return false;
21567   return *this == *o;
21568 }
21569 
21570 /// Comparison operator for @ref class_decl.
21571 ///
21572 /// @param other the instance of @ref class_decl to compare against.
21573 ///
21574 /// @return true iff the current instance of @ref class_decl equals @p
21575 /// other.
21576 bool
operator ==(const class_decl & other) const21577 class_decl::operator==(const class_decl& other) const
21578 {
21579   const decl_base& o = other;
21580   return *this == o;
21581 }
21582 
21583 /// Turn equality of shared_ptr of class_decl into a deep equality;
21584 /// that is, make it compare the pointed to objects too.
21585 ///
21586 /// @param l the shared_ptr of class_decl on left-hand-side of the
21587 /// equality.
21588 ///
21589 /// @param r the shared_ptr of class_decl on right-hand-side of the
21590 /// equality.
21591 ///
21592 /// @return true if the class_decl pointed to by the shared_ptrs are
21593 /// equal, false otherwise.
21594 bool
operator ==(const class_decl_sptr & l,const class_decl_sptr & r)21595 operator==(const class_decl_sptr& l, const class_decl_sptr& r)
21596 {
21597   if (l.get() == r.get())
21598     return true;
21599   if (!!l != !!r)
21600     return false;
21601 
21602   return *l == *r;
21603 }
21604 
21605 /// Turn inequality of shared_ptr of class_decl into a deep equality;
21606 /// that is, make it compare the pointed to objects too.
21607 ///
21608 /// @param l the shared_ptr of class_decl on left-hand-side of the
21609 /// equality.
21610 ///
21611 /// @param r the shared_ptr of class_decl on right-hand-side of the
21612 /// equality.
21613 ///
21614 /// @return true if the class_decl pointed to by the shared_ptrs are
21615 /// different, false otherwise.
21616 bool
operator !=(const class_decl_sptr & l,const class_decl_sptr & r)21617 operator!=(const class_decl_sptr& l, const class_decl_sptr& r)
21618 {return !operator==(l, r);}
21619 
21620 /// Turn equality of shared_ptr of class_or_union into a deep
21621 /// equality; that is, make it compare the pointed to objects too.
21622 ///
21623 /// @param l the left-hand-side operand of the operator
21624 ///
21625 /// @param r the right-hand-side operand of the operator.
21626 ///
21627 /// @return true iff @p l equals @p r.
21628 bool
operator ==(const class_or_union_sptr & l,const class_or_union_sptr & r)21629 operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
21630 {
21631   if (l.get() == r.get())
21632     return true;
21633   if (!!l != !!r)
21634     return false;
21635 
21636   return *l == *r;
21637 }
21638 
21639 /// Turn inequality of shared_ptr of class_or_union into a deep
21640 /// equality; that is, make it compare the pointed to objects too.
21641 ///
21642 /// @param l the left-hand-side operand of the operator
21643 ///
21644 /// @param r the right-hand-side operand of the operator.
21645 ///
21646 /// @return true iff @p l is different from @p r.
21647 bool
operator !=(const class_or_union_sptr & l,const class_or_union_sptr & r)21648 operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
21649 {return !operator==(l, r);}
21650 
21651 /// This implements the ir_traversable_base::traverse pure virtual
21652 /// function.
21653 ///
21654 /// @param v the visitor used on the current instance and on its
21655 /// members.
21656 ///
21657 /// @return true if the entire IR node tree got traversed, false
21658 /// otherwise.
21659 bool
traverse(ir_node_visitor & v)21660 class_decl::traverse(ir_node_visitor& v)
21661 {
21662   if (v.type_node_has_been_visited(this))
21663     return true;
21664 
21665   if (visiting())
21666     return true;
21667 
21668   if (v.visit_begin(this))
21669     {
21670       visiting(true);
21671       bool stop = false;
21672 
21673       for (base_specs::const_iterator i = get_base_specifiers().begin();
21674 	   i != get_base_specifiers().end();
21675 	   ++i)
21676 	{
21677 	  if (!(*i)->traverse(v))
21678 	    {
21679 	      stop = true;
21680 	      break;
21681 	    }
21682 	}
21683 
21684       if (!stop)
21685 	for (data_members::const_iterator i = get_data_members().begin();
21686 	     i != get_data_members().end();
21687 	     ++i)
21688 	  if (!(*i)->traverse(v))
21689 	    {
21690 	      stop = true;
21691 	      break;
21692 	    }
21693 
21694       if (!stop)
21695 	for (member_functions::const_iterator i= get_member_functions().begin();
21696 	     i != get_member_functions().end();
21697 	     ++i)
21698 	  if (!(*i)->traverse(v))
21699 	    {
21700 	      stop = true;
21701 	      break;
21702 	    }
21703 
21704       if (!stop)
21705 	for (member_types::const_iterator i = get_member_types().begin();
21706 	     i != get_member_types().end();
21707 	     ++i)
21708 	  if (!(*i)->traverse(v))
21709 	    {
21710 	      stop = true;
21711 	      break;
21712 	    }
21713 
21714       if (!stop)
21715 	for (member_function_templates::const_iterator i =
21716 	       get_member_function_templates().begin();
21717 	     i != get_member_function_templates().end();
21718 	     ++i)
21719 	  if (!(*i)->traverse(v))
21720 	    {
21721 	      stop = true;
21722 	      break;
21723 	    }
21724 
21725       if (!stop)
21726 	for (member_class_templates::const_iterator i =
21727 	       get_member_class_templates().begin();
21728 	     i != get_member_class_templates().end();
21729 	     ++i)
21730 	  if (!(*i)->traverse(v))
21731 	    {
21732 	      stop = true;
21733 	      break;
21734 	    }
21735       visiting(false);
21736     }
21737 
21738   bool result = v.visit_end(this);
21739   v.mark_type_node_as_visited(this);
21740   return result;
21741 }
21742 
21743 /// Destructor of the @ref class_decl type.
~class_decl()21744 class_decl::~class_decl()
21745 {delete priv_;}
21746 
~context_rel()21747 context_rel::~context_rel()
21748 {}
21749 
21750 bool
operator ==(const member_base & o) const21751 member_base::operator==(const member_base& o) const
21752 {
21753   return (get_access_specifier() == o.get_access_specifier()
21754 	  && get_is_static() == o.get_is_static());
21755 }
21756 
21757 /// Equality operator for smart pointers to @ref
21758 /// class_decl::base_specs.
21759 ///
21760 /// This compares the pointed-to objects.
21761 ///
21762 /// @param l the first instance to consider.
21763 ///
21764 /// @param r the second instance to consider.
21765 ///
21766 /// @return true iff @p l equals @p r.
21767 bool
operator ==(const class_decl::base_spec_sptr & l,const class_decl::base_spec_sptr & r)21768 operator==(const class_decl::base_spec_sptr& l,
21769 	   const class_decl::base_spec_sptr& r)
21770 {
21771   if (l.get() == r.get())
21772     return true;
21773   if (!!l != !!r)
21774     return false;
21775 
21776   return *l == static_cast<const decl_base&>(*r);
21777 }
21778 
21779 /// Inequality operator for smart pointers to @ref
21780 /// class_decl::base_specs.
21781 ///
21782 /// This compares the pointed-to objects.
21783 ///
21784 /// @param l the first instance to consider.
21785 ///
21786 /// @param r the second instance to consider.
21787 ///
21788 /// @return true iff @p l is different from @p r.
21789 bool
operator !=(const class_decl::base_spec_sptr & l,const class_decl::base_spec_sptr & r)21790 operator!=(const class_decl::base_spec_sptr& l,
21791 	   const class_decl::base_spec_sptr& r)
21792 {return !operator==(l, r);}
21793 
21794 /// Test if an ABI artifact is a class base specifier.
21795 ///
21796 /// @param tod the ABI artifact to consider.
21797 ///
21798 /// @return a pointer to the @ref class_decl::base_spec sub-object of
21799 /// @p tod iff it's a class base specifier.
21800 class_decl::base_spec*
is_class_base_spec(const type_or_decl_base * tod)21801 is_class_base_spec(const type_or_decl_base* tod)
21802 {
21803   return dynamic_cast<class_decl::base_spec*>
21804     (const_cast<type_or_decl_base*>(tod));
21805 }
21806 
21807 /// Test if an ABI artifact is a class base specifier.
21808 ///
21809 /// @param tod the ABI artifact to consider.
21810 ///
21811 /// @return a pointer to the @ref class_decl::base_spec sub-object of
21812 /// @p tod iff it's a class base specifier.
21813 class_decl::base_spec_sptr
is_class_base_spec(type_or_decl_base_sptr tod)21814 is_class_base_spec(type_or_decl_base_sptr tod)
21815 {return dynamic_pointer_cast<class_decl::base_spec>(tod);}
21816 
21817 bool
operator ==(const member_base & other) const21818 member_function_template::operator==(const member_base& other) const
21819 {
21820   try
21821     {
21822       const member_function_template& o =
21823 	dynamic_cast<const member_function_template&>(other);
21824 
21825       if (!(is_constructor() == o.is_constructor()
21826 	    && is_const() == o.is_const()
21827 	    && member_base::operator==(o)))
21828 	return false;
21829 
21830       if (function_tdecl_sptr ftdecl = as_function_tdecl())
21831 	{
21832 	  function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
21833 	  if (other_ftdecl)
21834 	    return ftdecl->function_tdecl::operator==(*other_ftdecl);
21835 	}
21836     }
21837   catch(...)
21838     {}
21839   return false;
21840 }
21841 
21842 /// Equality operator for smart pointers to @ref
21843 /// member_function_template.  This is compares the
21844 /// pointed-to instances.
21845 ///
21846 /// @param l the first instance to consider.
21847 ///
21848 /// @param r the second instance to consider.
21849 ///
21850 /// @return true iff @p l equals @p r.
21851 bool
operator ==(const member_function_template_sptr & l,const member_function_template_sptr & r)21852 operator==(const member_function_template_sptr& l,
21853 	   const member_function_template_sptr& r)
21854 {
21855   if (l.get() == r.get())
21856     return true;
21857   if (!!l != !!r)
21858     return false;
21859 
21860   return *l == *r;
21861 }
21862 
21863 /// Inequality operator for smart pointers to @ref
21864 /// member_function_template.  This is compares the pointed-to
21865 /// instances.
21866 ///
21867 /// @param l the first instance to consider.
21868 ///
21869 /// @param r the second instance to consider.
21870 ///
21871 /// @return true iff @p l equals @p r.
21872 bool
operator !=(const member_function_template_sptr & l,const member_function_template_sptr & r)21873 operator!=(const member_function_template_sptr& l,
21874 	   const member_function_template_sptr& r)
21875 {return !operator==(l, r);}
21876 
21877 /// This implements the ir_traversable_base::traverse pure virtual
21878 /// function.
21879 ///
21880 /// @param v the visitor used on the current instance and on its
21881 /// underlying function template.
21882 ///
21883 /// @return true if the entire IR node tree got traversed, false
21884 /// otherwise.
21885 bool
traverse(ir_node_visitor & v)21886 member_function_template::traverse(ir_node_visitor& v)
21887 {
21888   if (visiting())
21889     return true;
21890 
21891   if (v.visit_begin(this))
21892     {
21893       visiting(true);
21894       if (function_tdecl_sptr f = as_function_tdecl())
21895 	f->traverse(v);
21896       visiting(false);
21897     }
21898   return v.visit_end(this);
21899 }
21900 
21901 /// Equality operator of the the @ref member_class_template class.
21902 ///
21903 /// @param other the other @ref member_class_template to compare against.
21904 ///
21905 /// @return true iff the current instance equals @p other.
21906 bool
operator ==(const member_base & other) const21907 member_class_template::operator==(const member_base& other) const
21908 {
21909   try
21910     {
21911       const member_class_template& o =
21912 	dynamic_cast<const member_class_template&>(other);
21913 
21914       if (!member_base::operator==(o))
21915 	return false;
21916 
21917       return as_class_tdecl()->class_tdecl::operator==(o);
21918     }
21919   catch(...)
21920     {return false;}
21921 }
21922 
21923 /// Comparison operator for the @ref member_class_template
21924 /// type.
21925 ///
21926 /// @param other the other instance of @ref
21927 /// member_class_template to compare against.
21928 ///
21929 /// @return true iff the two instances are equal.
21930 bool
operator ==(const member_class_template & other) const21931 member_class_template::operator==(const member_class_template& other) const
21932 {
21933   const decl_base* o = dynamic_cast<const decl_base*>(&other);
21934   return *this == *o;
21935 }
21936 
21937 /// Comparison operator for the @ref member_class_template
21938 /// type.
21939 ///
21940 /// @param l the first argument of the operator.
21941 ///
21942 /// @param r the second argument of the operator.
21943 ///
21944 /// @return true iff the two instances are equal.
21945 bool
operator ==(const member_class_template_sptr & l,const member_class_template_sptr & r)21946 operator==(const member_class_template_sptr& l,
21947 	   const member_class_template_sptr& r)
21948 {
21949   if (l.get() == r.get())
21950     return true;
21951   if (!!l != !!r)
21952     return false;
21953 
21954   return *l == *r;
21955 }
21956 
21957 /// Inequality operator for the @ref member_class_template
21958 /// type.
21959 ///
21960 /// @param l the first argument of the operator.
21961 ///
21962 /// @param r the second argument of the operator.
21963 ///
21964 /// @return true iff the two instances are equal.
21965 bool
operator !=(const member_class_template_sptr & l,const member_class_template_sptr & r)21966 operator!=(const member_class_template_sptr& l,
21967 	   const member_class_template_sptr& r)
21968 {return !operator==(l, r);}
21969 
21970 /// This implements the ir_traversable_base::traverse pure virtual
21971 /// function.
21972 ///
21973 /// @param v the visitor used on the current instance and on the class
21974 /// pattern of the template.
21975 ///
21976 /// @return true if the entire IR node tree got traversed, false
21977 /// otherwise.
21978 bool
traverse(ir_node_visitor & v)21979 member_class_template::traverse(ir_node_visitor& v)
21980 {
21981   if (visiting())
21982     return true;
21983 
21984   if (v.visit_begin(this))
21985     {
21986       visiting(true);
21987       if (class_tdecl_sptr t = as_class_tdecl())
21988 	t->traverse(v);
21989       visiting(false);
21990     }
21991   return v.visit_end(this);
21992 }
21993 
21994 /// Streaming operator for class_decl::access_specifier.
21995 ///
21996 /// @param o the output stream to serialize the access specifier to.
21997 ///
21998 /// @param a the access specifier to serialize.
21999 ///
22000 /// @return the output stream.
22001 std::ostream&
operator <<(std::ostream & o,access_specifier a)22002 operator<<(std::ostream& o, access_specifier a)
22003 {
22004   string r;
22005 
22006   switch (a)
22007   {
22008   case no_access:
22009     r = "none";
22010     break;
22011   case private_access:
22012     r = "private";
22013     break;
22014   case protected_access:
22015     r = "protected";
22016     break;
22017   case public_access:
22018     r= "public";
22019     break;
22020   };
22021   o << r;
22022   return o;
22023 }
22024 
22025 /// Sets the static-ness property of a class member.
22026 ///
22027 /// @param d the class member to set the static-ness property for.
22028 /// Note that this must be a class member otherwise the function
22029 /// aborts the current process.
22030 ///
22031 /// @param s this must be true if the member is to be static, false
22032 /// otherwise.
22033 void
set_member_is_static(decl_base & d,bool s)22034 set_member_is_static(decl_base& d, bool s)
22035 {
22036   ABG_ASSERT(is_member_decl(d));
22037 
22038   context_rel* c = d.get_context_rel();
22039   ABG_ASSERT(c);
22040 
22041   c->set_is_static(s);
22042 
22043   scope_decl* scope = d.get_scope();
22044 
22045   if (class_or_union* cl = is_class_or_union_type(scope))
22046     {
22047       if (var_decl* v = is_var_decl(&d))
22048 	{
22049 	  if (s)
22050 	    // remove from the non-static data members
22051 	    for (class_decl::data_members::iterator i =
22052 		   cl->priv_->non_static_data_members_.begin();
22053 		 i != cl->priv_->non_static_data_members_.end();
22054 		 ++i)
22055 	      {
22056 		if ((*i)->get_name() == v->get_name())
22057 		  {
22058 		    cl->priv_->non_static_data_members_.erase(i);
22059 		    break;
22060 		  }
22061 	      }
22062 	  else
22063 	    {
22064 	      bool is_already_in_non_static_data_members = false;
22065 	      for (class_or_union::data_members::iterator i =
22066 		     cl->priv_->non_static_data_members_.begin();
22067 		   i != cl->priv_->non_static_data_members_.end();
22068 		   ++i)
22069 	      {
22070 		if ((*i)->get_name() == v->get_name())
22071 		  {
22072 		    is_already_in_non_static_data_members = true;
22073 		    break;
22074 		  }
22075 	      }
22076 	      if (!is_already_in_non_static_data_members)
22077 		{
22078 		  var_decl_sptr var;
22079 		  // add to non-static data members.
22080 		  for (class_or_union::data_members::const_iterator i =
22081 			 cl->priv_->data_members_.begin();
22082 		       i != cl->priv_->data_members_.end();
22083 		       ++i)
22084 		    {
22085 		      if ((*i)->get_name() == v->get_name())
22086 			{
22087 			  var = *i;
22088 			  break;
22089 			}
22090 		    }
22091 		  ABG_ASSERT(var);
22092 		  cl->priv_->non_static_data_members_.push_back(var);
22093 		}
22094 	    }
22095 	}
22096     }
22097 }
22098 
22099 /// Sets the static-ness property of a class member.
22100 ///
22101 /// @param d the class member to set the static-ness property for.
22102 /// Note that this must be a class member otherwise the function
22103 /// aborts the current process.
22104 ///
22105 /// @param s this must be true if the member is to be static, false
22106 /// otherwise.
22107 void
set_member_is_static(const decl_base_sptr & d,bool s)22108 set_member_is_static(const decl_base_sptr& d, bool s)
22109 {set_member_is_static(*d, s);}
22110 
22111 // </class_decl>
22112 
22113 // <union_decl>
22114 
22115 /// Constructor for the @ref union_decl type.
22116 ///
22117 /// @param env the @ref environment we are operating from.
22118 ///
22119 /// @param name the name of the union type.
22120 ///
22121 /// @param size_in_bits the size of the union, in bits.
22122 ///
22123 /// @param locus the location of the type.
22124 ///
22125 /// @param vis the visibility of instances of @ref union_decl.
22126 ///
22127 /// @param mbr_types the member types of the union.
22128 ///
22129 /// @param data_mbrs the data members of the union.
22130 ///
22131 /// @param member_fns the member functions of the union.
union_decl(const environment * env,const string & name,size_t size_in_bits,const location & locus,visibility vis,member_types & mbr_types,data_members & data_mbrs,member_functions & member_fns)22132 union_decl::union_decl(const environment* env, const string& name,
22133 		       size_t size_in_bits, const location& locus,
22134 		       visibility vis, member_types& mbr_types,
22135 		       data_members& data_mbrs, member_functions& member_fns)
22136   : type_or_decl_base(env,
22137 		      UNION_TYPE
22138 		      | ABSTRACT_TYPE_BASE
22139 		      | ABSTRACT_DECL_BASE),
22140     decl_base(env, name, locus, name, vis),
22141     type_base(env, size_in_bits, 0),
22142     class_or_union(env, name, size_in_bits, 0,
22143 		   locus, vis, mbr_types, data_mbrs, member_fns)
22144 {
22145   runtime_type_instance(this);
22146 }
22147 
22148 /// Constructor for the @ref union_decl type.
22149 ///
22150 /// @param env the @ref environment we are operating from.
22151 ///
22152 /// @param name the name of the union type.
22153 ///
22154 /// @param size_in_bits the size of the union, in bits.
22155 ///
22156 /// @param locus the location of the type.
22157 ///
22158 /// @param vis the visibility of instances of @ref union_decl.
22159 ///
22160 /// @param mbr_types the member types of the union.
22161 ///
22162 /// @param data_mbrs the data members of the union.
22163 ///
22164 /// @param member_fns the member functions of the union.
22165 ///
22166 /// @param is_anonymous whether the newly created instance is
22167 /// anonymous.
union_decl(const environment * env,const string & name,size_t size_in_bits,const location & locus,visibility vis,member_types & mbr_types,data_members & data_mbrs,member_functions & member_fns,bool is_anonymous)22168 union_decl::union_decl(const environment* env, const string& name,
22169 		       size_t size_in_bits, const location& locus,
22170 		       visibility vis, member_types& mbr_types,
22171 		       data_members& data_mbrs, member_functions& member_fns,
22172 		       bool is_anonymous)
22173   : type_or_decl_base(env,
22174 		      UNION_TYPE
22175 		      | ABSTRACT_TYPE_BASE
22176 		      | ABSTRACT_DECL_BASE),
22177     decl_base(env, name, locus,
22178 	      // If the class is anonymous then by default it won't
22179 	      // have a linkage name.  Also, the anonymous class does
22180 	      // have an internal-only unique name that is generally
22181 	      // not taken into account when comparing classes; such a
22182 	      // unique internal-only name, when used as a linkage
22183 	      // name might introduce spurious comparison false
22184 	      // negatives.
22185 	      /*linkage_name=*/is_anonymous ? string() : name,
22186 	      vis),
22187     type_base(env, size_in_bits, 0),
22188     class_or_union(env, name, size_in_bits, 0,
22189 		   locus, vis, mbr_types, data_mbrs, member_fns)
22190 {
22191   runtime_type_instance(this);
22192   set_is_anonymous(is_anonymous);
22193 }
22194 
22195 /// Constructor for the @ref union_decl type.
22196 ///
22197 /// @param env the @ref environment we are operating from.
22198 ///
22199 /// @param name the name of the union type.
22200 ///
22201 /// @param size_in_bits the size of the union, in bits.
22202 ///
22203 /// @param locus the location of the type.
22204 ///
22205 /// @param vis the visibility of instances of @ref union_decl.
union_decl(const environment * env,const string & name,size_t size_in_bits,const location & locus,visibility vis)22206 union_decl::union_decl(const environment* env, const string& name,
22207 		       size_t size_in_bits, const location& locus,
22208 		       visibility vis)
22209   : type_or_decl_base(env,
22210 		      UNION_TYPE
22211 		      | ABSTRACT_TYPE_BASE
22212 		      | ABSTRACT_DECL_BASE
22213 		      | ABSTRACT_SCOPE_TYPE_DECL
22214 		      | ABSTRACT_SCOPE_DECL),
22215     decl_base(env, name, locus, name, vis),
22216     type_base(env, size_in_bits, 0),
22217     class_or_union(env, name, size_in_bits,
22218 		   0, locus, vis)
22219 {
22220   runtime_type_instance(this);
22221 }
22222 
22223 /// Constructor for the @ref union_decl type.
22224 ///
22225 /// @param env the @ref environment we are operating from.
22226 ///
22227 /// @param name the name of the union type.
22228 ///
22229 /// @param size_in_bits the size of the union, in bits.
22230 ///
22231 /// @param locus the location of the type.
22232 ///
22233 /// @param vis the visibility of instances of @ref union_decl.
22234 ///
22235 /// @param is_anonymous whether the newly created instance is
22236 /// anonymous.
union_decl(const environment * env,const string & name,size_t size_in_bits,const location & locus,visibility vis,bool is_anonymous)22237 union_decl::union_decl(const environment* env, const string& name,
22238 		       size_t size_in_bits, const location& locus,
22239 		       visibility vis, bool is_anonymous)
22240   : type_or_decl_base(env,
22241 		      UNION_TYPE
22242 		      | ABSTRACT_TYPE_BASE
22243 		      | ABSTRACT_DECL_BASE
22244 		      | ABSTRACT_SCOPE_TYPE_DECL
22245 		      | ABSTRACT_SCOPE_DECL),
22246     decl_base(env, name, locus,
22247 	      // If the class is anonymous then by default it won't
22248 	      // have a linkage name.  Also, the anonymous class does
22249 	      // have an internal-only unique name that is generally
22250 	      // not taken into account when comparing classes; such a
22251 	      // unique internal-only name, when used as a linkage
22252 	      // name might introduce spurious comparison false
22253 	      // negatives.
22254 	      /*linkage_name=*/is_anonymous ? string() : name,
22255 	      vis),
22256     type_base(env, size_in_bits, 0),
22257     class_or_union(env, name, size_in_bits,
22258 		   0, locus, vis)
22259 {
22260   runtime_type_instance(this);
22261   set_is_anonymous(is_anonymous);
22262 }
22263 
22264 /// Constructor for the @ref union_decl type.
22265 ///
22266 /// @param env the @ref environment we are operating from.
22267 ///
22268 /// @param name the name of the union type.
22269 ///
22270 /// @param is_declaration_only a boolean saying whether the instance
22271 /// represents a declaration only, or not.
union_decl(const environment * env,const string & name,bool is_declaration_only)22272 union_decl::union_decl(const environment* env,
22273 		       const string& name,
22274 		       bool is_declaration_only)
22275   : type_or_decl_base(env,
22276 		      UNION_TYPE
22277 		      | ABSTRACT_TYPE_BASE
22278 		      | ABSTRACT_DECL_BASE
22279 		      | ABSTRACT_SCOPE_TYPE_DECL
22280 		      | ABSTRACT_SCOPE_DECL),
22281     decl_base(env, name, location(), name),
22282     type_base(env, 0, 0),
22283     class_or_union(env, name, is_declaration_only)
22284 {
22285   runtime_type_instance(this);
22286 }
22287 
22288 /// Getter of the pretty representation of the current instance of
22289 /// @ref union_decl.
22290 ///
22291 /// @param internal set to true if the call is intended for an
22292 /// internal use (for technical use inside the library itself), false
22293 /// otherwise.  If you don't know what this is for, then set it to
22294 /// false.
22295 ///
22296 /// @param qualified_name if true, names emitted in the pretty
22297 /// representation are fully qualified.
22298 ///
22299 /// @return the pretty representaion for a union_decl.
22300 string
get_pretty_representation(bool internal,bool qualified_name) const22301 union_decl::get_pretty_representation(bool internal,
22302 				      bool qualified_name) const
22303 {
22304   string repr;
22305   if (get_is_anonymous())
22306     repr = get_class_or_union_flat_representation(this, "",
22307 						  /*one_line=*/true,
22308 						  internal);
22309   else
22310     {
22311       repr = "union ";
22312       if (qualified_name)
22313 	repr += get_qualified_name(internal);
22314       else
22315 	repr += get_name();
22316     }
22317 
22318   return repr;
22319 }
22320 
22321 /// Comparison operator for @ref union_decl.
22322 ///
22323 /// @param other the instance of @ref union_decl to compare against.
22324 ///
22325 /// @return true iff the current instance of @ref union_decl equals @p
22326 /// other.
22327 bool
operator ==(const decl_base & other) const22328 union_decl::operator==(const decl_base& other) const
22329 {
22330   const union_decl* op = dynamic_cast<const union_decl*>(&other);
22331   if (!op)
22332     return false;
22333   return try_canonical_compare(this, op);
22334 }
22335 
22336 /// Equality operator for union_decl.
22337 ///
22338 /// Re-uses the equality operator that takes a decl_base.
22339 ///
22340 /// @param other the other union_decl to compare against.
22341 ///
22342 /// @return true iff the current instance equals the other one.
22343 bool
operator ==(const type_base & other) const22344 union_decl::operator==(const type_base& other) const
22345 {
22346   const decl_base *o = dynamic_cast<const decl_base*>(&other);
22347   if (!o)
22348     return false;
22349   return *this == *o;
22350 }
22351 
22352 /// Comparison operator for @ref union_decl.
22353 ///
22354 /// @param other the instance of @ref union_decl to compare against.
22355 ///
22356 /// @return true iff the current instance of @ref union_decl equals @p
22357 /// other.
22358 bool
operator ==(const union_decl & other) const22359 union_decl::operator==(const union_decl& other) const
22360 {
22361   const decl_base& o = other;
22362   return *this == o;
22363 }
22364 
22365 /// This implements the ir_traversable_base::traverse pure virtual
22366 /// function.
22367 ///
22368 /// @param v the visitor used on the current instance and on its
22369 /// members.
22370 ///
22371 /// @return true if the entire IR node tree got traversed, false
22372 /// otherwise.
22373 bool
traverse(ir_node_visitor & v)22374 union_decl::traverse(ir_node_visitor& v)
22375 {
22376   if (v.type_node_has_been_visited(this))
22377     return true;
22378 
22379   if (visiting())
22380     return true;
22381 
22382   if (v.visit_begin(this))
22383     {
22384       visiting(true);
22385       bool stop = false;
22386 
22387       if (!stop)
22388 	for (data_members::const_iterator i = get_data_members().begin();
22389 	     i != get_data_members().end();
22390 	     ++i)
22391 	  if (!(*i)->traverse(v))
22392 	    {
22393 	      stop = true;
22394 	      break;
22395 	    }
22396 
22397       if (!stop)
22398 	for (member_functions::const_iterator i= get_member_functions().begin();
22399 	     i != get_member_functions().end();
22400 	     ++i)
22401 	  if (!(*i)->traverse(v))
22402 	    {
22403 	      stop = true;
22404 	      break;
22405 	    }
22406 
22407       if (!stop)
22408 	for (member_types::const_iterator i = get_member_types().begin();
22409 	     i != get_member_types().end();
22410 	     ++i)
22411 	  if (!(*i)->traverse(v))
22412 	    {
22413 	      stop = true;
22414 	      break;
22415 	    }
22416 
22417       if (!stop)
22418 	for (member_function_templates::const_iterator i =
22419 	       get_member_function_templates().begin();
22420 	     i != get_member_function_templates().end();
22421 	     ++i)
22422 	  if (!(*i)->traverse(v))
22423 	    {
22424 	      stop = true;
22425 	      break;
22426 	    }
22427 
22428       if (!stop)
22429 	for (member_class_templates::const_iterator i =
22430 	       get_member_class_templates().begin();
22431 	     i != get_member_class_templates().end();
22432 	     ++i)
22433 	  if (!(*i)->traverse(v))
22434 	    {
22435 	      stop = true;
22436 	      break;
22437 	    }
22438       visiting(false);
22439     }
22440 
22441   bool result = v.visit_end(this);
22442   v.mark_type_node_as_visited(this);
22443   return result;
22444 }
22445 
22446 /// Destructor of the @ref union_decl type.
~union_decl()22447 union_decl::~union_decl()
22448 {}
22449 
22450 /// Compares two instances of @ref union_decl.
22451 ///
22452 /// If the two intances are different, set a bitfield to give some
22453 /// insight about the kind of differences there are.
22454 ///
22455 /// @param l the first artifact of the comparison.
22456 ///
22457 /// @param r the second artifact of the comparison.
22458 ///
22459 /// @param k a pointer to a bitfield that gives information about the
22460 /// kind of changes there are between @p l and @p r.  This one is set
22461 /// iff @p k is non-null and the function returns false.
22462 ///
22463 /// Please note that setting k to a non-null value does have a
22464 /// negative performance impact because even if @p l and @p r are not
22465 /// equal, the function keeps up the comparison in order to determine
22466 /// the different kinds of ways in which they are different.
22467 ///
22468 /// @return true if @p l equals @p r, false otherwise.
22469 bool
equals(const union_decl & l,const union_decl & r,change_kind * k)22470 equals(const union_decl& l, const union_decl& r, change_kind* k)
22471 {
22472   bool result = equals(static_cast<const class_or_union&>(l),
22473 		       static_cast<const class_or_union&>(r),
22474 		       k);
22475   if (result == true)
22476     maybe_propagate_canonical_type(l, r);
22477   return result;
22478 }
22479 
22480 /// Copy a method of a @ref union_decl into a new @ref
22481 /// union_decl.
22482 ///
22483 /// @param t the @ref union_decl into which the method is to be copied.
22484 ///
22485 /// @param method the method to copy into @p t.
22486 ///
22487 /// @return the resulting newly copied method.
22488 method_decl_sptr
copy_member_function(const union_decl_sptr & union_type,const method_decl_sptr & f)22489 copy_member_function(const union_decl_sptr& union_type,
22490 		     const method_decl_sptr& f)
22491 {return copy_member_function(union_type, f.get());}
22492 
22493 /// Copy a method of a @ref union_decl into a new @ref
22494 /// union_decl.
22495 ///
22496 /// @param t the @ref union_decl into which the method is to be copied.
22497 ///
22498 /// @param method the method to copy into @p t.
22499 ///
22500 /// @return the resulting newly copied method.
22501 method_decl_sptr
copy_member_function(const union_decl_sptr & union_type,const method_decl * f)22502 copy_member_function(const union_decl_sptr& union_type,
22503 		     const method_decl* f)
22504 {
22505   const class_or_union_sptr t = union_type;
22506   return copy_member_function(t, f);
22507 }
22508 
22509 /// Turn equality of shared_ptr of union_decl into a deep equality;
22510 /// that is, make it compare the pointed to objects too.
22511 ///
22512 /// @param l the left-hand-side operand of the operator
22513 ///
22514 /// @param r the right-hand-side operand of the operator.
22515 ///
22516 /// @return true iff @p l equals @p r.
22517 bool
operator ==(const union_decl_sptr & l,const union_decl_sptr & r)22518 operator==(const union_decl_sptr& l, const union_decl_sptr& r)
22519 {
22520   if (l.get() == r.get())
22521     return true;
22522   if (!!l != !!r)
22523     return false;
22524 
22525   return *l == *r;
22526 }
22527 
22528 /// Turn inequality of shared_ptr of union_decl into a deep equality;
22529 /// that is, make it compare the pointed to objects too.
22530 ///
22531 /// @param l the left-hand-side operand of the operator
22532 ///
22533 /// @param r the right-hand-side operand of the operator.
22534 ///
22535 /// @return true iff @p l is different from @p r.
22536 bool
operator !=(const union_decl_sptr & l,const union_decl_sptr & r)22537 operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
22538 {return !operator==(l, r);}
22539 // </union_decl>
22540 
22541 // <template_decl stuff>
22542 
22543 /// Data type of the private data of the @template_decl type.
22544 class template_decl::priv
22545 {
22546   friend class template_decl;
22547 
22548   std::list<template_parameter_sptr> parms_;
22549 public:
22550 
priv()22551   priv()
22552   {}
22553 }; // end class template_decl::priv
22554 
22555 /// Add a new template parameter to the current instance of @ref
22556 /// template_decl.
22557 ///
22558 /// @param p the new template parameter to add.
22559 void
add_template_parameter(const template_parameter_sptr p)22560 template_decl::add_template_parameter(const template_parameter_sptr p)
22561 {priv_->parms_.push_back(p);}
22562 
22563 /// Get the list of template parameters of the current instance of
22564 /// @ref template_decl.
22565 ///
22566 /// @return the list of template parameters.
22567 const std::list<template_parameter_sptr>&
get_template_parameters() const22568 template_decl::get_template_parameters() const
22569 {return priv_->parms_;}
22570 
22571 /// Constructor.
22572 ///
22573 /// @param env the environment we are operating from.
22574 ///
22575 /// @param name the name of the template decl.
22576 ///
22577 /// @param locus the source location where the template declaration is
22578 /// defined.
22579 ///
22580 /// @param vis the visibility of the template declaration.
template_decl(const environment * env,const string & name,const location & locus,visibility vis)22581 template_decl::template_decl(const environment* env,
22582 			     const string& name,
22583 			     const location& locus,
22584 			     visibility vis)
22585   : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
22586     decl_base(env, name, locus, /*mangled_name=*/"", vis),
22587     priv_(new priv)
22588 {
22589   runtime_type_instance(this);
22590 }
22591 
22592 /// Destructor.
~template_decl()22593 template_decl::~template_decl()
22594 {}
22595 
22596 /// Equality operator.
22597 ///
22598 /// @param o the other instance to compare against.
22599 ///
22600 /// @return true iff @p equals the current instance.
22601 bool
operator ==(const template_decl & o) const22602 template_decl::operator==(const template_decl& o) const
22603 {
22604   try
22605     {
22606       list<shared_ptr<template_parameter> >::const_iterator t0, t1;
22607       for (t0 = get_template_parameters().begin(),
22608 	     t1 = o.get_template_parameters().begin();
22609 	   (t0 != get_template_parameters().end()
22610 	    && t1 != o.get_template_parameters().end());
22611 	   ++t0, ++t1)
22612 	{
22613 	  if (**t0 != **t1)
22614 	    return false;
22615 	}
22616 
22617       if (t0 != get_template_parameters().end()
22618 	  || t1 != o.get_template_parameters().end())
22619 	return false;
22620 
22621       return true;
22622     }
22623   catch(...)
22624     {return false;}
22625 }
22626 
22627 // </template_decl stuff>
22628 
22629 //<template_parameter>
22630 
22631 /// The type of the private data of the @ref template_parameter type.
22632 class template_parameter::priv
22633 {
22634   friend class template_parameter;
22635 
22636   unsigned index_;
22637   template_decl_wptr template_decl_;
22638   mutable bool hashing_started_;
22639   mutable bool comparison_started_;
22640 
22641   priv();
22642 
22643 public:
22644 
priv(unsigned index,template_decl_sptr enclosing_template_decl)22645   priv(unsigned index, template_decl_sptr enclosing_template_decl)
22646     : index_(index),
22647       template_decl_(enclosing_template_decl),
22648       hashing_started_(),
22649       comparison_started_()
22650   {}
22651 }; // end class template_parameter::priv
22652 
template_parameter(unsigned index,template_decl_sptr enclosing_template)22653 template_parameter::template_parameter(unsigned	 index,
22654 				       template_decl_sptr enclosing_template)
22655   : priv_(new priv(index, enclosing_template))
22656   {}
22657 
22658 unsigned
get_index() const22659 template_parameter::get_index() const
22660 {return priv_->index_;}
22661 
22662 const template_decl_sptr
get_enclosing_template_decl() const22663 template_parameter::get_enclosing_template_decl() const
22664 {return priv_->template_decl_.lock();}
22665 
22666 bool
get_hashing_has_started() const22667 template_parameter::get_hashing_has_started() const
22668 {return priv_->hashing_started_;}
22669 
22670 void
set_hashing_has_started(bool f) const22671 template_parameter::set_hashing_has_started(bool f) const
22672 {priv_->hashing_started_ = f;}
22673 
22674 bool
operator ==(const template_parameter & o) const22675 template_parameter::operator==(const template_parameter& o) const
22676 {
22677   if (get_index() != o.get_index())
22678     return false;
22679 
22680   if (priv_->comparison_started_)
22681     return true;
22682 
22683   bool result = false;
22684 
22685   // Avoid inifite loops due to the fact that comparison the enclosing
22686   // template decl might lead to comparing this very same template
22687   // parameter with another one ...
22688   priv_->comparison_started_ = true;
22689 
22690   if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
22691     ;
22692   else if (get_enclosing_template_decl()
22693 	   && (*get_enclosing_template_decl()
22694 	       != *o.get_enclosing_template_decl()))
22695     ;
22696   else
22697     result = true;
22698 
22699   priv_->comparison_started_ = false;
22700 
22701   return result;
22702 }
22703 
22704 /// Inequality operator.
22705 ///
22706 /// @param other the other instance to compare against.
22707 ///
22708 /// @return true iff the other instance is different from the current
22709 /// one.
22710 bool
operator !=(const template_parameter & other) const22711 template_parameter::operator!=(const template_parameter& other) const
22712 {return !operator==(other);}
22713 
22714 /// Destructor.
~template_parameter()22715 template_parameter::~template_parameter()
22716 {}
22717 
22718 /// The type of the private data of the @ref type_tparameter type.
22719 class type_tparameter::priv
22720 {
22721   friend class type_tparameter;
22722 }; // end class type_tparameter::priv
22723 
22724 /// Constructor of the @ref type_tparameter type.
22725 ///
22726 /// @param index the index the type template parameter.
22727 ///
22728 /// @param enclosing_tdecl the enclosing template declaration.
22729 ///
22730 /// @param name the name of the template parameter.
22731 ///
22732 /// @param locus the location of the declaration of this type template
22733 /// parameter.
type_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,const location & locus)22734 type_tparameter::type_tparameter(unsigned		index,
22735 				 template_decl_sptr	enclosing_tdecl,
22736 				 const string&		name,
22737 				 const location&	locus)
22738   : type_or_decl_base(enclosing_tdecl->get_environment(),
22739 		      ABSTRACT_DECL_BASE
22740 		      | ABSTRACT_TYPE_BASE
22741 		      | BASIC_TYPE),
22742     decl_base(enclosing_tdecl->get_environment(), name, locus),
22743     type_base(enclosing_tdecl->get_environment(), 0, 0),
22744     type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
22745     template_parameter(index, enclosing_tdecl),
22746     priv_(new priv)
22747 {
22748   runtime_type_instance(this);
22749 }
22750 
22751 bool
operator ==(const type_base & other) const22752 type_tparameter::operator==(const type_base& other) const
22753 {
22754   if (!type_decl::operator==(other))
22755     return false;
22756 
22757   try
22758     {
22759       const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
22760       return template_parameter::operator==(o);
22761     }
22762   catch (...)
22763     {return false;}
22764 }
22765 
22766 bool
operator ==(const template_parameter & other) const22767 type_tparameter::operator==(const template_parameter& other) const
22768 {
22769   try
22770     {
22771       const type_base& o = dynamic_cast<const type_base&>(other);
22772       return *this == o;
22773     }
22774   catch(...)
22775     {return false;}
22776 }
22777 
22778 bool
operator ==(const type_tparameter & other) const22779 type_tparameter::operator==(const type_tparameter& other) const
22780 {return *this == static_cast<const type_base&>(other);}
22781 
~type_tparameter()22782 type_tparameter::~type_tparameter()
22783 {}
22784 
22785 /// The type of the private data of the @ref non_type_tparameter type.
22786 class non_type_tparameter::priv
22787 {
22788   friend class non_type_tparameter;
22789 
22790   type_base_wptr type_;
22791 
22792   priv();
22793 
22794 public:
22795 
priv(type_base_sptr type)22796   priv(type_base_sptr type)
22797     : type_(type)
22798   {}
22799 }; // end class non_type_tparameter::priv
22800 
22801 /// The constructor for the @ref non_type_tparameter type.
22802 ///
22803 /// @param index the index of the template parameter.
22804 ///
22805 /// @param enclosing_tdecl the enclosing template declaration that
22806 /// holds this parameter parameter.
22807 ///
22808 /// @param name the name of the template parameter.
22809 ///
22810 /// @param type the type of the template parameter.
22811 ///
22812 /// @param locus the location of the declaration of this template
22813 /// parameter.
non_type_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,type_base_sptr type,const location & locus)22814 non_type_tparameter::non_type_tparameter(unsigned		index,
22815 					 template_decl_sptr	enclosing_tdecl,
22816 					 const string&		name,
22817 					 type_base_sptr	type,
22818 					 const location&	locus)
22819   : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
22820     decl_base(type->get_environment(), name, locus, ""),
22821     template_parameter(index, enclosing_tdecl),
22822     priv_(new priv(type))
22823 {
22824   runtime_type_instance(this);
22825 }
22826 
22827 /// Getter for the type of the template parameter.
22828 ///
22829 /// @return the type of the template parameter.
22830 const type_base_sptr
get_type() const22831 non_type_tparameter::get_type() const
22832 {return priv_->type_.lock();}
22833 
22834 /// Get the hash value of the current instance.
22835 ///
22836 /// @return the hash value.
22837 size_t
get_hash() const22838 non_type_tparameter::get_hash() const
22839 {
22840   non_type_tparameter::hash hash_tparm;
22841   return hash_tparm(this);
22842 }
22843 
22844 bool
operator ==(const decl_base & other) const22845 non_type_tparameter::operator==(const decl_base& other) const
22846 {
22847   if (!decl_base::operator==(other))
22848     return false;
22849 
22850   try
22851     {
22852       const non_type_tparameter& o =
22853 	dynamic_cast<const non_type_tparameter&>(other);
22854       return (template_parameter::operator==(o)
22855 	      && get_type() == o.get_type());
22856     }
22857   catch(...)
22858     {return false;}
22859 }
22860 
22861 bool
operator ==(const template_parameter & other) const22862 non_type_tparameter::operator==(const template_parameter& other) const
22863 {
22864   try
22865     {
22866       const decl_base& o = dynamic_cast<const decl_base&>(other);
22867       return *this == o;
22868     }
22869   catch(...)
22870     {return false;}
22871 }
22872 
~non_type_tparameter()22873 non_type_tparameter::~non_type_tparameter()
22874 {}
22875 
22876 // <template_tparameter stuff>
22877 
22878 /// Type of the private data of the @ref template_tparameter type.
22879 class template_tparameter::priv
22880 {
22881 }; //end class template_tparameter::priv
22882 
22883 /// Constructor for the @ref template_tparameter.
22884 ///
22885 /// @param index the index of the template parameter.
22886 ///
22887 /// @param enclosing_tdecl the enclosing template declaration.
22888 ///
22889 /// @param name the name of the template parameter.
22890 ///
22891 /// @param locus the location of the declaration of the template
22892 /// parameter.
template_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,const location & locus)22893 template_tparameter::template_tparameter(unsigned		index,
22894 					 template_decl_sptr	enclosing_tdecl,
22895 					 const string&		name,
22896 					 const location&	locus)
22897   : type_or_decl_base(enclosing_tdecl->get_environment(),
22898 		      ABSTRACT_DECL_BASE
22899 		      | ABSTRACT_TYPE_BASE
22900 		      | BASIC_TYPE),
22901     decl_base(enclosing_tdecl->get_environment(), name, locus),
22902     type_base(enclosing_tdecl->get_environment(), 0, 0),
22903     type_decl(enclosing_tdecl->get_environment(), name,
22904 	      0, 0, locus, name, VISIBILITY_DEFAULT),
22905     type_tparameter(index, enclosing_tdecl, name, locus),
22906     template_decl(enclosing_tdecl->get_environment(), name, locus),
22907     priv_(new priv)
22908 {
22909   runtime_type_instance(this);
22910 }
22911 
22912 bool
operator ==(const type_base & other) const22913 template_tparameter::operator==(const type_base& other) const
22914 {
22915   try
22916     {
22917       const template_tparameter& o =
22918 	dynamic_cast<const template_tparameter&>(other);
22919       return (type_tparameter::operator==(o)
22920 	      && template_decl::operator==(o));
22921     }
22922   catch(...)
22923     {return false;}
22924 }
22925 
22926 bool
operator ==(const template_parameter & o) const22927 template_tparameter::operator==(const template_parameter& o) const
22928 {
22929   try
22930     {
22931       const template_tparameter& other =
22932 	dynamic_cast<const template_tparameter&>(o);
22933       return *this == static_cast<const type_base&>(other);
22934     }
22935   catch(...)
22936     {return false;}
22937 }
22938 
22939 bool
operator ==(const template_decl & o) const22940 template_tparameter::operator==(const template_decl& o) const
22941 {
22942   try
22943     {
22944       const template_tparameter& other =
22945 	dynamic_cast<const template_tparameter&>(o);
22946       return type_base::operator==(other);
22947     }
22948   catch(...)
22949     {return false;}
22950 }
22951 
~template_tparameter()22952 template_tparameter::~template_tparameter()
22953 {}
22954 
22955 // </template_tparameter stuff>
22956 
22957 // <type_composition stuff>
22958 
22959 /// The type of the private data of the @ref type_composition type.
22960 class type_composition::priv
22961 {
22962   friend class type_composition;
22963 
22964   type_base_wptr type_;
22965 
22966   // Forbid this.
22967   priv();
22968 
22969 public:
22970 
priv(type_base_wptr type)22971   priv(type_base_wptr type)
22972     : type_(type)
22973   {}
22974 }; //end class type_composition::priv
22975 
22976 /// Constructor for the @ref type_composition type.
22977 ///
22978 /// @param index the index of the template type composition.
22979 ///
22980 /// @param tdecl the enclosing template parameter that owns the
22981 /// composition.
22982 ///
22983 /// @param t the resulting type.
type_composition(unsigned index,template_decl_sptr tdecl,type_base_sptr t)22984 type_composition::type_composition(unsigned		index,
22985 				   template_decl_sptr	tdecl,
22986 				   type_base_sptr	t)
22987   : type_or_decl_base(tdecl->get_environment(),
22988 		      ABSTRACT_DECL_BASE),
22989     decl_base(tdecl->get_environment(), "", location()),
22990     template_parameter(index, tdecl),
22991     priv_(new priv(t))
22992 {
22993   runtime_type_instance(this);
22994 }
22995 
22996 /// Getter for the resulting composed type.
22997 ///
22998 /// @return the composed type.
22999 const type_base_sptr
get_composed_type() const23000 type_composition::get_composed_type() const
23001 {return priv_->type_.lock();}
23002 
23003 /// Setter for the resulting composed type.
23004 ///
23005 /// @param t the composed type.
23006 void
set_composed_type(type_base_sptr t)23007 type_composition::set_composed_type(type_base_sptr t)
23008 {priv_->type_ = t;}
23009 
23010 /// Get the hash value for the current instance.
23011 ///
23012 /// @return the hash value.
23013 size_t
get_hash() const23014 type_composition::get_hash() const
23015 {
23016   type_composition::hash hash_type_composition;
23017   return hash_type_composition(this);
23018 }
23019 
~type_composition()23020 type_composition::~type_composition()
23021 {}
23022 
23023 // </type_composition stuff>
23024 
23025 //</template_parameter stuff>
23026 
23027 // <function_template>
23028 
23029 class function_tdecl::priv
23030 {
23031   friend class function_tdecl;
23032 
23033   function_decl_sptr pattern_;
23034   binding binding_;
23035 
23036   priv();
23037 
23038 public:
23039 
priv(function_decl_sptr pattern,binding bind)23040   priv(function_decl_sptr pattern, binding bind)
23041     : pattern_(pattern), binding_(bind)
23042   {}
23043 
priv(binding bind)23044   priv(binding bind)
23045     : binding_(bind)
23046   {}
23047 }; // end class function_tdecl::priv
23048 
23049 /// Constructor for a function template declaration.
23050 ///
23051 /// @param env the environment we are operating from.
23052 ///
23053 /// @param locus the location of the declaration.
23054 ///
23055 /// @param vis the visibility of the declaration.  This is the
23056 /// visibility the functions instantiated from this template are going
23057 /// to have.
23058 ///
23059 /// @param bind the binding of the declaration.  This is the binding
23060 /// the functions instantiated from this template are going to have.
function_tdecl(const environment * env,const location & locus,visibility vis,binding bind)23061 function_tdecl::function_tdecl(const environment*	env,
23062 			       const location&		locus,
23063 			       visibility		vis,
23064 			       binding			bind)
23065   : type_or_decl_base(env,
23066 		      ABSTRACT_DECL_BASE
23067 		      | TEMPLATE_DECL
23068 		      | ABSTRACT_SCOPE_DECL),
23069     decl_base(env, "", locus, "", vis),
23070     template_decl(env, "", locus, vis),
23071     scope_decl(env, "", locus),
23072     priv_(new priv(bind))
23073 {
23074   runtime_type_instance(this);
23075 }
23076 
23077 /// Constructor for a function template declaration.
23078 ///
23079 /// @param pattern the pattern of the template.
23080 ///
23081 /// @param locus the location of the declaration.
23082 ///
23083 /// @param vis the visibility of the declaration.  This is the
23084 /// visibility the functions instantiated from this template are going
23085 /// to have.
23086 ///
23087 /// @param bind the binding of the declaration.  This is the binding
23088 /// the functions instantiated from this template are going to have.
function_tdecl(function_decl_sptr pattern,const location & locus,visibility vis,binding bind)23089 function_tdecl::function_tdecl(function_decl_sptr	pattern,
23090 			       const location&		locus,
23091 			       visibility		vis,
23092 			       binding			bind)
23093   : type_or_decl_base(pattern->get_environment(),
23094 		      ABSTRACT_DECL_BASE
23095 		      | TEMPLATE_DECL
23096 		      | ABSTRACT_SCOPE_DECL),
23097     decl_base(pattern->get_environment(), pattern->get_name(), locus,
23098 	      pattern->get_name(), vis),
23099     template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
23100     scope_decl(pattern->get_environment(), pattern->get_name(), locus),
23101     priv_(new priv(pattern, bind))
23102 {
23103   runtime_type_instance(this);
23104 }
23105 
23106 /// Set a new pattern to the function template.
23107 ///
23108 /// @param p the new pattern.
23109 void
set_pattern(function_decl_sptr p)23110 function_tdecl::set_pattern(function_decl_sptr p)
23111 {
23112   priv_->pattern_ = p;
23113   add_decl_to_scope(p, this);
23114   set_name(p->get_name());
23115 }
23116 
23117 /// Get the pattern of the function template.
23118 ///
23119 /// @return the pattern.
23120 function_decl_sptr
get_pattern() const23121 function_tdecl::get_pattern() const
23122 {return priv_->pattern_;}
23123 
23124 /// Get the binding of the function template.
23125 ///
23126 /// @return the binding
23127 decl_base::binding
get_binding() const23128 function_tdecl::get_binding() const
23129 {return priv_->binding_;}
23130 
23131 /// Comparison operator for the @ref function_tdecl type.
23132 ///
23133 /// @param other the other instance of @ref function_tdecl to compare against.
23134 ///
23135 /// @return true iff the two instance are equal.
23136 bool
operator ==(const decl_base & other) const23137 function_tdecl::operator==(const decl_base& other) const
23138 {
23139   const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
23140   if (o)
23141     return *this == *o;
23142   return false;
23143 }
23144 
23145 /// Comparison operator for the @ref function_tdecl type.
23146 ///
23147 /// @param other the other instance of @ref function_tdecl to compare against.
23148 ///
23149 /// @return true iff the two instance are equal.
23150 bool
operator ==(const template_decl & other) const23151 function_tdecl::operator==(const template_decl& other) const
23152 {
23153   const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
23154   if (o)
23155     return *this == *o;
23156   return false;
23157 }
23158 
23159 /// Comparison operator for the @ref function_tdecl type.
23160 ///
23161 /// @param o the other instance of @ref function_tdecl to compare against.
23162 ///
23163 /// @return true iff the two instance are equal.
23164 bool
operator ==(const function_tdecl & o) const23165 function_tdecl::operator==(const function_tdecl& o) const
23166 {
23167   if (!(get_binding() == o.get_binding()
23168 	&& template_decl::operator==(o)
23169 	&& scope_decl::operator==(o)
23170 	&& !!get_pattern() == !!o.get_pattern()))
23171     return false;
23172 
23173   if (get_pattern())
23174     return (*get_pattern() == *o.get_pattern());
23175 
23176   return true;
23177 }
23178 
23179 /// This implements the ir_traversable_base::traverse pure virtual
23180 /// function.
23181 ///
23182 /// @param v the visitor used on the current instance and on the
23183 /// function pattern of the template.
23184 ///
23185 /// @return true if the entire IR node tree got traversed, false
23186 /// otherwise.
23187 bool
traverse(ir_node_visitor & v)23188 function_tdecl::traverse(ir_node_visitor&v)
23189 {
23190   if (visiting())
23191     return true;
23192 
23193   if (!v.visit_begin(this))
23194     {
23195       visiting(true);
23196       if (get_pattern())
23197 	get_pattern()->traverse(v);
23198       visiting(false);
23199     }
23200   return v.visit_end(this);
23201 }
23202 
~function_tdecl()23203 function_tdecl::~function_tdecl()
23204 {}
23205 
23206 // </function_template>
23207 
23208 // <class template>
23209 
23210 /// Type of the private data of the the @ref class_tdecl type.
23211 class class_tdecl::priv
23212 {
23213   friend class class_tdecl;
23214   class_decl_sptr pattern_;
23215 
23216 public:
23217 
priv()23218   priv()
23219   {}
23220 
priv(class_decl_sptr pattern)23221   priv(class_decl_sptr pattern)
23222     : pattern_(pattern)
23223   {}
23224 }; // end class class_tdecl::priv
23225 
23226 /// Constructor for the @ref class_tdecl type.
23227 ///
23228 /// @param env the environment we are operating from.
23229 ///
23230 /// @param locus the location of the declaration of the class_tdecl
23231 /// type.
23232 ///
23233 /// @param vis the visibility of the instance of class instantiated
23234 /// from this template.
class_tdecl(const environment * env,const location & locus,visibility vis)23235 class_tdecl::class_tdecl(const environment*	env,
23236 			 const location&	locus,
23237 			 visibility		vis)
23238   : type_or_decl_base(env,
23239 		      ABSTRACT_DECL_BASE
23240 		      | TEMPLATE_DECL
23241 		      | ABSTRACT_SCOPE_DECL),
23242     decl_base(env, "", locus, "", vis),
23243     template_decl(env, "", locus, vis),
23244     scope_decl(env, "", locus),
23245     priv_(new priv)
23246 {
23247   runtime_type_instance(this);
23248 }
23249 
23250 /// Constructor for the @ref class_tdecl type.
23251 ///
23252 /// @param pattern The details of the class template. This must NOT be a
23253 /// null pointer.  If you really this to be null, please use the
23254 /// constructor above instead.
23255 ///
23256 /// @param locus the source location of the declaration of the type.
23257 ///
23258 /// @param vis the visibility of the instances of class instantiated
23259 /// from this template.
class_tdecl(class_decl_sptr pattern,const location & locus,visibility vis)23260 class_tdecl::class_tdecl(class_decl_sptr	pattern,
23261 			 const location&	locus,
23262 			 visibility		vis)
23263   : type_or_decl_base(pattern->get_environment(),
23264 		      ABSTRACT_DECL_BASE
23265 		      | TEMPLATE_DECL
23266 		      | ABSTRACT_SCOPE_DECL),
23267     decl_base(pattern->get_environment(), pattern->get_name(),
23268 	      locus, pattern->get_name(), vis),
23269     template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
23270     scope_decl(pattern->get_environment(), pattern->get_name(), locus),
23271     priv_(new priv(pattern))
23272 {
23273   runtime_type_instance(this);
23274 }
23275 
23276 /// Setter of the pattern of the template.
23277 ///
23278 /// @param p the new template.
23279 void
set_pattern(class_decl_sptr p)23280 class_tdecl::set_pattern(class_decl_sptr p)
23281 {
23282   priv_->pattern_ = p;
23283   add_decl_to_scope(p, this);
23284   set_name(p->get_name());
23285 }
23286 
23287 /// Getter of the pattern of the template.
23288 ///
23289 /// @return p the new template.
23290 class_decl_sptr
get_pattern() const23291 class_tdecl::get_pattern() const
23292 {return priv_->pattern_;}
23293 
23294 bool
operator ==(const decl_base & other) const23295 class_tdecl::operator==(const decl_base& other) const
23296 {
23297   try
23298     {
23299       const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
23300 
23301       if (!(template_decl::operator==(o)
23302 	    && scope_decl::operator==(o)
23303 	    && !!get_pattern() == !!o.get_pattern()))
23304 	return false;
23305 
23306       if (!get_pattern() || !o.get_pattern())
23307 	return true;
23308 
23309       return get_pattern()->decl_base::operator==(*o.get_pattern());
23310     }
23311   catch(...) {}
23312   return false;
23313 }
23314 
23315 bool
operator ==(const template_decl & other) const23316 class_tdecl::operator==(const template_decl& other) const
23317 {
23318   try
23319     {
23320       const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
23321       return *this == static_cast<const decl_base&>(o);
23322     }
23323   catch(...)
23324     {return false;}
23325 }
23326 
23327 bool
operator ==(const class_tdecl & o) const23328 class_tdecl::operator==(const class_tdecl& o) const
23329 {return *this == static_cast<const decl_base&>(o);}
23330 
23331 /// This implements the ir_traversable_base::traverse pure virtual
23332 /// function.
23333 ///
23334 /// @param v the visitor used on the current instance and on the class
23335 /// pattern of the template.
23336 ///
23337 /// @return true if the entire IR node tree got traversed, false
23338 /// otherwise.
23339 bool
traverse(ir_node_visitor & v)23340 class_tdecl::traverse(ir_node_visitor&v)
23341 {
23342   if (visiting())
23343     return true;
23344 
23345   if (v.visit_begin(this))
23346     {
23347       visiting(true);
23348       if (class_decl_sptr pattern = get_pattern())
23349 	pattern->traverse(v);
23350       visiting(false);
23351     }
23352   return v.visit_end(this);
23353 }
23354 
~class_tdecl()23355 class_tdecl::~class_tdecl()
23356 {}
23357 
23358 /// This visitor checks if a given type as non-canonicalized sub
23359 /// types.
23360 class non_canonicalized_subtype_detector : public ir::ir_node_visitor
23361 {
23362   type_base* type_;
23363   type_base* has_non_canonical_type_;
23364 
23365 private:
23366   non_canonicalized_subtype_detector();
23367 
23368 public:
non_canonicalized_subtype_detector(type_base * type)23369   non_canonicalized_subtype_detector(type_base* type)
23370     : type_(type),
23371       has_non_canonical_type_()
23372   {}
23373 
23374   /// Return true if the visitor detected that there is a
23375   /// non-canonicalized sub-type.
23376   ///
23377   /// @return true if the visitor detected that there is a
23378   /// non-canonicalized sub-type.
23379   type_base*
has_non_canonical_type() const23380   has_non_canonical_type() const
23381   {return has_non_canonical_type_;}
23382 
23383   /// The intent of this visitor handler is to avoid looking into
23384   /// sub-types of member functions of the type we are traversing.
23385   bool
visit_begin(function_decl * f)23386   visit_begin(function_decl* f)
23387   {
23388     // Do not look at sub-types of non-virtual member functions.
23389     if (is_member_function(f)
23390 	&& get_member_function_is_virtual(*f))
23391       return false;
23392     return true;
23393   }
23394 
23395   /// When visiting a sub-type, if it's *NOT* been canonicalized, set
23396   /// the 'has_non_canonical_type' flag.  And in any case, when
23397   /// visiting a sub-type, do not visit its children nodes.  So this
23398   /// function only goes to the level below the level of the top-most
23399   /// type.
23400   ///
23401   /// @return true if we are at the same level as the top-most type,
23402   /// otherwise return false.
23403   bool
visit_begin(type_base * t)23404   visit_begin(type_base* t)
23405   {
23406     if (t != type_)
23407       {
23408 	if (!t->get_canonical_type())
23409 	  // We are looking a sub-type of 'type_' which has no
23410 	  // canonical type.  So tada! we found one!  Get out right
23411 	  // now with the trophy.
23412 	  has_non_canonical_type_ = t;
23413 
23414 	return false;
23415       }
23416     return true;
23417   }
23418 
23419   /// When we are done visiting a sub-type, if it's been flagged as
23420   /// been non-canonicalized, then stop the traversing.
23421   ///
23422   /// Otherwise, keep going.
23423   ///
23424   /// @return false iff the sub-type that has been visited is
23425   /// non-canonicalized.
23426   bool
visit_end(type_base *)23427   visit_end(type_base* )
23428   {
23429     if (has_non_canonical_type_)
23430       return false;
23431     return true;
23432   }
23433 }; //end class non_canonicalized_subtype_detector
23434 
23435 /// Test if a type has sub-types that are non-canonicalized.
23436 ///
23437 /// @param t the type which sub-types to consider.
23438 ///
23439 /// @return true if a type has sub-types that are non-canonicalized.
23440 type_base*
type_has_non_canonicalized_subtype(type_base_sptr t)23441 type_has_non_canonicalized_subtype(type_base_sptr t)
23442 {
23443   if (!t)
23444     return 0;
23445 
23446   non_canonicalized_subtype_detector v(t.get());
23447   t->traverse(v);
23448   return v.has_non_canonical_type();
23449 }
23450 
23451 /// Tests if the change of a given type effectively comes from just
23452 /// its sub-types.  That is, if the type has changed but its type name
23453 /// hasn't changed, then the change of the type mostly likely is a
23454 /// sub-type change.
23455 ///
23456 /// @param t_v1 the first version of the type.
23457 ///
23458 /// @param t_v2 the second version of the type.
23459 ///
23460 /// @return true iff the type changed and the change is about its
23461 /// sub-types.
23462 bool
type_has_sub_type_changes(const type_base_sptr t_v1,const type_base_sptr t_v2)23463 type_has_sub_type_changes(const type_base_sptr t_v1,
23464 			  const type_base_sptr t_v2)
23465 {
23466   type_base_sptr t1 = strip_typedef(t_v1);
23467   type_base_sptr t2 = strip_typedef(t_v2);
23468 
23469   string repr1 = get_pretty_representation(t1),
23470     repr2 = get_pretty_representation(t2);
23471   return (t1 != t2 && repr1 == repr2);
23472 }
23473 
23474 /// Make sure that the life time of a given (smart pointer to a) type
23475 /// is the same as the life time of the libabigail library.
23476 ///
23477 /// @param t the type to consider.
23478 void
keep_type_alive(type_base_sptr t)23479 keep_type_alive(type_base_sptr t)
23480 {
23481   environment* env = t->get_environment();
23482   ABG_ASSERT(env);
23483   env->priv_->extra_live_types_.push_back(t);
23484 }
23485 
23486 /// Hash an ABI artifact that is either a type or a decl.
23487 ///
23488 /// This function intends to provides the fastest possible hashing for
23489 /// types and decls, while being completely correct.
23490 ///
23491 /// Note that if the artifact is a type and if it has a canonical
23492 /// type, the hash value is going to be the pointer value of the
23493 /// canonical type.  Otherwise, this function computes a hash value
23494 /// for the type by recursively walking the type members.  This last
23495 /// code path is possibly *very* slow and should only be used when
23496 /// only handful of types are going to be hashed.
23497 ///
23498 /// If the artifact is a decl, then a combination of the hash of its
23499 /// type and the hash of the other properties of the decl is computed.
23500 ///
23501 /// @param tod the type or decl to hash.
23502 ///
23503 /// @return the resulting hash value.
23504 size_t
hash_type_or_decl(const type_or_decl_base * tod)23505 hash_type_or_decl(const type_or_decl_base *tod)
23506 {
23507   size_t result = 0;
23508 
23509   if (tod == 0)
23510     ;
23511   else if (const type_base* t = is_type(tod))
23512     result = hash_type(t);
23513   else if (const decl_base* d = is_decl(tod))
23514     {
23515       if (var_decl* v = is_var_decl(d))
23516 	{
23517 	  ABG_ASSERT(v->get_type());
23518 	  size_t h = hash_type_or_decl(v->get_type());
23519 	  string repr = v->get_pretty_representation();
23520 	  std::hash<string> hash_string;
23521 	  h = hashing::combine_hashes(h, hash_string(repr));
23522 	  result = h;
23523 	}
23524       else if (function_decl* f = is_function_decl(d))
23525 	{
23526 	  ABG_ASSERT(f->get_type());
23527 	  size_t h = hash_type_or_decl(f->get_type());
23528 	  string repr = f->get_pretty_representation();
23529 	  std::hash<string> hash_string;
23530 	  h = hashing::combine_hashes(h, hash_string(repr));
23531 	  result = h;
23532 	}
23533       else if (function_decl::parameter* p = is_function_parameter(d))
23534 	{
23535 	  type_base_sptr parm_type = p->get_type();
23536 	  ABG_ASSERT(parm_type);
23537 	  std::hash<bool> hash_bool;
23538 	  std::hash<unsigned> hash_unsigned;
23539 	  size_t h = hash_type_or_decl(parm_type);
23540 	  h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
23541 	  h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
23542 	  result = h;
23543 	}
23544       else if (class_decl::base_spec *bs = is_class_base_spec(d))
23545 	{
23546 	  member_base::hash hash_member;
23547 	  std::hash<size_t> hash_size;
23548 	  std::hash<bool> hash_bool;
23549 	  type_base_sptr type = bs->get_base_class();
23550 	  size_t h = hash_type_or_decl(type);
23551 	  h = hashing::combine_hashes(h, hash_member(*bs));
23552 	  h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
23553 	  h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
23554 	  result = h;
23555 	}
23556       else
23557 	// This is a *really* *SLOW* path.  If it shows up in a
23558 	// performance profile, I bet it'd be a good idea to try to
23559 	// avoid it altogether.
23560 	result = d->get_hash();
23561     }
23562   else
23563     // We should never get here.
23564     abort();
23565   return result;
23566 }
23567 
23568 /// Hash an ABI artifact that is either a type.
23569 ///
23570 /// This function intends to provides the fastest possible hashing for
23571 /// types while being completely correct.
23572 ///
23573 /// Note that if the type artifact has a canonical type, the hash
23574 /// value is going to be the pointer value of the canonical type.
23575 /// Otherwise, this function computes a hash value for the type by
23576 /// recursively walking the type members.  This last code path is
23577 /// possibly *very* slow and should only be used when only handful of
23578 /// types are going to be hashed.
23579 ///
23580 /// @param t the type or decl to hash.
23581 ///
23582 /// @return the resulting hash value.
23583 size_t
hash_type(const type_base * t)23584 hash_type(const type_base *t)
23585 {return hash_as_canonical_type_or_constant(t);}
23586 
23587 /// Hash an ABI artifact that is either a type of a decl.
23588 ///
23589 /// @param tod the ABI artifact to hash.
23590 ///
23591 /// @return the hash value of the ABI artifact.
23592 size_t
hash_type_or_decl(const type_or_decl_base_sptr & tod)23593 hash_type_or_decl(const type_or_decl_base_sptr& tod)
23594 {return hash_type_or_decl(tod.get());}
23595 
23596 /// Hash a type by either returning the pointer value of its canonical
23597 /// type or by returning a constant if the type doesn't have a
23598 /// canonical type.
23599 ///
23600 /// This is a subroutine of hash_type.
23601 ///
23602 /// @param t the type to consider.
23603 ///
23604 /// @return the hash value.
23605 static size_t
hash_as_canonical_type_or_constant(const type_base * t)23606 hash_as_canonical_type_or_constant(const type_base *t)
23607 {
23608   type_base *canonical_type = 0;
23609 
23610   if (t)
23611     canonical_type = t->get_naked_canonical_type();
23612 
23613   if (!canonical_type)
23614     {
23615       // If the type doesn't have a canonical type, maybe it's because
23616       // it's a declaration-only type?  If that's the case, let's try
23617       // to get the canonical type of the definition of this
23618       // declaration.
23619       decl_base *decl = is_decl(t);
23620       if (decl
23621 	  && decl->get_is_declaration_only()
23622 	  && decl->get_naked_definition_of_declaration())
23623 	{
23624 	  type_base *definition =
23625 	    is_type(decl->get_naked_definition_of_declaration());
23626 	  ABG_ASSERT(definition);
23627 	  canonical_type = definition->get_naked_canonical_type();
23628 	}
23629     }
23630 
23631   if (canonical_type)
23632     return reinterpret_cast<size_t>(canonical_type);
23633 
23634   // If we reached this point, it means we are seeing a
23635   // non-canonicalized type.  It must be a decl-only class or a
23636   // function type, otherwise it means that for some weird reason, the
23637   // type hasn't been canonicalized.  It should be!
23638   ABG_ASSERT(is_declaration_only_class_or_union_type(t));
23639 
23640   return 0xDEADBABE;
23641 }
23642 
23643 /// Test if the pretty representation of a given @ref function_decl is
23644 /// lexicographically less then the pretty representation of another
23645 /// @ref function_decl.
23646 ///
23647 /// @param f the first @ref function_decl to consider for comparison.
23648 ///
23649 /// @param s the second @ref function_decl to consider for comparison.
23650 ///
23651 /// @return true iff the pretty representation of @p f is
23652 /// lexicographically less than the pretty representation of @p s.
23653 bool
function_decl_is_less_than(const function_decl & f,const function_decl & s)23654 function_decl_is_less_than(const function_decl &f, const function_decl &s)
23655 {
23656   string fr = f.get_pretty_representation_of_declarator(),
23657     sr = s.get_pretty_representation_of_declarator();
23658 
23659   if (fr != sr)
23660     return fr < sr;
23661 
23662   fr = f.get_pretty_representation(),
23663     sr = s.get_pretty_representation();
23664 
23665   if (fr != sr)
23666     return fr < sr;
23667 
23668   if (f.get_symbol())
23669     fr = f.get_symbol()->get_id_string();
23670   else if (!f.get_linkage_name().empty())
23671     fr = f.get_linkage_name();
23672 
23673   if (s.get_symbol())
23674     sr = s.get_symbol()->get_id_string();
23675   else if (!s.get_linkage_name().empty())
23676     sr = s.get_linkage_name();
23677 
23678   return fr < sr;
23679 }
23680 
23681 /// Test if two types have similar structures, even though they are
23682 /// (or can be) different.
23683 ///
23684 /// const and volatile qualifiers are completely ignored.
23685 ///
23686 /// typedef are resolved to their definitions; their names are ignored.
23687 ///
23688 /// Two indirect types (pointers or references) have similar structure
23689 /// if their underlying types are of the same kind and have the same
23690 /// name.  In the indirect types case, the size of the underlying type
23691 /// does not matter.
23692 ///
23693 /// Two direct types (i.e, non indirect) have a similar structure if
23694 /// they have the same kind, name and size.  Two class types have
23695 /// similar structure if they have the same name, size, and if the
23696 /// types of their data members have similar types.
23697 ///
23698 /// @param first the first type to consider.
23699 ///
23700 /// @param second the second type to consider.
23701 ///
23702 /// @param indirect_type whether to do an indirect comparison
23703 ///
23704 /// @return true iff @p first and @p second have similar structures.
23705 bool
types_have_similar_structure(const type_base_sptr & first,const type_base_sptr & second,bool indirect_type)23706 types_have_similar_structure(const type_base_sptr& first,
23707 			     const type_base_sptr& second,
23708 			     bool indirect_type)
23709 {return types_have_similar_structure(first.get(), second.get(), indirect_type);}
23710 
23711 /// Test if two types have similar structures, even though they are
23712 /// (or can be) different.
23713 ///
23714 /// const and volatile qualifiers are completely ignored.
23715 ///
23716 /// typedef are resolved to their definitions; their names are ignored.
23717 ///
23718 /// Two indirect types (pointers, references or arrays) have similar
23719 /// structure if their underlying types are of the same kind and have
23720 /// the same name.  In the indirect types case, the size of the
23721 /// underlying type does not matter.
23722 ///
23723 /// Two direct types (i.e, non indirect) have a similar structure if
23724 /// they have the same kind, name and size.  Two class types have
23725 /// similar structure if they have the same name, size, and if the
23726 /// types of their data members have similar types.
23727 ///
23728 /// @param first the first type to consider.
23729 ///
23730 /// @param second the second type to consider.
23731 ///
23732 /// @param indirect_type if true, then consider @p first and @p
23733 /// second as being underlying types of indirect types.  Meaning that
23734 /// their size does not matter.
23735 ///
23736 /// @return true iff @p first and @p second have similar structures.
23737 bool
types_have_similar_structure(const type_base * first,const type_base * second,bool indirect_type)23738 types_have_similar_structure(const type_base* first,
23739 			     const type_base* second,
23740 			     bool indirect_type)
23741 {
23742   if (!!first != !!second)
23743     return false;
23744 
23745   if (!first)
23746     return false;
23747 
23748   // Treat typedefs purely as type aliases and ignore CV-qualifiers.
23749   first = peel_qualified_or_typedef_type(first);
23750   second = peel_qualified_or_typedef_type(second);
23751 
23752   // Eliminate all but N of the N^2 comparison cases. This also guarantees the
23753   // various ty2 below cannot be null.
23754   if (typeid(*first) != typeid(*second))
23755     return false;
23756 
23757   // Peel off matching pointers.
23758   if (const pointer_type_def* ty1 = is_pointer_type(first))
23759     {
23760       const pointer_type_def* ty2 = is_pointer_type(second);
23761       return types_have_similar_structure(ty1->get_pointed_to_type(),
23762 					  ty2->get_pointed_to_type(),
23763 					  /*indirect_type=*/true);
23764     }
23765 
23766   // Peel off matching references.
23767   if (const reference_type_def* ty1 = is_reference_type(first))
23768     {
23769       const reference_type_def* ty2 = is_reference_type(second);
23770       if (ty1->is_lvalue() != ty2->is_lvalue())
23771 	return false;
23772       return types_have_similar_structure(ty1->get_pointed_to_type(),
23773 					  ty2->get_pointed_to_type(),
23774 					  /*indirect_type=*/true);
23775     }
23776 
23777   if (const type_decl* ty1 = is_type_decl(first))
23778     {
23779       const type_decl* ty2 = is_type_decl(second);
23780       if (!indirect_type)
23781 	if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
23782 	  return false;
23783 
23784       return ty1->get_name() == ty2->get_name();
23785     }
23786 
23787   if (const enum_type_decl* ty1 = is_enum_type(first))
23788     {
23789       const enum_type_decl* ty2 = is_enum_type(second);
23790       if (!indirect_type)
23791 	if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
23792 	  return false;
23793 
23794       return (get_name(ty1->get_underlying_type())
23795 	      == get_name(ty2->get_underlying_type()));
23796     }
23797 
23798   if (const class_decl* ty1 = is_class_type(first))
23799     {
23800       const class_decl* ty2 = is_class_type(second);
23801       if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
23802 	  && ty1->get_name() != ty2->get_name())
23803 	return false;
23804 
23805       if (!indirect_type)
23806 	{
23807 	  if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
23808 	      || (ty1->get_non_static_data_members().size()
23809 		  != ty2->get_non_static_data_members().size()))
23810 	    return false;
23811 
23812 	  for (class_or_union::data_members::const_iterator
23813 		 i = ty1->get_non_static_data_members().begin(),
23814 		 j = ty2->get_non_static_data_members().begin();
23815 	       (i != ty1->get_non_static_data_members().end()
23816 		&& j != ty2->get_non_static_data_members().end());
23817 	       ++i, ++j)
23818 	    {
23819 	      var_decl_sptr dm1 = *i;
23820 	      var_decl_sptr dm2 = *j;
23821 	      if (!types_have_similar_structure(dm1->get_type().get(),
23822 						dm2->get_type().get(),
23823 						indirect_type))
23824 		return false;
23825 	    }
23826 	}
23827 
23828       return true;
23829     }
23830 
23831   if (const union_decl* ty1 = is_union_type(first))
23832     {
23833       const union_decl* ty2 = is_union_type(second);
23834       if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
23835 	  && ty1->get_name() != ty2->get_name())
23836 	return false;
23837 
23838       if (!indirect_type)
23839 	return ty1->get_size_in_bits() == ty2->get_size_in_bits();
23840 
23841       return true;
23842     }
23843 
23844   if (const array_type_def* ty1 = is_array_type(first))
23845     {
23846       const array_type_def* ty2 = is_array_type(second);
23847       // TODO: Handle int[5][2] vs int[2][5] better.
23848       if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
23849 	  || ty1->get_dimension_count() != ty2->get_dimension_count()
23850 	  || !types_have_similar_structure(ty1->get_element_type(),
23851 					   ty2->get_element_type(),
23852 					   /*indirect_type=*/true))
23853 	return false;
23854 
23855       return true;
23856     }
23857 
23858   if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
23859     {
23860       const array_type_def::subrange_type *ty2 = is_subrange_type(second);
23861       if (ty1->get_upper_bound() != ty2->get_upper_bound()
23862 	  || ty1->get_lower_bound() != ty2->get_lower_bound()
23863 	  || ty1->get_language() != ty2->get_language()
23864 	  || !types_have_similar_structure(ty1->get_underlying_type(),
23865 					   ty2->get_underlying_type(),
23866 					   indirect_type))
23867 	return false;
23868 
23869       return true;
23870     }
23871 
23872   if (const function_type* ty1 = is_function_type(first))
23873     {
23874       const function_type* ty2 = is_function_type(second);
23875       if (!types_have_similar_structure(ty1->get_return_type(),
23876 					ty2->get_return_type(),
23877 					indirect_type))
23878 	return false;
23879 
23880       if (ty1->get_parameters().size() != ty2->get_parameters().size())
23881 	return false;
23882 
23883       for (function_type::parameters::const_iterator
23884 	     i = ty1->get_parameters().begin(),
23885 	     j = ty2->get_parameters().begin();
23886 	   (i != ty1->get_parameters().end()
23887 	    && j != ty2->get_parameters().end());
23888 	   ++i, ++j)
23889 	if (!types_have_similar_structure((*i)->get_type(),
23890 					  (*j)->get_type(),
23891 					  indirect_type))
23892 	  return false;
23893 
23894       return true;
23895     }
23896 
23897   // All kinds of type should have been handled at this point.
23898   ABG_ASSERT_NOT_REACHED;
23899 
23900   return false;
23901 }
23902 
23903 /// Look for a data member of a given class, struct or union type and
23904 /// return it.
23905 ///
23906 /// The data member is designated by its name.
23907 ///
23908 /// @param type the class, struct or union type to consider.
23909 ///
23910 /// @param dm_name the name of the data member to lookup.
23911 ///
23912 /// @return the data member iff it was found in @type or NULL if no
23913 /// data member with that name was found.
23914 const var_decl*
lookup_data_member(const type_base * type,const char * dm_name)23915 lookup_data_member(const type_base* type,
23916 		   const char* dm_name)
23917 
23918 {
23919   class_or_union *cou = is_class_or_union_type(type);
23920   if (!cou)
23921     return 0;
23922 
23923   return cou->find_data_member(dm_name).get();
23924 }
23925 
23926 /// Get the function parameter designated by its index.
23927 ///
23928 /// Note that the first function parameter has index 0.
23929 ///
23930 /// @param fun the function to consider.
23931 ///
23932 /// @param parm_index the index of the function parameter to get.
23933 ///
23934 /// @return the function parameter designated by its index, of NULL if
23935 /// no function parameter with that index was found.
23936 const function_decl::parameter*
get_function_parameter(const decl_base * fun,unsigned parm_index)23937 get_function_parameter(const decl_base* fun,
23938 		       unsigned parm_index)
23939 {
23940   function_decl* fn = is_function_decl(fun);
23941   if (!fn)
23942     return 0;
23943 
23944   const function_decl::parameters &parms = fn->get_type()->get_parameters();
23945   if (parms.size() <= parm_index)
23946     return 0;
23947 
23948   return parms[parm_index].get();
23949 }
23950 
23951 bool
traverse(ir_node_visitor &)23952 ir_traversable_base::traverse(ir_node_visitor&)
23953 {return true;}
23954 
23955 // <ir_node_visitor stuff>
23956 
23957 /// The private data structure of the ir_node_visitor type.
23958 struct ir_node_visitor::priv
23959 {
23960   pointer_set visited_ir_nodes;
23961   bool allow_visiting_already_visited_type_node;
23962 
privabigail::ir::ir_node_visitor::priv23963   priv()
23964     : allow_visiting_already_visited_type_node(true)
23965   {}
23966 }; // end struct ir_node_visitory::priv
23967 
23968 /// Default Constructor of the ir_node_visitor type.
ir_node_visitor()23969 ir_node_visitor::ir_node_visitor()
23970   : priv_(new priv)
23971 {}
23972 
23973 /// Set if the walker using this visitor is allowed to re-visit a type
23974 /// node that was previously visited or not.
23975 ///
23976 /// @param f if true, then the walker using this visitor is allowed to
23977 /// re-visit a type node that was previously visited.
23978 void
allow_visiting_already_visited_type_node(bool f)23979 ir_node_visitor::allow_visiting_already_visited_type_node(bool f)
23980 {priv_->allow_visiting_already_visited_type_node = f;}
23981 
23982 /// Get if the walker using this visitor is allowed to re-visit a type
23983 /// node that was previously visited or not.
23984 ///
23985 /// @return true iff the walker using this visitor is allowed to
23986 /// re-visit a type node that was previously visited.
23987 bool
allow_visiting_already_visited_type_node() const23988 ir_node_visitor::allow_visiting_already_visited_type_node() const
23989 {return priv_->allow_visiting_already_visited_type_node;}
23990 
23991 /// Mark a given type node as having been visited.
23992 ///
23993 /// Note that for this function to work, the type node must have been
23994 /// canonicalized.  Otherwise the process is aborted.
23995 ///
23996 /// @param p the type to mark as having been visited.
23997 void
mark_type_node_as_visited(type_base * p)23998 ir_node_visitor::mark_type_node_as_visited(type_base *p)
23999 {
24000   if (allow_visiting_already_visited_type_node())
24001     return;
24002 
24003   if (p == 0 || type_node_has_been_visited(p))
24004     return;
24005 
24006   type_base* canonical_type = p->get_naked_canonical_type();
24007   ABG_ASSERT(canonical_type);
24008 
24009   size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
24010   priv_->visited_ir_nodes.insert(canonical_ptr_value);
24011 }
24012 
24013 /// Un-mark all visited type nodes.
24014 ///
24015 /// That is, no type node is going to be considered as having been
24016 /// visited anymore.
24017 ///
24018 /// In other words, after invoking this funciton,
24019 /// ir_node_visitor::type_node_has_been_visited() is going to return
24020 /// false on all type nodes.
24021 void
forget_visited_type_nodes()24022 ir_node_visitor::forget_visited_type_nodes()
24023 {priv_->visited_ir_nodes.clear();}
24024 
24025 /// Test if a given type node has been marked as visited.
24026 ///
24027 /// @param p the type node to consider.
24028 ///
24029 /// @return true iff the type node @p p has been marked as visited by
24030 /// the function ir_node_visitor::mark_type_node_as_visited.
24031 bool
type_node_has_been_visited(type_base * p) const24032 ir_node_visitor::type_node_has_been_visited(type_base* p) const
24033 {
24034   if (allow_visiting_already_visited_type_node())
24035     return false;
24036 
24037   if (p == 0)
24038     return false;
24039 
24040   type_base *canonical_type = p->get_naked_canonical_type();
24041   ABG_ASSERT(canonical_type);
24042 
24043   size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
24044   pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
24045   if (it == priv_->visited_ir_nodes.end())
24046     return false;
24047 
24048   return true;
24049 }
24050 
24051 bool
visit_begin(decl_base *)24052 ir_node_visitor::visit_begin(decl_base*)
24053 {return true;}
24054 
24055 bool
visit_end(decl_base *)24056 ir_node_visitor::visit_end(decl_base*)
24057 {return true;}
24058 
24059 bool
visit_begin(scope_decl *)24060 ir_node_visitor::visit_begin(scope_decl*)
24061 {return true;}
24062 
24063 bool
visit_end(scope_decl *)24064 ir_node_visitor::visit_end(scope_decl*)
24065 {return true;}
24066 
24067 bool
visit_begin(type_base *)24068 ir_node_visitor::visit_begin(type_base*)
24069 {return true;}
24070 
24071 bool
visit_end(type_base *)24072 ir_node_visitor::visit_end(type_base*)
24073 {return true;}
24074 
24075 bool
visit_begin(scope_type_decl * t)24076 ir_node_visitor::visit_begin(scope_type_decl* t)
24077 {return visit_begin(static_cast<type_base*>(t));}
24078 
24079 bool
visit_end(scope_type_decl * t)24080 ir_node_visitor::visit_end(scope_type_decl* t)
24081 {return visit_end(static_cast<type_base*>(t));}
24082 
24083 bool
visit_begin(type_decl * t)24084 ir_node_visitor::visit_begin(type_decl* t)
24085 {return visit_begin(static_cast<type_base*>(t));}
24086 
24087 bool
visit_end(type_decl * t)24088 ir_node_visitor::visit_end(type_decl* t)
24089 {return visit_end(static_cast<type_base*>(t));}
24090 
24091 bool
visit_begin(namespace_decl * d)24092 ir_node_visitor::visit_begin(namespace_decl* d)
24093 {return visit_begin(static_cast<decl_base*>(d));}
24094 
24095 bool
visit_end(namespace_decl * d)24096 ir_node_visitor::visit_end(namespace_decl* d)
24097 {return visit_end(static_cast<decl_base*>(d));}
24098 
24099 bool
visit_begin(qualified_type_def * t)24100 ir_node_visitor::visit_begin(qualified_type_def* t)
24101 {return visit_begin(static_cast<type_base*>(t));}
24102 
24103 bool
visit_end(qualified_type_def * t)24104 ir_node_visitor::visit_end(qualified_type_def* t)
24105 {return visit_end(static_cast<type_base*>(t));}
24106 
24107 bool
visit_begin(pointer_type_def * t)24108 ir_node_visitor::visit_begin(pointer_type_def* t)
24109 {return visit_begin(static_cast<type_base*>(t));}
24110 
24111 bool
visit_end(pointer_type_def * t)24112 ir_node_visitor::visit_end(pointer_type_def* t)
24113 {return visit_end(static_cast<type_base*>(t));}
24114 
24115 bool
visit_begin(reference_type_def * t)24116 ir_node_visitor::visit_begin(reference_type_def* t)
24117 {return visit_begin(static_cast<type_base*>(t));}
24118 
24119 bool
visit_end(reference_type_def * t)24120 ir_node_visitor::visit_end(reference_type_def* t)
24121 {return visit_end(static_cast<type_base*>(t));}
24122 
24123 bool
visit_begin(array_type_def * t)24124 ir_node_visitor::visit_begin(array_type_def* t)
24125 {return visit_begin(static_cast<type_base*>(t));}
24126 
24127 bool
visit_end(array_type_def * t)24128 ir_node_visitor::visit_end(array_type_def* t)
24129 {return visit_end(static_cast<type_base*>(t));}
24130 
24131 bool
visit_begin(array_type_def::subrange_type * t)24132 ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
24133 {return visit_begin(static_cast<type_base*>(t));}
24134 
24135 bool
visit_end(array_type_def::subrange_type * t)24136 ir_node_visitor::visit_end(array_type_def::subrange_type* t)
24137 {return visit_end(static_cast<type_base*>(t));}
24138 
24139 bool
visit_begin(enum_type_decl * t)24140 ir_node_visitor::visit_begin(enum_type_decl* t)
24141 {return visit_begin(static_cast<type_base*>(t));}
24142 
24143 bool
visit_end(enum_type_decl * t)24144 ir_node_visitor::visit_end(enum_type_decl* t)
24145 {return visit_end(static_cast<type_base*>(t));}
24146 
24147 bool
visit_begin(typedef_decl * t)24148 ir_node_visitor::visit_begin(typedef_decl* t)
24149 {return visit_begin(static_cast<type_base*>(t));}
24150 
24151 bool
visit_end(typedef_decl * t)24152 ir_node_visitor::visit_end(typedef_decl* t)
24153 {return visit_end(static_cast<type_base*>(t));}
24154 
24155 bool
visit_begin(function_type * t)24156 ir_node_visitor::visit_begin(function_type* t)
24157 {return visit_begin(static_cast<type_base*>(t));}
24158 
24159 bool
visit_end(function_type * t)24160 ir_node_visitor::visit_end(function_type* t)
24161 {return visit_end(static_cast<type_base*>(t));}
24162 
24163 bool
visit_begin(var_decl * d)24164 ir_node_visitor::visit_begin(var_decl* d)
24165 {return visit_begin(static_cast<decl_base*>(d));}
24166 
24167 bool
visit_end(var_decl * d)24168 ir_node_visitor::visit_end(var_decl* d)
24169 {return visit_end(static_cast<decl_base*>(d));}
24170 
24171 bool
visit_begin(function_decl * d)24172 ir_node_visitor::visit_begin(function_decl* d)
24173 {return visit_begin(static_cast<decl_base*>(d));}
24174 
24175 bool
visit_end(function_decl * d)24176 ir_node_visitor::visit_end(function_decl* d)
24177 {return visit_end(static_cast<decl_base*>(d));}
24178 
24179 bool
visit_begin(function_decl::parameter * d)24180 ir_node_visitor::visit_begin(function_decl::parameter* d)
24181 {return visit_begin(static_cast<decl_base*>(d));}
24182 
24183 bool
visit_end(function_decl::parameter * d)24184 ir_node_visitor::visit_end(function_decl::parameter* d)
24185 {return visit_end(static_cast<decl_base*>(d));}
24186 
24187 bool
visit_begin(function_tdecl * d)24188 ir_node_visitor::visit_begin(function_tdecl* d)
24189 {return visit_begin(static_cast<decl_base*>(d));}
24190 
24191 bool
visit_end(function_tdecl * d)24192 ir_node_visitor::visit_end(function_tdecl* d)
24193 {return visit_end(static_cast<decl_base*>(d));}
24194 
24195 bool
visit_begin(class_tdecl * d)24196 ir_node_visitor::visit_begin(class_tdecl* d)
24197 {return visit_begin(static_cast<decl_base*>(d));}
24198 
24199 bool
visit_end(class_tdecl * d)24200 ir_node_visitor::visit_end(class_tdecl* d)
24201 {return visit_end(static_cast<decl_base*>(d));}
24202 
24203 bool
visit_begin(class_or_union * t)24204 ir_node_visitor::visit_begin(class_or_union* t)
24205 {return visit_begin(static_cast<type_base*>(t));}
24206 
24207 bool
visit_end(class_or_union * t)24208 ir_node_visitor::visit_end(class_or_union* t)
24209 {return visit_end(static_cast<type_base*>(t));}
24210 
24211 bool
visit_begin(class_decl * t)24212 ir_node_visitor::visit_begin(class_decl* t)
24213 {return visit_begin(static_cast<type_base*>(t));}
24214 
24215 bool
visit_end(class_decl * t)24216 ir_node_visitor::visit_end(class_decl* t)
24217 {return visit_end(static_cast<type_base*>(t));}
24218 
24219 bool
visit_begin(union_decl * t)24220 ir_node_visitor::visit_begin(union_decl* t)
24221 {return visit_begin(static_cast<type_base*>(t));}
24222 
24223 bool
visit_end(union_decl * t)24224 ir_node_visitor::visit_end(union_decl* t)
24225 {return visit_end(static_cast<type_base*>(t));}
24226 
24227 bool
visit_begin(class_decl::base_spec * d)24228 ir_node_visitor::visit_begin(class_decl::base_spec* d)
24229 {return visit_begin(static_cast<decl_base*>(d));}
24230 
24231 bool
visit_end(class_decl::base_spec * d)24232 ir_node_visitor::visit_end(class_decl::base_spec* d)
24233 {return visit_end(static_cast<decl_base*>(d));}
24234 
24235 bool
visit_begin(member_function_template * d)24236 ir_node_visitor::visit_begin(member_function_template* d)
24237 {return visit_begin(static_cast<decl_base*>(d));}
24238 
24239 bool
visit_end(member_function_template * d)24240 ir_node_visitor::visit_end(member_function_template* d)
24241 {return visit_end(static_cast<decl_base*>(d));}
24242 
24243 bool
visit_begin(member_class_template * d)24244 ir_node_visitor::visit_begin(member_class_template* d)
24245 {return visit_begin(static_cast<decl_base*>(d));}
24246 
24247 bool
visit_end(member_class_template * d)24248 ir_node_visitor::visit_end(member_class_template* d)
24249 {return visit_end(static_cast<decl_base*>(d));}
24250 
24251 // </ir_node_visitor stuff>
24252 
24253 // <debugging facilities>
24254 
24255 /// Generate a different string at each invocation.
24256 ///
24257 /// @return the resulting string.
24258 static string
get_next_string()24259 get_next_string()
24260 {
24261   static __thread size_t counter;
24262   ++counter;
24263   std::ostringstream o;
24264   o << counter;
24265   return o.str();
24266 }
24267 
24268 /// Convenience typedef for a hash map of pointer to function_decl and
24269 /// string.
24270 typedef unordered_map<const function_decl*, string,
24271 		      function_decl::hash,
24272 		      function_decl::ptr_equal> fns_to_str_map_type;
24273 
24274 /// Return a string associated to a given function.  Two functions
24275 /// that compare equal would yield the same string, as far as this
24276 /// routine is concerned.  And two functions that are different would
24277 /// yield different strings.
24278 ///
24279 /// This is used to debug core diffing issues on functions.  The
24280 /// sequence of strings can be given to the 'testdiff2' program that
24281 /// is in the tests/ directory of the source tree, to reproduce core
24282 /// diffing issues on string and thus ease the debugging.
24283 ///
24284 /// @param fn the function to generate a string for.
24285 ///
24286 /// @param m the function_decl* <-> string map to be used by this
24287 /// function to generate strings associated to a function.
24288 ///
24289 /// @return the resulting string.
24290 static const string&
fn_to_str(const function_decl * fn,fns_to_str_map_type & m)24291 fn_to_str(const function_decl* fn,
24292 	  fns_to_str_map_type& m)
24293 {
24294   fns_to_str_map_type::const_iterator i = m.find(fn);
24295   if (i != m.end())
24296     return i->second;
24297   string s = get_next_string();
24298   return m[fn]= s;
24299 }
24300 
24301 /// Generate a sequence of string that matches a given sequence of
24302 /// function.  In the resulting sequence, each function is "uniquely
24303 /// representated" by a string.  For instance, if the same function "foo"
24304 /// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
24305 /// we don't care about the actual string) would appear at index 1 and 3.
24306 ///
24307 /// @param begin the beginning of the sequence of functions to consider.
24308 ///
24309 /// @param end the end of the sequence of functions.  This points to
24310 /// one-passed-the-end of the actual sequence.
24311 ///
24312 /// @param m the function_decl* <-> string map to be used by this
24313 /// function to generate strings associated to a function.
24314 ///
24315 /// @param o the output stream where to emit the generated list of
24316 /// strings to.
24317 static void
fns_to_str(vector<function_decl * >::const_iterator begin,vector<function_decl * >::const_iterator end,fns_to_str_map_type & m,std::ostream & o)24318 fns_to_str(vector<function_decl*>::const_iterator begin,
24319 	   vector<function_decl*>::const_iterator end,
24320 	   fns_to_str_map_type& m,
24321 	   std::ostream& o)
24322 {
24323   vector<function_decl*>::const_iterator i;
24324   for (i = begin; i != end; ++i)
24325     o << "'" << fn_to_str(*i, m) << "' ";
24326 }
24327 
24328 /// For each sequence of functions given in argument, generate a
24329 /// sequence of string that matches a given sequence of function.  In
24330 /// the resulting sequence, each function is "uniquely representated"
24331 /// by a string.  For instance, if the same function "foo" appears at
24332 /// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
24333 /// care about the actual string) would appear at index 1 and 3.
24334 ///
24335 /// @param a_begin the beginning of the sequence of functions to consider.
24336 ///
24337 /// @param a_end the end of the sequence of functions.  This points to
24338 /// one-passed-the-end of the actual sequence.
24339 ///
24340 /// @param b_begin the beginning of the second sequence of functions
24341 /// to consider.
24342 ///
24343 /// @param b_end the end of the second sequence of functions.
24344 ///
24345 /// @param m the function_decl* <-> string map to be used by this
24346 /// function to generate strings associated to a function.
24347 ///
24348 /// @param o the output stream where to emit the generated list of
24349 /// strings to.
24350 static void
fns_to_str(vector<function_decl * >::const_iterator a_begin,vector<function_decl * >::const_iterator a_end,vector<function_decl * >::const_iterator b_begin,vector<function_decl * >::const_iterator b_end,fns_to_str_map_type & m,std::ostream & o)24351 fns_to_str(vector<function_decl*>::const_iterator a_begin,
24352 	   vector<function_decl*>::const_iterator a_end,
24353 	   vector<function_decl*>::const_iterator b_begin,
24354 	   vector<function_decl*>::const_iterator b_end,
24355 	   fns_to_str_map_type& m,
24356 	   std::ostream& o)
24357 {
24358   fns_to_str(a_begin, a_end, m, o);
24359   o << "->|<- ";
24360   fns_to_str(b_begin, b_end, m, o);
24361   o << "\n";
24362 }
24363 
24364 /// For each sequence of functions given in argument, generate a
24365 /// sequence of string that matches a given sequence of function.  In
24366 /// the resulting sequence, each function is "uniquely representated"
24367 /// by a string.  For instance, if the same function "foo" appears at
24368 /// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
24369 /// care about the actual string) would appear at index 1 and 3.
24370 ///
24371 /// @param a_begin the beginning of the sequence of functions to consider.
24372 ///
24373 /// @param a_end the end of the sequence of functions.  This points to
24374 /// one-passed-the-end of the actual sequence.
24375 ///
24376 /// @param b_begin the beginning of the second sequence of functions
24377 /// to consider.
24378 ///
24379 /// @param b_end the end of the second sequence of functions.
24380 ///
24381 /// @param o the output stream where to emit the generated list of
24382 /// strings to.
24383 void
fns_to_str(vector<function_decl * >::const_iterator a_begin,vector<function_decl * >::const_iterator a_end,vector<function_decl * >::const_iterator b_begin,vector<function_decl * >::const_iterator b_end,std::ostream & o)24384 fns_to_str(vector<function_decl*>::const_iterator a_begin,
24385 	   vector<function_decl*>::const_iterator a_end,
24386 	   vector<function_decl*>::const_iterator b_begin,
24387 	   vector<function_decl*>::const_iterator b_end,
24388 	   std::ostream& o)
24389 {
24390   fns_to_str_map_type m;
24391   fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
24392 }
24393 
24394 // </debugging facilities>
24395 
24396 // </class template>
24397 
24398 }// end namespace ir
24399 }//end namespace abigail
24400 
24401 namespace
24402 {
24403 
24404 /// Update the qualified parent name, qualified name and scoped name
24405 /// of a tree decl node.
24406 ///
24407 /// @return true if the tree walking should continue, false otherwise.
24408 ///
24409 /// @param d the tree node to take in account.
24410 bool
do_update(abigail::ir::decl_base * d)24411 qualified_name_setter::do_update(abigail::ir::decl_base* d)
24412 {
24413   std::string parent_qualified_name;
24414   abigail::ir::scope_decl* parent = d->get_scope();
24415   if (parent)
24416     d->priv_->qualified_parent_name_ = parent->get_qualified_name();
24417   else
24418     d->priv_->qualified_parent_name_ = abigail::interned_string();
24419 
24420   abigail::environment* env = d->get_environment();
24421   ABG_ASSERT(env);
24422   if (!d->priv_->qualified_parent_name_.empty())
24423     {
24424       if (d->get_name().empty())
24425 	d->priv_->qualified_name_ = abigail::interned_string();
24426       else
24427 	d->priv_->qualified_name_ =
24428 	  env->intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
24429     }
24430 
24431   if (d->priv_->scoped_name_.empty())
24432     {
24433       if (parent
24434 	  && !parent->get_is_anonymous()
24435 	  && !parent->get_name().empty())
24436 	d->priv_->scoped_name_ =
24437 	  env->intern(parent->get_name() + "::" + d->get_name());
24438       else
24439 	d->priv_->scoped_name_ =
24440 	  env->intern(d->get_name());
24441     }
24442 
24443   if (!is_scope_decl(d))
24444     return false;
24445 
24446   return true;
24447 }
24448 
24449 /// This is called when we start visiting a decl node, during the
24450 /// udpate of the qualified name of a given sub-tree.
24451 ///
24452 /// @param d the decl node we are visiting.
24453 ///
24454 /// @return true iff the traversal should keep going.
24455 bool
visit_begin(abigail::ir::decl_base * d)24456 qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
24457 {return do_update(d);}
24458 
24459 /// This is called when we start visiting a type node, during the
24460 /// udpate of the qualified name of a given sub-tree.
24461 ///
24462 /// @param d the decl node we are visiting.
24463 ///
24464 /// @return true iff the traversal should keep going.
24465 bool
visit_begin(abigail::ir::type_base * t)24466 qualified_name_setter::visit_begin(abigail::ir::type_base* t)
24467 {
24468   if (abigail::ir::decl_base* d = get_type_declaration(t))
24469     return do_update(d);
24470   return false;
24471 }
24472 }// end anonymous namespace.
24473