• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -*- mode:
2 // C++ -*-
3 //
4 // Copyright (C) 2013-2023 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-regex.h"
32 
33 ABG_END_EXPORT_DECLARATIONS
34 // </headers defining libabigail's API>
35 
36 #include "abg-corpus-priv.h"
37 #include "abg-tools-utils.h"
38 #include "abg-comp-filter.h"
39 #include "abg-ir-priv.h"
40 
41 namespace
42 {
43 /// This internal type is a tree walking that is used to set the
44 /// qualified name of a tree of decls and types.  It used by the
45 /// function update_qualified_name().
46 class qualified_name_setter : public abigail::ir::ir_node_visitor
47 {
48 
49 public:
50   bool
51   do_update(abigail::ir::decl_base* d);
52 
53   bool
54   visit_begin(abigail::ir::decl_base* d);
55 
56   bool
57   visit_begin(abigail::ir::type_base* d);
58 }; // end class qualified_name_setter
59 
60 }// end anon namespace
61 
62 namespace abigail
63 {
64 
65 // Inject.
66 using std::string;
67 using std::list;
68 using std::vector;
69 using std::unordered_map;
70 using std::dynamic_pointer_cast;
71 using std::static_pointer_cast;
72 
73 /// Convenience typedef for a map of string -> string*.
74 typedef unordered_map<string, string*> pool_map_type;
75 
76 /// The type of the private data structure of type @ref
77 /// intered_string_pool.
78 struct interned_string_pool::priv
79 {
80   pool_map_type map;
81 }; //end struc struct interned_string_pool::priv
82 
83 /// Default constructor.
interned_string_pool()84 interned_string_pool::interned_string_pool()
85   : priv_(new priv)
86 {
87   priv_->map[""] = 0;
88 }
89 
90 /// Test if the interned string pool already contains a string with a
91 /// given value.
92 ///
93 /// @param s the string to test for.
94 ///
95 /// @return true if the pool contains a string with the value @p s.
96 bool
has_string(const char * s) const97 interned_string_pool::has_string(const char* s) const
98 {return priv_->map.find(s) != priv_->map.end();}
99 
100 /// Get a pointer to the interned string which has a given value.
101 ///
102 /// @param s the value of the interned string to look for.
103 ///
104 /// @return a pointer to the raw string of characters which has the
105 /// value of @p s.  Or null if no string with value @p s was interned.
106 const char*
get_string(const char * s) const107 interned_string_pool::get_string(const char* s) const
108 {
109   unordered_map<string, string*>::const_iterator i =
110     priv_->map.find(s);
111   if (i == priv_->map.end())
112     return 0;
113   if (i->second)
114     return i->second->c_str();
115   return "";
116 }
117 
118 /// Create an interned string with a given value.
119 ///
120 /// @param str_value the value of the interned string to create.
121 ///
122 /// @return the new created instance of @ref interned_string created.
123 interned_string
create_string(const std::string & str_value)124 interned_string_pool::create_string(const std::string& str_value)
125 {
126   string*& result = priv_->map[str_value];
127   if (!result && !str_value.empty())
128     result = new string(str_value);
129   return interned_string(result);
130 }
131 
132 /// Destructor.
~interned_string_pool()133 interned_string_pool::~interned_string_pool()
134 {
135   for (pool_map_type::iterator i = priv_->map.begin();
136        i != priv_->map.end();
137        ++i)
138     if (i->second)
139       delete i->second;
140 }
141 
142 /// Equality operator.
143 ///
144 /// @param l the instance of std::string on the left-hand-side of the
145 /// equality operator.
146 ///
147 /// @param r the instance of @ref interned_string on the
148 /// right-hand-side of the equality operator.
149 ///
150 /// @return true iff the two string are equal.
151 bool
operator ==(const std::string & l,const interned_string & r)152 operator==(const std::string& l, const interned_string& r)
153 {return r.operator==(l);}
154 
155 bool
operator !=(const std::string & l,const interned_string & r)156 operator!=(const std::string& l, const interned_string& r)
157 {return !(l == r);}
158 
159 /// Streaming operator.
160 ///
161 /// Streams an instance of @ref interned_string to an output stream.
162 ///
163 /// @param o the destination output stream.
164 ///
165 /// @param s the instance of @ref interned_string to stream out.
166 ///
167 /// @return the output stream this function just streamed to.
168 std::ostream&
operator <<(std::ostream & o,const interned_string & s)169 operator<<(std::ostream& o, const interned_string& s)
170 {
171   o << static_cast<std::string>(s);
172   return o;
173 }
174 
175 /// Concatenation operator.
176 ///
177 /// Concatenate two instances of @ref interned_string, builds an
178 /// instance of std::string with the resulting string and return it.
179 ///
180 /// @param s1 the first string to consider.
181 ///
182 /// @param s2 the second string to consider.
183 ///
184 /// @return the resuting concatenated string.
185 std::string
operator +(const interned_string & s1,const std::string & s2)186 operator+(const interned_string& s1,const std::string& s2)
187 {return static_cast<std::string>(s1) + s2;}
188 
189 /// Concatenation operator.
190 ///
191 /// Concatenate two instances of @ref interned_string, builds an
192 /// instance of std::string with the resulting string and return it.
193 ///
194 /// @param s1 the first string to consider.
195 ///
196 /// @param s2 the second string to consider.
197 ///
198 /// @return the resuting concatenated string.
199 std::string
operator +(const std::string & s1,const interned_string & s2)200 operator+(const std::string& s1, const interned_string& s2)
201 {return s1 + static_cast<std::string>(s2);}
202 
203 namespace ir
204 {
205 
206 static size_t
207 hash_as_canonical_type_or_constant(const type_base *t);
208 
209 static bool
210 has_generic_anonymous_internal_type_name(const decl_base *d);
211 
212 static interned_string
213 get_generic_anonymous_internal_type_name(const decl_base *d);
214 
215 static string
216 get_internal_integral_type_name(const type_base*);
217 
218 static void
219 update_qualified_name(decl_base * d);
220 
221 static void
222 update_qualified_name(decl_base_sptr d);
223 
224 void
225 push_composite_type_comparison_operands(const type_base& left,
226 					const type_base& right);
227 
228 void
229 pop_composite_type_comparison_operands(const type_base& left,
230 				       const type_base& right);
231 
232 bool
233 mark_dependant_types_compared_until(const type_base &r);
234 
235 /// Push a pair of operands on the stack of operands of the current
236 /// type comparison, during type canonicalization.
237 ///
238 /// For more information on this, please look at the description of
239 /// the environment::priv::right_type_comp_operands_ data member.
240 ///
241 /// @param left the left-hand-side comparison operand to push.
242 ///
243 /// @param right the right-hand-side comparison operand to push.
244 void
push_composite_type_comparison_operands(const type_base & left,const type_base & right)245 push_composite_type_comparison_operands(const type_base& left,
246 					const type_base& right)
247 {
248   const environment& env = left.get_environment();
249   env.priv_->push_composite_type_comparison_operands(&left, &right);
250 }
251 
252 /// Pop a pair of operands from the stack of operands to the current
253 /// type comparison.
254 ///
255 /// For more information on this, please look at the description of
256 /// the environment::privright_type_comp_operands_ data member.
257 ///
258 /// @param left the left-hand-side comparison operand we expect to
259 /// pop from the top of the stack.  If this doesn't match the
260 /// operand found on the top of the stack, the function aborts.
261 ///
262 /// @param right the right-hand-side comparison operand we expect to
263 /// pop from the bottom of the stack. If this doesn't match the
264 /// operand found on the top of the stack, the function aborts.
265 void
pop_composite_type_comparison_operands(const type_base & left,const type_base & right)266 pop_composite_type_comparison_operands(const type_base& left,
267 				       const type_base& right)
268 {
269   const environment& env = left.get_environment();
270   env.priv_->pop_composite_type_comparison_operands(&left, &right);
271 }
272 
273 /// In the stack of the current types being compared (as part of type
274 /// canonicalization), mark all the types that comes after a certain
275 /// one as NOT being eligible to the canonical type propagation
276 /// optimization.
277 ///
278 /// For a starter, please read about the @ref
279 /// OnTheFlyCanonicalization, aka, "canonical type propagation
280 /// optimization".
281 ///
282 /// To implement that optimization, we need, among other things to
283 /// maintain stack of the types (and their sub-types) being
284 /// currently compared as part of type canonicalization.
285 ///
286 /// Note that we only consider the type that is the right-hand-side
287 /// operand of the comparison because it's that one that is being
288 /// canonicalized and thus, that is not yet canonicalized.
289 ///
290 /// The reason why a type is deemed NON-eligible to the canonical
291 /// type propagation optimization is that it "depends" on
292 /// recursively present type.  Let me explain.
293 ///
294 /// Suppose we have a type T that has sub-types named ST0 and ST1.
295 /// Suppose ST1 itself has a sub-type that is T itself.  In this
296 /// case, we say that T is a recursive type, because it has T
297 /// (itself) as one of its sub-types:
298 ///
299 ///   T
300 ///   +-- ST0
301 ///   |
302 ///   +-- ST1
303 ///        +
304 ///        |
305 ///        +-- T
306 ///
307 /// ST1 is said to "depend" on T because it has T as a sub-type.
308 /// But because T is recursive, then ST1 is said to depend on a
309 /// recursive type.  Notice however that ST0 does not depend on any
310 /// recursive type.
311 ///
312 /// When we are at the point of comparing the sub-type T of ST1
313 /// against its counterpart, the stack of the right-hand-side
314 /// operands of the type canonicalization is going to look like
315 /// this:
316 ///
317 ///    | T | ST1 |
318 ///
319 /// We don't add the type T to the stack as we detect that T was
320 /// already in there (recursive cycle).
321 ///
322 /// So, this function will basically mark ST1 as being NON-eligible
323 /// to being the target of canonical type propagation, by marking ST1
324 /// as being dependant on T.
325 ///
326 /// @param right the right-hand-side operand of the type comparison.
327 ///
328 /// @return true iff the operation was successful.
329 bool
mark_dependant_types_compared_until(const type_base & r)330 mark_dependant_types_compared_until(const type_base &r)
331 {
332   const environment& env = r.get_environment();
333   if (env.do_on_the_fly_canonicalization())
334     return env.priv_->mark_dependant_types_compared_until(&r);
335   return false;
336 }
337 
338 /// @brief the location of a token represented in its simplest form.
339 /// Instances of this type are to be stored in a sorted vector, so the
340 /// type must have proper relational operators.
341 class expanded_location
342 {
343   string	path_;
344   unsigned	line_;
345   unsigned	column_;
346 
347   expanded_location();
348 
349 public:
350 
351   friend class location_manager;
352 
expanded_location(const string & path,unsigned line,unsigned column)353   expanded_location(const string& path, unsigned line, unsigned column)
354   : path_(path), line_(line), column_(column)
355   {}
356 
357   bool
operator ==(const expanded_location & l) const358   operator==(const expanded_location& l) const
359   {
360     return (path_ == l.path_
361 	    && line_ == l.line_
362 	    && column_ && l.column_);
363   }
364 
365   bool
operator <(const expanded_location & l) const366   operator<(const expanded_location& l) const
367   {
368     if (path_ < l.path_)
369       return true;
370     else if (path_ > l.path_)
371       return false;
372 
373     if (line_ < l.line_)
374       return true;
375     else if (line_ > l.line_)
376       return false;
377 
378     return column_ < l.column_;
379   }
380 };
381 
382 /// Expand the location into a tripplet path, line and column number.
383 ///
384 /// @param path the output parameter where this function sets the
385 /// expanded path.
386 ///
387 /// @param line the output parameter where this function sets the
388 /// expanded line.
389 ///
390 /// @param column the ouptut parameter where this function sets the
391 /// expanded column.
392 void
expand(std::string & path,unsigned & line,unsigned & column) const393 location::expand(std::string& path, unsigned& line, unsigned& column) const
394 {
395   if (!get_location_manager())
396     {
397       // We don't have a location manager maybe because this location
398       // was just freshly instanciated.  We still want to be able to
399       // expand to default values.
400       path = "";
401       line = 0;
402       column = 0;
403       return;
404     }
405   get_location_manager()->expand_location(*this, path, line, column);
406 }
407 
408 
409 /// Expand the location into a string.
410 ///
411 /// @return the string representing the location.
412 string
expand(void) const413 location::expand(void) const
414 {
415   string path, result;
416   unsigned line = 0, column = 0;
417   expand(path, line, column);
418 
419   std::ostringstream o;
420   o << path << ":" << line << ":" << column;
421   return o.str();
422 }
423 
424 struct location_manager::priv
425 {
426   /// This sorted vector contains the expanded locations of the tokens
427   /// coming from a given ABI Corpus.  The index of a given expanded
428   /// location in the table gives us an integer that is used to build
429   /// instance of location types.
430   std::vector<expanded_location> locs;
431 };
432 
location_manager()433 location_manager::location_manager()
434   : priv_(new location_manager::priv)
435 {}
436 
437 location_manager::~location_manager() = default;
438 
439 /// Insert the triplet representing a source locus into our internal
440 /// vector of location triplet.  Return an instance of location type,
441 /// built from an integral type that represents the index of the
442 /// source locus triplet into our source locus table.
443 ///
444 /// @param file_path the file path of the source locus
445 /// @param line the line number of the source location
446 /// @param col the column number of the source location
447 location
create_new_location(const std::string & file_path,size_t line,size_t col)448 location_manager::create_new_location(const std::string&	file_path,
449 				      size_t			line,
450 				      size_t			col)
451 {
452   expanded_location l(file_path, line, col);
453 
454   // Just append the new expanded location to the end of the vector
455   // and return its index.  Note that indexes start at 1.
456   priv_->locs.push_back(l);
457   return location(priv_->locs.size(), this);
458 }
459 
460 /// Given an instance of location type, return the triplet
461 /// {path,line,column} that represents the source locus.  Note that
462 /// the location must have been previously created from the function
463 /// location_manager::create_new_location, otherwise this function yields
464 /// unexpected results, including possibly a crash.
465 ///
466 /// @param location the instance of location type to expand
467 /// @param path the resulting path of the source locus
468 /// @param line the resulting line of the source locus
469 /// @param column the resulting colum of the source locus
470 void
expand_location(const location & location,std::string & path,unsigned & line,unsigned & column) const471 location_manager::expand_location(const location&	location,
472 				  std::string&		path,
473 				  unsigned&		line,
474 				  unsigned&		column) const
475 {
476   if (location.value_ == 0)
477     return;
478   expanded_location &l = priv_->locs[location.value_ - 1];
479   path = l.path_;
480   line = l.line_;
481   column = l.column_;
482 }
483 
484 typedef unordered_map<function_type_sptr,
485 		      bool,
486 		      function_type::hash,
487 		      type_shared_ptr_equal> fn_type_ptr_map;
488 
489 // <type_maps stuff>
490 
491 struct type_maps::priv
492 {
493   mutable istring_type_base_wptrs_map_type	basic_types_;
494   mutable istring_type_base_wptrs_map_type	class_types_;
495   mutable istring_type_base_wptrs_map_type	union_types_;
496   mutable istring_type_base_wptrs_map_type	enum_types_;
497   mutable istring_type_base_wptrs_map_type	typedef_types_;
498   mutable istring_type_base_wptrs_map_type	qualified_types_;
499   mutable istring_type_base_wptrs_map_type	pointer_types_;
500   mutable istring_type_base_wptrs_map_type	reference_types_;
501   mutable istring_type_base_wptrs_map_type	array_types_;
502   mutable istring_type_base_wptrs_map_type	subrange_types_;
503   mutable istring_type_base_wptrs_map_type	function_types_;
504   mutable vector<type_base_wptr>		sorted_types_;
505 }; // end struct type_maps::priv
506 
type_maps()507 type_maps::type_maps()
508   : priv_(new priv)
509 {}
510 
511 type_maps::~type_maps() = default;
512 
513 /// Test if the type_maps is empty.
514 ///
515 /// @return true iff the type_maps is empty.
516 bool
empty() const517 type_maps::empty() const
518 {
519   return (basic_types().empty()
520 	  && class_types().empty()
521 	  && union_types().empty()
522 	  && enum_types().empty()
523 	  && typedef_types().empty()
524 	  && qualified_types().empty()
525 	  && pointer_types().empty()
526 	  && reference_types().empty()
527 	  && array_types().empty()
528 	  && subrange_types().empty()
529 	  && function_types().empty());
530 }
531 
532 /// Getter for the map that associates the name of a basic type to the
533 /// vector instances of type_decl_sptr that represents that type.
534 const istring_type_base_wptrs_map_type&
basic_types() const535 type_maps::basic_types() const
536 {return priv_->basic_types_;}
537 
538 /// Getter for the map that associates the name of a basic type to the
539 /// vector of instances of @ref type_decl_sptr that represents that
540 /// type.
541 istring_type_base_wptrs_map_type&
basic_types()542 type_maps::basic_types()
543 {return priv_->basic_types_;}
544 
545 /// Getter for the map that associates the name of a class type to the
546 /// vector of instances of @ref class_decl_sptr that represents that
547 /// type.
548 const istring_type_base_wptrs_map_type&
class_types() const549 type_maps::class_types() const
550 {return priv_->class_types_;}
551 
552 /// Getter for the map that associates the name of a class type to the
553 /// vector of instances of @ref class_decl_sptr that represents that
554 /// type.
555 istring_type_base_wptrs_map_type&
class_types()556 type_maps::class_types()
557 {return priv_->class_types_;}
558 
559 /// Getter for the map that associates the name of a union type to the
560 /// vector of instances of @ref union_decl_sptr that represents that
561 /// type.
562 istring_type_base_wptrs_map_type&
union_types()563 type_maps::union_types()
564 {return priv_->union_types_;}
565 
566 /// Getter for the map that associates the name of a union type to the
567 /// vector of instances of @ref union_decl_sptr that represents that
568 /// type.
569 const istring_type_base_wptrs_map_type&
union_types() const570 type_maps::union_types() const
571 {return priv_->union_types_;}
572 
573 /// Getter for the map that associates the name of an enum type to the
574 /// vector of instances of @ref enum_type_decl_sptr that represents
575 /// that type.
576 istring_type_base_wptrs_map_type&
enum_types()577 type_maps::enum_types()
578 {return priv_->enum_types_;}
579 
580 /// Getter for the map that associates the name of an enum type to the
581 /// vector of instances of @ref enum_type_decl_sptr that represents
582 /// that type.
583 const istring_type_base_wptrs_map_type&
enum_types() const584 type_maps::enum_types() const
585 {return priv_->enum_types_;}
586 
587 /// Getter for the map that associates the name of a typedef to the
588 /// vector of instances of @ref typedef_decl_sptr that represents tha
589 /// type.
590 istring_type_base_wptrs_map_type&
typedef_types()591 type_maps::typedef_types()
592 {return priv_->typedef_types_;}
593 
594 /// Getter for the map that associates the name of a typedef to the
595 /// vector of instances of @ref typedef_decl_sptr that represents tha
596 /// type.
597 const istring_type_base_wptrs_map_type&
typedef_types() const598 type_maps::typedef_types() const
599 {return priv_->typedef_types_;}
600 
601 /// Getter for the map that associates the name of a qualified type to
602 /// the vector of instances of @ref qualified_type_def_sptr.
603 istring_type_base_wptrs_map_type&
qualified_types()604 type_maps::qualified_types()
605 {return priv_->qualified_types_;}
606 
607 /// Getter for the map that associates the name of a qualified type to
608 /// the vector of instances of @ref qualified_type_def_sptr.
609 const istring_type_base_wptrs_map_type&
qualified_types() const610 type_maps::qualified_types() const
611 {return priv_->qualified_types_;}
612 
613 /// Getter for the map that associates the name of a pointer type to
614 /// the vector of instances of @ref pointer_type_def_sptr that
615 /// represents that type.
616 istring_type_base_wptrs_map_type&
pointer_types()617 type_maps::pointer_types()
618 {return priv_->pointer_types_;}
619 
620 /// Getter for the map that associates the name of a pointer type to
621 /// the vector of instances of @ref pointer_type_def_sptr that
622 /// represents that type.
623 const istring_type_base_wptrs_map_type&
pointer_types() const624 type_maps::pointer_types() const
625 {return priv_->pointer_types_;}
626 
627 /// Getter for the map that associates the name of a reference type to
628 /// the vector of instances of @ref reference_type_def_sptr that
629 /// represents that type.
630 istring_type_base_wptrs_map_type&
reference_types()631 type_maps::reference_types()
632 {return priv_->reference_types_;}
633 
634 /// Getter for the map that associates the name of a reference type to
635 /// the vector of instances of @ref reference_type_def_sptr that
636 /// represents that type.
637 const istring_type_base_wptrs_map_type&
reference_types() const638 type_maps::reference_types() const
639 {return priv_->reference_types_;}
640 
641 /// Getter for the map that associates the name of an array type to
642 /// the vector of instances of @ref array_type_def_sptr that
643 /// represents that type.
644 istring_type_base_wptrs_map_type&
array_types()645 type_maps::array_types()
646 {return priv_->array_types_;}
647 
648 /// Getter for the map that associates the name of an array type to
649 /// the vector of instances of @ref array_type_def_sptr that
650 /// represents that type.
651 const istring_type_base_wptrs_map_type&
array_types() const652 type_maps::array_types() const
653 {return priv_->array_types_;}
654 
655 /// Getter for the map that associates the name of a subrange type to
656 /// the vector of instances of @ref array_type_def::subrange_sptr that
657 /// represents that type.
658 istring_type_base_wptrs_map_type&
subrange_types()659 type_maps::subrange_types()
660 {return priv_->subrange_types_;}
661 
662 /// Getter for the map that associates the name of a subrange type to
663 /// the vector of instances of @ref array_type_def::subrange_sptr that
664 /// represents that type.
665 const istring_type_base_wptrs_map_type&
subrange_types() const666 type_maps::subrange_types() const
667 {return priv_->subrange_types_;}
668 
669 /// Getter for the map that associates the name of a function type to
670 /// the vector of instances of @ref function_type_sptr that represents
671 /// that type.
672 const istring_type_base_wptrs_map_type&
function_types() const673 type_maps::function_types() const
674 {return priv_->function_types_;}
675 
676 /// Getter for the map that associates the name of a function type to
677 /// the vector of instances of @ref function_type_sptr that represents
678 /// that type.
679 istring_type_base_wptrs_map_type&
function_types()680 type_maps::function_types()
681 {return priv_->function_types_;}
682 
683 /// A comparison functor to compare/sort types based on their pretty
684 /// representations.
685 struct type_name_comp
686 {
687   /// Comparison operator for two instances of @ref type_base.
688   ///
689   /// This compares the two types by lexicographically comparing their
690   /// pretty representation.
691   ///
692   /// @param l the left-most type to compare.
693   ///
694   /// @param r the right-most type to compare.
695   ///
696   /// @return true iff @p l < @p r.
697   bool
operator ()abigail::ir::type_name_comp698   operator()(type_base *l, type_base *r) const
699   {
700     if (l == 0 && r == 0)
701       return false;
702 
703     string l_repr = get_pretty_representation(l);
704     string r_repr = get_pretty_representation(r);
705     return l_repr < r_repr;
706   }
707 
708   /// Comparison operator for two instances of @ref type_base.
709   ///
710   /// This compares the two types by lexicographically comparing their
711   /// pretty representation.
712   ///
713   /// @param l the left-most type to compare.
714   ///
715   /// @param r the right-most type to compare.
716   ///
717   /// @return true iff @p l < @p r.
718   bool
operator ()abigail::ir::type_name_comp719   operator()(const type_base_sptr &l, const type_base_sptr &r) const
720   {return operator()(l.get(), r.get());}
721 
722   /// Comparison operator for two instances of @ref type_base.
723   ///
724   /// This compares the two types by lexicographically comparing their
725   /// pretty representation.
726   ///
727   /// @param l the left-most type to compare.
728   ///
729   /// @param r the right-most type to compare.
730   ///
731   /// @return true iff @p l < @p r.
732   bool
operator ()abigail::ir::type_name_comp733   operator()(const type_base_wptr &l, const type_base_wptr &r) const
734   {return operator()(type_base_sptr(l), type_base_sptr(r));}
735 }; // end struct type_name_comp
736 
737 #ifdef WITH_DEBUG_SELF_COMPARISON
738 
739 /// This is a function called when the ABG_RETURN* macros defined
740 /// below return false.
741 ///
742 /// The purpose of this function is to ease debugging.  To know where
743 /// the equality functions first compare non-equal, we can just set a
744 /// breakpoint on this notify_equality_failed function and run the
745 /// equality functions.  Because all the equality functions use the
746 /// ABG_RETURN* macros to return their values, this function is always
747 /// called when any of those equality function return false.
748 ///
749 /// @param l the first operand of the equality.
750 ///
751 /// @param r the second operand of the equality.
752 static void
notify_equality_failed(const type_or_decl_base & l,const type_or_decl_base & r)753 notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
754 		       const type_or_decl_base &r __attribute__((unused)))
755 {}
756 
757 /// This is a function called when the ABG_RETURN* macros defined
758 /// below return false.
759 ///
760 /// The purpose of this function is to ease debugging.  To know where
761 /// the equality functions first compare non-equal, we can just set a
762 /// breakpoint on this notify_equality_failed function and run the
763 /// equality functions.  Because all the equality functions use the
764 /// ABG_RETURN* macros to return their values, this function is always
765 /// called when any of those equality function return false.
766 ///
767 /// @param l the first operand of the equality.
768 ///
769 /// @param r the second operand of the equality.
770 static void
notify_equality_failed(const type_or_decl_base * l,const type_or_decl_base * r)771 notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
772 		       const type_or_decl_base *r __attribute__((unused)))
773 {}
774 
775 #define ABG_RETURN_EQUAL(l, r)			\
776   do						\
777     {						\
778       if (l != r)				\
779         notify_equality_failed(l, r);		\
780       return (l == r);				\
781     }						\
782   while(false)
783 
784 
785 #define ABG_RETURN_FALSE	    \
786   do				    \
787     {				    \
788       notify_equality_failed(l, r); \
789       return false;		    \
790     } while(false)
791 
792 #define ABG_RETURN(value)			\
793   do						\
794     {						\
795       if (value == false)			\
796 	notify_equality_failed(l, r);		\
797       return value;				\
798     } while (false)
799 
800 #else // WITH_DEBUG_SELF_COMPARISON
801 
802 #define ABG_RETURN_FALSE return false
803 #define ABG_RETURN(value) return (value)
804 #define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
805 #endif
806 
807 /// Compare two types by comparing their canonical types if present.
808 ///
809 /// If the canonical types are not present (because the types have not
810 /// yet been canonicalized, for instance) then the types are compared
811 /// structurally.
812 ///
813 /// @param l the first type to take into account in the comparison.
814 ///
815 /// @param r the second type to take into account in the comparison.
816 template<typename T>
817 bool
try_canonical_compare(const T * l,const T * r)818 try_canonical_compare(const T *l, const T *r)
819 {
820 #if WITH_DEBUG_TYPE_CANONICALIZATION
821   // We are debugging the canonicalization of a type down the stack.
822   // 'l' is a subtype of a canonical type and 'r' is a subtype of the
823   // type being canonicalized.  We are at a point where we can compare
824   // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
825   // have canonical types) or structural comparison.
826   //
827   // Because we are debugging the process of type canonicalization, we
828   // want to compare 'l' and 'r' canonically *AND* structurally.  Both
829   // kinds of comparison should yield the same result, otherwise type
830   // canonicalization just failed for the subtype 'r' of the type
831   // being canonicalized.
832   //
833   // In concrete terms, this function is going to be called twice with
834   // the same pair {'l', 'r'} to compare: The first time with
835   // environment::priv_->use_canonical_type_comparison_ set to true,
836   // instructing us to compare them canonically, and the second time
837   // with that boolean set to false, instructing us to compare them
838   // structurally.
839   const environment&env = l->get_environment();
840   if (env.priv_->use_canonical_type_comparison_)
841     {
842       if (const type_base *lc = l->get_naked_canonical_type())
843 	if (const type_base *rc = r->get_naked_canonical_type())
844 	  ABG_RETURN_EQUAL(lc, rc);
845     }
846   return equals(*l, *r, 0);
847 #else
848   if (const type_base *lc = l->get_naked_canonical_type())
849     if (const type_base *rc = r->get_naked_canonical_type())
850       ABG_RETURN_EQUAL(lc, rc);
851   return equals(*l, *r, 0);
852 #endif
853 
854 
855 }
856 
857 /// Detect if a recursive comparison cycle is detected while
858 /// structurally comparing two types (a.k.a member-wise comparison).
859 ///
860 /// @param l the left-hand-side operand of the current comparison.
861 ///
862 /// @param r the right-hand-side operand of the current comparison.
863 ///
864 /// @return true iff a comparison cycle is detected.
865 template<typename T>
866 bool
is_comparison_cycle_detected(T & l,T & r)867 is_comparison_cycle_detected(T& l, T& r)
868 {
869   bool result = l.priv_->comparison_started(l, r);
870   return result ;
871 }
872 
873 /// Detect if a recursive comparison cycle is detected while
874 /// structurally comparing two @ref class_decl types.
875 ///
876 /// @param l the left-hand-side operand of the current comparison.
877 ///
878 /// @param r the right-hand-side operand of the current comparison.
879 ///
880 /// @return true iff a comparison cycle is detected.
881 template<>
882 bool
is_comparison_cycle_detected(const class_decl & l,const class_decl & r)883 is_comparison_cycle_detected(const class_decl& l, const class_decl& r)
884 {
885   return is_comparison_cycle_detected(static_cast<const class_or_union&>(l),
886 				      static_cast<const class_or_union&>(r));
887 }
888 
889 /// This macro is to be used while comparing composite types that
890 /// might recursively refer to themselves.  Comparing two such types
891 /// might get us into a cyle.
892 ///
893 /// Practically, if we detect that we are already into comparing 'l'
894 /// and 'r'; then, this is a cycle.
895 //
896 /// To break the cycle, we assume the result of the comparison is true
897 /// for now.  Comparing the other sub-types of l & r will tell us later
898 /// if l & r are actually different or not.
899 ///
900 /// In the mean time, returning true from this macro should not be
901 /// used to propagate the canonical type of 'l' onto 'r' as we don't
902 /// know yet if l equals r.  All the types that depend on l and r
903 /// can't (and that are in the comparison stack currently) can't have
904 /// their canonical type propagated either.  So this macro disallows
905 /// canonical type propagation for those types that depend on a
906 /// recursively defined sub-type for now.
907 ///
908 /// @param l the left-hand-side operand of the comparison.
909 #define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r)			\
910   do									\
911     {									\
912       if (is_comparison_cycle_detected(l, r))				\
913 	{								\
914 	  mark_dependant_types_compared_until(r);			\
915 	  return true;							\
916 	}								\
917     }									\
918   while(false)
919 
920 
921 /// Mark a pair of types as being compared.
922 ///
923 /// This is helpful to later detect recursive cycles in the comparison
924 /// stack.
925 ///
926 /// @param l the left-hand-side operand of the comparison.
927 ///
928 /// @parm r the right-hand-side operand of the comparison.
929 template<typename T>
930 void
mark_types_as_being_compared(T & l,T & r)931 mark_types_as_being_compared(T& l, T&r)
932 {
933   l.priv_->mark_as_being_compared(l, r);
934   push_composite_type_comparison_operands(l, r);
935 }
936 
937 /// Mark a pair of @ref class_decl types as being compared.
938 ///
939 /// This is helpful to later detect recursive cycles in the comparison
940 /// stack.
941 ///
942 /// @param l the left-hand-side operand of the comparison.
943 ///
944 /// @parm r the right-hand-side operand of the comparison.
945 template<>
946 void
mark_types_as_being_compared(const class_decl & l,const class_decl & r)947 mark_types_as_being_compared(const class_decl& l, const class_decl &r)
948 {
949   return mark_types_as_being_compared(static_cast<const class_or_union&>(l),
950 				      static_cast<const class_or_union&>(r));
951 }
952 
953 /// Mark a pair of types as being not compared anymore.
954 ///
955 /// This is helpful to later detect recursive cycles in the comparison
956 /// stack.
957 ///
958 /// Note that the types must have been passed to
959 /// mark_types_as_being_compared prior to calling this function.
960 ///
961 /// @param l the left-hand-side operand of the comparison.
962 ///
963 /// @parm r the right-hand-side operand of the comparison.
964 template<typename T>
965 void
unmark_types_as_being_compared(T & l,T & r)966 unmark_types_as_being_compared(T& l, T&r)
967 {
968   l.priv_->unmark_as_being_compared(l, r);
969   pop_composite_type_comparison_operands(l, r);
970 }
971 
972 /// Mark a pair of @ref class_decl types as being not compared
973 /// anymore.
974 ///
975 /// This is helpful to later detect recursive cycles in the comparison
976 /// stack.
977 ///
978 /// Note that the types must have been passed to
979 /// mark_types_as_being_compared prior to calling this function.
980 ///
981 /// @param l the left-hand-side operand of the comparison.
982 ///
983 /// @parm r the right-hand-side operand of the comparison.
984 template<>
985 void
unmark_types_as_being_compared(const class_decl & l,const class_decl & r)986 unmark_types_as_being_compared(const class_decl& l, const class_decl &r)
987 {
988   return unmark_types_as_being_compared(static_cast<const class_or_union&>(l),
989 					static_cast<const class_or_union&>(r));
990 }
991 
992 /// Return the result of the comparison of two (sub) types.
993 ///
994 /// The function does the necessary book keeping before returning the
995 /// result of the comparison of two (sub) types.
996 ///
997 /// The book-keeping done is in the following
998 /// areas:
999 ///
1000 ///   * Management of the Canonical Type Propagation optimization
1001 ///   * type comparison cycle detection
1002 ///
1003 ///   @param l the left-hand-side operand of the type comparison
1004 ///
1005 ///   @param r the right-hand-side operand of the type comparison
1006 ///
1007 ///   @param propagate_canonical_type if true, it means the function
1008 ///   performs the @ref OnTheFlyCanonicalization, aka, "canonical type
1009 ///   propagation optimization".
1010 ///
1011 ///   @param value the result of the comparison of @p l and @p r.
1012 ///
1013 ///   @return the value @p value.
1014 template<typename T>
1015 bool
return_comparison_result(T & l,T & r,bool value,bool propagate_canonical_type=true)1016 return_comparison_result(T& l, T& r, bool value,
1017 			 bool propagate_canonical_type = true)
1018 {
1019   if (propagate_canonical_type && (value == true))
1020     maybe_propagate_canonical_type(l, r);
1021 
1022   unmark_types_as_being_compared(l, r);
1023 
1024   const environment& env = l.get_environment();
1025   if (env.do_on_the_fly_canonicalization())
1026     // We are instructed to perform the "canonical type propagation"
1027     // optimization, making 'r' to possibly get the canonical type of
1028     // 'l' if it has one.  This mostly means that we are currently
1029     // canonicalizing the type that contain the subtype provided in
1030     // the 'r' argument.
1031     {
1032       if (value == true
1033 	  && (is_type(&r)->priv_->depends_on_recursive_type()
1034 	      || env.priv_->is_recursive_type(&r))
1035 	  && is_type(&r)->priv_->canonical_type_propagated()
1036 	  && !is_type(&r)->priv_->propagated_canonical_type_confirmed()
1037 	  && !env.priv_->right_type_comp_operands_.empty())
1038 	{
1039 	  // Track the object 'r' for which the propagated canonical
1040 	  // type might be re-initialized if the current comparison
1041 	  // eventually fails.
1042 	  env.priv_->add_to_types_with_non_confirmed_propagated_ct(is_type(&r));
1043 	}
1044       else if (value == true
1045 	       && env.priv_->right_type_comp_operands_.empty()
1046 	       && is_type(&r)->priv_->canonical_type_propagated()
1047 	       && !is_type(&r)->priv_->propagated_canonical_type_confirmed())
1048 	{
1049 	  // The type provided in the 'r' argument is the type that is
1050 	  // being canonicalized; 'r' is not a mere subtype being
1051 	  // compared, it's the whole type being canonicalized.  And
1052 	  // its canonicalization has just succeeded.
1053 	  //
1054 	  // Let's confirm the canonical type resulting from the
1055 	  // "canonical type propagation" optimization.
1056 	  env.priv_->confirm_ct_propagation(&r);
1057 	}
1058       else if (value == true
1059 	       && is_type(&r)->priv_->canonical_type_propagated()
1060 	       && !is_type(&r)->priv_->propagated_canonical_type_confirmed())
1061 	// In any other case, we are not sure if propagated types
1062 	// should be confirmed yet.  So let's mark them as such.
1063 	env.priv_->add_to_types_with_non_confirmed_propagated_ct(is_type(&r));
1064       else if (value == false)
1065 	{
1066 	  // The comparison of the current sub-type failed.  So all
1067 	  // the with non-confirmed propagated types (those in
1068 	  // env.prix_->types_with_non_confirmed_propagated_ct_)
1069 	  // should see their tentatively propagated canonical type
1070 	  // cancelled.
1071 	  env.priv_->cancel_all_non_confirmed_propagated_canonical_types();
1072 	}
1073     }
1074 
1075   // If we reached this point with value == true and the stack of
1076   // types being compared is empty, then it means that the type pair
1077   // that was at the bottom of the stack is now fully compared.
1078   //
1079   // It follows that all types that were target of canonical type
1080   // propagation can now see their tentative canonical type be
1081   // confirmed for real.
1082   if (value == true
1083       && env.priv_->right_type_comp_operands_.empty()
1084       && !env.priv_->types_with_non_confirmed_propagated_ct_.empty())
1085     // So the comparison is completely done and there are some
1086     // types for which their propagated canonical type is sitll
1087     // considered not confirmed.  As the comparison did yield true, we
1088     // shall now confirm the propagation for all those types.
1089     env.priv_->confirm_ct_propagation();
1090 
1091 #ifdef WITH_DEBUG_SELF_COMPARISON
1092   if (value == false && env.priv_->right_type_comp_operands_.empty())
1093     {
1094       for (const auto i : env.priv_->types_with_non_confirmed_propagated_ct_)
1095 	{
1096 	  type_base *t = reinterpret_cast<type_base*>(i);
1097 	  env.priv_->check_abixml_canonical_type_propagation_during_self_comp(t);
1098 	}
1099     }
1100 #endif
1101 
1102   ABG_RETURN(value);
1103 }
1104 
1105 #define CACHE_AND_RETURN_COMPARISON_RESULT(value)			\
1106   do									\
1107     {									\
1108       bool res = return_comparison_result(l, r, value);		\
1109       l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1110       return res;							\
1111     } while (false)
1112 
1113 /// Cache the result of a comparison between too artifacts (l & r) and
1114 /// return immediately.
1115 ///
1116 /// @param value the value to cache.
1117 #define CACHE_COMPARISON_RESULT_AND_RETURN(value)			\
1118   do									\
1119     {									\
1120       l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1121       return value;							\
1122     } while (false)
1123 
1124 /// Getter of all types types sorted by their pretty representation.
1125 ///
1126 /// @return a sorted vector of all types sorted by their pretty
1127 /// representation.
1128 const vector<type_base_wptr>&
get_types_sorted_by_name() const1129 type_maps::get_types_sorted_by_name() const
1130 {
1131   if (priv_->sorted_types_.empty())
1132     {
1133       istring_type_base_wptrs_map_type::const_iterator i;
1134       vector<type_base_wptr>::const_iterator j;
1135 
1136       for (i = basic_types().begin(); i != basic_types().end(); ++i)
1137 	for (j = i->second.begin(); j != i->second.end(); ++j)
1138 	  priv_->sorted_types_.push_back(*j);
1139 
1140       for (i = class_types().begin(); i != class_types().end(); ++i)
1141 	for (j = i->second.begin(); j != i->second.end(); ++j)
1142 	  priv_->sorted_types_.push_back(*j);
1143 
1144       for (i = union_types().begin(); i != union_types().end(); ++i)
1145 	for (j = i->second.begin(); j != i->second.end(); ++j)
1146 	  priv_->sorted_types_.push_back(*j);
1147 
1148       for (i = enum_types().begin(); i != enum_types().end(); ++i)
1149 	for (j = i->second.begin(); j != i->second.end(); ++j)
1150 	  priv_->sorted_types_.push_back(*j);
1151 
1152       for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
1153 	for (j = i->second.begin(); j != i->second.end(); ++j)
1154 	  priv_->sorted_types_.push_back(*j);
1155 
1156       type_name_comp comp;
1157       sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
1158     }
1159 
1160   return priv_->sorted_types_;
1161 }
1162 
1163 // </type_maps stuff>
1164 
1165 // <translation_unit stuff>
1166 
1167 /// Constructor of translation_unit.
1168 ///
1169 /// @param env the environment of this translation unit.  Please note
1170 /// that the life time of the environment must be greater than the
1171 /// life time of the translation unit because the translation uses
1172 /// resources that are allocated in the environment.
1173 ///
1174 /// @param path the location of the translation unit.
1175 ///
1176 /// @param address_size the size of addresses in the translation unit,
1177 /// in bits.
translation_unit(const environment & env,const std::string & path,char address_size)1178 translation_unit::translation_unit(const environment&	env,
1179 				   const std::string&	path,
1180 				   char		address_size)
1181   : priv_(new priv(env))
1182 {
1183   priv_->path_ = path;
1184   priv_->address_size_ = address_size;
1185 }
1186 
1187 /// Getter of the the global scope of the translation unit.
1188 ///
1189 /// @return the global scope of the current translation unit.  If
1190 /// there is not global scope allocated yet, this function creates one
1191 /// and returns it.
1192 const scope_decl_sptr&
get_global_scope() const1193 translation_unit::get_global_scope() const
1194 {
1195   return const_cast<translation_unit*>(this)->get_global_scope();
1196 }
1197 
1198 /// Getter of the the global scope of the translation unit.
1199 ///
1200 /// @return the global scope of the current translation unit.  If
1201 /// there is not global scope allocated yet, this function creates one
1202 /// and returns it.
1203 scope_decl_sptr&
get_global_scope()1204 translation_unit::get_global_scope()
1205 {
1206   if (!priv_->global_scope_)
1207     {
1208       priv_->global_scope_.reset
1209 	(new global_scope(const_cast<translation_unit*>(this)));
1210       priv_->global_scope_->set_translation_unit
1211 	(const_cast<translation_unit*>(this));
1212     }
1213   return priv_->global_scope_;
1214 }
1215 
1216 /// Getter of the types of the current @ref translation_unit.
1217 ///
1218 /// @return the maps of the types of the translation unit.
1219 const type_maps&
get_types() const1220 translation_unit::get_types() const
1221 {return priv_->types_;}
1222 
1223 /// Getter of the types of the current @ref translation_unit.
1224 ///
1225 /// @return the maps of the types of the translation unit.
1226 type_maps&
get_types()1227 translation_unit::get_types()
1228 {return priv_->types_;}
1229 
1230 /// Get the vector of function types that are used in the current
1231 /// translation unit.
1232 ///
1233 /// @return the vector of function types that are used in the current
1234 /// translation unit.
1235 const vector<function_type_sptr>&
get_live_fn_types() const1236 translation_unit::get_live_fn_types() const
1237 {return priv_->live_fn_types_;}
1238 
1239 /// Getter of the environment of the current @ref translation_unit.
1240 ///
1241 /// @return the translation unit of the current translation unit.
1242 const environment&
get_environment() const1243 translation_unit::get_environment() const
1244 {return priv_->env_;}
1245 
1246 /// Getter of the language of the source code of the translation unit.
1247 ///
1248 /// @return the language of the source code.
1249 translation_unit::language
get_language() const1250 translation_unit::get_language() const
1251 {return priv_->language_;}
1252 
1253 /// Setter of the language of the source code of the translation unit.
1254 ///
1255 /// @param l the new language.
1256 void
set_language(language l)1257 translation_unit::set_language(language l)
1258 {priv_->language_ = l;}
1259 
1260 
1261 /// Get the path of the current translation unit.
1262 ///
1263 /// This path is relative to the build directory of the translation
1264 /// unit as returned by translation_unit::get_compilation_dir_path.
1265 ///
1266 /// @return the relative path of the compilation unit associated to
1267 /// the current instance of translation_unit.
1268 //
1269 const std::string&
get_path() const1270 translation_unit::get_path() const
1271 {return priv_->path_;}
1272 
1273 /// Set the path associated to the current instance of
1274 /// translation_unit.
1275 ///
1276 /// This path is relative to the build directory of the translation
1277 /// unit as returned by translation_unit::get_compilation_dir_path.
1278 ///
1279 /// @param a_path the new relative path to set.
1280 void
set_path(const string & a_path)1281 translation_unit::set_path(const string& a_path)
1282 {priv_->path_ = a_path;}
1283 
1284 
1285 /// Get the path of the directory that was 'current' when the
1286 /// translation unit was compiled.
1287 ///
1288 /// Note that the path returned by translation_unit::get_path is
1289 /// relative to the path returned by this function.
1290 ///
1291 /// @return the compilation directory for the current translation
1292 /// unit.
1293 const std::string&
get_compilation_dir_path() const1294 translation_unit::get_compilation_dir_path() const
1295 {return priv_->comp_dir_path_;}
1296 
1297 /// Set the path of the directory that was 'current' when the
1298 /// translation unit was compiled.
1299 ///
1300 /// Note that the path returned by translation_unit::get_path is
1301 /// relative to the path returned by this function.
1302 ///
1303 /// @param the compilation directory for the current translation unit.
1304 void
set_compilation_dir_path(const std::string & d)1305 translation_unit::set_compilation_dir_path(const std::string& d)
1306 {priv_->comp_dir_path_ = d;}
1307 
1308 /// Get the concatenation of the build directory and the relative path
1309 /// of the translation unit.
1310 ///
1311 /// @return the absolute path of the translation unit.
1312 const std::string&
get_absolute_path() const1313 translation_unit::get_absolute_path() const
1314 {
1315   if (priv_->abs_path_.empty())
1316     {
1317       string path;
1318       if (!priv_->path_.empty())
1319 	{
1320 	  if (!priv_->comp_dir_path_.empty())
1321 	    {
1322 	      path = priv_->comp_dir_path_;
1323 	      path += "/";
1324 	    }
1325 	  path += priv_->path_;
1326 	}
1327       priv_->abs_path_ = path;
1328     }
1329 
1330   return priv_->abs_path_;
1331 }
1332 
1333 /// Set the corpus this translation unit is a member of.
1334 ///
1335 /// Note that adding a translation unit to a @ref corpus automatically
1336 /// triggers a call to this member function.
1337 ///
1338 /// @param corpus the corpus.
1339 void
set_corpus(corpus * c)1340 translation_unit::set_corpus(corpus* c)
1341 {priv_->corp = c;}
1342 
1343 /// Get the corpus this translation unit is a member of.
1344 ///
1345 /// @return the parent corpus, or nil if this doesn't belong to any
1346 /// corpus yet.
1347 corpus*
get_corpus()1348 translation_unit::get_corpus()
1349 {return priv_->corp;}
1350 
1351 /// Get the corpus this translation unit is a member of.
1352 ///
1353 /// @return the parent corpus, or nil if this doesn't belong to any
1354 /// corpus yet.
1355 const corpus*
get_corpus() const1356 translation_unit::get_corpus() const
1357 {return const_cast<translation_unit*>(this)->get_corpus();}
1358 
1359 /// Getter of the location manager for the current translation unit.
1360 ///
1361 /// @return a reference to the location manager for the current
1362 /// translation unit.
1363 location_manager&
get_loc_mgr()1364 translation_unit::get_loc_mgr()
1365 {return priv_->loc_mgr_;}
1366 
1367 /// const Getter of the location manager.
1368 ///
1369 /// @return a const reference to the location manager for the current
1370 /// translation unit.
1371 const location_manager&
get_loc_mgr() const1372 translation_unit::get_loc_mgr() const
1373 {return priv_->loc_mgr_;}
1374 
1375 /// Tests whether if the current translation unit contains ABI
1376 /// artifacts or not.
1377 ///
1378 /// @return true iff the current translation unit is empty.
1379 bool
is_empty() const1380 translation_unit::is_empty() const
1381 {
1382   if (!priv_->global_scope_)
1383     return true;
1384   return get_global_scope()->is_empty();
1385 }
1386 
1387 /// Getter of the address size in this translation unit.
1388 ///
1389 /// @return the address size, in bits.
1390 char
get_address_size() const1391 translation_unit::get_address_size() const
1392 {return priv_->address_size_;}
1393 
1394 /// Setter of the address size in this translation unit.
1395 ///
1396 /// @param a the new address size in bits.
1397 void
set_address_size(char a)1398 translation_unit::set_address_size(char a)
1399 {priv_->address_size_= a;}
1400 
1401 /// Getter of the 'is_constructed" flag.  It says if the translation
1402 /// unit is fully constructed or not.
1403 ///
1404 /// This flag is important for cases when comparison might depend on
1405 /// if the translation unit is fully built or not.  For instance, when
1406 /// reading types from DWARF, the virtual methods of a class are not
1407 /// necessarily fully constructed until we have reached the end of the
1408 /// translation unit.  In that case, before we've reached the end of
1409 /// the translation unit, we might not take virtual functions into
1410 /// account when comparing classes.
1411 ///
1412 /// @return true if the translation unit is constructed.
1413 bool
is_constructed() const1414 translation_unit::is_constructed() const
1415 {return priv_->is_constructed_;}
1416 
1417 /// Setter of the 'is_constructed" flag.  It says if the translation
1418 /// unit is fully constructed or not.
1419 ///
1420 /// This flag is important for cases when comparison might depend on
1421 /// if the translation unit is fully built or not.  For instance, when
1422 /// reading types from DWARF, the virtual methods of a class are not
1423 /// necessarily fully constructed until we have reached the end of the
1424 /// translation unit.  In that case, before we've reached the end of
1425 /// the translation unit, we might not take virtual functions into
1426 /// account when comparing classes.
1427 ///
1428 /// @param f true if the translation unit is constructed.
1429 void
set_is_constructed(bool f)1430 translation_unit::set_is_constructed(bool f)
1431 {priv_->is_constructed_ = f;}
1432 
1433 /// Compare the current translation unit against another one.
1434 ///
1435 /// @param other the other tu to compare against.
1436 ///
1437 /// @return true if the two translation units are equal, false
1438 /// otherwise.
1439 bool
operator ==(const translation_unit & other) const1440 translation_unit::operator==(const translation_unit& other)const
1441 {
1442   if (get_address_size() != other.get_address_size())
1443     return false;
1444 
1445   return *get_global_scope() == *other.get_global_scope();
1446 }
1447 
1448 /// Inequality operator.
1449 ///
1450 /// @param o the instance of @ref translation_unit to compare the
1451 /// current instance against.
1452 ///
1453 /// @return true iff the current instance is different from @p o.
1454 bool
operator !=(const translation_unit & o) const1455 translation_unit::operator!=(const translation_unit& o) const
1456 {return ! operator==(o);}
1457 
1458 /// Ensure that the life time of a function type is bound to the life
1459 /// time of the current translation unit.
1460 ///
1461 /// @param ftype the function time which life time to bind to the life
1462 /// time of the current instance of @ref translation_unit.  That is,
1463 /// it's onlyh when the translation unit is destroyed that the
1464 /// function type can be destroyed to.
1465 void
bind_function_type_life_time(function_type_sptr ftype) const1466 translation_unit::bind_function_type_life_time(function_type_sptr ftype) const
1467 {
1468   const environment& env = get_environment();
1469 
1470   const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1471 
1472   interned_string repr = get_type_name(ftype);
1473   const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1474     push_back(ftype);
1475 
1476   // The function type must be out of the same environment as its
1477   // translation unit.
1478   {
1479     const environment& e = ftype->get_environment();
1480     ABG_ASSERT(&env == &e);
1481   }
1482 
1483   if (const translation_unit* existing_tu = ftype->get_translation_unit())
1484     ABG_ASSERT(existing_tu == this);
1485   else
1486     ftype->set_translation_unit(const_cast<translation_unit*>(this));
1487 
1488   maybe_update_types_lookup_map(ftype);
1489 }
1490 
1491 /// This implements the ir_traversable_base::traverse virtual
1492 /// function.
1493 ///
1494 /// @param v the visitor used on the member nodes of the translation
1495 /// unit during the traversal.
1496 ///
1497 /// @return true if the entire type IR tree got traversed, false
1498 /// otherwise.
1499 bool
traverse(ir_node_visitor & v)1500 translation_unit::traverse(ir_node_visitor& v)
1501 {return get_global_scope()->traverse(v);}
1502 
~translation_unit()1503 translation_unit::~translation_unit()
1504 {}
1505 
1506 /// Converts a translation_unit::language enumerator into a string.
1507 ///
1508 /// @param l the language enumerator to translate.
1509 ///
1510 /// @return the resulting string.
1511 string
translation_unit_language_to_string(translation_unit::language l)1512 translation_unit_language_to_string(translation_unit::language l)
1513 {
1514   switch (l)
1515     {
1516     case translation_unit::LANG_UNKNOWN:
1517       return "LANG_UNKNOWN";
1518     case translation_unit::LANG_Cobol74:
1519       return "LANG_Cobol74";
1520     case translation_unit::LANG_Cobol85:
1521       return "LANG_Cobol85";
1522     case translation_unit::LANG_C89:
1523       return "LANG_C89";
1524     case translation_unit::LANG_C99:
1525       return "LANG_C99";
1526     case translation_unit::LANG_C11:
1527       return "LANG_C11";
1528     case translation_unit::LANG_C:
1529       return "LANG_C";
1530     case translation_unit::LANG_C_plus_plus_11:
1531       return "LANG_C_plus_plus_11";
1532     case translation_unit::LANG_C_plus_plus_14:
1533       return "LANG_C_plus_plus_14";
1534     case translation_unit::LANG_C_plus_plus:
1535       return "LANG_C_plus_plus";
1536     case translation_unit::LANG_ObjC:
1537       return "LANG_ObjC";
1538     case translation_unit::LANG_ObjC_plus_plus:
1539       return "LANG_ObjC_plus_plus";
1540     case translation_unit::LANG_Fortran77:
1541       return "LANG_Fortran77";
1542     case translation_unit::LANG_Fortran90:
1543       return "LANG_Fortran90";
1544     case translation_unit::LANG_Fortran95:
1545       return "LANG_Fortran95";
1546     case translation_unit::LANG_Ada83:
1547       return "LANG_Ada83";
1548     case translation_unit::LANG_Ada95:
1549       return "LANG_Ada95";
1550     case translation_unit::LANG_Pascal83:
1551       return "LANG_Pascal83";
1552     case translation_unit::LANG_Modula2:
1553       return "LANG_Modula2";
1554     case translation_unit::LANG_Java:
1555       return "LANG_Java";
1556     case translation_unit::LANG_PLI:
1557       return "LANG_PLI";
1558     case translation_unit::LANG_UPC:
1559       return "LANG_UPC";
1560     case translation_unit::LANG_D:
1561       return "LANG_D";
1562     case translation_unit::LANG_Python:
1563       return "LANG_Python";
1564     case translation_unit::LANG_Go:
1565       return "LANG_Go";
1566     case translation_unit::LANG_Mips_Assembler:
1567       return "LANG_Mips_Assembler";
1568     default:
1569       return "LANG_UNKNOWN";
1570     }
1571 
1572   return "LANG_UNKNOWN";
1573 }
1574 
1575 /// Parse a string representing a language into a
1576 /// translation_unit::language enumerator into a string.
1577 ///
1578 /// @param l the string representing the language.
1579 ///
1580 /// @return the resulting translation_unit::language enumerator.
1581 translation_unit::language
string_to_translation_unit_language(const string & l)1582 string_to_translation_unit_language(const string& l)
1583 {
1584   if (l == "LANG_Cobol74")
1585     return translation_unit::LANG_Cobol74;
1586   else if (l == "LANG_Cobol85")
1587     return translation_unit::LANG_Cobol85;
1588   else if (l == "LANG_C89")
1589     return translation_unit::LANG_C89;
1590   else if (l == "LANG_C99")
1591     return translation_unit::LANG_C99;
1592   else if (l == "LANG_C11")
1593     return translation_unit::LANG_C11;
1594   else if (l == "LANG_C")
1595     return translation_unit::LANG_C;
1596   else if (l == "LANG_C_plus_plus_11")
1597     return translation_unit::LANG_C_plus_plus_11;
1598   else if (l == "LANG_C_plus_plus_14")
1599     return translation_unit::LANG_C_plus_plus_14;
1600   else if (l == "LANG_C_plus_plus")
1601     return translation_unit::LANG_C_plus_plus;
1602   else if (l == "LANG_ObjC")
1603     return translation_unit::LANG_ObjC;
1604   else if (l == "LANG_ObjC_plus_plus")
1605     return translation_unit::LANG_ObjC_plus_plus;
1606   else if (l == "LANG_Fortran77")
1607     return translation_unit::LANG_Fortran77;
1608   else if (l == "LANG_Fortran90")
1609     return translation_unit::LANG_Fortran90;
1610     else if (l == "LANG_Fortran95")
1611     return translation_unit::LANG_Fortran95;
1612   else if (l == "LANG_Ada83")
1613     return translation_unit::LANG_Ada83;
1614   else if (l == "LANG_Ada95")
1615     return translation_unit::LANG_Ada95;
1616   else if (l == "LANG_Pascal83")
1617     return translation_unit::LANG_Pascal83;
1618   else if (l == "LANG_Modula2")
1619     return translation_unit::LANG_Modula2;
1620   else if (l == "LANG_Java")
1621     return translation_unit::LANG_Java;
1622   else if (l == "LANG_PLI")
1623     return translation_unit::LANG_PLI;
1624   else if (l == "LANG_UPC")
1625     return translation_unit::LANG_UPC;
1626   else if (l == "LANG_D")
1627     return translation_unit::LANG_D;
1628   else if (l == "LANG_Python")
1629     return translation_unit::LANG_Python;
1630   else if (l == "LANG_Go")
1631     return translation_unit::LANG_Go;
1632   else if (l == "LANG_Mips_Assembler")
1633     return translation_unit::LANG_Mips_Assembler;
1634 
1635   return translation_unit::LANG_UNKNOWN;
1636 }
1637 
1638 /// Test if a language enumerator designates the C language.
1639 ///
1640 /// @param l the language enumerator to consider.
1641 ///
1642 /// @return true iff @p l designates the C language.
1643 bool
is_c_language(translation_unit::language l)1644 is_c_language(translation_unit::language l)
1645 {
1646   return (l == translation_unit::LANG_C89
1647 	  || l == translation_unit::LANG_C99
1648 	  || l == translation_unit::LANG_C11
1649 	  || l == translation_unit::LANG_C);
1650 }
1651 
1652 /// Test if a language enumerator designates the C++ language.
1653 ///
1654 /// @param l the language enumerator to consider.
1655 ///
1656 /// @return true iff @p l designates the C++ language.
1657 bool
is_cplus_plus_language(translation_unit::language l)1658 is_cplus_plus_language(translation_unit::language l)
1659 {
1660   return (l == translation_unit::LANG_C_plus_plus_03
1661 	  || l == translation_unit::LANG_C_plus_plus_11
1662 	  || l == translation_unit::LANG_C_plus_plus_14
1663 	  || l == translation_unit::LANG_C_plus_plus);
1664 }
1665 
1666 /// Test if a language enumerator designates the Java language.
1667 ///
1668 /// @param l the language enumerator to consider.
1669 ///
1670 /// @return true iff @p l designates the Java language.
1671 bool
is_java_language(translation_unit::language l)1672 is_java_language(translation_unit::language l)
1673 {return l == translation_unit::LANG_Java;}
1674 
1675 /// Test if a language enumerator designates the Ada language.
1676 ///
1677 /// @param l the language enumerator to consider.
1678 ///
1679 /// @return true iff @p l designates the Ada language.
1680 bool
is_ada_language(translation_unit::language l)1681 is_ada_language(translation_unit::language l)
1682 {
1683   return (l == translation_unit::LANG_Ada83
1684 	 || l == translation_unit::LANG_Ada95);
1685 }
1686 
1687 /// A deep comparison operator for pointers to translation units.
1688 ///
1689 /// @param l the first translation unit to consider for the comparison.
1690 ///
1691 /// @param r the second translation unit to consider for the comparison.
1692 ///
1693 /// @return true if the two translation units are equal, false otherwise.
1694 bool
operator ==(const translation_unit_sptr & l,const translation_unit_sptr & r)1695 operator==(const translation_unit_sptr& l, const translation_unit_sptr& r)
1696 {
1697   if (l.get() == r.get())
1698     return true;
1699 
1700   if (!!l != !!r)
1701     return false;
1702 
1703   return *l == *r;
1704 }
1705 
1706 /// A deep inequality operator for pointers to translation units.
1707 ///
1708 /// @param l the first translation unit to consider for the comparison.
1709 ///
1710 /// @param r the second translation unit to consider for the comparison.
1711 ///
1712 /// @return true iff the two translation units are different.
1713 bool
operator !=(const translation_unit_sptr & l,const translation_unit_sptr & r)1714 operator!=(const translation_unit_sptr& l, const translation_unit_sptr& r)
1715 {return !operator==(l, r);}
1716 
1717 // </translation_unit stuff>
1718 
1719 // <elf_symbol stuff>
1720 struct elf_symbol::priv
1721 {
1722   const environment&	env_;
1723   size_t		index_;
1724   size_t		size_;
1725   string		name_;
1726   elf_symbol::type	type_;
1727   elf_symbol::binding	binding_;
1728   elf_symbol::version	version_;
1729   elf_symbol::visibility visibility_;
1730   bool			is_defined_;
1731   // This flag below says if the symbol is a common elf symbol.  In
1732   // relocatable files, a common symbol is a symbol defined in a
1733   // section of kind SHN_COMMON.
1734   //
1735   // Note that a symbol of kind STT_COMMON is also considered a common
1736   // symbol.  Here is what the gABI says about STT_COMMON and
1737   // SHN_COMMON:
1738   //
1739   //     Symbols with type STT_COMMON label uninitialized common
1740   //     blocks. In relocatable objects, these symbols are not
1741   //     allocated and must have the special section index SHN_COMMON
1742   //     (see below). In shared objects and executables these symbols
1743   //     must be allocated to some section in the defining object.
1744   //
1745   //     In relocatable objects, symbols with type STT_COMMON are
1746   //     treated just as other symbols with index SHN_COMMON. If the
1747   //     link-editor allocates space for the SHN_COMMON symbol in an
1748   //     output section of the object it is producing, it must
1749   //     preserve the type of the output symbol as STT_COMMON.
1750   //
1751   //     When the dynamic linker encounters a reference to a symbol
1752   //     that resolves to a definition of type STT_COMMON, it may (but
1753   //     is not required to) change its symbol resolution rules as
1754   //     follows: instead of binding the reference to the first symbol
1755   //     found with the given name, the dynamic linker searches for
1756   //     the first symbol with that name with type other than
1757   //     STT_COMMON. If no such symbol is found, it looks for the
1758   //     STT_COMMON definition of that name that has the largest size.
1759   bool			is_common_;
1760   bool			is_in_ksymtab_;
1761   abg_compat::optional<uint32_t>	crc_;
1762   abg_compat::optional<std::string>	namespace_;
1763   bool			is_suppressed_;
1764   elf_symbol_wptr	main_symbol_;
1765   elf_symbol_wptr	next_alias_;
1766   elf_symbol_wptr	next_common_instance_;
1767   string		id_string_;
1768 
privabigail::ir::elf_symbol::priv1769   priv(const environment& e)
1770     : env_(e),
1771       index_(),
1772       size_(),
1773       type_(elf_symbol::NOTYPE_TYPE),
1774       binding_(elf_symbol::GLOBAL_BINDING),
1775       visibility_(elf_symbol::DEFAULT_VISIBILITY),
1776       is_defined_(false),
1777       is_common_(false),
1778       is_in_ksymtab_(false),
1779       crc_(),
1780       namespace_(),
1781       is_suppressed_(false)
1782   {}
1783 
privabigail::ir::elf_symbol::priv1784   priv(const environment&	  e,
1785        size_t			  i,
1786        size_t			  s,
1787        const string&		  n,
1788        elf_symbol::type		  t,
1789        elf_symbol::binding	  b,
1790        bool			  d,
1791        bool			  c,
1792        const elf_symbol::version& ve,
1793        elf_symbol::visibility	  vi,
1794        bool			  is_in_ksymtab,
1795        const abg_compat::optional<uint32_t>&	crc,
1796        const abg_compat::optional<std::string>&	ns,
1797        bool			  is_suppressed)
1798     : env_(e),
1799       index_(i),
1800       size_(s),
1801       name_(n),
1802       type_(t),
1803       binding_(b),
1804       version_(ve),
1805       visibility_(vi),
1806       is_defined_(d),
1807       is_common_(c),
1808       is_in_ksymtab_(is_in_ksymtab),
1809       crc_(crc),
1810       namespace_(ns),
1811       is_suppressed_(is_suppressed)
1812   {
1813     if (!is_common_)
1814       is_common_ = type_ == COMMON_TYPE;
1815   }
1816 }; // end struct elf_symbol::priv
1817 
1818 /// Constructor of the @ref elf_symbol type.
1819 ///
1820 /// Note that this constructor is private, so client code cannot use
1821 /// it to create instances of @ref elf_symbol.  Rather, client code
1822 /// should use the @ref elf_symbol::create() function to create
1823 /// instances of @ref elf_symbol instead.
1824 ///
1825 /// @param e the environment we are operating from.
1826 ///
1827 /// @param i the index of the symbol in the (ELF) symbol table.
1828 ///
1829 /// @param s the size of the symbol.
1830 ///
1831 /// @param n the name of the symbol.
1832 ///
1833 /// @param t the type of the symbol.
1834 ///
1835 /// @param b the binding of the symbol.
1836 ///
1837 /// @param d true if the symbol is defined, false otherwise.
1838 ///
1839 /// @param c true if the symbol is a common symbol, false otherwise.
1840 ///
1841 /// @param ve the version of the symbol.
1842 ///
1843 /// @param vi the visibility of the symbol.
1844 ///
1845 /// @param crc the CRC (modversions) value of Linux Kernel symbols
1846 ///
1847 /// @param ns the namespace of Linux Kernel symbols, if any
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_in_ksymtab,const abg_compat::optional<uint32_t> & crc,const abg_compat::optional<std::string> & ns,bool is_suppressed)1848 elf_symbol::elf_symbol(const environment& e,
1849 		       size_t		  i,
1850 		       size_t		  s,
1851 		       const string&	  n,
1852 		       type		  t,
1853 		       binding		  b,
1854 		       bool		  d,
1855 		       bool		  c,
1856 		       const version&	  ve,
1857 		       visibility	  vi,
1858 		       bool		  is_in_ksymtab,
1859 		       const abg_compat::optional<uint32_t>&	crc,
1860 		       const abg_compat::optional<std::string>&	ns,
1861 		       bool		  is_suppressed)
1862   : priv_(new priv(e,
1863 		   i,
1864 		   s,
1865 		   n,
1866 		   t,
1867 		   b,
1868 		   d,
1869 		   c,
1870 		   ve,
1871 		   vi,
1872 		   is_in_ksymtab,
1873 		   crc,
1874 		   ns,
1875 		   is_suppressed))
1876 {}
1877 
1878 /// Factory of instances of @ref elf_symbol.
1879 ///
1880 /// This is the function to use to create instances of @ref elf_symbol.
1881 ///
1882 /// @param e the environment we are operating from.
1883 ///
1884 /// @param i the index of the symbol in the (ELF) symbol table.
1885 ///
1886 /// @param s the size of the symbol.
1887 ///
1888 /// @param n the name of the symbol.
1889 ///
1890 /// @param t the type of the symbol.
1891 ///
1892 /// @param b the binding of the symbol.
1893 ///
1894 /// @param d true if the symbol is defined, false otherwise.
1895 ///
1896 /// @param c true if the symbol is a common symbol.
1897 ///
1898 /// @param ve the version of the symbol.
1899 ///
1900 /// @param vi the visibility of the symbol.
1901 ///
1902 /// @param crc the CRC (modversions) value of Linux Kernel symbols
1903 ///
1904 /// @param ns the namespace of Linux Kernel symbols, if any
1905 ///
1906 /// @return a (smart) pointer to a newly created instance of @ref
1907 /// elf_symbol.
1908 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_in_ksymtab,const abg_compat::optional<uint32_t> & crc,const abg_compat::optional<std::string> & ns,bool is_suppressed)1909 elf_symbol::create(const environment& e,
1910 		   size_t	      i,
1911 		   size_t	      s,
1912 		   const string&      n,
1913 		   type		      t,
1914 		   binding	      b,
1915 		   bool		      d,
1916 		   bool		      c,
1917 		   const version&     ve,
1918 		   visibility	      vi,
1919 		   bool		      is_in_ksymtab,
1920 		   const abg_compat::optional<uint32_t>&	crc,
1921 		   const abg_compat::optional<std::string>&	ns,
1922 		   bool		      is_suppressed)
1923 {
1924   elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
1925 				     is_in_ksymtab, crc, ns, is_suppressed));
1926   sym->priv_->main_symbol_ = sym;
1927   return sym;
1928 }
1929 
1930 /// Test textual equality between two symbols.
1931 ///
1932 /// Textual equality means that the aliases of the compared symbols
1933 /// are not taken into account.  Only the name, type, and version of
1934 /// the symbols are compared.
1935 ///
1936 /// @return true iff the two symbols are textually equal.
1937 static bool
textually_equals(const elf_symbol & l,const elf_symbol & r)1938 textually_equals(const elf_symbol&l,
1939 		 const elf_symbol&r)
1940 {
1941   bool equals = (l.get_name() == r.get_name()
1942 		 && l.get_type() == r.get_type()
1943 		 && l.is_public() == r.is_public()
1944 		 && l.is_defined() == r.is_defined()
1945 		 && l.is_common_symbol() == r.is_common_symbol()
1946 		 && l.get_version() == r.get_version()
1947 		 && l.get_crc() == r.get_crc()
1948 		 && l.get_namespace() == r.get_namespace());
1949 
1950   if (equals && l.is_variable())
1951     // These are variable symbols.  Let's compare their symbol size.
1952     // The symbol size in this case is the size taken by the storage
1953     // of the variable.  If that size changes, then it's an ABI
1954     // change.
1955     equals = l.get_size() == r.get_size();
1956 
1957   return equals;
1958 }
1959 
1960 /// Getter of the environment used by the current instance of @ref
1961 /// elf_symbol.
1962 ///
1963 /// @return the enviroment used by the current instance of @ref elf_symbol.
1964 const environment&
get_environment() const1965 elf_symbol::get_environment() const
1966 {return priv_->env_;}
1967 
1968 /// Getter for the index
1969 ///
1970 /// @return the index of the symbol.
1971 size_t
get_index() const1972 elf_symbol::get_index() const
1973 {return priv_->index_;}
1974 
1975 /// Setter for the index.
1976 ///
1977 /// @param s the new index.
1978 void
set_index(size_t s)1979 elf_symbol::set_index(size_t s)
1980 {priv_->index_ = s;}
1981 
1982 /// Getter for the name of the @ref elf_symbol.
1983 ///
1984 /// @return a reference to the name of the @ref symbol.
1985 const string&
get_name() const1986 elf_symbol::get_name() const
1987 {return priv_->name_;}
1988 
1989 /// Setter for the name of the current intance of @ref elf_symbol.
1990 ///
1991 /// @param n the new name.
1992 void
set_name(const string & n)1993 elf_symbol::set_name(const string& n)
1994 {
1995   priv_->name_ = n;
1996   priv_->id_string_.clear();
1997 }
1998 
1999 /// Getter for the type of the current instance of @ref elf_symbol.
2000 ///
2001 /// @return the type of the elf symbol.
2002 elf_symbol::type
get_type() const2003 elf_symbol::get_type() const
2004 {return priv_->type_;}
2005 
2006 /// Setter for the type of the current instance of @ref elf_symbol.
2007 ///
2008 /// @param t the new symbol type.
2009 void
set_type(type t)2010 elf_symbol::set_type(type t)
2011 {priv_->type_ = t;}
2012 
2013 /// Getter of the size of the symbol.
2014 ///
2015 /// @return the size of the symbol, in bytes.
2016 size_t
get_size() const2017 elf_symbol::get_size() const
2018 {return priv_->size_;}
2019 
2020 /// Setter of the size of the symbol.
2021 ///
2022 /// @param size the new size of the symbol, in bytes.
2023 void
set_size(size_t size)2024 elf_symbol::set_size(size_t size)
2025 {priv_->size_ = size;}
2026 
2027 /// Getter for the binding of the current instance of @ref elf_symbol.
2028 ///
2029 /// @return the binding of the symbol.
2030 elf_symbol::binding
get_binding() const2031 elf_symbol::get_binding() const
2032 {return priv_->binding_;}
2033 
2034 /// Setter for the binding of the current instance of @ref elf_symbol.
2035 ///
2036 /// @param b the new binding.
2037 void
set_binding(binding b)2038 elf_symbol::set_binding(binding b)
2039 {priv_->binding_ = b;}
2040 
2041 /// Getter for the version of the current instanc of @ref elf_symbol.
2042 ///
2043 /// @return the version of the elf symbol.
2044 elf_symbol::version&
get_version() const2045 elf_symbol::get_version() const
2046 {return priv_->version_;}
2047 
2048 /// Setter for the version of the current instance of @ref elf_symbol.
2049 ///
2050 /// @param v the new version of the elf symbol.
2051 void
set_version(const version & v)2052 elf_symbol::set_version(const version& v)
2053 {
2054   priv_->version_ = v;
2055   priv_->id_string_.clear();
2056 }
2057 
2058 /// Setter of the visibility of the current instance of @ref
2059 /// elf_symbol.
2060 ///
2061 /// @param v the new visibility of the elf symbol.
2062 void
set_visibility(visibility v)2063 elf_symbol::set_visibility(visibility v)
2064 {priv_->visibility_ = v;}
2065 
2066 /// Getter of the visibility of the current instance of @ref
2067 /// elf_symbol.
2068 ///
2069 /// @return the visibility of the elf symbol.
2070 elf_symbol::visibility
get_visibility() const2071 elf_symbol::get_visibility() const
2072 {return priv_->visibility_;}
2073 
2074 /// Test if the current instance of @ref elf_symbol is defined or not.
2075 ///
2076 /// @return true if the current instance of @ref elf_symbol is
2077 /// defined, false otherwise.
2078 bool
is_defined() const2079 elf_symbol::is_defined() const
2080 {return priv_->is_defined_;}
2081 
2082 /// Sets a flag saying if the current instance of @ref elf_symbol is
2083 /// defined
2084 ///
2085 /// @param b the new value of the flag.
2086 void
is_defined(bool d)2087 elf_symbol::is_defined(bool d)
2088 {priv_->is_defined_ = d;}
2089 
2090 /// Test if the current instance of @ref elf_symbol is public or not.
2091 ///
2092 /// This tests if the symbol is defined, has default or protected
2093 ///visibility, and either:
2094 ///		- has global binding
2095 ///		- has weak binding
2096 ///		- or has a GNU_UNIQUE binding.
2097 ///
2098 /// return true if the current instance of @ref elf_symbol is public,
2099 /// false otherwise.
2100 bool
is_public() const2101 elf_symbol::is_public() const
2102 {
2103   return (is_defined()
2104 	  && (get_binding() == GLOBAL_BINDING
2105 	      || get_binding() == WEAK_BINDING
2106 	      || get_binding() == GNU_UNIQUE_BINDING)
2107 	  && (get_visibility() == DEFAULT_VISIBILITY
2108 	      || get_visibility() == PROTECTED_VISIBILITY));
2109 }
2110 
2111 /// Test if the current instance of @ref elf_symbol is a function
2112 /// symbol or not.
2113 ///
2114 /// @return true if the current instance of @ref elf_symbol is a
2115 /// function symbol, false otherwise.
2116 bool
is_function() const2117 elf_symbol::is_function() const
2118 {return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2119 
2120 /// Test if the current instance of @ref elf_symbol is a variable
2121 /// symbol or not.
2122 ///
2123 /// @return true if the current instance of @ref elf_symbol is a
2124 /// variable symbol, false otherwise.
2125 bool
is_variable() const2126 elf_symbol::is_variable() const
2127 {return get_type() == OBJECT_TYPE || get_type() == TLS_TYPE;}
2128 
2129 /// Getter of the 'is-in-ksymtab' property.
2130 ///
2131 /// @return true iff the current symbol is in the Linux Kernel
2132 /// specific 'ksymtab' symbol table.
2133 bool
is_in_ksymtab() const2134 elf_symbol::is_in_ksymtab() const
2135 {return priv_->is_in_ksymtab_;}
2136 
2137 /// Setter of the 'is-in-ksymtab' property.
2138 ///
2139 /// @param is_in_ksymtab this is true iff the current symbol is in the
2140 /// Linux Kernel specific 'ksymtab' symbol table.
2141 void
set_is_in_ksymtab(bool is_in_ksymtab)2142 elf_symbol::set_is_in_ksymtab(bool is_in_ksymtab)
2143 {priv_->is_in_ksymtab_ = is_in_ksymtab;}
2144 
2145 /// Getter of the 'crc' property.
2146 ///
2147 /// @return the CRC (modversions) value for Linux Kernel symbols, if any
2148 const abg_compat::optional<uint32_t>&
get_crc() const2149 elf_symbol::get_crc() const
2150 {return priv_->crc_;}
2151 
2152 /// Setter of the 'crc' property.
2153 ///
2154 /// @param crc the new CRC (modversions) value for Linux Kernel symbols
2155 void
set_crc(const abg_compat::optional<uint32_t> & crc)2156 elf_symbol::set_crc(const abg_compat::optional<uint32_t>& crc)
2157 {priv_->crc_ = crc;}
2158 
2159 /// Getter of the 'namespace' property.
2160 ///
2161 /// @return the namespace for Linux Kernel symbols, if any
2162 const abg_compat::optional<std::string>&
get_namespace() const2163 elf_symbol::get_namespace() const
2164 {return priv_->namespace_;}
2165 
2166 /// Setter of the 'namespace' property.
2167 ///
2168 /// @param ns the new namespace for Linux Kernel symbols, if any
2169 void
set_namespace(const abg_compat::optional<std::string> & ns)2170 elf_symbol::set_namespace(const abg_compat::optional<std::string>& ns)
2171 {priv_->namespace_ = ns;}
2172 
2173 /// Getter for the 'is-suppressed' property.
2174 ///
2175 /// @return true iff the current symbol has been suppressed by a
2176 /// suppression specification that was provided in the context that
2177 /// led to the creation of the corpus this ELF symbol belongs to.
2178 bool
is_suppressed() const2179 elf_symbol::is_suppressed() const
2180 {return priv_->is_suppressed_;}
2181 
2182 /// Setter for the 'is-suppressed' property.
2183 ///
2184 /// @param true iff the current symbol has been suppressed by a
2185 /// suppression specification that was provided in the context that
2186 /// led to the creation of the corpus this ELF symbol belongs to.
2187 void
set_is_suppressed(bool is_suppressed)2188 elf_symbol::set_is_suppressed(bool is_suppressed)
2189 {priv_->is_suppressed_ = is_suppressed;}
2190 
2191 /// @name Elf symbol aliases
2192 ///
2193 /// An alias A for an elf symbol S is a symbol that is defined at the
2194 /// same address as S.  S is chained to A through the
2195 /// elf_symbol::get_next_alias() method.
2196 ///
2197 /// When there are several aliases to a symbol, the main symbol is the
2198 /// the first symbol found in the symbol table for a given address.
2199 ///
2200 /// The alias chain is circular.  That means if S is the main symbol
2201 /// and A is the alias, S is chained to A and A
2202 /// is chained back to the main symbol S.  The last alias in an alias
2203 ///chain is always chained to the main symbol.
2204 ///
2205 /// Thus, when looping over the aliases of an elf_symbol A, detecting
2206 /// an alias that is equal to the main symbol should logically be a
2207 /// loop exit condition.
2208 ///
2209 /// Accessing and adding aliases for instances of elf_symbol is done
2210 /// through the member functions below.
2211 
2212 /// @{
2213 
2214 /// Get the main symbol of an alias chain.
2215 ///
2216 ///@return the main symbol.
2217 const elf_symbol_sptr
get_main_symbol() const2218 elf_symbol::get_main_symbol() const
2219 {return priv_->main_symbol_.lock();}
2220 
2221 /// Get the main symbol of an alias chain.
2222 ///
2223 ///@return the main symbol.
2224 elf_symbol_sptr
get_main_symbol()2225 elf_symbol::get_main_symbol()
2226 {return priv_->main_symbol_.lock();}
2227 
2228 /// Tests whether this symbol is the main symbol.
2229 ///
2230 /// @return true iff this symbol is the main symbol.
2231 bool
is_main_symbol() const2232 elf_symbol::is_main_symbol() const
2233 {return get_main_symbol().get() == this;}
2234 
2235 /// Get the next alias of the current symbol.
2236 ///
2237 ///@return the alias, or NULL if there is no alias.
2238 elf_symbol_sptr
get_next_alias() const2239 elf_symbol::get_next_alias() const
2240 {return priv_->next_alias_.lock();}
2241 
2242 
2243 /// Check if the current elf_symbol has an alias.
2244 ///
2245 ///@return true iff the current elf_symbol has an alias.
2246 bool
has_aliases() const2247 elf_symbol::has_aliases() const
2248 {return bool(get_next_alias());}
2249 
2250 /// Get the number of aliases to this elf symbol
2251 ///
2252 /// @return the number of aliases to this elf symbol.
2253 int
get_number_of_aliases() const2254 elf_symbol::get_number_of_aliases() const
2255 {
2256   int result = 0;
2257 
2258   for (elf_symbol_sptr a = get_next_alias();
2259        a && a.get() != get_main_symbol().get();
2260        a = a->get_next_alias())
2261     ++result;
2262 
2263   return result;
2264 }
2265 
2266 /// Add an alias to the current elf symbol.
2267 ///
2268 /// @param alias the new alias.  Note that this elf_symbol should *NOT*
2269 /// have aliases prior to the invocation of this function.
2270 void
add_alias(const elf_symbol_sptr & alias)2271 elf_symbol::add_alias(const elf_symbol_sptr& alias)
2272 {
2273   if (!alias)
2274     return;
2275 
2276   ABG_ASSERT(!alias->has_aliases());
2277   ABG_ASSERT(is_main_symbol());
2278 
2279   if (has_aliases())
2280     {
2281       elf_symbol_sptr last_alias;
2282       for (elf_symbol_sptr a = get_next_alias();
2283 	   a && !a->is_main_symbol();
2284 	   a = a->get_next_alias())
2285 	{
2286 	  if (a->get_next_alias()->is_main_symbol())
2287 	    {
2288 	      ABG_ASSERT(last_alias == 0);
2289 	      last_alias = a;
2290 	    }
2291 	}
2292       ABG_ASSERT(last_alias);
2293 
2294       last_alias->priv_->next_alias_ = alias;
2295     }
2296   else
2297     priv_->next_alias_ = alias;
2298 
2299   alias->priv_->next_alias_ = get_main_symbol();
2300   alias->priv_->main_symbol_ = get_main_symbol();
2301 }
2302 
2303 /// Update the main symbol for a group of aliased symbols
2304 ///
2305 /// If after the construction of the symbols (in order of discovery), the
2306 /// actual main symbol can be identified (e.g. as the symbol that actually is
2307 /// defined in the code), this method offers a way of updating the main symbol
2308 /// through one of the aliased symbols.
2309 ///
2310 /// For that, locate the new main symbol by name and update all references to
2311 /// the main symbol among the group of aliased symbols.
2312 ///
2313 /// @param name the name of the main symbol
2314 ///
2315 /// @return the new main elf_symbol
2316 elf_symbol_sptr
update_main_symbol(const std::string & name)2317 elf_symbol::update_main_symbol(const std::string& name)
2318 {
2319   ABG_ASSERT(is_main_symbol());
2320   if (!has_aliases() || get_name() == name)
2321     return get_main_symbol();
2322 
2323   // find the new main symbol
2324   elf_symbol_sptr new_main;
2325   // we've already checked this; check the rest of the aliases
2326   for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2327        a = a->get_next_alias())
2328     if (a->get_name() == name)
2329       {
2330 	new_main = a;
2331 	break;
2332       }
2333 
2334   if (!new_main)
2335     return get_main_symbol();
2336 
2337   // now update all main symbol references
2338   priv_->main_symbol_ = new_main;
2339   for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2340        a = a->get_next_alias())
2341     a->priv_->main_symbol_ = new_main;
2342 
2343   return new_main;
2344 }
2345 
2346 /// Return true if the symbol is a common one.
2347 ///
2348 /// @return true iff the symbol is common.
2349 bool
is_common_symbol() const2350 elf_symbol::is_common_symbol() const
2351 {return priv_->is_common_;}
2352 
2353 /// Return true if this common common symbol has other common instances.
2354 ///
2355 /// A common instance of a given common symbol is another common
2356 /// symbol with the same name.  Those exist in relocatable files.  The
2357 /// linker normally allocates all the instances into a common block in
2358 /// the final output file.
2359 ///
2360 /// Note that the current object must be a common symbol, otherwise,
2361 /// this function aborts.
2362 ///
2363 /// @return true iff the current common symbol has other common
2364 /// instances.
2365 bool
has_other_common_instances() const2366 elf_symbol::has_other_common_instances() const
2367 {
2368   ABG_ASSERT(is_common_symbol());
2369   return bool(get_next_common_instance());
2370 }
2371 
2372 /// Get the next common instance of the current common symbol.
2373 ///
2374 /// A common instance of a given common symbol is another common
2375 /// symbol with the same name.  Those exist in relocatable files.  The
2376 /// linker normally allocates all the instances into a common block in
2377 /// the final output file.
2378 ///
2379 /// @return the next common instance, or nil if there is not any.
2380 elf_symbol_sptr
get_next_common_instance() const2381 elf_symbol::get_next_common_instance() const
2382 {return priv_->next_common_instance_.lock();}
2383 
2384 /// Add a common instance to the current common elf symbol.
2385 ///
2386 /// Note that this symbol must be the main symbol.  Being the main
2387 /// symbol means being the first common symbol to appear in the symbol
2388 /// table.
2389 ///
2390 /// @param common the other common instance to add.
2391 void
add_common_instance(const elf_symbol_sptr & common)2392 elf_symbol::add_common_instance(const elf_symbol_sptr& common)
2393 {
2394   if (!common)
2395     return;
2396 
2397   ABG_ASSERT(!common->has_other_common_instances());
2398   ABG_ASSERT(is_common_symbol());
2399   ABG_ASSERT(is_main_symbol());
2400 
2401   if (has_other_common_instances())
2402     {
2403       elf_symbol_sptr last_common_instance;
2404       for (elf_symbol_sptr c = get_next_common_instance();
2405 	   c && (c.get() != get_main_symbol().get());
2406 	   c = c->get_next_common_instance())
2407 	{
2408 	  if (c->get_next_common_instance().get() == get_main_symbol().get())
2409 	    {
2410 	      ABG_ASSERT(last_common_instance == 0);
2411 	      last_common_instance = c;
2412 	    }
2413 	}
2414       ABG_ASSERT(last_common_instance);
2415 
2416       last_common_instance->priv_->next_common_instance_ = common;
2417     }
2418   else
2419     priv_->next_common_instance_ = common;
2420 
2421   common->priv_->next_common_instance_ = get_main_symbol();
2422   common->priv_->main_symbol_ = get_main_symbol();
2423 }
2424 
2425 /// Get a string that is representative of a given elf_symbol.
2426 ///
2427 /// If the symbol has a version, then the ID string is the
2428 /// concatenation of the name of the symbol, the '@' character, and
2429 /// the version of the symbol.  If the version is the default version
2430 /// of the symbol then the '@' character is replaced by a "@@" string.
2431 ///
2432 /// Otherwise, if the symbol does not have any version, this function
2433 /// returns the name of the symbol.
2434 ///
2435 /// @return a the ID string.
2436 const string&
get_id_string() const2437 elf_symbol::get_id_string() const
2438 {
2439   if (priv_->id_string_.empty())
2440     {
2441       string s = get_name ();
2442 
2443       if (!get_version().is_empty())
2444 	{
2445 	  if (get_version().is_default())
2446 	    s += "@@";
2447 	  else
2448 	    s += "@";
2449 	  s += get_version().str();
2450 	}
2451       priv_->id_string_ = s;
2452     }
2453 
2454   return priv_->id_string_;
2455 }
2456 
2457 /// From the aliases of the current symbol, lookup one with a given name.
2458 ///
2459 /// @param name the name of symbol alias we are looking for.
2460 ///
2461 /// @return the symbol alias that has the name @p name, or nil if none
2462 /// has been found.
2463 elf_symbol_sptr
get_alias_from_name(const string & name) const2464 elf_symbol::get_alias_from_name(const string& name) const
2465 {
2466   if (name == get_name())
2467     return elf_symbol_sptr(priv_->main_symbol_);
2468 
2469    for (elf_symbol_sptr a = get_next_alias();
2470 	a && a.get() != get_main_symbol().get();
2471 	a = a->get_next_alias())
2472      if (a->get_name() == name)
2473        return a;
2474 
2475    return elf_symbol_sptr();
2476 }
2477 
2478 /// In the list of aliases of a given elf symbol, get the alias that
2479 /// equals this current symbol.
2480 ///
2481 /// @param other the elf symbol to get the potential aliases from.
2482 ///
2483 /// @return the alias of @p other that texually equals the current
2484 /// symbol, or nil if no alias textually equals the current symbol.
2485 elf_symbol_sptr
get_alias_which_equals(const elf_symbol & other) const2486 elf_symbol::get_alias_which_equals(const elf_symbol& other) const
2487 {
2488   for (elf_symbol_sptr a = other.get_next_alias();
2489        a && a.get() != a->get_main_symbol().get();
2490        a = a->get_next_alias())
2491     if (textually_equals(*this, *a))
2492       return a;
2493   return elf_symbol_sptr();
2494 }
2495 
2496 /// Return a comma separated list of the id of the current symbol as
2497 /// well as the id string of its aliases.
2498 ///
2499 /// @param syms a map of all the symbols of the corpus the current
2500 /// symbol belongs to.
2501 ///
2502 /// @param include_symbol_itself if set to true, then the name of the
2503 /// current symbol is included in the list of alias names that is emitted.
2504 ///
2505 /// @return the string.
2506 string
get_aliases_id_string(const string_elf_symbols_map_type & syms,bool include_symbol_itself) const2507 elf_symbol::get_aliases_id_string(const string_elf_symbols_map_type& syms,
2508 				  bool include_symbol_itself) const
2509 {
2510   string result;
2511 
2512   if (include_symbol_itself)
2513       result = get_id_string();
2514 
2515   vector<elf_symbol_sptr> aliases;
2516   compute_aliases_for_elf_symbol(*this, syms, aliases);
2517   if (!aliases.empty() && include_symbol_itself)
2518     result += ", ";
2519 
2520   for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2521        i != aliases.end();
2522        ++i)
2523     {
2524       if (i != aliases.begin())
2525 	result += ", ";
2526       result += (*i)->get_id_string();
2527     }
2528   return result;
2529 }
2530 
2531 /// Return a comma separated list of the id of the current symbol as
2532 /// well as the id string of its aliases.
2533 ///
2534 /// @param include_symbol_itself if set to true, then the name of the
2535 /// current symbol is included in the list of alias names that is emitted.
2536 ///
2537 /// @return the string.
2538 string
get_aliases_id_string(bool include_symbol_itself) const2539 elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2540 {
2541   vector<elf_symbol_sptr> aliases;
2542   if (include_symbol_itself)
2543     aliases.push_back(get_main_symbol());
2544 
2545   for (elf_symbol_sptr a = get_next_alias();
2546        a && a.get() != get_main_symbol().get();
2547        a = a->get_next_alias())
2548     aliases.push_back(a);
2549 
2550   string result;
2551   for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2552        i != aliases.end();
2553        ++i)
2554     {
2555       if (i != aliases.begin())
2556 	result += ", ";
2557       result += (*i)->get_id_string();
2558     }
2559 
2560   return result;
2561 }
2562 
2563 /// Given the ID of a symbol, get the name and the version of said
2564 /// symbol.
2565 ///
2566 /// @param id the symbol ID to consider.
2567 ///
2568 /// @param name the symbol name extracted from the ID.  This is set
2569 /// only if the function returned true.
2570 ///
2571 /// @param ver the symbol version extracted from the ID.
2572 bool
get_name_and_version_from_id(const string & id,string & name,string & ver)2573 elf_symbol::get_name_and_version_from_id(const string&	id,
2574 					 string&	name,
2575 					 string&	ver)
2576 {
2577   name.clear(), ver.clear();
2578 
2579   string::size_type i = id.find('@');
2580   if (i == string::npos)
2581     {
2582       name = id;
2583       return true;
2584     }
2585 
2586   name = id.substr(0, i);
2587   ++i;
2588 
2589   if (i >= id.size())
2590     return true;
2591 
2592   string::size_type j = id.find('@', i);
2593   if (j == string::npos)
2594     j = i;
2595   else
2596     ++j;
2597 
2598   if (j >= id.size())
2599     {
2600       ver = "";
2601       return true;
2602     }
2603 
2604   ver = id.substr(j);
2605   return true;
2606 }
2607 
2608 ///@}
2609 
2610 /// Test if two main symbols are textually equal, or, if they have
2611 /// aliases that are textually equal.
2612 ///
2613 /// @param other the symbol to compare against.
2614 ///
2615 /// @return true iff the current instance of elf symbol equals the @p
2616 /// other.
2617 bool
operator ==(const elf_symbol & other) const2618 elf_symbol::operator==(const elf_symbol& other) const
2619 {
2620   bool are_equal = textually_equals(*this, other);
2621   if (!are_equal)
2622     are_equal = bool(get_alias_which_equals(other));
2623   return are_equal;
2624 }
2625 
2626 /// Test if the current symbol aliases another one.
2627 ///
2628 /// @param o the other symbol to test against.
2629 ///
2630 /// @return true iff the current symbol aliases @p o.
2631 bool
does_alias(const elf_symbol & o) const2632 elf_symbol::does_alias(const elf_symbol& o) const
2633 {
2634   if (*this == o)
2635     return true;
2636 
2637   if (get_main_symbol() == o.get_main_symbol())
2638     return true;
2639 
2640   for (elf_symbol_sptr a = get_next_alias();
2641        a && !a->is_main_symbol();
2642        a = a->get_next_alias())
2643     {
2644       if (o == *a)
2645 	return true;
2646     }
2647   return false;
2648 }
2649 
2650 /// Equality operator for smart pointers to elf_symbol.
2651 ///
2652 /// @param lhs the first elf symbol to consider.
2653 ///
2654 /// @param rhs the second elf symbol to consider.
2655 ///
2656 /// @return true iff @p lhs equals @p rhs.
2657 bool
operator ==(const elf_symbol_sptr & lhs,const elf_symbol_sptr & rhs)2658 operator==(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
2659 {
2660   if (!!lhs != !!rhs)
2661     return false;
2662 
2663   if (!lhs)
2664     return true;
2665 
2666   return *lhs == *rhs;
2667 }
2668 
2669 /// Inequality operator for smart pointers to elf_symbol.
2670 ///
2671 /// @param lhs the first elf symbol to consider.
2672 ///
2673 /// @param rhs the second elf symbol to consider.
2674 ///
2675 /// @return true iff @p lhs is different from @p rhs.
2676 bool
operator !=(const elf_symbol_sptr & lhs,const elf_symbol_sptr & rhs)2677 operator!=(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
2678 {return !operator==(lhs, rhs);}
2679 
2680 /// Test if two symbols alias.
2681 ///
2682 /// @param s1 the first symbol to consider.
2683 ///
2684 /// @param s2 the second symbol to consider.
2685 ///
2686 /// @return true if @p s1 aliases @p s2.
2687 bool
elf_symbols_alias(const elf_symbol & s1,const elf_symbol & s2)2688 elf_symbols_alias(const elf_symbol& s1, const elf_symbol& s2)
2689 {return s1.does_alias(s2) || s2.does_alias(s1);}
2690 
2691 void
compute_aliases_for_elf_symbol(const elf_symbol & sym,const string_elf_symbols_map_type & symtab,vector<elf_symbol_sptr> & aliases)2692 compute_aliases_for_elf_symbol(const elf_symbol& sym,
2693 			       const string_elf_symbols_map_type& symtab,
2694 			       vector<elf_symbol_sptr>& aliases)
2695 {
2696 
2697   if (elf_symbol_sptr a = sym.get_next_alias())
2698     for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2699       aliases.push_back(a);
2700   else
2701     for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2702 	 i != symtab.end();
2703 	 ++i)
2704       for (elf_symbols::const_iterator j = i->second.begin();
2705 	   j != i->second.end();
2706 	   ++j)
2707 	{
2708 	  if (**j == sym)
2709 	    for (elf_symbol_sptr s = (*j)->get_next_alias();
2710 		 s && !s->is_main_symbol();
2711 		 s = s->get_next_alias())
2712 	      aliases.push_back(s);
2713 	  else
2714 	    for (elf_symbol_sptr s = (*j)->get_next_alias();
2715 		 s && !s->is_main_symbol();
2716 		 s = s->get_next_alias())
2717 	      if (*s == sym)
2718 		aliases.push_back(*j);
2719 	}
2720 }
2721 
2722 /// Test if two symbols alias.
2723 ///
2724 /// @param s1 the first symbol to consider.
2725 ///
2726 /// @param s2 the second symbol to consider.
2727 ///
2728 /// @return true if @p s1 aliases @p s2.
2729 bool
elf_symbols_alias(const elf_symbol * s1,const elf_symbol * s2)2730 elf_symbols_alias(const elf_symbol* s1, const elf_symbol* s2)
2731 {
2732   if (!!s1 != !!s2)
2733     return false;
2734   if (s1 == s2)
2735     return true;
2736   return elf_symbols_alias(*s1, *s2);
2737 }
2738 
2739 /// Test if two symbols alias.
2740 ///
2741 /// @param s1 the first symbol to consider.
2742 ///
2743 /// @param s2 the second symbol to consider.
2744 ///
2745 /// @return true if @p s1 aliases @p s2.
2746 bool
elf_symbols_alias(const elf_symbol_sptr s1,const elf_symbol_sptr s2)2747 elf_symbols_alias(const elf_symbol_sptr s1, const elf_symbol_sptr s2)
2748 {return elf_symbols_alias(s1.get(), s2.get());}
2749 
2750 /// Serialize an instance of @ref symbol_type and stream it to a given
2751 /// output stream.
2752 ///
2753 /// @param o the output stream to serialize the symbole type to.
2754 ///
2755 /// @param t the symbol type to serialize.
2756 std::ostream&
operator <<(std::ostream & o,elf_symbol::type t)2757 operator<<(std::ostream& o, elf_symbol::type t)
2758 {
2759   string repr;
2760 
2761   switch (t)
2762     {
2763     case elf_symbol::NOTYPE_TYPE:
2764       repr = "unspecified symbol type";
2765       break;
2766     case elf_symbol::OBJECT_TYPE:
2767       repr = "variable symbol type";
2768       break;
2769     case elf_symbol::FUNC_TYPE:
2770       repr = "function symbol type";
2771       break;
2772     case elf_symbol::SECTION_TYPE:
2773       repr = "section symbol type";
2774       break;
2775     case elf_symbol::FILE_TYPE:
2776       repr = "file symbol type";
2777       break;
2778     case elf_symbol::COMMON_TYPE:
2779       repr = "common data object symbol type";
2780       break;
2781     case elf_symbol::TLS_TYPE:
2782       repr = "thread local data object symbol type";
2783       break;
2784     case elf_symbol::GNU_IFUNC_TYPE:
2785       repr = "indirect function symbol type";
2786       break;
2787     default:
2788       {
2789 	std::ostringstream s;
2790 	s << "unknown symbol type (" << (char)t << ')';
2791 	repr = s.str();
2792       }
2793       break;
2794     }
2795 
2796   o << repr;
2797   return o;
2798 }
2799 
2800 /// Serialize an instance of @ref symbol_binding and stream it to a
2801 /// given output stream.
2802 ///
2803 /// @param o the output stream to serialize the symbole type to.
2804 ///
2805 /// @param b the symbol binding to serialize.
2806 std::ostream&
operator <<(std::ostream & o,elf_symbol::binding b)2807 operator<<(std::ostream& o, elf_symbol::binding b)
2808 {
2809   string repr;
2810 
2811   switch (b)
2812     {
2813     case elf_symbol::LOCAL_BINDING:
2814       repr = "local binding";
2815       break;
2816     case elf_symbol::GLOBAL_BINDING:
2817       repr = "global binding";
2818       break;
2819     case elf_symbol::WEAK_BINDING:
2820       repr = "weak binding";
2821       break;
2822     case elf_symbol::GNU_UNIQUE_BINDING:
2823       repr = "GNU unique binding";
2824       break;
2825     default:
2826       {
2827 	std::ostringstream s;
2828 	s << "unknown binding (" << (unsigned char) b << ")";
2829 	repr = s.str();
2830       }
2831       break;
2832     }
2833 
2834   o << repr;
2835   return o;
2836 }
2837 
2838 /// Serialize an instance of @ref elf_symbol::visibility and stream it
2839 /// to a given output stream.
2840 ///
2841 /// @param o the output stream to serialize the symbole type to.
2842 ///
2843 /// @param v the symbol visibility to serialize.
2844 std::ostream&
operator <<(std::ostream & o,elf_symbol::visibility v)2845 operator<<(std::ostream& o, elf_symbol::visibility v)
2846 {
2847   string repr;
2848 
2849   switch (v)
2850     {
2851     case elf_symbol::DEFAULT_VISIBILITY:
2852       repr = "default visibility";
2853       break;
2854     case elf_symbol::PROTECTED_VISIBILITY:
2855       repr = "protected visibility";
2856       break;
2857     case elf_symbol::HIDDEN_VISIBILITY:
2858       repr = "hidden visibility";
2859       break;
2860     case elf_symbol::INTERNAL_VISIBILITY:
2861       repr = "internal visibility";
2862       break;
2863     default:
2864       {
2865 	std::ostringstream s;
2866 	s << "unknown visibility (" << (unsigned char) v << ")";
2867 	repr = s.str();
2868       }
2869       break;
2870     }
2871 
2872   o << repr;
2873   return o;
2874 }
2875 
2876 /// Convert a string representing a symbol type into an
2877 /// elf_symbol::type.
2878 ///
2879 ///@param s the string to convert.
2880 ///
2881 ///@param t the resulting elf_symbol::type.
2882 ///
2883 /// @return true iff the conversion completed successfully.
2884 bool
string_to_elf_symbol_type(const string & s,elf_symbol::type & t)2885 string_to_elf_symbol_type(const string& s, elf_symbol::type& t)
2886 {
2887   if (s == "no-type")
2888     t = elf_symbol::NOTYPE_TYPE;
2889   else if (s == "object-type")
2890     t = elf_symbol::OBJECT_TYPE;
2891   else if (s == "func-type")
2892     t = elf_symbol::FUNC_TYPE;
2893   else if (s == "section-type")
2894     t = elf_symbol::SECTION_TYPE;
2895   else if (s == "file-type")
2896     t = elf_symbol::FILE_TYPE;
2897   else if (s == "common-type")
2898     t = elf_symbol::COMMON_TYPE;
2899   else if (s == "tls-type")
2900     t = elf_symbol::TLS_TYPE;
2901   else if (s == "gnu-ifunc-type")
2902     t = elf_symbol::GNU_IFUNC_TYPE;
2903   else
2904     return false;
2905 
2906   return true;
2907 }
2908 
2909 /// Convert a string representing a an elf symbol binding into an
2910 /// elf_symbol::binding.
2911 ///
2912 /// @param s the string to convert.
2913 ///
2914 /// @param b the resulting elf_symbol::binding.
2915 ///
2916 /// @return true iff the conversion completed successfully.
2917 bool
string_to_elf_symbol_binding(const string & s,elf_symbol::binding & b)2918 string_to_elf_symbol_binding(const string& s, elf_symbol::binding& b)
2919 {
2920     if (s == "local-binding")
2921       b = elf_symbol::LOCAL_BINDING;
2922     else if (s == "global-binding")
2923       b = elf_symbol::GLOBAL_BINDING;
2924     else if (s == "weak-binding")
2925       b = elf_symbol::WEAK_BINDING;
2926     else if (s == "gnu-unique-binding")
2927       b = elf_symbol::GNU_UNIQUE_BINDING;
2928     else
2929       return false;
2930 
2931     return true;
2932 }
2933 
2934 /// Convert a string representing a an elf symbol visibility into an
2935 /// elf_symbol::visibility.
2936 ///
2937 /// @param s the string to convert.
2938 ///
2939 /// @param b the resulting elf_symbol::visibility.
2940 ///
2941 /// @return true iff the conversion completed successfully.
2942 bool
string_to_elf_symbol_visibility(const string & s,elf_symbol::visibility & v)2943 string_to_elf_symbol_visibility(const string& s, elf_symbol::visibility& v)
2944 {
2945   if (s == "default-visibility")
2946     v = elf_symbol::DEFAULT_VISIBILITY;
2947   else if (s == "protected-visibility")
2948     v = elf_symbol::PROTECTED_VISIBILITY;
2949   else if (s == "hidden-visibility")
2950     v = elf_symbol::HIDDEN_VISIBILITY;
2951   else if (s == "internal-visibility")
2952     v = elf_symbol::INTERNAL_VISIBILITY;
2953   else
2954     return false;
2955 
2956   return true;
2957 }
2958 
2959 /// Test if the type of an ELF symbol denotes a function symbol.
2960 ///
2961 /// @param t the type of the ELF symbol.
2962 ///
2963 /// @return true iff elf symbol type @p t denotes a function symbol
2964 /// type.
2965 bool
elf_symbol_is_function(elf_symbol::type t)2966 elf_symbol_is_function(elf_symbol::type t)
2967 {return t == elf_symbol::FUNC_TYPE;}
2968 
2969 /// Test if the type of an ELF symbol denotes a function symbol.
2970 ///
2971 /// @param t the type of the ELF symbol.
2972 ///
2973 /// @return true iff elf symbol type @p t denotes a function symbol
2974 /// type.
2975 bool
elf_symbol_is_variable(elf_symbol::type t)2976 elf_symbol_is_variable(elf_symbol::type t)
2977 {return t == elf_symbol::OBJECT_TYPE;}
2978 
2979 // <elf_symbol::version stuff>
2980 
2981 struct elf_symbol::version::priv
2982 {
2983   string	version_;
2984   bool		is_default_;
2985 
privabigail::ir::elf_symbol::version::priv2986   priv()
2987     : is_default_(false)
2988   {}
2989 
privabigail::ir::elf_symbol::version::priv2990   priv(const string& v,
2991        bool d)
2992     : version_(v),
2993       is_default_(d)
2994   {}
2995 }; // end struct elf_symbol::version::priv
2996 
version()2997 elf_symbol::version::version()
2998   : priv_(new priv)
2999 {}
3000 
3001 /// @param v the name of the version.
3002 ///
3003 /// @param is_default true if this is a default version.
version(const string & v,bool is_default)3004 elf_symbol::version::version(const string& v,
3005 			     bool is_default)
3006   : priv_(new priv(v, is_default))
3007 {}
3008 
version(const elf_symbol::version & v)3009 elf_symbol::version::version(const elf_symbol::version& v)
3010   : priv_(new priv(v.str(), v.is_default()))
3011 {
3012 }
3013 
3014 elf_symbol::version::~version() = default;
3015 
3016 /// Cast the version_type into a string that is its name.
3017 ///
3018 /// @return the name of the version.
operator const string&() const3019 elf_symbol::version::operator const string&() const
3020 {return priv_->version_;}
3021 
3022 /// Getter for the version name.
3023 ///
3024 /// @return the version name.
3025 const string&
str() const3026 elf_symbol::version::str() const
3027 {return priv_->version_;}
3028 
3029 /// Setter for the version name.
3030 ///
3031 /// @param s the version name.
3032 void
str(const string & s)3033 elf_symbol::version::str(const string& s)
3034 {priv_->version_ = s;}
3035 
3036 /// Getter for the 'is_default' property of the version.
3037 ///
3038 /// @return true iff this is a default version.
3039 bool
is_default() const3040 elf_symbol::version::is_default() const
3041 {return priv_->is_default_;}
3042 
3043 /// Setter for the 'is_default' property of the version.
3044 ///
3045 /// @param f true if this is the default version.
3046 void
is_default(bool f)3047 elf_symbol::version::is_default(bool f)
3048 {priv_->is_default_ = f;}
3049 
3050 bool
is_empty() const3051 elf_symbol::version::is_empty() const
3052 {return str().empty();}
3053 
3054 /// Compares the current version against another one.
3055 ///
3056 /// @param o the other version to compare the current one to.
3057 ///
3058 /// @return true iff the current version equals @p o.
3059 bool
operator ==(const elf_symbol::version & o) const3060 elf_symbol::version::operator==(const elf_symbol::version& o) const
3061 {return str() == o.str();}
3062 
3063 /// Inequality operator.
3064 ///
3065 /// @param o the version to compare against the current one.
3066 ///
3067 /// @return true iff both versions are different.
3068 bool
operator !=(const version & o) const3069 elf_symbol::version::operator!=(const version& o) const
3070 {return !operator==(o);}
3071 
3072 /// Assign a version to the current one.
3073 ///
3074 /// @param o the other version to assign to this one.
3075 ///
3076 /// @return a reference to the assigned version.
3077 elf_symbol::version&
operator =(const elf_symbol::version & o)3078 elf_symbol::version::operator=(const elf_symbol::version& o)
3079 {
3080   str(o.str());
3081   is_default(o.is_default());
3082   return *this;
3083 }
3084 
3085 // </elf_symbol::version stuff>
3086 
3087 // </elf_symbol stuff>
3088 
3089 // <class dm_context_rel stuff>
3090 struct dm_context_rel::priv
3091 {
3092   bool is_laid_out_;
3093   size_t offset_in_bits_;
3094   var_decl* anonymous_data_member_;
3095 
privabigail::ir::dm_context_rel::priv3096   priv(bool is_static = false)
3097     : is_laid_out_(!is_static),
3098       offset_in_bits_(0),
3099       anonymous_data_member_()
3100   {}
3101 
privabigail::ir::dm_context_rel::priv3102   priv(bool is_laid_out, size_t offset_in_bits)
3103     : is_laid_out_(is_laid_out),
3104       offset_in_bits_(offset_in_bits),
3105       anonymous_data_member_()
3106   {}
3107 }; //end struct dm_context_rel::priv
3108 
dm_context_rel()3109 dm_context_rel::dm_context_rel()
3110   : context_rel(),
3111     priv_(new priv)
3112 {}
3113 
dm_context_rel(scope_decl * s,bool is_laid_out,size_t offset_in_bits,access_specifier a,bool is_static)3114 dm_context_rel::dm_context_rel(scope_decl* s,
3115 			       bool is_laid_out,
3116 			       size_t offset_in_bits,
3117 			       access_specifier a,
3118 			       bool is_static)
3119   : context_rel(s, a, is_static),
3120     priv_(new priv(is_laid_out, offset_in_bits))
3121 {}
3122 
dm_context_rel(scope_decl * s)3123 dm_context_rel::dm_context_rel(scope_decl* s)
3124   : context_rel(s),
3125     priv_(new priv())
3126 {}
3127 
3128 bool
get_is_laid_out() const3129 dm_context_rel::get_is_laid_out() const
3130 {return priv_->is_laid_out_;}
3131 
3132 void
set_is_laid_out(bool f)3133 dm_context_rel::set_is_laid_out(bool f)
3134 {priv_->is_laid_out_ = f;}
3135 
3136 size_t
get_offset_in_bits() const3137 dm_context_rel::get_offset_in_bits() const
3138 {return priv_->offset_in_bits_;}
3139 
3140 void
set_offset_in_bits(size_t o)3141 dm_context_rel::set_offset_in_bits(size_t o)
3142 {priv_->offset_in_bits_ = o;}
3143 
3144 bool
operator ==(const dm_context_rel & o) const3145 dm_context_rel::operator==(const dm_context_rel& o) const
3146 {
3147   if (!context_rel::operator==(o))
3148     return false;
3149 
3150   return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3151 	    && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3152 }
3153 
3154 bool
operator !=(const dm_context_rel & o) const3155 dm_context_rel::operator!=(const dm_context_rel& o) const
3156 {return !operator==(o);}
3157 
3158 /// Return a non-nil value if this data member context relationship
3159 /// has an anonymous data member.  That means, if the data member this
3160 /// relation belongs to is part of an anonymous data member.
3161 ///
3162 /// @return the containing anonymous data member of this data member
3163 /// relationship.  Nil if there is none.
3164 const var_decl*
get_anonymous_data_member() const3165 dm_context_rel::get_anonymous_data_member() const
3166 {return priv_->anonymous_data_member_;}
3167 
3168 /// Set the containing anonymous data member of this data member
3169 /// context relationship. That means that the data member this
3170 /// relation belongs to is part of an anonymous data member.
3171 ///
3172 /// @param anon_dm the containing anonymous data member of this data
3173 /// member relationship.  Nil if there is none.
3174 void
set_anonymous_data_member(var_decl * anon_dm)3175 dm_context_rel::set_anonymous_data_member(var_decl* anon_dm)
3176 {priv_->anonymous_data_member_ = anon_dm;}
3177 
~dm_context_rel()3178 dm_context_rel::~dm_context_rel()
3179 {}
3180 // </class dm_context_rel stuff>
3181 
3182 // <environment stuff>
3183 
3184 /// Convenience typedef for a map of interned_string -> bool.
3185 typedef unordered_map<interned_string,
3186 		      bool, hash_interned_string> interned_string_bool_map_type;
3187 
3188 
3189 /// Default constructor of the @ref environment type.
environment()3190 environment::environment()
3191   :priv_(new priv)
3192 {}
3193 
3194 /// Destructor for the @ref environment type.
~environment()3195 environment::~environment()
3196 {}
3197 
3198 /// Getter the map of canonical types.
3199 ///
3200 /// @return the map of canonical types.  The key of the map is the
3201 /// hash of the canonical type and its value if the canonical type.
3202 environment::canonical_types_map_type&
get_canonical_types_map()3203 environment::get_canonical_types_map()
3204 {return priv_->canonical_types_;}
3205 
3206 /// Getter the map of canonical types.
3207 ///
3208 /// @return the map of canonical types.  The key of the map is the
3209 /// hash of the canonical type and its value if the canonical type.
3210 const environment::canonical_types_map_type&
get_canonical_types_map() const3211 environment::get_canonical_types_map() const
3212 {return const_cast<environment*>(this)->get_canonical_types_map();}
3213 
3214 /// Helper to detect if a type is either a reference, a pointer, or a
3215 /// qualified type.
3216 static bool
is_ptr_ref_or_qual_type(const type_base * t)3217 is_ptr_ref_or_qual_type(const type_base *t)
3218 {
3219   if (is_pointer_type(t)
3220       || is_reference_type(t)
3221       || is_qualified_type(t))
3222     return true;
3223   return false;
3224 }
3225 
3226 /// Compare decls using their locations.
3227 ///
3228 /// @param f the first decl to compare.
3229 ///
3230 /// @param s the second decl to compare.
3231 ///
3232 /// @return true if @p f compares less than @p s.
3233 static bool
compare_using_locations(const decl_base * f,const decl_base * s)3234 compare_using_locations(const decl_base *f,
3235 			const decl_base *s)
3236 {
3237   // If a decl has artificial location, then use that one over the
3238   // natural one.
3239   location fl = get_artificial_or_natural_location(f);
3240   location sl = get_artificial_or_natural_location(s);
3241 
3242   ABG_ASSERT(fl.get_value() && sl.get_value());
3243   if (fl.get_is_artificial() == sl.get_is_artificial())
3244     {
3245       // The locations of the two artfifacts have the same
3246       // artificial-ness so they can be compared.
3247       string p1, p2;
3248       unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3249       fl.expand(p1, l1, c1);
3250       sl.expand(p2, l2, c2);
3251       if (p1 != p2)
3252 	return p1 < p2;
3253       if (l1 != l2)
3254 	return l1 < l2;
3255       if (c1 != c2)
3256 	return c1 < c2;
3257     }
3258 
3259   return (get_pretty_representation(f, /*internal=*/false)
3260 	  < get_pretty_representation(s, /*internal=*/false));
3261 }
3262 
3263 /// A functor to sort decls somewhat topologically.  That is, types
3264 /// are sorted in a way that makes the ones that are defined "first"
3265 /// to come first.
3266 ///
3267 /// The topological criteria is a lexicographic sort of the definition
3268 /// location of the type.  For types that have no location (or the
3269 /// same location), it's their qualified name that is used for the
3270 /// lexicographic sort.
3271 struct decl_topo_comp
3272 {
3273 
3274   /// The "Less Than" comparison operator of this functor.
3275   ///
3276   /// @param f the first decl to be considered for the comparison.
3277   ///
3278   /// @param s the second decl to be considered for the comparison.
3279   ///
3280   /// @return true iff @p f is less than @p s.
3281   bool
operator ()abigail::ir::decl_topo_comp3282   operator()(const decl_base *f,
3283 	     const decl_base *s)
3284   {
3285     if (!!f != !!s)
3286       return f && !s;
3287 
3288     if (!f)
3289       return false;
3290 
3291     // Unique types that are artificially created in the environment
3292     // don't have locations.  They ought to be compared on the basis
3293     // of their pretty representation before we start looking at IR
3294     // nodes' locations down the road.
3295     if (is_unique_type(is_type(f)) || is_unique_type(is_type(s)))
3296       return (get_pretty_representation(f, /*internal=*/false)
3297 	      < get_pretty_representation(s, /*internal=*/false));
3298 
3299     // If both decls come from an abixml file, keep the order they
3300     // have from that abixml file.
3301     if ((!f->get_corpus() && !s->get_corpus())
3302 	|| (f->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
3303 	    && s->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN))
3304       return compare_using_locations(f, s);
3305 
3306     // If a decl has artificial location, then use that one over the
3307     // natural one.
3308     location fl = get_artificial_or_natural_location(f);
3309     location sl = get_artificial_or_natural_location(s);
3310 
3311     if (fl.get_value() && sl.get_value())
3312       return compare_using_locations(f, s);
3313     else if (!!fl != !!sl)
3314       // So one of the decls doesn't have location data.
3315       // The first decl is less than the second if it's the one not
3316       // having location data.
3317       return !fl && sl;
3318 
3319     // We reach this point if location data is useless.
3320     if (f->get_is_anonymous()
3321 	&& s->get_is_anonymous()
3322 	&& (get_pretty_representation(f, /*internal=*/false)
3323 	    == get_pretty_representation(s, /*internal=*/false)))
3324       return f->get_name() < s->get_name();
3325 
3326     return (get_pretty_representation(f, /*internal=*/false)
3327 	    < get_pretty_representation(s, /*internal=*/false));
3328   }
3329 
3330   /// The "Less Than" comparison operator of this functor.
3331   ///
3332   /// @param f the first decl to be considered for the comparison.
3333   ///
3334   /// @param s the second decl to be considered for the comparison.
3335   ///
3336   /// @return true iff @p f is less than @p s.
3337   bool
operator ()abigail::ir::decl_topo_comp3338   operator()(const decl_base_sptr &f,
3339 	     const decl_base_sptr &s)
3340   {return operator()(f.get(), s.get());}
3341 
3342 }; // end struct decl_topo_comp
3343 
3344 /// A functor to sort types somewhat topologically.  That is, types
3345 /// are sorted in a way that makes the ones that are defined "first"
3346 /// to come first.
3347 ///
3348 /// The topological criteria is a lexicographic sort of the definition
3349 /// location of the type.  For types that have no location, it's their
3350 /// qualified name that is used for the lexicographic sort.
3351 struct type_topo_comp
3352 {
3353   /// Test if a decl has an artificial or natural location.
3354   ///
3355   /// @param d the decl to consider
3356   ///
3357   /// @return true iff @p d has a location.
3358   bool
has_artificial_or_natural_locationabigail::ir::type_topo_comp3359   has_artificial_or_natural_location(const decl_base* d)
3360   {return get_artificial_or_natural_location(d);}
3361 
3362   /// Test if a type has an artificial or natural location.
3363   ///
3364   /// @param t the type to consider
3365   ///
3366   /// @return true iff @p t has a location.
3367   bool
has_artificial_or_natural_locationabigail::ir::type_topo_comp3368   has_artificial_or_natural_location(const type_base* t)
3369   {
3370     if (decl_base *d = is_decl(t))
3371       return has_artificial_or_natural_location(d);
3372     return false;
3373   }
3374 
3375   /// The "Less Than" comparison operator of this functor.
3376   ///
3377   /// @param f the first type to be considered for the comparison.
3378   ///
3379   /// @param s the second type to be considered for the comparison.
3380   ///
3381   /// @return true iff @p f is less than @p s.
3382   bool
operator ()abigail::ir::type_topo_comp3383   operator()(const type_base_sptr &f,
3384 	     const type_base_sptr &s)
3385   {return operator()(f.get(), s.get());}
3386 
3387   /// The "Less Than" comparison operator of this functor.
3388   ///
3389   /// @param f the first type to be considered for the comparison.
3390   ///
3391   /// @param s the second type to be considered for the comparison.
3392   ///
3393   /// @return true iff @p f is less than @p s.
3394   bool
operator ()abigail::ir::type_topo_comp3395   operator()(const type_base *f,
3396 	     const type_base *s)
3397   {
3398     // If both decls come from an abixml file, keep the order they
3399     // have from that abixml file.
3400     if ((!f->get_corpus() && !s->get_corpus())
3401 	|| (f->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
3402 	    && s->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN))
3403       return compare_using_locations(is_decl(f), is_decl(s));
3404 
3405     bool f_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(f);
3406     bool s_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(s);
3407 
3408     if (f_is_ptr_ref_or_qual != s_is_ptr_ref_or_qual)
3409       return !f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual;
3410 
3411     if (f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual
3412 	&& !has_artificial_or_natural_location(f)
3413 	&& !has_artificial_or_natural_location(s))
3414       {
3415 	string s1 = get_pretty_representation(f, /*internal=*/false);
3416 	string s2 = get_pretty_representation(s, /*internal=*/false);
3417 	if (s1 == s2)
3418 	  {
3419 	    if (qualified_type_def * q = is_qualified_type(f))
3420 	      {
3421 		if (q->get_cv_quals() == qualified_type_def::CV_NONE)
3422 		  if (!is_qualified_type(s))
3423 		    // We are looking at two types that are the result of
3424 		    // an optimization that happens during the IR
3425 		    // construction.  Namely, type f is a cv-qualified
3426 		    // type with no qualifier (no const, no volatile, no
3427 		    // nothing, we call it an empty-qualified type).
3428 		    // These are the result of an optimization which
3429 		    // removes "redundant qualifiers" from some types.
3430 		    // For instance, consider a "const reference".  The
3431 		    // const there is redundant because a reference is
3432 		    // always const.  So as a result of the optimizaton
3433 		    // that type is going to be transformed into an
3434 		    // empty-qualified reference. If we don't make that
3435 		    // optimization, then we risk having spurious change
3436 		    // reports down the road.  But then, as a consequence
3437 		    // of that optimization, we need to sort the
3438 		    // empty-qualified type and its non-qualified variant
3439 		    // e.g, to ensure stability in the abixml output; both
3440 		    // types are logically equal, but here, we decide that
3441 		    // the empty-qualified one is topologically "less
3442 		    // than" the non-qualified counterpart.
3443 		    //
3444 		    // So here, type f is an empty-qualified type and type
3445 		    // s is its non-qualified variant.  We decide that f
3446 		    // is topologically less than s.
3447 		    return true;
3448 	      }
3449 	    // Now let's peel off the pointer (or reference types) and
3450 	    // see if the ultimate underlying types have the same
3451 	    // textual representation; if not, use that as sorting
3452 	    // criterion.
3453 	    type_base *peeled_f =
3454 	      peel_pointer_or_reference_type(f, true);
3455 	    type_base *peeled_s =
3456 	      peel_pointer_or_reference_type(s, true);
3457 
3458 	    s1 = get_pretty_representation(peeled_f, /*internal=*/false);
3459 	    s2 = get_pretty_representation(peeled_s, /*internal=*/false);
3460 	    if (s1 != s2)
3461 	      return s1 < s2;
3462 
3463 	    // The underlying type of pointer/reference have the same
3464 	    // textual representation; let's try to peel of typedefs
3465 	    // as well and we'll consider sorting the result as decls.
3466 	    peeled_f = peel_typedef_pointer_or_reference_type(peeled_f, true);
3467 	    peeled_s = peel_typedef_pointer_or_reference_type(peeled_s, true);
3468 
3469 	    s1 = get_pretty_representation(peeled_f, false);
3470 	    s2 = get_pretty_representation(peeled_s, false);
3471 	    if (s1 != s2)
3472 	      return s1 < s2;
3473 	  }
3474       }
3475 
3476     string s1 = get_pretty_representation(f, false);
3477     string s2 = get_pretty_representation(s, false);
3478 
3479     if (s1 != s2)
3480       return s1 < s2;
3481 
3482     if (is_typedef(f) && is_typedef(s))
3483       {
3484 	s1 = get_pretty_representation(is_typedef(f)->get_underlying_type(),
3485 				       false);
3486 	s2 = get_pretty_representation(is_typedef(s)->get_underlying_type(),
3487 				       false);
3488 	if (s1 != s2)
3489 	  return s1 < s2;
3490       }
3491 
3492     type_base *peeled_f = peel_typedef_pointer_or_reference_type(f, true);
3493     type_base *peeled_s = peel_typedef_pointer_or_reference_type(s, true);
3494 
3495     s1 = get_pretty_representation(peeled_f, false);
3496     s2 = get_pretty_representation(peeled_s, false);
3497 
3498     if (s1 != s2)
3499       return s1 < s2;
3500 
3501     decl_base *fd = is_decl(f);
3502     decl_base *sd = is_decl(s);
3503 
3504     if (!!fd != !!sd)
3505       return fd && !sd;
3506 
3507     // If the two types have no decls, how come we could not sort them
3508     // until now? Let's investigate.
3509     ABG_ASSERT(fd);
3510 
3511     // From this point, fd and sd should be non-nil
3512     decl_topo_comp decl_comp;
3513     return decl_comp(fd, sd);
3514   }
3515 }; //end struct type_topo_comp
3516 
3517 /// Sort types in a hopefully stable manner.
3518 ///
3519 /// @param types a set of types with canonical types to sort.
3520 ///
3521 /// @param result the resulting sorted vector.
3522 void
sort_types(const canonical_type_sptr_set_type & types,vector<type_base_sptr> & result)3523 sort_types(const canonical_type_sptr_set_type& types,
3524 	   vector<type_base_sptr>& result)
3525 {
3526   for (auto t: types)
3527     result.push_back(t);
3528 
3529   type_topo_comp comp;
3530   std::stable_sort(result.begin(), result.end(), comp);
3531 }
3532 
3533 /// Get the unique @ref type_decl that represents a "void" type for
3534 /// the current environment.  This node must be the only one
3535 /// representing a void type in the system.
3536 ///
3537 /// Note that upon first use of this IR node (by the relevant
3538 /// front-end, for instance) it must be added to a scope using e.g,
3539 /// the @ref add_decl_to_scope() function.
3540 ///
3541 /// @return the @ref type_decl that represents a "void" type.
3542 const type_base_sptr&
get_void_type() const3543 environment::get_void_type() const
3544 {
3545   if (!priv_->void_type_)
3546     priv_->void_type_.reset(new type_decl(*this,
3547 					  intern("void"),
3548 					  0, 0, location()));
3549   return priv_->void_type_;
3550 }
3551 
3552 /// Getter of the "pointer-to-void" IR node that is shared across the
3553 /// ABI corpus.  This node must be the only one representing a void
3554 /// pointer type in the system.
3555 ///
3556 /// Note that upon first use of this IR node (by the relevant
3557 /// front-end, for instance) it must be added to a scope using e.g,
3558 /// the @ref add_decl_to_scope() function.
3559 ///
3560 /// @return the "pointer-to-void" IR node.
3561 const type_base_sptr&
get_void_pointer_type() const3562 environment::get_void_pointer_type() const
3563 {
3564   if (!priv_->void_pointer_type_)
3565     priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3566 							 0, 0, location()));
3567   return priv_->void_pointer_type_;
3568 }
3569 
3570 /// Get a @ref type_decl instance that represents a the type of a
3571 /// variadic function parameter. This node must be the only one
3572 /// representing a variadic parameter type in the system.
3573 ///
3574 /// Note that upon first use of this IR node (by the relevant
3575 /// front-end, for instance) it must be added to a scope using e.g,
3576 /// the @ref add_decl_to_scope() function.
3577 ///
3578 /// @return the Get a @ref type_decl instance that represents a the
3579 /// type of a variadic function parameter.
3580 const type_base_sptr&
get_variadic_parameter_type() const3581 environment::get_variadic_parameter_type() const
3582 {
3583   if (!priv_->variadic_marker_type_)
3584     priv_->variadic_marker_type_.
3585       reset(new type_decl(*this, intern(get_variadic_parameter_type_name()),
3586 			  0, 0, location()));
3587   return priv_->variadic_marker_type_;
3588 }
3589 
3590 /// Getter of the name of the variadic parameter type.
3591 ///
3592 /// @return the name of the variadic parameter type.
3593 string&
get_variadic_parameter_type_name()3594 environment::get_variadic_parameter_type_name()
3595 {
3596   static string variadic_parameter_type_name = "variadic parameter type";
3597   return variadic_parameter_type_name;
3598 }
3599 
3600 /// Test if the canonicalization of types created out of the current
3601 /// environment is done.
3602 ///
3603 /// @return true iff the canonicalization of types created out of the current
3604 /// environment is done.
3605 bool
canonicalization_is_done() const3606 environment::canonicalization_is_done() const
3607 {return priv_->canonicalization_is_done_;}
3608 
3609 /// Set a flag saying if the canonicalization of types created out of
3610 /// the current environment is done or not.
3611 ///
3612 /// Note that this function must only be called by internal code of
3613 /// the library that creates ABI artifacts (e.g, read an abi corpus
3614 /// from elf or from our own xml format and creates representations of
3615 /// types out of it) and thus needs to canonicalize types to speed-up
3616 /// further type comparison.
3617 ///
3618 /// @param f the new value of the flag.
3619 void
canonicalization_is_done(bool f)3620 environment::canonicalization_is_done(bool f)
3621 {priv_->canonicalization_is_done_ = f;}
3622 
3623 /// Getter for the "on-the-fly-canonicalization" flag.
3624 ///
3625 /// @return true iff @ref OnTheFlyCanonicalization
3626 /// "on-the-fly-canonicalization" is to be performed during
3627 /// comparison.
3628 bool
do_on_the_fly_canonicalization() const3629 environment::do_on_the_fly_canonicalization() const
3630 {return priv_->do_on_the_fly_canonicalization_;}
3631 
3632 /// Setter for the "on-the-fly-canonicalization" flag.
3633 ///
3634 /// @param f If this is true then @ref OnTheFlyCanonicalization
3635 /// "on-the-fly-canonicalization" is to be performed during
3636 /// comparison.
3637 void
do_on_the_fly_canonicalization(bool f)3638 environment::do_on_the_fly_canonicalization(bool f)
3639 {priv_->do_on_the_fly_canonicalization_ = f;}
3640 
3641 /// Getter of the "decl-only-class-equals-definition" flag.
3642 ///
3643 /// Usually, a declaration-only class named 'struct foo' compares
3644 /// equal to any class definition named "struct foo'.  This is at
3645 /// least true for C++.
3646 ///
3647 /// In C, though, because there can be multiple definitions of 'struct
3648 /// foo' in the binary, a declaration-only "struct foo" might be
3649 /// considered to *NOT* resolve to any of the struct foo defined.  In
3650 /// that case, the declaration-only "struct foo" is considered
3651 /// different from the definitions.
3652 ///
3653 /// This flag controls the behaviour of the comparison of an
3654 /// unresolved decl-only class against a definition of the same name.
3655 ///
3656 /// If set to false, the the declaration equals the definition.  If
3657 /// set to false, then the decalration is considered different from
3658 /// the declaration.
3659 ///
3660 /// @return the value of the "decl-only-class-equals-definition" flag.
3661 bool
decl_only_class_equals_definition() const3662 environment::decl_only_class_equals_definition() const
3663 {return priv_->decl_only_class_equals_definition_;}
3664 
3665 /// Setter of the "decl-only-class-equals-definition" flag.
3666 ///
3667 /// Usually, a declaration-only class named 'struct foo' compares
3668 /// equal to any class definition named "struct foo'.  This is at
3669 /// least true for C++.
3670 ///
3671 /// In C, though, because there can be multiple definitions of 'struct
3672 /// foo' in the binary, a declaration-only "struct foo" might be
3673 /// considered to *NOT* resolve to any of the struct foo defined.  In
3674 /// that case, the declaration-only "struct foo" is considered
3675 /// different from the definitions.
3676 ///
3677 /// This flag controls the behaviour of the comparison of an
3678 /// unresolved decl-only class against a definition of the same name.
3679 ///
3680 /// If set to false, the the declaration equals the definition.  If
3681 /// set to false, then the decalration is considered different from
3682 /// the declaration.
3683 ///
3684 /// @param the new value of the "decl-only-class-equals-definition"
3685 /// flag.
3686 void
decl_only_class_equals_definition(bool f) const3687 environment::decl_only_class_equals_definition(bool f) const
3688 {priv_->decl_only_class_equals_definition_ = f;}
3689 
3690 /// Test if a given type is a void type as defined in the current
3691 /// environment.
3692 ///
3693 /// @param t the type to consider.
3694 ///
3695 /// @return true iff @p t is a void type as defined in the current
3696 /// environment.
3697 bool
is_void_type(const type_base_sptr & t) const3698 environment::is_void_type(const type_base_sptr& t) const
3699 {
3700   if (!t)
3701     return false;
3702   return is_void_type(t.get());
3703 }
3704 
3705 /// Test if a given type is a void type as defined in the current
3706 /// environment.
3707 ///
3708 /// @param t the type to consider.
3709 ///
3710 /// @return true iff @p t is a void type as defined in the current
3711 /// environment.
3712 bool
is_void_type(const type_base * t) const3713 environment::is_void_type(const type_base* t) const
3714 {
3715   if (!t)
3716     return false;
3717   return (t == get_void_type().get()
3718 	  || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3719 }
3720 
3721 /// Test if a given type is the same as the void pointer type of the
3722 /// environment.
3723 ///
3724 /// @param t the IR type to test.
3725 ///
3726 /// @return true iff @p t is the void pointer returned by
3727 /// environment::get_void_pointer_type().
3728 bool
is_void_pointer_type(const type_base_sptr & t) const3729 environment::is_void_pointer_type(const type_base_sptr& t) const
3730 {
3731   if (!t)
3732     return false;
3733 
3734   return t.get() == get_void_pointer_type().get();
3735 }
3736 
3737 /// Test if a given type is the same as the void pointer type of the
3738 /// environment.
3739 ///
3740 /// @param t the IR type to test.
3741 ///
3742 /// @return true iff @p t is the void pointer returned by
3743 /// environment::get_void_pointer_type().
3744 bool
is_void_pointer_type(const type_base * t) const3745 environment::is_void_pointer_type(const type_base* t) const
3746 {
3747   if (!t)
3748     return false;
3749 
3750   return t == get_void_pointer_type().get();
3751 }
3752 
3753 /// Test if a type is a variadic parameter type as defined in the
3754 /// current environment.
3755 ///
3756 /// @param t the type to consider.
3757 ///
3758 /// @return true iff @p t is a variadic parameter type as defined in
3759 /// the current environment.
3760 bool
is_variadic_parameter_type(const type_base * t) const3761 environment::is_variadic_parameter_type(const type_base* t) const
3762 {
3763   if (!t)
3764     return false;
3765   return t == get_variadic_parameter_type().get();
3766 }
3767 
3768 /// Test if a type is a variadic parameter type as defined in the
3769 /// current environment.
3770 ///
3771 /// @param t the type to consider.
3772 ///
3773 /// @return true iff @p t is a variadic parameter type as defined in
3774 /// the current environment.
3775 bool
is_variadic_parameter_type(const type_base_sptr & t) const3776 environment::is_variadic_parameter_type(const type_base_sptr& t) const
3777 {return is_variadic_parameter_type(t.get());}
3778 
3779 /// Do intern a string.
3780 ///
3781 /// If a value of this string already exists in the interned string
3782 /// pool of the current environment, then this function returns a new
3783 /// interned_string pointing to that already existing string.
3784 /// Otherwise, a new string is created, stored in the interned string
3785 /// pool and a new interned_string instance is created to point to
3786 /// that new intrerned string, and it's return.
3787 ///
3788 /// @param s the value of the string to intern.
3789 ///
3790 /// @return the interned string.
3791 interned_string
intern(const string & s) const3792 environment::intern(const string& s) const
3793 {return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3794 
3795 /// Getter of the general configuration object.
3796 ///
3797 /// @return the configuration object.
3798 const config&
get_config() const3799 environment::get_config() const
3800 {return priv_->config_;}
3801 
3802 /// Getter for a property that says if the user actually did set the
3803 /// analyze_exported_interfaces_only() property.  If not, it means
3804 /// the default behaviour prevails.
3805 ///
3806 /// @return tru iff the user did set the
3807 /// analyze_exported_interfaces_only() property.
3808 bool
user_set_analyze_exported_interfaces_only() const3809 environment::user_set_analyze_exported_interfaces_only() const
3810 {return priv_->analyze_exported_interfaces_only_.has_value();}
3811 
3812 /// Setter for the property that controls if we are to restrict the
3813 /// analysis to the types that are only reachable from the exported
3814 /// interfaces only, or if the set of types should be more broad than
3815 /// that.  Typically, we'd restrict the analysis to types reachable
3816 /// from exported interfaces only (stricto sensu, that would really be
3817 /// only the types that are part of the ABI of well designed
3818 /// libraries) for performance reasons.
3819 ///
3820 /// @param f the value of the flag.
3821 void
analyze_exported_interfaces_only(bool f)3822 environment::analyze_exported_interfaces_only(bool f)
3823 {priv_->analyze_exported_interfaces_only_ = f;}
3824 
3825 /// Getter for the property that controls if we are to restrict the
3826 /// analysis to the types that are only reachable from the exported
3827 /// interfaces only, or if the set of types should be more broad than
3828 /// that.  Typically, we'd restrict the analysis to types reachable
3829 /// from exported interfaces only (stricto sensu, that would really be
3830 /// only the types that are part of the ABI of well designed
3831 /// libraries) for performance reasons.
3832 ///
3833 /// @param f the value of the flag.
3834 bool
analyze_exported_interfaces_only() const3835 environment::analyze_exported_interfaces_only() const
3836 {return priv_->analyze_exported_interfaces_only_.value_or(false);}
3837 
3838 #ifdef WITH_DEBUG_SELF_COMPARISON
3839 /// Setter of the corpus of the input corpus of the self comparison
3840 /// that takes place when doing "abidw --debug-abidiff <binary>".
3841 ///
3842 /// The first invocation of this function sets the first corpus of the
3843 /// self comparison.  The second invocation of this very same function
3844 /// sets the second corpus of the self comparison.  That second corpus
3845 /// is supposed to come from the abixml serialization of the first
3846 /// corpus.
3847 ///
3848 /// @param c the corpus of the input binary or the corpus of the
3849 /// abixml serialization of the initial binary input.
3850 void
set_self_comparison_debug_input(const corpus_sptr & c)3851 environment::set_self_comparison_debug_input(const corpus_sptr& c)
3852 {
3853   self_comparison_debug_is_on(true);
3854   if (priv_->first_self_comparison_corpus_.expired())
3855     priv_->first_self_comparison_corpus_ = c;
3856   else if (priv_->second_self_comparison_corpus_.expired()
3857 	   && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3858     priv_->second_self_comparison_corpus_ = c;
3859 }
3860 
3861 /// Getter for the corpora of the input binary and the intermediate
3862 /// abixml of the self comparison that takes place when doing
3863 ///   'abidw --debug-abidiff <binary>'.
3864 ///
3865 /// @param first_corpus output parameter that is set to the corpus of
3866 /// the input corpus.
3867 ///
3868 /// @param second_corpus output parameter that is set to the corpus of
3869 /// the second corpus.
3870 void
get_self_comparison_debug_inputs(corpus_sptr & first_corpus,corpus_sptr & second_corpus)3871 environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3872 					      corpus_sptr& second_corpus)
3873 {
3874     first_corpus = priv_->first_self_comparison_corpus_.lock();
3875     second_corpus = priv_->second_self_comparison_corpus_.lock();
3876 }
3877 
3878 /// Turn on/off the self comparison debug mode.
3879 ///
3880 /// @param f true iff the self comparison debug mode is turned on.
3881 void
self_comparison_debug_is_on(bool f)3882 environment::self_comparison_debug_is_on(bool f)
3883 {priv_->self_comparison_debug_on_ = f;}
3884 
3885 /// Test if we are in the process of the 'self-comparison
3886 /// debugging' as triggered by 'abidw --debug-abidiff' command.
3887 ///
3888 /// @return true if self comparison debug is on.
3889 bool
self_comparison_debug_is_on() const3890 environment::self_comparison_debug_is_on() const
3891 {return priv_->self_comparison_debug_on_;}
3892 #endif
3893 
3894 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3895 /// Set the "type canonicalization debugging" mode, triggered by using
3896 /// the command: "abidw --debug-tc".
3897 ///
3898 /// @param flag if true then the type canonicalization debugging mode
3899 /// is enabled.
3900 void
debug_type_canonicalization_is_on(bool flag)3901 environment::debug_type_canonicalization_is_on(bool flag)
3902 {priv_->debug_type_canonicalization_ = flag;}
3903 
3904 /// Getter of the "type canonicalization debugging" mode, triggered by
3905 /// using the command: "abidw --debug-tc".
3906 ///
3907 /// @return true iff the type canonicalization debugging mode is
3908 /// enabled.
3909 bool
debug_type_canonicalization_is_on() const3910 environment::debug_type_canonicalization_is_on() const
3911 {return priv_->debug_type_canonicalization_;}
3912 
3913 /// Setter of the "DIE canonicalization debugging" mode, triggered by
3914 /// using the command: "abidw --debug-dc".
3915 ///
3916 /// @param flag true iff the DIE canonicalization debugging mode is
3917 /// enabled.
3918 void
debug_die_canonicalization_is_on(bool flag)3919 environment::debug_die_canonicalization_is_on(bool flag)
3920 {priv_->debug_die_canonicalization_ = flag;}
3921 
3922 /// Getter of the "DIE canonicalization debugging" mode, triggered by
3923 /// using the command: "abidw --debug-dc".
3924 ///
3925 /// @return true iff the DIE canonicalization debugging mode is
3926 /// enabled.
3927 bool
debug_die_canonicalization_is_on() const3928 environment::debug_die_canonicalization_is_on() const
3929 {return priv_->debug_die_canonicalization_;}
3930 #endif // WITH_DEBUG_TYPE_CANONICALIZATION
3931 
3932 /// Get the vector of canonical types which have a given "string
3933 /// representation".
3934 ///
3935 /// @param 'name', the textual representation of the type as returned
3936 /// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3937 ///                                                 /*qualified=*/true)
3938 ///
3939 /// This is useful to for debugging purposes as it's handy to use from
3940 /// inside a debugger like GDB.
3941 ///
3942 /// @return a pointer to the vector of canonical types having the
3943 /// representation @p name, or nullptr if no type with that
3944 /// representation exists.
3945 vector<type_base_sptr>*
get_canonical_types(const char * name)3946 environment::get_canonical_types(const char* name)
3947 {
3948   auto ti = get_canonical_types_map().find(name);
3949   if (ti == get_canonical_types_map().end())
3950     return nullptr;
3951   return &ti->second;
3952 }
3953 
3954 /// Get a given canonical type which has a given "string
3955 /// representation".
3956 ///
3957 /// @param 'name', the textual representation of the type as returned
3958 /// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3959 ///                                                 /*qualified=*/true).
3960 ///
3961 /// @param index, the index of the type in the vector of types that
3962 /// all have the same textual representation @p 'name'.  That vector
3963 /// is returned by the function environment::get_canonical_types().
3964 ///
3965 /// @return the canonical type which has the representation @p name,
3966 /// and which is at index @p index in the vector of canonical types
3967 /// having that same textual representation.
3968 type_base*
get_canonical_type(const char * name,unsigned index)3969 environment::get_canonical_type(const char* name, unsigned index)
3970 {
3971   vector<type_base_sptr> *types = get_canonical_types(name);
3972   if (!types ||index >= types->size())
3973     return nullptr;
3974   return (*types)[index].get();
3975 }
3976 
3977 #ifdef WITH_DEBUG_SELF_COMPARISON
3978 /// Get the set of abixml type-id and the pointer value of the
3979 /// (canonical) type it's associated to.
3980 ///
3981 /// This is useful for debugging purposes, especially in the context
3982 /// of the use of the command:
3983 ///   'abidw --debug-abidiff <binary>'.
3984 ///
3985 /// @return the set of abixml type-id and the pointer value of the
3986 /// (canonical) type it's associated to.
3987 const unordered_map<string, uintptr_t>&
get_type_id_canonical_type_map() const3988 environment::get_type_id_canonical_type_map() const
3989 {return priv_->get_type_id_canonical_type_map();}
3990 
3991 /// Get the set of abixml type-id and the pointer value of the
3992 /// (canonical) type it's associated to.
3993 ///
3994 /// This is useful for debugging purposes, especially in the context
3995 /// of the use of the command:
3996 ///   'abidw --debug-abidiff <binary>'.
3997 ///
3998 /// @return the set of abixml type-id and the pointer value of the
3999 /// (canonical) type it's associated to.
4000 unordered_map<string, uintptr_t>&
get_type_id_canonical_type_map()4001 environment::get_type_id_canonical_type_map()
4002 {return priv_->get_type_id_canonical_type_map();}
4003 
4004 /// Getter of the map that associates the values of type pointers to
4005 /// their type-id strings.
4006 ///
4007 /// Note that this map is populated at abixml reading time, (by
4008 /// build_type()) when a given XML element representing a type is
4009 /// read into a corresponding abigail::ir::type_base.
4010 ///
4011 /// This is used only for the purpose of debugging the
4012 /// self-comparison process.  That is, when invoking "abidw
4013 /// --debug-abidiff".
4014 ///
4015 /// @return the map that associates the values of type pointers to
4016 /// their type-id strings.
4017 const unordered_map<uintptr_t, string>&
get_pointer_type_id_map() const4018 environment::get_pointer_type_id_map() const
4019 {return priv_->get_pointer_type_id_map();}
4020 
4021 /// Getter of the map that associates the values of type pointers to
4022 /// their type-id strings.
4023 ///
4024 /// Note that this map is populated at abixml reading time, (by
4025 /// build_type()) when a given XML element representing a type is
4026 /// read into a corresponding abigail::ir::type_base.
4027 ///
4028 /// This is used only for the purpose of debugging the
4029 /// self-comparison process.  That is, when invoking "abidw
4030 /// --debug-abidiff".
4031 ///
4032 /// @return the map that associates the values of type pointers to
4033 /// their type-id strings.
4034 unordered_map<uintptr_t, string>&
get_pointer_type_id_map()4035 environment::get_pointer_type_id_map()
4036 {return priv_->get_pointer_type_id_map();}
4037 
4038 /// Getter of the type-id that corresponds to the value of a pointer
4039 /// to abigail::ir::type_base that was created from the abixml reader.
4040 ///
4041 /// That value is retrieved from the map returned from
4042 /// environment::get_pointer_type_id_map().
4043 ///
4044 /// That map is populated at abixml reading time, (by build_type())
4045 /// when a given XML element representing a type is read into a
4046 /// corresponding abigail::ir::type_base.
4047 ///
4048 /// This is used only for the purpose of debugging the
4049 /// self-comparison process.  That is, when invoking "abidw
4050 /// --debug-abidiff".
4051 ///
4052 /// @return the type-id strings that corresponds
4053 string
get_type_id_from_pointer(uintptr_t ptr) const4054 environment::get_type_id_from_pointer(uintptr_t ptr) const
4055 {return priv_->get_type_id_from_pointer(ptr);}
4056 
4057 /// Getter of the type-id that corresponds to the value of an
4058 /// abigail::ir::type_base that was created from the abixml reader.
4059 ///
4060 /// That value is retrieved from the map returned from
4061 /// environment::get_pointer_type_id_map().
4062 ///
4063 /// That map is populated at abixml reading time, (by build_type())
4064 /// when a given XML element representing a type is read into a
4065 /// corresponding abigail::ir::type_base.
4066 ///
4067 /// This is used only for the purpose of debugging the
4068 /// self-comparison process.  That is, when invoking "abidw
4069 /// --debug-abidiff".
4070 ///
4071 /// @return the type-id strings that corresponds
4072 string
get_type_id_from_type(const type_base * t) const4073 environment::get_type_id_from_type(const type_base *t) const
4074 {return priv_->get_type_id_from_type(t);}
4075 
4076 /// Getter of the canonical type of the artifact designated by a
4077 /// type-id.
4078 ///
4079 /// That type-id was generated by the abixml writer at the emitting
4080 /// time of the abixml file.  The corresponding canonical type was
4081 /// stored in the map returned by
4082 /// environment::get_type_id_canonical_type_map().
4083 ///
4084 /// This is useful for debugging purposes, especially in the context
4085 /// of the use of the command:
4086 ///   'abidw --debug-abidiff <binary>'.
4087 ///
4088 /// @return the set of abixml type-id and the pointer value of the
4089 /// (canonical) type it's associated to.
4090 uintptr_t
get_canonical_type_from_type_id(const char * type_id) const4091 environment::get_canonical_type_from_type_id(const char* type_id) const
4092 {return priv_->get_canonical_type_from_type_id(type_id);}
4093 #endif
4094 
4095 // </environment stuff>
4096 
4097 // <type_or_decl_base stuff>
4098 
4099 /// The private data of @ref type_or_decl_base.
4100 struct type_or_decl_base::priv
4101 {
4102   // This holds the kind of dynamic type of particular instance.
4103   // Yes, this is part of the implementation of a "poor man" runtime
4104   // type identification.  We are doing this because profiling shows
4105   // that using dynamic_cast in some places is really to slow and is
4106   // constituting a hotspot.  This poor man's implementation made
4107   // things be much faster.
4108   enum type_or_decl_kind	kind_;
4109   // This holds the runtime type instance pointer of particular
4110   // instance.  In other words, this is the "this pointer" of the
4111   // dynamic type of a particular instance.
4112   void*			rtti_;
4113   // This holds a pointer to either the type_base sub-object (if the
4114   // current instance is a type) or the decl_base sub-object (if the
4115   // current instance is a decl).  This is used by the is_decl() and
4116   // is_type() functions, which also show up during profiling as
4117   // hotspots, due to their use of dynamic_cast.
4118   void*			type_or_decl_ptr_;
4119   bool				hashing_started_;
4120   const environment&		env_;
4121   translation_unit*		translation_unit_;
4122   // The location of an artifact as seen from its input by the
4123   // artifact reader.  This might be different from the source
4124   // location advertised by the original emitter of the artifact
4125   // emitter.
4126   location			artificial_location_;
4127   // Flags if the current ABI artifact is artificial (i.e, *NOT*
4128   // generated from the initial source code, but rather either
4129   // artificially by the compiler or by libabigail itself).
4130   bool				is_artificial_;
4131 
4132   /// Constructor of the type_or_decl_base::priv private type.
4133   ///
4134   /// @param e the environment in which the ABI artifact was created.
4135   ///
4136   /// @param k the identifier of the runtime type of the current
4137   /// instance of ABI artifact.
privabigail::ir::type_or_decl_base::priv4138   priv(const environment& e,
4139        enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL)
4140     : kind_(k),
4141       rtti_(),
4142       type_or_decl_ptr_(),
4143       hashing_started_(),
4144       env_(e),
4145       translation_unit_(),
4146       is_artificial_()
4147   {}
4148 
4149   enum type_or_decl_kind
kindabigail::ir::type_or_decl_base::priv4150   kind() const
4151   {return kind_;}
4152 
4153   void
kindabigail::ir::type_or_decl_base::priv4154   kind (enum type_or_decl_kind k)
4155   {kind_ |= k;}
4156 }; // end struct type_or_decl_base::priv
4157 
4158 /// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
4159 /// bitmap type.
4160 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)4161 operator|(type_or_decl_base::type_or_decl_kind l,
4162 	  type_or_decl_base::type_or_decl_kind r)
4163 {
4164   return static_cast<type_or_decl_base::type_or_decl_kind>
4165     (static_cast<unsigned>(l) | static_cast<unsigned>(r));
4166 }
4167 
4168 /// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
4169 /// bitmap type.
4170 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)4171 operator|=(type_or_decl_base::type_or_decl_kind& l,
4172 	   type_or_decl_base::type_or_decl_kind r)
4173 {
4174   l = l | r;
4175   return l;
4176 }
4177 
4178 /// bitwise "AND" operator for the
4179 /// type_or_decl_base::type_or_decl_kind bitmap type.
4180 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)4181 operator&(type_or_decl_base::type_or_decl_kind l,
4182 	  type_or_decl_base::type_or_decl_kind r)
4183 {
4184   return static_cast<type_or_decl_base::type_or_decl_kind>
4185     (static_cast<unsigned>(l) & static_cast<unsigned>(r));
4186 }
4187 
4188 /// bitwise "A&=" operator for the
4189 /// type_or_decl_base::type_or_decl_kind bitmap type.
4190 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)4191 operator&=(type_or_decl_base::type_or_decl_kind& l,
4192 	  type_or_decl_base::type_or_decl_kind r)
4193 {
4194   l = l & r;
4195   return l;
4196 }
4197 
4198 /// Constructor of @ref type_or_decl_base.
4199 ///
4200 /// @param the environment the current ABI artifact is constructed
4201 /// from.
4202 ///
4203 /// @param k the runtime identifier bitmap of the type being built.
type_or_decl_base(const environment & e,enum type_or_decl_kind k)4204 type_or_decl_base::type_or_decl_base(const environment& e,
4205 				     enum type_or_decl_kind k)
4206   :priv_(new priv(e, k))
4207 {}
4208 
4209 /// The destructor of the @ref type_or_decl_base type.
~type_or_decl_base()4210 type_or_decl_base::~type_or_decl_base()
4211 {}
4212 
4213 /// Getter of the flag that says if the artefact is artificial.
4214 ///
4215 /// Being artificial means it was not explicitely mentionned in the
4216 /// source code, but was rather artificially created by the compiler
4217 /// or libabigail.
4218 ///
4219 /// @return true iff the declaration is artificial.
4220 bool
get_is_artificial() const4221 type_or_decl_base::get_is_artificial() const
4222 {return priv_->is_artificial_;}
4223 
4224 /// Setter of the flag that says if the artefact is artificial.
4225 ///
4226 /// Being artificial means the artefact was not explicitely
4227 /// mentionned in the source code, but was rather artificially created
4228 /// by the compiler or by libabigail.
4229 ///
4230 /// @param f the new value of the flag that says if the artefact is
4231 /// artificial.
4232 void
set_is_artificial(bool f)4233 type_or_decl_base::set_is_artificial(bool f)
4234 {priv_->is_artificial_ = f;}
4235 
4236 /// Getter for the "kind" property of @ref type_or_decl_base type.
4237 ///
4238 /// This property holds the identifier bitmap of the runtime type of
4239 /// an ABI artifact.
4240 ///
4241 /// @return the runtime type identifier bitmap of the current ABI
4242 /// artifact.
4243 enum type_or_decl_base::type_or_decl_kind
kind() const4244 type_or_decl_base::kind() const
4245 {return priv_->kind();}
4246 
4247 /// Setter for the "kind" property of @ref type_or_decl_base type.
4248 ///
4249 /// This property holds the identifier bitmap of the runtime type of
4250 /// an ABI artifact.
4251 ///
4252 /// @param the runtime type identifier bitmap of the current ABI
4253 /// artifact.
4254 void
kind(enum type_or_decl_kind k)4255 type_or_decl_base::kind(enum type_or_decl_kind k)
4256 {priv_->kind(k);}
4257 
4258 /// Getter of the pointer to the runtime type sub-object of the
4259 /// current instance.
4260 ///
4261 /// @return the pointer to the runtime type sub-object of the current
4262 /// instance.
4263 const void*
runtime_type_instance() const4264 type_or_decl_base::runtime_type_instance() const
4265 {return priv_->rtti_;}
4266 
4267 /// Getter of the pointer to the runtime type sub-object of the
4268 /// current instance.
4269 ///
4270 /// @return the pointer to the runtime type sub-object of the current
4271 /// instance.
4272 void*
runtime_type_instance()4273 type_or_decl_base::runtime_type_instance()
4274 {return priv_->rtti_;}
4275 
4276 /// Setter of the pointer to the runtime type sub-object of the
4277 /// current instance.
4278 ///
4279 /// @param i the new pointer to the runtime type sub-object of the
4280 /// current instance.
4281 void
runtime_type_instance(void * i)4282 type_or_decl_base::runtime_type_instance(void* i)
4283 {
4284   priv_->rtti_ = i;
4285   if (type_base* t = dynamic_cast<type_base*>(this))
4286     priv_->type_or_decl_ptr_ = t;
4287   else if (decl_base *d = dynamic_cast<decl_base*>(this))
4288     priv_->type_or_decl_ptr_ = d;
4289 }
4290 
4291 /// Getter of the pointer to either the type_base sub-object of the
4292 /// current instance if it's a type, or to the decl_base sub-object of
4293 /// the current instance if it's a decl.
4294 ///
4295 /// @return the pointer to either the type_base sub-object of the
4296 /// current instance if it's a type, or to the decl_base sub-object of
4297 /// the current instance if it's a decl.
4298 const void*
type_or_decl_base_pointer() const4299 type_or_decl_base::type_or_decl_base_pointer() const
4300 {return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
4301 
4302 /// Getter of the pointer to either the type_base sub-object of the
4303 /// current instance if it's a type, or to the decl_base sub-object of
4304 /// the current instance if it's a decl.
4305 ///
4306 /// @return the pointer to either the type_base sub-object of the
4307 /// current instance if it's a type, or to the decl_base sub-object of
4308 /// the current instance if it's a decl.
4309 void*
type_or_decl_base_pointer()4310 type_or_decl_base::type_or_decl_base_pointer()
4311 {return priv_->type_or_decl_ptr_;}
4312 
4313 /// Getter for the 'hashing_started' property.
4314 ///
4315 /// @return the 'hashing_started' property.
4316 bool
hashing_started() const4317 type_or_decl_base::hashing_started() const
4318 {return priv_->hashing_started_;}
4319 
4320 /// Setter for the 'hashing_started' property.
4321 ///
4322 /// @param b the value to set the 'hashing_property' to.
4323 void
hashing_started(bool b) const4324 type_or_decl_base::hashing_started(bool b) const
4325 {priv_->hashing_started_ = b;}
4326 
4327 /// Getter of the environment of the current ABI artifact.
4328 ///
4329 /// @return the environment of the artifact.
4330 const environment&
get_environment() const4331 type_or_decl_base::get_environment() const
4332 {return priv_->env_;}
4333 
4334 /// Setter of the artificial location of the artificat.
4335 ///
4336 /// The artificial location is a location that was artificially
4337 /// generated by libabigail, not generated by the original emitter of
4338 /// the ABI meta-data.  For instance, when reading an XML element from
4339 /// an abixml file, the artificial location is the source location of
4340 /// the XML element within the file, not the value of the
4341 /// 'location'property that might be carried by the element.
4342 ///
4343 /// Artificial locations might be useful to ensure that abixml emitted
4344 /// by the abixml writer are sorted the same way as the input abixml
4345 /// read by the reader.
4346 ///
4347 /// @param l the new artificial location.
4348 void
set_artificial_location(const location & l)4349 type_or_decl_base::set_artificial_location(const location &l)
4350 {priv_->artificial_location_ = l;}
4351 
4352 /// Getter of the artificial location of the artifact.
4353 ///
4354 /// The artificial location is a location that was artificially
4355 /// generated by libabigail, not generated by the original emitter of
4356 /// the ABI meta-data.  For instance, when reading an XML element from
4357 /// an abixml file, the artificial location is the source location of
4358 /// the XML element within the file, not the value of the
4359 /// 'location'property that might be carried by the element.
4360 ///
4361 /// Artificial locations might be useful to ensure that the abixml
4362 /// emitted by the abixml writer is sorted the same way as the input
4363 /// abixml read by the reader.
4364 ///
4365 /// @return the new artificial location.
4366 location&
get_artificial_location() const4367 type_or_decl_base::get_artificial_location() const
4368 {return priv_->artificial_location_;}
4369 
4370 /// Test if the current ABI artifact carries an artificial location.
4371 ///
4372 /// @return true iff the current ABI artifact carries an artificial location.
4373 bool
has_artificial_location() const4374 type_or_decl_base::has_artificial_location() const
4375 {
4376   return (priv_->artificial_location_
4377 	  && priv_->artificial_location_.get_is_artificial());
4378 }
4379 
4380 /// Get the @ref corpus this ABI artifact belongs to.
4381 ///
4382 /// @return the corpus this ABI artifact belongs to, or nil if it
4383 /// belongs to none for now.
4384 corpus*
get_corpus()4385 type_or_decl_base::get_corpus()
4386 {
4387   translation_unit* tu = get_translation_unit();
4388   if (!tu)
4389     return 0;
4390   return tu->get_corpus();
4391 }
4392 
4393 
4394 /// Get the @ref corpus this ABI artifact belongs to.
4395 ///
4396 /// @return the corpus this ABI artifact belongs to, or nil if it
4397 /// belongs to none for now.
4398 const corpus*
get_corpus() const4399 type_or_decl_base::get_corpus() const
4400 {return const_cast<type_or_decl_base*>(this)->get_corpus();}
4401 
4402 /// Set the @ref translation_unit this ABI artifact belongs to.
4403 ///
4404 /// Note that adding an ABI artifact to a containining on should
4405 /// invoke this member function.
4406 void
set_translation_unit(translation_unit * tu)4407 type_or_decl_base::set_translation_unit(translation_unit* tu)
4408 {priv_->translation_unit_ = tu;}
4409 
4410 
4411 /// Get the @ref translation_unit this ABI artifact belongs to.
4412 ///
4413 /// @return the translation unit this ABI artifact belongs to, or nil
4414 /// if belongs to none for now.
4415 translation_unit*
get_translation_unit()4416 type_or_decl_base::get_translation_unit()
4417 {return priv_->translation_unit_;}
4418 
4419 /// Get the @ref translation_unit this ABI artifact belongs to.
4420 ///
4421 /// @return the translation unit this ABI artifact belongs to, or nil
4422 /// if belongs to none for now.
4423 const translation_unit*
get_translation_unit() const4424 type_or_decl_base::get_translation_unit() const
4425 {return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
4426 
4427 /// Traverse the the ABI artifact.
4428 ///
4429 /// @param v the visitor used to traverse the sub-tree nodes of the
4430 /// artifact.
4431 bool
traverse(ir_node_visitor &)4432 type_or_decl_base::traverse(ir_node_visitor&)
4433 {return true;}
4434 
4435 /// Non-member equality operator for the @type_or_decl_base type.
4436 ///
4437 /// @param lr the left-hand operand of the equality.
4438 ///
4439 /// @param rr the right-hand operatnr of the equality.
4440 ///
4441 /// @return true iff @p lr equals @p rr.
4442 bool
operator ==(const type_or_decl_base & lr,const type_or_decl_base & rr)4443 operator==(const type_or_decl_base& lr, const type_or_decl_base& rr)
4444 {
4445   const type_or_decl_base* l = &lr;
4446   const type_or_decl_base* r = &rr;
4447 
4448   const decl_base* dl = dynamic_cast<const decl_base*>(l),
4449     *dr = dynamic_cast<const decl_base*>(r);
4450 
4451   if (!!dl != !!dr)
4452     return false;
4453 
4454   if (dl && dr)
4455     return *dl == *dr;
4456 
4457   const type_base* tl = dynamic_cast<const type_base*>(l),
4458     *tr = dynamic_cast<const type_base*>(r);
4459 
4460   if (!!tl != !!tr)
4461     return false;
4462 
4463   if (tl && tr)
4464     return *tl == *tr;
4465 
4466   return false;
4467 }
4468 
4469 /// Non-member equality operator for the @type_or_decl_base type.
4470 ///
4471 /// @param l the left-hand operand of the equality.
4472 ///
4473 /// @param r the right-hand operatnr of the equality.
4474 ///
4475 /// @return true iff @p l equals @p r.
4476 bool
operator ==(const type_or_decl_base_sptr & l,const type_or_decl_base_sptr & r)4477 operator==(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
4478 {
4479   if (!! l != !!r)
4480     return false;
4481 
4482   if (!l)
4483     return true;
4484 
4485   return *r == *l;
4486 }
4487 
4488 /// Non-member inequality operator for the @type_or_decl_base type.
4489 ///
4490 /// @param l the left-hand operand of the equality.
4491 ///
4492 /// @param r the right-hand operator of the equality.
4493 ///
4494 /// @return true iff @p l is different from @p r.
4495 bool
operator !=(const type_or_decl_base_sptr & l,const type_or_decl_base_sptr & r)4496 operator!=(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
4497 {return !operator==(l, r);}
4498 
4499 // </type_or_decl_base stuff>
4500 
4501 // <Decl definition>
4502 
4503 struct decl_base::priv
4504 {
4505   bool			in_pub_sym_tab_;
4506   bool			is_anonymous_;
4507   location		location_;
4508   context_rel		*context_;
4509   interned_string	name_;
4510   interned_string	qualified_parent_name_;
4511   // This temporary qualified name is the cache used for the qualified
4512   // name before the type associated to this decl (if applicable) is
4513   // canonicalized.  Once the type is canonicalized, the cached use is
4514   // the data member qualified_parent_name_ above.
4515   interned_string	temporary_qualified_name_;
4516   // This is the fully qualified name of the decl.  It contains the
4517   // name of the decl and the qualified name of its scope.  So if in
4518   // the parent scopes of the decl, there is one anonymous struct,
4519   // somewhere in the name, there is going to by an
4520   // __anonymous_struct__ string, even if the anonymous struct is not
4521   // the direct containing scope of this decl.
4522   interned_string	qualified_name_;
4523   interned_string	temporary_internal_qualified_name_;
4524   interned_string	internal_qualified_name_;
4525   // Unline qualified_name_, scoped_name_ contains the name of the
4526   // decl and the name of its scope; not the qualified name of the
4527   // scope.
4528   interned_string	scoped_name_;
4529   interned_string	linkage_name_;
4530   visibility		visibility_;
4531   decl_base_sptr	declaration_;
4532   decl_base_wptr	definition_of_declaration_;
4533   decl_base*		naked_definition_of_declaration_;
4534   bool			is_declaration_only_;
4535   typedef_decl_sptr	naming_typedef_;
4536 
privabigail::ir::decl_base::priv4537   priv()
4538     : in_pub_sym_tab_(false),
4539       is_anonymous_(true),
4540       context_(),
4541       visibility_(VISIBILITY_DEFAULT),
4542       naked_definition_of_declaration_(),
4543       is_declaration_only_(false)
4544   {}
4545 
privabigail::ir::decl_base::priv4546   priv(interned_string name, interned_string linkage_name, visibility vis)
4547     : in_pub_sym_tab_(false),
4548       context_(),
4549       name_(name),
4550       qualified_name_(name),
4551       linkage_name_(linkage_name),
4552       visibility_(vis),
4553       naked_definition_of_declaration_(),
4554       is_declaration_only_(false)
4555   {
4556     is_anonymous_ = name_.empty();
4557   }
4558 
~privabigail::ir::decl_base::priv4559   ~priv()
4560   {
4561     delete context_;
4562   }
4563 };// end struct decl_base::priv
4564 
4565 /// Constructor for the @ref decl_base type.
4566 ///
4567 /// @param e the environment the current @ref decl_base is being
4568 /// created in.
4569 ///
4570 /// @param name the name of the declaration.
4571 ///
4572 /// @param locus the location where to find the declaration in the
4573 /// source code.
4574 ///
4575 /// @param linkage_name the linkage name of the declaration.
4576 ///
4577 /// @param vis the visibility of the declaration.
decl_base(const environment & e,const string & name,const location & locus,const string & linkage_name,visibility vis)4578 decl_base::decl_base(const environment& e,
4579 		     const string&	name,
4580 		     const location&	locus,
4581 		     const string&	linkage_name,
4582 		     visibility	vis)
4583   : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4584     priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4585 {
4586   set_location(locus);
4587 }
4588 
4589 /// Constructor.
4590 ///
4591 /// @param e the environment this instance of @ref decl_base is
4592 /// created in.
4593 ///
4594 /// @param name the name of the declaration being constructed.
4595 ///
4596 /// @param locus the source location of the declaration being constructed.
4597 ///
4598 /// @param linkage_name the linkage name of the declaration being
4599 /// constructed.
4600 ///
4601 /// @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)4602 decl_base::decl_base(const environment& e,
4603 		     const interned_string& name,
4604 		     const location& locus,
4605 		     const interned_string& linkage_name,
4606 		     visibility vis)
4607   : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4608     priv_(new priv(name, linkage_name, vis))
4609 {
4610   set_location(locus);
4611 }
4612 
4613 /// Constructor for the @ref decl_base type.
4614 ///
4615 ///@param environment the environment this instance of @ref decl_base
4616 /// is being constructed in.
4617 ///
4618 /// @param l the location where to find the declaration in the source
4619 /// code.
decl_base(const environment & e,const location & l)4620 decl_base::decl_base(const environment& e, const location& l)
4621   : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4622     priv_(new priv())
4623 {
4624   set_location(l);
4625 }
4626 
4627 /// Getter for the qualified name.
4628 ///
4629 /// Unlike decl_base::get_qualified_name() this doesn't try to update
4630 /// the qualified name.
4631 ///
4632 /// @return the qualified name.
4633 const interned_string&
peek_qualified_name() const4634 decl_base::peek_qualified_name() const
4635 {return priv_->qualified_name_;}
4636 
4637 /// Clear the qualified name of this decl.
4638 ///
4639 /// This is useful to ensure that the cache for the qualified name of
4640 /// the decl is refreshed right after type canonicalization, for
4641 /// instance.
4642 void
clear_qualified_name()4643 decl_base::clear_qualified_name()
4644 {priv_->qualified_name_.clear();}
4645 
4646 /// Setter for the qualified name.
4647 ///
4648 /// @param n the new qualified name.
4649 void
set_qualified_name(const interned_string & n) const4650 decl_base::set_qualified_name(const interned_string& n) const
4651 {priv_->qualified_name_ = n;}
4652 
4653 /// Getter of the temporary qualified name of the current declaration.
4654 ///
4655 /// This temporary qualified name is used as a qualified name cache by
4656 /// the type for which this is the declaration (when applicable)
4657 /// before the type is canonicalized.  Once the type is canonicalized,
4658 /// it's the result of decl_base::peek_qualified_name() that becomes
4659 /// the qualified name cached.
4660 ///
4661 /// @return the temporary qualified name.
4662 const interned_string&
peek_temporary_qualified_name() const4663 decl_base::peek_temporary_qualified_name() const
4664 {return priv_->temporary_qualified_name_;}
4665 
4666 /// Setter for the temporary qualified name of the current
4667 /// declaration.
4668 ///
4669 ///@param n the new temporary qualified name.
4670 ///
4671 /// This temporary qualified name is used as a qualified name cache by
4672 /// the type for which this is the declaration (when applicable)
4673 /// before the type is canonicalized.  Once the type is canonicalized,
4674 /// it's the result of decl_base::peek_qualified_name() that becomes
4675 /// the qualified name cached.
4676 void
set_temporary_qualified_name(const interned_string & n) const4677 decl_base::set_temporary_qualified_name(const interned_string& n) const
4678 {priv_->temporary_qualified_name_ = n;}
4679 
4680 ///Getter for the context relationship.
4681 ///
4682 ///@return the context relationship for the current decl_base.
4683 const context_rel*
get_context_rel() const4684 decl_base::get_context_rel() const
4685 {return priv_->context_;}
4686 
4687 ///Getter for the context relationship.
4688 ///
4689 ///@return the context relationship for the current decl_base.
4690 context_rel*
get_context_rel()4691 decl_base::get_context_rel()
4692 {return priv_->context_;}
4693 
4694 void
set_context_rel(context_rel * c)4695 decl_base::set_context_rel(context_rel *c)
4696 {priv_->context_ = c;}
4697 
4698 /// Get the hash of a decl.  If the hash hasn't been computed yet,
4699 /// compute it ans store its value; otherwise, just return the hash.
4700 ///
4701 /// @return the hash of the decl.
4702 size_t
get_hash() const4703 decl_base::get_hash() const
4704 {
4705   size_t result = 0;
4706 
4707   if (const type_base* t = dynamic_cast<const type_base*>(this))
4708     {
4709       type_base::dynamic_hash hash;
4710       result = hash(t);
4711     }
4712   else
4713     // If we reach this point, it mean we are missing a virtual
4714     // overload for decl_base::get_hash.  Add it!
4715     abort();
4716 
4717   return result;
4718 }
4719 
4720 /// Test if the decl is defined in a ELF symbol table as a public
4721 /// symbol.
4722 ///
4723 /// @return true iff the decl is defined in a ELF symbol table as a
4724 /// public symbol.
4725 bool
get_is_in_public_symbol_table() const4726 decl_base::get_is_in_public_symbol_table() const
4727 {return priv_->in_pub_sym_tab_;}
4728 
4729 /// Set the flag saying if this decl is from a symbol that is in
4730 /// a public symbols table, defined as public (global or weak).
4731 ///
4732 /// @param f the new flag value.
4733 void
set_is_in_public_symbol_table(bool f)4734 decl_base::set_is_in_public_symbol_table(bool f)
4735 {priv_->in_pub_sym_tab_ = f;}
4736 
4737 /// Get the location of a given declaration.
4738 ///
4739 /// The location is an abstraction for the tripplet {file path,
4740 /// line, column} that defines where the declaration appeared in the
4741 /// source code.
4742 ///
4743 /// To get the value of the tripplet {file path, line, column} from
4744 /// the @ref location, you need to use the
4745 /// location_manager::expand_location() method.
4746 ///
4747 /// The instance of @ref location_manager that you want is
4748 /// accessible from the instance of @ref translation_unit that the
4749 /// current instance of @ref decl_base belongs to, via a call to
4750 /// translation_unit::get_loc_mgr().
4751 ///
4752 /// @return the location of the current instance of @ref decl_base.
4753 const location&
get_location() const4754 decl_base::get_location() const
4755 {return priv_->location_;}
4756 
4757 /// Set the location for a given declaration.
4758 ///
4759 /// The location is an abstraction for the tripplet {file path,
4760 /// line, column} that defines where the declaration appeared in the
4761 /// source code.
4762 ///
4763 /// To create a location from a tripplet {file path, line, column},
4764 /// you need to use the method @ref
4765 /// location_manager::create_new_location().
4766 ///
4767 /// Note that there can be two kinds of location.  An artificial
4768 /// location and a non-artificial one.  The non-artificial location is
4769 /// the one emitted by the original emitter of the ABI artifact, for
4770 /// instance, if the ABI artifact comes from debug info, then the
4771 /// source location that is present in the debug info represent a
4772 /// non-artificial location.  When looking at an abixml file on the
4773 /// other hand, the value of the 'location' attribute of an XML
4774 /// element describing an artifact is the non-artificial location.
4775 /// The artificial location is the location (line number from the
4776 /// beginning of the file) of the XML element within the abixml file.
4777 ///
4778 /// So, if the location that is being set is artificial, note that the
4779 /// type_or_decl_base::has_artificial_location() method of this decl will
4780 /// subsequently return true and that artificial location will have to
4781 /// be retrieved using type_or_decl_base::get_artificial_location().
4782 /// If the location is non-artificial however,
4783 /// type_or_decl_base::has_artificial_location() will subsequently
4784 /// return false and the non-artificial location will have to be
4785 /// retrieved using decl_base::get_location().
4786 ///
4787 /// The instance of @ref location_manager that you want is
4788 /// accessible from the instance of @ref translation_unit that the
4789 /// current instance of @ref decl_base belongs to, via a call to
4790 /// translation_unit::get_loc_mgr().
4791 void
set_location(const location & l)4792 decl_base::set_location(const location& l)
4793 {
4794   if (l.get_is_artificial())
4795     set_artificial_location(l);
4796   else
4797     priv_->location_ = l;
4798 }
4799 
4800 /// Setter for the name of the decl.
4801 ///
4802 /// @param n the new name to set.
4803 void
set_name(const string & n)4804 decl_base::set_name(const string& n)
4805 {
4806   priv_->name_ = get_environment().intern(n);
4807   priv_->is_anonymous_ = n.empty();
4808 }
4809 
4810 /// Test if the current declaration is anonymous.
4811 ///
4812 /// Being anonymous means that the declaration was created without a
4813 /// name.  This can usually happen for enum or struct types.
4814 ///
4815 /// @return true iff the type is anonymous.
4816 bool
get_is_anonymous() const4817 decl_base::get_is_anonymous() const
4818 {return priv_->is_anonymous_;}
4819 
4820 /// Set the "is_anonymous" flag of the current declaration.
4821 ///
4822 /// Being anonymous means that the declaration was created without a
4823 /// name.  This can usually happen for enum or struct types.
4824 ///
4825 /// @param f the new value of the flag.
4826 void
set_is_anonymous(bool f)4827 decl_base::set_is_anonymous(bool f)
4828 {priv_->is_anonymous_ = f;}
4829 
4830 
4831 /// Get the "has_anonymous_parent" flag of the current declaration.
4832 ///
4833 /// Having an anoymous parent means having a anonymous parent scope
4834 /// (containing type or namespace) which is either direct or indirect.
4835 ///
4836 /// @return true iff the current decl has a direct or indirect scope
4837 /// which is anonymous.
4838 bool
get_has_anonymous_parent() const4839 decl_base::get_has_anonymous_parent() const
4840 {
4841   scope_decl *scope = get_scope();
4842   if (!scope)
4843     return false;
4844   return scope->get_is_anonymous();
4845 }
4846 
4847 /// @return the logical "OR" of decl_base::get_is_anonymous() and
4848 /// decl_base::get_has_anonymous_parent().
4849 bool
get_is_anonymous_or_has_anonymous_parent() const4850 decl_base::get_is_anonymous_or_has_anonymous_parent() const
4851 {return get_is_anonymous() || get_has_anonymous_parent();}
4852 
4853 /// Getter for the naming typedef of the current decl.
4854 ///
4855 /// Consider the C idiom:
4856 ///
4857 ///    typedef struct {int member;} foo_type;
4858 ///
4859 /// In that idiom, foo_type is the naming typedef of the anonymous
4860 /// struct that is declared.
4861 ///
4862 /// @return the naming typedef, if any.  Otherwise, returns nil.
4863 typedef_decl_sptr
get_naming_typedef() const4864 decl_base::get_naming_typedef() const
4865 {return priv_->naming_typedef_;}
4866 
4867 /// Set the naming typedef of the current instance of @ref decl_base.
4868 ///
4869 /// Consider the C idiom:
4870 ///
4871 ///    typedef struct {int member;} foo_type;
4872 ///
4873 /// In that idiom, foo_type is the naming typedef of the anonymous
4874 /// struct that is declared.
4875 ///
4876 /// After completion of this function, the decl will not be considered
4877 /// anonymous anymore.  It's name is going to be the name of the
4878 /// naming typedef.
4879 ///
4880 /// @param typedef_type the new naming typedef.
4881 void
set_naming_typedef(const typedef_decl_sptr & t)4882 decl_base::set_naming_typedef(const typedef_decl_sptr& t)
4883 {
4884   // A naming typedef is usually for an anonymous type.
4885   ABG_ASSERT(get_is_anonymous()
4886 	     // Whe the typedef-named decl is saved into abixml, it's
4887 	     // not anonymous anymore.  Its name is the typedef name.
4888 	     // So when we read it back, we must still be able to
4889 	     // apply the naming typedef to the decl.
4890 	     || t->get_name() == get_name());
4891   // Only non canonicalized types can be edited this way.
4892   ABG_ASSERT(is_type(this)
4893 	     && is_type(this)->get_naked_canonical_type() == nullptr);
4894 
4895   priv_->naming_typedef_ = t;
4896   set_name(t->get_name());
4897   string qualified_name = build_qualified_name(get_scope(), t->get_name());
4898   set_qualified_name(get_environment().intern(qualified_name));
4899   set_is_anonymous(false);
4900   // Now that the qualified type of the decl has changed, let's update
4901   // the qualified names of the member types of this decls.
4902   update_qualified_name(this);
4903 }
4904 
4905 /// Getter for the mangled name.
4906 ///
4907 /// @return the new mangled name.
4908 const interned_string&
get_linkage_name() const4909 decl_base::get_linkage_name() const
4910 {return priv_->linkage_name_;}
4911 
4912 /// Setter for the linkage name.
4913 ///
4914 /// @param m the new linkage name.
4915 void
set_linkage_name(const string & m)4916 decl_base::set_linkage_name(const string& m)
4917 {
4918   const environment& env = get_environment();
4919   priv_->linkage_name_ = env.intern(m);
4920 }
4921 
4922 /// Getter for the visibility of the decl.
4923 ///
4924 /// @return the new visibility.
4925 decl_base::visibility
get_visibility() const4926 decl_base::get_visibility() const
4927 {return priv_->visibility_;}
4928 
4929 /// Setter for the visibility of the decl.
4930 ///
4931 /// @param v the new visibility.
4932 void
set_visibility(visibility v)4933 decl_base::set_visibility(visibility v)
4934 {priv_->visibility_ = v;}
4935 
4936 /// Return the type containing the current decl, if any.
4937 ///
4938 /// @return the type that contains the current decl, or NULL if there
4939 /// is none.
4940 scope_decl*
get_scope() const4941 decl_base::get_scope() const
4942 {
4943   if (priv_->context_)
4944     return priv_->context_->get_scope();
4945   return 0;
4946 }
4947 
4948 /// Return a copy of the qualified name of the parent of the current
4949 /// decl.
4950 ///
4951 /// @return the newly-built qualified name of the of the current decl.
4952 const interned_string&
get_qualified_parent_name() const4953 decl_base::get_qualified_parent_name() const
4954 {return priv_->qualified_parent_name_;}
4955 
4956 /// Getter for the name of the current decl.
4957 ///
4958 /// @return the name of the current decl.
4959 const interned_string&
get_name() const4960 decl_base::get_name() const
4961 {return priv_->name_;}
4962 
4963 /// Compute the qualified name of the decl.
4964 ///
4965 /// @param qn the resulting qualified name.
4966 ///
4967 /// @param internal set to true if the call is intended for an
4968 /// internal use (for technical use inside the library itself), false
4969 /// otherwise.  If you don't know what this is for, then set it to
4970 /// false.
4971 void
get_qualified_name(interned_string & qn,bool internal) const4972 decl_base::get_qualified_name(interned_string& qn, bool internal) const
4973 {qn = get_qualified_name(internal);}
4974 
4975 /// Get the pretty representatin of the current declaration.
4976 ///
4977 ///
4978 /// @param internal set to true if the call is intended to get a
4979 /// representation of the decl (or type) for the purpose of canonical
4980 /// type comparison.  This is mainly used in the function
4981 /// type_base::get_canonical_type_for().
4982 ///
4983 /// In other words if the argument for this parameter is true then the
4984 /// call is meant for internal use (for technical use inside the
4985 /// library itself), false otherwise.  If you don't know what this is
4986 /// for, then set it to false.
4987 ///
4988 /// @param qualified_name if true, names emitted in the pretty
4989 /// representation are fully qualified.
4990 ///
4991 /// @return the default pretty representation for a decl.  This is
4992 /// basically the fully qualified name of the decl optionally prefixed
4993 /// with a meaningful string to add context for the user.
4994 string
get_pretty_representation(bool internal,bool qualified_name) const4995 decl_base::get_pretty_representation(bool internal,
4996 				     bool qualified_name) const
4997 {
4998   if (internal
4999       && get_is_anonymous()
5000       && has_generic_anonymous_internal_type_name(this))
5001     {
5002       // We are looking at an anonymous enum, union or class and we
5003       // want an *internal* pretty representation for it.  All
5004       // anonymous types of this kind in the same namespace must have
5005       // the same internal representation for type canonicalization to
5006       // work properly.
5007       //
5008       // OK, in practise, we are certainly looking at an enum because
5009       // classes and unions should have their own overloaded virtual
5010       // member function for this.
5011       string name = get_generic_anonymous_internal_type_name(this);
5012       if (qualified_name && !get_qualified_parent_name().empty())
5013 	name = get_qualified_parent_name() + "::" + name;
5014       return name;
5015     }
5016 
5017   if (qualified_name)
5018     return get_qualified_name(internal);
5019   return get_name();
5020 }
5021 
5022 /// Return the qualified name of the decl.
5023 ///
5024 /// This is the fully qualified name of the decl.  It's made of the
5025 /// concatenation of the name of the decl with the qualified name of
5026 /// its scope.
5027 ///
5028 /// Note that the value returned by this function is computed by @ref
5029 /// update_qualified_name when the decl is added to its scope.
5030 ///
5031 /// @param internal set to true if the call is intended for an
5032 /// internal use (for technical use inside the library itself), false
5033 /// otherwise.  If you don't know what this is for, then set it to
5034 /// false.
5035 ///
5036 /// @return the resulting qualified name.
5037 const interned_string&
get_qualified_name(bool) const5038 decl_base::get_qualified_name(bool /*internal*/) const
5039 {return priv_->qualified_name_;}
5040 
5041 /// Return the scoped name of the decl.
5042 ///
5043 /// This is made of the concatenation of the name of the decl with the
5044 /// name of its scope.  It doesn't contain the qualified name of its
5045 /// scope, unlike what is returned by decl_base::get_qualified_name.
5046 ///
5047 /// Note that the value returned by this function is computed by @ref
5048 /// update_qualified_name when the decl is added to its scope.
5049 ///
5050 /// @return the scoped name of the decl.
5051 const interned_string&
get_scoped_name() const5052 decl_base::get_scoped_name() const
5053 {return priv_->scoped_name_;}
5054 
5055 /// If this @ref decl_base is a definition, get its earlier
5056 /// declaration.
5057 ///
5058 /// @return the earlier declaration of the class, if any.
5059 const decl_base_sptr
get_earlier_declaration() const5060 decl_base::get_earlier_declaration() const
5061 {return priv_->declaration_;}
5062 
5063 /// set the earlier declaration of this @ref decl_base definition.
5064 ///
5065 /// @param d the earlier declaration to set.  Note that it's set only
5066 /// if it's a pure declaration.
5067 void
set_earlier_declaration(const decl_base_sptr & d)5068 decl_base::set_earlier_declaration(const decl_base_sptr& d)
5069 {
5070   if (d && d->get_is_declaration_only())
5071     priv_->declaration_ = d;
5072 }
5073 
5074 
5075 /// If this @ref decl_base is declaration-only, get its definition, if
5076 /// any.
5077 ///
5078 /// @return the definition of this decl-only @ref decl_base.
5079 const decl_base_sptr
get_definition_of_declaration() const5080 decl_base::get_definition_of_declaration() const
5081 {return priv_->definition_of_declaration_.lock();}
5082 
5083 ///  If this @ref decl_base is declaration-only, get its definition,
5084 ///  if any.
5085 ///
5086 /// Note that this function doesn't return a smart pointer, but rather
5087 /// the underlying pointer managed by the smart pointer.  So it's as
5088 /// fast as possible.  This getter is to be used in code paths that
5089 /// are proven to be performance hot spots; especially, when comparing
5090 /// sensitive types like enums, classes or unions.  Those are compared
5091 /// extremely frequently and thus, their access to the definition of
5092 /// declaration must be fast.
5093 ///
5094 /// @return the definition of the declaration.
5095 const decl_base*
get_naked_definition_of_declaration() const5096 decl_base::get_naked_definition_of_declaration() const
5097 {return priv_->naked_definition_of_declaration_;}
5098 
5099 /// Test if a @ref decl_base is a declaration-only decl.
5100 ///
5101 /// @return true iff the current @ref decl_base is declaration-only.
5102 bool
get_is_declaration_only() const5103 decl_base::get_is_declaration_only() const
5104 {return priv_->is_declaration_only_;}
5105 
5106 /// Set a flag saying if the @ref enum_type_decl is a declaration-only
5107 /// @ref enum_type_decl.
5108 ///
5109 /// @param f true if the @ref enum_type_decl is a declaration-only
5110 /// @ref enum_type_decl.
5111 void
set_is_declaration_only(bool f)5112 decl_base::set_is_declaration_only(bool f)
5113 {
5114   bool update_types_lookup_map = !f && priv_->is_declaration_only_;
5115 
5116   priv_->is_declaration_only_ = f;
5117 
5118   if (update_types_lookup_map)
5119     if (scope_decl* s = get_scope())
5120       {
5121 	scope_decl::declarations::iterator i;
5122 	if (s->find_iterator_for_member(this, i))
5123 	  maybe_update_types_lookup_map(*i);
5124 	else
5125 	  ABG_ASSERT_NOT_REACHED;
5126       }
5127 }
5128 
5129 change_kind
operator |(change_kind l,change_kind r)5130 operator|(change_kind l, change_kind r)
5131 {
5132   return static_cast<change_kind>(static_cast<unsigned>(l)
5133 				  | static_cast<unsigned>(r));
5134 }
5135 
5136 change_kind
operator &(change_kind l,change_kind r)5137 operator&(change_kind l, change_kind r)
5138 {
5139   return static_cast<change_kind>(static_cast<unsigned>(l)
5140 				  & static_cast<unsigned>(r));
5141 }
5142 
5143 change_kind&
operator |=(change_kind & l,change_kind r)5144 operator|=(change_kind& l, change_kind r)
5145 {
5146   l = l | r;
5147   return l;
5148 }
5149 
5150 change_kind&
operator &=(change_kind & l,change_kind r)5151 operator&=(change_kind& l, change_kind r)
5152 {
5153   l = l & r;
5154   return l;
5155 }
5156 
5157 /// Compare the properties that belong to the "is-a-member-relation"
5158 /// of a decl.
5159 ///
5160 /// For instance, access specifiers are part of the
5161 /// "is-a-member-relation" of a decl.
5162 ///
5163 /// This comparison however doesn't take decl names into account.  So
5164 /// typedefs for instance are decls that we want to compare with this
5165 /// function.
5166 ///
5167 /// This function is a sub-routine of the more general 'equals'
5168 /// overload for instances of decl_base.
5169 ///
5170 /// @param l the left-hand side operand of the comparison.
5171 ///
5172 /// @param r the right-hand side operand of the comparison.
5173 ///
5174 /// @return true iff @p l compare equals, as a member decl, to @p r.
5175 bool
maybe_compare_as_member_decls(const decl_base & l,const decl_base & r,change_kind * k)5176 maybe_compare_as_member_decls(const decl_base& l,
5177 			      const decl_base& r,
5178 			      change_kind* k)
5179 {
5180   bool result = true;
5181   if (is_member_decl(l) && is_member_decl(r))
5182     {
5183       context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
5184       context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
5185 
5186       access_specifier la = no_access, ra = no_access;
5187       bool member_types_or_functions =
5188 	((is_type(l) && is_type(r))
5189 	 || (is_function_decl(l) && is_function_decl(r)));
5190 
5191       if (member_types_or_functions)
5192 	{
5193 	  // Access specifiers on member types in DWARF is not
5194 	  // reliable; in the same DSO, the same struct can be either
5195 	  // a class or a struct, and the access specifiers of its
5196 	  // member types are not necessarily given, so they
5197 	  // effectively can be considered differently, again, in the
5198 	  // same DSO.  So, here, let's avoid considering those!
5199 	  // during comparison.
5200 	  la = r1->get_access_specifier();
5201 	  ra = r2->get_access_specifier();
5202 	  r1->set_access_specifier(no_access);
5203 	  r2->set_access_specifier(no_access);
5204 	}
5205 
5206       bool rels_are_different = *r1 != *r2;
5207 
5208       if (member_types_or_functions)
5209 	{
5210 	  // restore the access specifiers.
5211 	  r1->set_access_specifier(la);
5212 	  r2->set_access_specifier(ra);
5213 	}
5214 
5215       if (rels_are_different)
5216 	{
5217 	  result = false;
5218 	  if (k)
5219 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
5220 	}
5221     }
5222   ABG_RETURN(result);
5223 }
5224 
5225 /// Get the name of a decl for the purpose of comparing two decl
5226 /// names.
5227 ///
5228 /// This is a sub-routine of the 'equal' overload for decl_base.
5229 ///
5230 /// This function takes into account the fact that all anonymous names
5231 /// shall have the same name for the purpose of comparison.
5232 ///
5233 /// For decls that are part of an anonymous scope, only the
5234 /// non-qualified name should be taken into account.
5235 static interned_string
get_decl_name_for_comparison(const decl_base & d)5236 get_decl_name_for_comparison(const decl_base &d)
5237 {
5238   if (has_generic_anonymous_internal_type_name(&d)
5239       && d.get_is_anonymous())
5240     {
5241       // The decl is anonymous.   It should have the same name ass the
5242       // other anymous types of the same kind.
5243       string r;
5244       r += get_generic_anonymous_internal_type_name(&d);
5245       return d.get_environment().intern(r);
5246     }
5247 
5248   interned_string n = (is_anonymous_or_typedef_named(d)
5249 		       || d.get_has_anonymous_parent()
5250 		       || is_typedef(&d))
5251     ? d.get_name()
5252     : d.get_qualified_name(/*internal=*/true);
5253   return n;
5254 }
5255 
5256 /// Compares two instances of @ref decl_base.
5257 ///
5258 /// If the two intances are different, set a bitfield to give some
5259 /// insight about the kind of differences there are.
5260 ///
5261 /// @param l the first artifact of the comparison.
5262 ///
5263 /// @param r the second artifact of the comparison.
5264 ///
5265 /// @param k a pointer to a bitfield that gives information about the
5266 /// kind of changes there are between @p l and @p r.  This one is set
5267 /// iff it's non-null and if the function returns false.
5268 ///
5269 /// Please note that setting k to a non-null value does have a
5270 /// negative performance impact because even if @p l and @p r are not
5271 /// equal, the function keeps up the comparison in order to determine
5272 /// the different kinds of ways in which they are different.
5273 ///
5274 /// @return true if @p l equals @p r, false otherwise.
5275 bool
equals(const decl_base & l,const decl_base & r,change_kind * k)5276 equals(const decl_base& l, const decl_base& r, change_kind* k)
5277 {
5278   bool result = true;
5279   const interned_string &l_linkage_name = l.get_linkage_name();
5280   const interned_string &r_linkage_name = r.get_linkage_name();
5281   if (!l_linkage_name.empty() && !r_linkage_name.empty())
5282     {
5283       if (l_linkage_name != r_linkage_name)
5284 	{
5285 	  // Linkage names are different.  That usually means the two
5286 	  // decls are different, unless we are looking at two
5287 	  // function declarations which have two different symbols
5288 	  // that are aliases of each other.
5289 	  const function_decl *f1 = is_function_decl(&l),
5290 	    *f2 = is_function_decl(&r);
5291 	  if (f1 && f2 && function_decls_alias(*f1, *f2))
5292 	    ;// The two functions are aliases, so they are not
5293 	     // different.
5294 	  else
5295 	    {
5296 	      result = false;
5297 	      if (k)
5298 		*k |= LOCAL_NON_TYPE_CHANGE_KIND;
5299 	      else
5300 		ABG_RETURN_FALSE;
5301 	    }
5302 	}
5303     }
5304 
5305   // This is the qualified name of the decls that we want to compare.
5306   // We want to use the "internal" version of the qualified name as
5307   // that one is stable even for anonymous decls.
5308   interned_string ln = get_decl_name_for_comparison(l);
5309   interned_string rn = get_decl_name_for_comparison(r);
5310 
5311   /// If both of the current decls have an anonymous scope then let's
5312   /// compare their name component by component by properly handling
5313   /// anonymous scopes. That's the slow path.
5314   ///
5315   /// Otherwise, let's just compare their name, the obvious way.
5316   /// That's the fast path because in that case the names are
5317   /// interned_string and comparing them is much faster.
5318   bool decls_are_same = (ln == rn);
5319   if (!decls_are_same
5320       && l.get_is_anonymous()
5321       && !l.get_has_anonymous_parent()
5322       && r.get_is_anonymous()
5323       && !r.get_has_anonymous_parent())
5324     // Both decls are anonymous and their scope are *NOT* anonymous.
5325     // So we consider the decls to have equivalent names (both
5326     // anonymous, remember).  We are still in the fast path here.
5327     decls_are_same = true;
5328 
5329   if (!decls_are_same
5330       && l.get_has_anonymous_parent()
5331       && r.get_has_anonymous_parent())
5332     // This is the slow path as we are comparing the decl qualified
5333     // names component by component, properly handling anonymous
5334     // scopes.
5335     decls_are_same = tools_utils::decl_names_equal(ln, rn);
5336 
5337   if (!decls_are_same)
5338     {
5339       result = false;
5340       if (k)
5341 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
5342       else
5343 	ABG_RETURN_FALSE;
5344     }
5345 
5346   result &= maybe_compare_as_member_decls(l, r, k);
5347 
5348   ABG_RETURN(result);
5349 }
5350 
5351 /// Return true iff the two decls have the same name.
5352 ///
5353 /// This function doesn't test if the scopes of the the two decls are
5354 /// equal.
5355 ///
5356 /// Note that this virtual function is to be implemented by classes
5357 /// that extend the \p decl_base class.
5358 bool
operator ==(const decl_base & other) const5359 decl_base::operator==(const decl_base& other) const
5360 {return equals(*this, other, 0);}
5361 
5362 /// Inequality operator.
5363 ///
5364 /// @param other to other instance of @ref decl_base to compare the
5365 /// current instance to.
5366 ///
5367 /// @return true iff the current instance of @ref decl_base is
5368 /// different from @p other.
5369 bool
operator !=(const decl_base & other) const5370 decl_base::operator!=(const decl_base& other) const
5371 {return !operator==(other);}
5372 
5373 /// Destructor of the @ref decl_base type.
~decl_base()5374 decl_base::~decl_base()
5375 {delete priv_;}
5376 
5377 /// This implements the ir_traversable_base::traverse pure virtual
5378 /// function.
5379 ///
5380 /// @param v the visitor used on the member nodes of the translation
5381 /// unit during the traversal.
5382 ///
5383 /// @return true if the entire IR node tree got traversed, false
5384 /// otherwise.
5385 bool
traverse(ir_node_visitor &)5386 decl_base::traverse(ir_node_visitor&)
5387 {
5388   // Do nothing in the base class.
5389   return true;
5390 }
5391 
5392 /// Setter of the scope of the current decl.
5393 ///
5394 /// Note that the decl won't hold a reference on the scope.  It's
5395 /// rather the scope that holds a reference on its members.
5396 void
set_scope(scope_decl * scope)5397 decl_base::set_scope(scope_decl* scope)
5398 {
5399   if (!priv_->context_)
5400     priv_->context_ = new context_rel(scope);
5401   else
5402     priv_->context_->set_scope(scope);
5403 }
5404 
5405 // </decl_base definition>
5406 
5407 /// Streaming operator for the decl_base::visibility.
5408 ///
5409 /// @param o the output stream to serialize the visibility to.
5410 ///
5411 /// @param v the visibility to serialize.
5412 ///
5413 /// @return the output stream.
5414 std::ostream&
operator <<(std::ostream & o,decl_base::visibility v)5415 operator<<(std::ostream& o, decl_base::visibility v)
5416 {
5417   string r;
5418   switch (v)
5419     {
5420     case decl_base::VISIBILITY_NONE:
5421       r = "none";
5422       break;
5423     case decl_base::VISIBILITY_DEFAULT:
5424       r = "default";
5425       break;
5426     case decl_base::VISIBILITY_PROTECTED:
5427       r = "protected";
5428       break;
5429     case decl_base::VISIBILITY_HIDDEN:
5430       r = "hidden";
5431       break;
5432     case decl_base::VISIBILITY_INTERNAL:
5433       r = "internal";
5434       break;
5435     }
5436   return o;
5437 }
5438 
5439 /// Streaming operator for decl_base::binding.
5440 ///
5441 /// @param o the output stream to serialize the visibility to.
5442 ///
5443 /// @param b the binding to serialize.
5444 ///
5445 /// @return the output stream.
5446 std::ostream&
operator <<(std::ostream & o,decl_base::binding b)5447 operator<<(std::ostream& o, decl_base::binding b)
5448 {
5449   string r;
5450   switch (b)
5451     {
5452     case decl_base::BINDING_NONE:
5453       r = "none";
5454       break;
5455     case decl_base::BINDING_LOCAL:
5456       r = "local";
5457       break;
5458     case decl_base::BINDING_GLOBAL:
5459       r = "global";
5460       break;
5461     case decl_base::BINDING_WEAK:
5462       r = "weak";
5463       break;
5464     }
5465   o << r;
5466   return o;
5467 }
5468 
5469 /// Turn equality of shared_ptr of decl_base into a deep equality;
5470 /// that is, make it compare the pointed to objects, not just the
5471 /// pointers.
5472 ///
5473 /// @param l the shared_ptr of decl_base on left-hand-side of the
5474 /// equality.
5475 ///
5476 /// @param r the shared_ptr of decl_base on right-hand-side of the
5477 /// equality.
5478 ///
5479 /// @return true if the decl_base pointed to by the shared_ptrs are
5480 /// equal, false otherwise.
5481 bool
operator ==(const decl_base_sptr & l,const decl_base_sptr & r)5482 operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5483 {
5484   if (l.get() == r.get())
5485     return true;
5486   if (!!l != !!r)
5487     return false;
5488 
5489   return *l == *r;
5490 }
5491 
5492 /// Inequality operator of shared_ptr of @ref decl_base.
5493 ///
5494 /// This is a deep equality operator, that is, it compares the
5495 /// pointed-to objects, rather than just the pointers.
5496 ///
5497 /// @param l the left-hand-side operand.
5498 ///
5499 /// @param r the right-hand-side operand.
5500 ///
5501 /// @return true iff @p l is different from @p r.
5502 bool
operator !=(const decl_base_sptr & l,const decl_base_sptr & r)5503 operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5504 {return !operator==(l, r);}
5505 
5506 /// Turn equality of shared_ptr of type_base into a deep equality;
5507 /// that is, make it compare the pointed to objects too.
5508 ///
5509 /// @param l the shared_ptr of type_base on left-hand-side of the
5510 /// equality.
5511 ///
5512 /// @param r the shared_ptr of type_base on right-hand-side of the
5513 /// equality.
5514 ///
5515 /// @return true if the type_base pointed to by the shared_ptrs are
5516 /// equal, false otherwise.
5517 bool
operator ==(const type_base_sptr & l,const type_base_sptr & r)5518 operator==(const type_base_sptr& l, const type_base_sptr& r)
5519 {
5520     if (l.get() == r.get())
5521     return true;
5522   if (!!l != !!r)
5523     return false;
5524 
5525   return *l == *r;
5526 }
5527 
5528 /// Turn inequality of shared_ptr of type_base into a deep equality;
5529 /// that is, make it compare the pointed to objects..
5530 ///
5531 /// @param l the shared_ptr of type_base on left-hand-side of the
5532 /// equality.
5533 ///
5534 /// @param r the shared_ptr of type_base on right-hand-side of the
5535 /// equality.
5536 ///
5537 /// @return true iff the type_base pointed to by the shared_ptrs are
5538 /// different.
5539 bool
operator !=(const type_base_sptr & l,const type_base_sptr & r)5540 operator!=(const type_base_sptr& l, const type_base_sptr& r)
5541 {return !operator==(l, r);}
5542 
5543 /// Tests if a declaration has got a scope.
5544 ///
5545 /// @param d the declaration to consider.
5546 ///
5547 /// @return true if the declaration has got a scope, false otherwise.
5548 bool
has_scope(const decl_base & d)5549 has_scope(const decl_base& d)
5550 {return (d.get_scope());}
5551 
5552 /// Tests if a declaration has got a scope.
5553 ///
5554 /// @param d the declaration to consider.
5555 ///
5556 /// @return true if the declaration has got a scope, false otherwise.
5557 bool
has_scope(const decl_base_sptr d)5558 has_scope(const decl_base_sptr d)
5559 {return has_scope(*d.get());}
5560 
5561 /// Tests if a declaration is a class member.
5562 ///
5563 /// @param d the declaration to consider.
5564 ///
5565 /// @return true if @p d is a class member, false otherwise.
5566 bool
is_member_decl(const decl_base_sptr d)5567 is_member_decl(const decl_base_sptr d)
5568 {return is_at_class_scope(d) || is_method_decl(d);}
5569 
5570 /// Tests if a declaration is a class member.
5571 ///
5572 /// @param d the declaration to consider.
5573 ///
5574 /// @return true if @p d is a class member, false otherwise.
5575 bool
is_member_decl(const decl_base * d)5576 is_member_decl(const decl_base* d)
5577 {return is_at_class_scope(d) || is_method_decl(d);}
5578 
5579 /// Tests if a declaration is a class member.
5580 ///
5581 /// @param d the declaration to consider.
5582 ///
5583 /// @return true if @p d is a class member, false otherwise.
5584 bool
is_member_decl(const decl_base & d)5585 is_member_decl(const decl_base& d)
5586 {return is_at_class_scope(d) || is_method_decl(d);}
5587 
5588 /// Test if a declaration is a @ref scope_decl.
5589 ///
5590 /// @param d the declaration to take in account.
5591 ///
5592 /// @return the a pointer to the @ref scope_decl sub-object of @p d,
5593 /// if d is a @ref scope_decl.
5594 scope_decl*
is_scope_decl(decl_base * d)5595 is_scope_decl(decl_base* d)
5596 {return dynamic_cast<scope_decl*>(d);}
5597 
5598 /// Test if a declaration is a @ref scope_decl.
5599 ///
5600 /// @param d the declaration to take in account.
5601 ///
5602 /// @return the a pointer to the @ref scope_decl sub-object of @p d,
5603 /// if d is a @ref scope_decl.
5604 scope_decl_sptr
is_scope_decl(const decl_base_sptr & d)5605 is_scope_decl(const decl_base_sptr& d)
5606 {return dynamic_pointer_cast<scope_decl>(d);}
5607 
5608 /// Tests if a type is a class member.
5609 ///
5610 /// @param t the type to consider.
5611 ///
5612 /// @return true if @p t is a class member type, false otherwise.
5613 bool
is_member_type(const type_base_sptr & t)5614 is_member_type(const type_base_sptr& t)
5615 {
5616   decl_base_sptr d = get_type_declaration(t);
5617   return is_member_decl(d);
5618 }
5619 
5620 /// Test if a type is user-defined.
5621 ///
5622 /// A type is considered user-defined if it's a
5623 /// struct/class/union/enum that is *NOT* artificial.
5624 ///
5625 /// @param t the type to consider.
5626 ///
5627 /// @return true iff the type @p t is user-defined.
5628 bool
is_user_defined_type(const type_base * t)5629 is_user_defined_type(const type_base* t)
5630 {
5631   if (t == 0)
5632     return false;
5633 
5634   t = peel_qualified_or_typedef_type(t);
5635   decl_base *d = is_decl(t);
5636 
5637   if ((is_class_or_union_type(t) || is_enum_type(t))
5638       && d && !d->get_is_artificial())
5639     return true;
5640 
5641   return false;
5642 }
5643 
5644 /// Test if a type is user-defined.
5645 ///
5646 /// A type is considered user-defined if it's a
5647 /// struct/class/union/enum.
5648 ///
5649 ///
5650 /// @param t the type to consider.
5651 ///
5652 /// @return true iff the type @p t is user-defined.
5653 bool
is_user_defined_type(const type_base_sptr & t)5654 is_user_defined_type(const type_base_sptr& t)
5655 {return is_user_defined_type(t.get());}
5656 
5657 /// Gets the access specifier for a class member.
5658 ///
5659 /// @param d the declaration of the class member to consider.  Note
5660 /// that this must be a class member otherwise the function aborts the
5661 /// current process.
5662 ///
5663 /// @return the access specifier for the class member @p d.
5664 access_specifier
get_member_access_specifier(const decl_base & d)5665 get_member_access_specifier(const decl_base& d)
5666 {
5667   ABG_ASSERT(is_member_decl(d));
5668 
5669   const context_rel* c = d.get_context_rel();
5670   ABG_ASSERT(c);
5671 
5672   return c->get_access_specifier();
5673 }
5674 
5675 /// Gets the access specifier for a class member.
5676 ///
5677 /// @param d the declaration of the class member to consider.  Note
5678 /// that this must be a class member otherwise the function aborts the
5679 /// current process.
5680 ///
5681 /// @return the access specifier for the class member @p d.
5682 access_specifier
get_member_access_specifier(const decl_base_sptr & d)5683 get_member_access_specifier(const decl_base_sptr& d)
5684 {return get_member_access_specifier(*d);}
5685 
5686 /// Sets the access specifier for a class member.
5687 ///
5688 /// @param d the class member to set the access specifier for.  Note
5689 /// that this must be a class member otherwise the function aborts the
5690 /// current process.
5691 ///
5692 /// @param a the new access specifier to set the class member to.
5693 void
set_member_access_specifier(decl_base & d,access_specifier a)5694 set_member_access_specifier(decl_base& d,
5695 			    access_specifier a)
5696 {
5697   ABG_ASSERT(is_member_decl(d));
5698 
5699   context_rel* c = d.get_context_rel();
5700   ABG_ASSERT(c);
5701 
5702   c->set_access_specifier(a);
5703 }
5704 
5705 /// Sets the access specifier for a class member.
5706 ///
5707 /// @param d the class member to set the access specifier for.  Note
5708 /// that this must be a class member otherwise the function aborts the
5709 /// current process.
5710 ///
5711 /// @param a the new access specifier to set the class member to.
5712 void
set_member_access_specifier(const decl_base_sptr & d,access_specifier a)5713 set_member_access_specifier(const decl_base_sptr& d,
5714 			    access_specifier a)
5715 {set_member_access_specifier(*d, a);}
5716 
5717 /// Gets a flag saying if a class member is static or not.
5718 ///
5719 /// @param d the declaration for the class member to consider. Note
5720 /// that this must be a class member otherwise the function aborts the
5721 /// current process.
5722 ///
5723 /// @return true if the class member @p d is static, false otherwise.
5724 bool
get_member_is_static(const decl_base & d)5725 get_member_is_static(const decl_base&d)
5726 {
5727   ABG_ASSERT(is_member_decl(d));
5728 
5729   const context_rel* c = d.get_context_rel();
5730   ABG_ASSERT(c);
5731 
5732   return c->get_is_static();
5733 }
5734 
5735 /// Gets a flag saying if a class member is static or not.
5736 ///
5737 /// @param d the declaration for the class member to consider. Note
5738 /// that this must be a class member otherwise the function aborts the
5739 /// current process.
5740 ///
5741 /// @return true if the class member @p d is static, false otherwise.
5742 bool
get_member_is_static(const decl_base * d)5743 get_member_is_static(const decl_base* d)
5744 {return get_member_is_static(*d);}
5745 
5746 /// Gets a flag saying if a class member is static or not.
5747 ///
5748 /// @param d the declaration for the class member to consider.  Note
5749 /// that this must be a class member otherwise the function aborts the
5750 /// current process.
5751 ///
5752 /// @return true if the class member @p d is static, false otherwise.
5753 bool
get_member_is_static(const decl_base_sptr & d)5754 get_member_is_static(const decl_base_sptr& d)
5755 {return get_member_is_static(*d);}
5756 
5757 /// Test if a var_decl is a data member.
5758 ///
5759 /// @param v the var_decl to consider.
5760 ///
5761 /// @return true if @p v is data member, false otherwise.
5762 bool
is_data_member(const var_decl & v)5763 is_data_member(const var_decl& v)
5764 {return is_at_class_scope(v);}
5765 
5766 /// Test if a var_decl is a data member.
5767 ///
5768 /// @param v the var_decl to consider.
5769 ///
5770 /// @return true if @p v is data member, false otherwise.
5771 bool
is_data_member(const var_decl * v)5772 is_data_member(const var_decl* v)
5773 {return is_data_member(*v);}
5774 
5775 /// Test if a var_decl is a data member.
5776 ///
5777 /// @param v the var_decl to consider.
5778 ///
5779 /// @return true if @p v is data member, false otherwise.
5780 bool
is_data_member(const var_decl_sptr d)5781 is_data_member(const var_decl_sptr d)
5782 {return is_at_class_scope(d);}
5783 
5784 /// Test if a decl is a data member.
5785 ///
5786 /// @param d the decl to consider.
5787 ///
5788 /// @return a pointer to the data member iff @p d is a data member, or
5789 /// a null pointer.
5790 var_decl_sptr
is_data_member(const decl_base_sptr & d)5791 is_data_member(const decl_base_sptr& d)
5792 {
5793   if (var_decl_sptr v = is_var_decl(d))
5794     {
5795       if (is_data_member(v))
5796 	return v;
5797     }
5798   return var_decl_sptr();
5799 }
5800 
5801 /// Test if a decl is a data member.
5802 ///
5803 /// @param d the decl to consider.
5804 ///
5805 /// @return a pointer to the data member iff @p d is a data member, or
5806 /// a null pointer.
5807 var_decl_sptr
is_data_member(const type_or_decl_base_sptr & d)5808 is_data_member(const type_or_decl_base_sptr& d)
5809 {
5810   if (var_decl_sptr v = is_var_decl(d))
5811     {
5812       if (is_data_member(v))
5813 	return v;
5814     }
5815   return var_decl_sptr();
5816 }
5817 
5818 /// Test if a decl is a data member.
5819 ///
5820 /// @param d the decl to consider.
5821 ///
5822 /// @return a pointer to the data member iff @p d is a data member, or
5823 /// a null pointer.
5824 var_decl*
is_data_member(const type_or_decl_base * d)5825 is_data_member(const type_or_decl_base* d)
5826 {
5827  if (var_decl *v = is_var_decl(d))
5828     if (is_data_member(v))
5829       return v;
5830   return 0;
5831 }
5832 
5833 /// Test if a decl is a data member.
5834 ///
5835 /// @param d the decl to consider.
5836 ///
5837 /// @return a pointer to the data member iff @p d is a data member, or
5838 /// a null pointer.
5839 var_decl*
is_data_member(const decl_base * d)5840 is_data_member(const decl_base *d)
5841 {
5842   if (var_decl *v = is_var_decl(d))
5843     if (is_data_member(v))
5844       return v;
5845   return 0;
5846 }
5847 
5848 /// Get the first non-anonymous data member of a given anonymous data
5849 /// member.
5850 ///
5851 /// E.g:
5852 ///
5853 ///   struct S
5854 ///   {
5855 ///     union // <-- for this anonymous data member, the function
5856 ///           // returns a.
5857 ///     {
5858 ///       int a;
5859 ///       charb;
5860 ///     };
5861 ///   };
5862 ///
5863 /// @return anon_dm the anonymous data member to consider.
5864 ///
5865 /// @return the first non-anonymous data member of @p anon_dm.  If no
5866 /// data member was found then this function returns @p anon_dm.
5867 const var_decl_sptr
get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)5868 get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
5869 {
5870   if (!anon_dm || !is_anonymous_data_member(anon_dm))
5871     return anon_dm;
5872 
5873   class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5874  var_decl_sptr first = *klass->get_non_static_data_members().begin();
5875 
5876  if (is_anonymous_data_member(first))
5877    return get_first_non_anonymous_data_member(first);
5878 
5879  return first;
5880 }
5881 
5882 /// In the context of a given class or union, this function returns
5883 /// the data member that is located after a given data member.
5884 ///
5885 /// @param klass the class or union to consider.
5886 ///
5887 /// @param the data member to consider.
5888 ///
5889 /// @return the data member that is located right after @p
5890 /// data_member.
5891 const var_decl_sptr
get_next_data_member(const class_or_union * klass,const var_decl_sptr & data_member)5892 get_next_data_member(const class_or_union *klass,
5893 		     const var_decl_sptr &data_member)
5894 {
5895   if (!klass ||!data_member)
5896     return var_decl_sptr();
5897 
5898   for (class_or_union::data_members::const_iterator it =
5899 	 klass->get_non_static_data_members().begin();
5900        it != klass->get_non_static_data_members().end();
5901        ++it)
5902     if (**it == *data_member)
5903       {
5904 	++it;
5905 	if (it != klass->get_non_static_data_members().end())
5906 	  return get_first_non_anonymous_data_member(*it);
5907 	break;
5908       }
5909 
5910   return var_decl_sptr();
5911 }
5912 
5913 /// In the context of a given class or union, this function returns
5914 /// the data member that is located after a given data member.
5915 ///
5916 /// @param klass the class or union to consider.
5917 ///
5918 /// @param the data member to consider.
5919 ///
5920 /// @return the data member that is located right after @p
5921 /// data_member.
5922 const var_decl_sptr
get_next_data_member(const class_or_union_sptr & klass,const var_decl_sptr & data_member)5923 get_next_data_member(const class_or_union_sptr& klass,
5924 		     const var_decl_sptr &data_member)
5925 {return get_next_data_member(klass.get(), data_member);}
5926 
5927 /// Get the last data member of a class type.
5928 ///
5929 /// @param klass the class type to consider.
5930 var_decl_sptr
get_last_data_member(const class_or_union & klass)5931 get_last_data_member(const class_or_union& klass)
5932 {return klass.get_non_static_data_members().back();}
5933 
5934 /// Get the last data member of a class type.
5935 ///
5936 /// @param klass the class type to consider.
5937 var_decl_sptr
get_last_data_member(const class_or_union * klass)5938 get_last_data_member(const class_or_union* klass)
5939 {return get_last_data_member(*klass);}
5940 
5941 /// Get the last data member of a class type.
5942 ///
5943 /// @param klass the class type to consider.
5944 var_decl_sptr
get_last_data_member(const class_or_union_sptr & klass)5945 get_last_data_member(const class_or_union_sptr &klass)
5946 {return get_last_data_member(klass.get());}
5947 
5948 /// Test if a decl is an anonymous data member.
5949 ///
5950 /// @param d the decl to consider.
5951 ///
5952 /// @return true iff @p d is an anonymous data member.
5953 bool
is_anonymous_data_member(const decl_base & d)5954 is_anonymous_data_member(const decl_base& d)
5955 {return is_anonymous_data_member(&d);}
5956 
5957 /// Test if a decl is an anonymous data member.
5958 ///
5959 /// @param d the decl to consider.
5960 ///
5961 /// @return the var_decl representing the data member iff @p d is an
5962 /// anonymous data member.
5963 const var_decl*
is_anonymous_data_member(const type_or_decl_base * d)5964 is_anonymous_data_member(const type_or_decl_base* d)
5965 {
5966   if (const var_decl* v = is_data_member(d))
5967     {
5968       if (is_anonymous_data_member(v))
5969 	return v;
5970     }
5971   return 0;
5972 }
5973 
5974 /// Test if a decl is an anonymous data member.
5975 ///
5976 /// @param d the decl to consider.
5977 ///
5978 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5979 /// it's an anonymous data member.  Otherwise returns a nil pointer.
5980 const var_decl*
is_anonymous_data_member(const decl_base * d)5981 is_anonymous_data_member(const decl_base* d)
5982 {
5983   if (const var_decl* v = is_data_member(d))
5984     {
5985       if (is_anonymous_data_member(v))
5986 	return v;
5987     }
5988   return 0;
5989 }
5990 
5991 /// Test if a decl is an anonymous data member.
5992 ///
5993 /// @param d the decl to consider.
5994 ///
5995 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5996 /// it's an anonymous data member.  Otherwise returns a nil pointer.
5997 var_decl_sptr
is_anonymous_data_member(const type_or_decl_base_sptr & d)5998 is_anonymous_data_member(const type_or_decl_base_sptr& d)
5999 {
6000   if (var_decl_sptr v = is_data_member(d))
6001     {
6002       if (is_anonymous_data_member(v))
6003 	return v;
6004     }
6005   return var_decl_sptr();
6006 }
6007 
6008 /// Test if a decl is an anonymous data member.
6009 ///
6010 /// @param d the decl to consider.
6011 ///
6012 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6013 /// it's an anonymous data member.  Otherwise returns a nil pointer.
6014 var_decl_sptr
is_anonymous_data_member(const decl_base_sptr & d)6015 is_anonymous_data_member(const decl_base_sptr& d)
6016 {
6017   if (var_decl_sptr v = is_data_member(d))
6018     return is_anonymous_data_member(v);
6019   return var_decl_sptr();
6020 }
6021 
6022 /// Test if a @ref var_decl is an anonymous data member.
6023 ///
6024 /// @param d the @ref var_decl to consider.
6025 ///
6026 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6027 /// it's an anonymous data member.  Otherwise returns a nil pointer.
6028 var_decl_sptr
is_anonymous_data_member(const var_decl_sptr & d)6029 is_anonymous_data_member(const var_decl_sptr& d)
6030 {
6031   if (is_anonymous_data_member(d.get()))
6032     return d;
6033   return var_decl_sptr();
6034 }
6035 
6036 /// Test if a @ref var_decl is an anonymous data member.
6037 ///
6038 /// @param d the @ref var_decl to consider.
6039 ///
6040 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6041 /// it's an anonymous data member.  Otherwise returns a nil pointer.
6042 const var_decl*
is_anonymous_data_member(const var_decl * d)6043 is_anonymous_data_member(const var_decl* d)
6044 {
6045   if (d && is_anonymous_data_member(*d))
6046     return d;
6047   return 0;
6048 }
6049 
6050 /// Test if a @ref var_decl is an anonymous data member.
6051 ///
6052 /// @param d the @ref var_decl to consider.
6053 ///
6054 /// @return true iff @p d is an anonymous data member.
6055 bool
is_anonymous_data_member(const var_decl & d)6056 is_anonymous_data_member(const var_decl& d)
6057 {
6058   return (is_data_member(d)
6059 	  && d.get_is_anonymous()
6060 	  && d.get_name().empty()
6061 	  && is_class_or_union_type(d.get_type()));
6062 }
6063 
6064 /// Test if a @ref var_decl is a data member belonging to an anonymous
6065 /// type.
6066 ///
6067 /// @param d the @ref var_decl to consider.
6068 ///
6069 /// @return true iff @p d is a data member belonging to an anonymous
6070 /// type.
6071 bool
is_data_member_of_anonymous_class_or_union(const var_decl & d)6072 is_data_member_of_anonymous_class_or_union(const var_decl& d)
6073 {
6074   if (is_data_member(d))
6075     {
6076       scope_decl* scope = d.get_scope();
6077       if (scope && scope->get_is_anonymous())
6078 	return true;
6079     }
6080   return false;
6081 }
6082 
6083 /// Test if a @ref var_decl is a data member belonging to an anonymous
6084 /// type.
6085 ///
6086 /// @param d the @ref var_decl to consider.
6087 ///
6088 /// @return true iff @p d is a data member belonging to an anonymous
6089 /// type.
6090 bool
is_data_member_of_anonymous_class_or_union(const var_decl * d)6091 is_data_member_of_anonymous_class_or_union(const var_decl* d)
6092 {return is_data_member_of_anonymous_class_or_union(*d);}
6093 
6094 /// Test if a @ref var_decl is a data member belonging to an anonymous
6095 /// type.
6096 ///
6097 /// @param d the @ref var_decl to consider.
6098 ///
6099 /// @return true iff @p d is a data member belonging to an anonymous
6100 /// type.
6101 bool
is_data_member_of_anonymous_class_or_union(const var_decl_sptr & d)6102 is_data_member_of_anonymous_class_or_union(const var_decl_sptr& d)
6103 {return is_data_member_of_anonymous_class_or_union(d.get());}
6104 
6105 /// Get the @ref class_or_union type of a given anonymous data member.
6106 ///
6107 /// @param d the anonymous data member to consider.
6108 ///
6109 /// @return the @ref class_or_union type of the anonymous data member
6110 /// @p d.
6111 class_or_union*
anonymous_data_member_to_class_or_union(const var_decl * d)6112 anonymous_data_member_to_class_or_union(const var_decl* d)
6113 {
6114   if ((d = is_anonymous_data_member(d)))
6115     return is_class_or_union_type(d->get_type().get());
6116   return 0;
6117 }
6118 
6119 /// Get the @ref class_or_union type of a given anonymous data member.
6120 ///
6121 /// @param d the anonymous data member to consider.
6122 ///
6123 /// @return the @ref class_or_union type of the anonymous data member
6124 /// @p d.
6125 class_or_union_sptr
anonymous_data_member_to_class_or_union(const var_decl & d)6126 anonymous_data_member_to_class_or_union(const var_decl& d)
6127 {
6128   if (is_anonymous_data_member(d))
6129     return is_class_or_union_type(d.get_type());
6130   return class_or_union_sptr();
6131 }
6132 
6133 /// Test if a data member has annonymous type or not.
6134 ///
6135 /// @param d the data member to consider.
6136 ///
6137 /// @return the anonymous class or union type iff @p turns out to have
6138 /// an anonymous type.  Otherwise, returns nil.
6139 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl & d)6140 data_member_has_anonymous_type(const var_decl& d)
6141 {
6142   if (is_data_member(d))
6143     if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
6144       if (cou->get_is_anonymous())
6145 	return cou;
6146 
6147   return class_or_union_sptr();
6148 }
6149 
6150 /// Test if a data member has annonymous type or not.
6151 ///
6152 /// @param d the data member to consider.
6153 ///
6154 /// @return the anonymous class or union type iff @p turns out to have
6155 /// an anonymous type.  Otherwise, returns nil.
6156 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl * d)6157 data_member_has_anonymous_type(const var_decl* d)
6158 {
6159   if (d)
6160     return data_member_has_anonymous_type(*d);
6161   return class_or_union_sptr();
6162 }
6163 
6164 /// Test if a data member has annonymous type or not.
6165 ///
6166 /// @param d the data member to consider.
6167 ///
6168 /// @return the anonymous class or union type iff @p turns out to have
6169 /// an anonymous type.  Otherwise, returns nil.
6170 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl_sptr & d)6171 data_member_has_anonymous_type(const var_decl_sptr& d)
6172 {return data_member_has_anonymous_type(d.get());}
6173 
6174 /// Get the @ref class_or_union type of a given anonymous data member.
6175 ///
6176 /// @param d the anonymous data member to consider.
6177 ///
6178 /// @return the @ref class_or_union type of the anonymous data member
6179 /// @p d.
6180 class_or_union_sptr
anonymous_data_member_to_class_or_union(const var_decl_sptr & d)6181 anonymous_data_member_to_class_or_union(const var_decl_sptr &d)
6182 {
6183   if (var_decl_sptr v = is_anonymous_data_member(d))
6184     return is_class_or_union_type(v->get_type());
6185   return class_or_union_sptr();
6186 }
6187 
6188 /// Test if a given anonymous data member exists in a class or union.
6189 ///
6190 /// @param anon_dm the anonymous data member to consider.
6191 ///
6192 /// @param clazz the class to consider.
6193 ///
6194 /// @return true iff @p anon_dm exists in the @clazz.
6195 bool
anonymous_data_member_exists_in_class(const var_decl & anon_dm,const class_or_union & clazz)6196 anonymous_data_member_exists_in_class(const var_decl& anon_dm,
6197 				      const class_or_union& clazz)
6198 {
6199   if (!anon_dm.get_is_anonymous()
6200       || !is_class_or_union_type(anon_dm.get_type()))
6201     return false;
6202 
6203   class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
6204   ABG_ASSERT(cl);
6205 
6206   // Look for the presence of each data member of anon_dm in clazz.
6207   //
6208   // If one data member of anon_dm is not present in clazz, then the
6209   // data member anon_dm is considered to not exist in clazz.
6210   for (auto anon_dm_m : cl->get_non_static_data_members())
6211     {
6212       // If the data member anon_dm_m is not an anonymous data member,
6213       // it's easy to look for it.
6214       if (!is_anonymous_data_member(anon_dm_m))
6215 	{
6216 	  if (!clazz.find_data_member(anon_dm_m->get_name()))
6217 	    return false;
6218 	}
6219       // If anon_dm_m is itself an anonymous data member then recurse
6220       else
6221 	{
6222 	  if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
6223 	    return false;
6224 	}
6225     }
6226 
6227   return true;
6228 }
6229 
6230 /// Test if a given decl is anonymous or has a naming typedef.
6231 ///
6232 /// @param d the decl to consider.
6233 ///
6234 /// @return true iff @p d is anonymous or has a naming typedef.
6235 bool
is_anonymous_or_typedef_named(const decl_base & d)6236 is_anonymous_or_typedef_named(const decl_base& d)
6237 {
6238   if (d.get_is_anonymous() || d.get_naming_typedef())
6239     return true;
6240   return false;
6241 }
6242 
6243 /// Set the offset of a data member into its containing class.
6244 ///
6245 /// @param m the data member to consider.
6246 ///
6247 /// @param o the offset, in bits.
6248 void
set_data_member_offset(var_decl_sptr m,uint64_t o)6249 set_data_member_offset(var_decl_sptr m, uint64_t o)
6250 {
6251   ABG_ASSERT(is_data_member(m));
6252 
6253   dm_context_rel* ctxt_rel =
6254     dynamic_cast<dm_context_rel*>(m->get_context_rel());
6255   ABG_ASSERT(ctxt_rel);
6256 
6257   ctxt_rel->set_offset_in_bits(o);
6258 }
6259 
6260 /// Get the offset of a data member.
6261 ///
6262 /// @param m the data member to consider.
6263 ///
6264 /// @return the offset (in bits) of @p m in its containing class.
6265 uint64_t
get_data_member_offset(const var_decl & m)6266 get_data_member_offset(const var_decl& m)
6267 {
6268   ABG_ASSERT(is_data_member(m));
6269   const dm_context_rel* ctxt_rel =
6270     dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6271   ABG_ASSERT(ctxt_rel);
6272   return ctxt_rel->get_offset_in_bits();
6273 }
6274 
6275 /// Get the offset of a data member.
6276 ///
6277 /// @param m the data member to consider.
6278 ///
6279 /// @return the offset (in bits) of @p m in its containing class.
6280 uint64_t
get_data_member_offset(const var_decl_sptr m)6281 get_data_member_offset(const var_decl_sptr m)
6282 {return get_data_member_offset(*m);}
6283 
6284 /// Get the offset of a data member.
6285 ///
6286 /// @param m the data member to consider.
6287 ///
6288 /// @return the offset (in bits) of @p m in its containing class.
6289 uint64_t
get_data_member_offset(const decl_base_sptr d)6290 get_data_member_offset(const decl_base_sptr d)
6291 {return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6292 
6293 /// Get the offset of the non-static data member that comes after a
6294 /// given one.
6295 ///
6296 /// If there is no data member after after the one given to this
6297 /// function (maybe because the given one is the last data member of
6298 /// the class type) then the function return false.
6299 ///
6300 /// @param klass the class to consider.
6301 ///
6302 /// @param dm the data member before the one we want to retrieve.
6303 ///
6304 /// @param offset out parameter.  This parameter is set by the
6305 /// function to the offset of the data member that comes right after
6306 /// the data member @p dm, iff the function returns true.
6307 ///
6308 /// @return true iff the data member coming right after @p dm was
6309 /// found.
6310 bool
get_next_data_member_offset(const class_or_union * klass,const var_decl_sptr & dm,uint64_t & offset)6311 get_next_data_member_offset(const class_or_union* klass,
6312 			    const var_decl_sptr& dm,
6313 			    uint64_t& offset)
6314 {
6315   var_decl_sptr next_dm = get_next_data_member(klass, dm);
6316   if (!next_dm)
6317     return false;
6318   offset = get_data_member_offset(next_dm);
6319   return true;
6320 }
6321 
6322 /// Get the offset of the non-static data member that comes after a
6323 /// given one.
6324 ///
6325 /// If there is no data member after after the one given to this
6326 /// function (maybe because the given one is the last data member of
6327 /// the class type) then the function return false.
6328 ///
6329 /// @param klass the class to consider.
6330 ///
6331 /// @param dm the data member before the one we want to retrieve.
6332 ///
6333 /// @param offset out parameter.  This parameter is set by the
6334 /// function to the offset of the data member that comes right after
6335 /// the data member @p dm, iff the function returns true.
6336 ///
6337 /// @return true iff the data member coming right after @p dm was
6338 /// found.
6339 bool
get_next_data_member_offset(const class_or_union_sptr & klass,const var_decl_sptr & dm,uint64_t & offset)6340 get_next_data_member_offset(const class_or_union_sptr& klass,
6341 			    const var_decl_sptr& dm,
6342 			    uint64_t& offset)
6343 {return get_next_data_member_offset(klass.get(), dm, offset);}
6344 
6345 /// Get the absolute offset of a data member.
6346 ///
6347 /// If the data member is part of an anonymous data member then this
6348 /// returns the absolute offset -- relative to the beginning of the
6349 /// containing class of the anonymous data member.
6350 ///
6351 /// @param m the data member to consider.
6352 ///
6353 /// @return the aboslute offset of the data member @p m.
6354 uint64_t
get_absolute_data_member_offset(const var_decl & m)6355 get_absolute_data_member_offset(const var_decl& m)
6356 {
6357   ABG_ASSERT(is_data_member(m));
6358   const dm_context_rel* ctxt_rel =
6359     dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6360   ABG_ASSERT(ctxt_rel);
6361 
6362   const var_decl *containing_anonymous_data_member =
6363     ctxt_rel->get_anonymous_data_member();
6364 
6365   uint64_t containing_anonymous_data_member_offset = 0;
6366   if (containing_anonymous_data_member)
6367     containing_anonymous_data_member_offset =
6368       get_absolute_data_member_offset(*containing_anonymous_data_member);
6369 
6370   return (ctxt_rel->get_offset_in_bits()
6371 	  +
6372 	  containing_anonymous_data_member_offset);
6373 }
6374 
6375 /// Get the absolute offset of a data member.
6376 ///
6377 /// If the data member is part of an anonymous data member then this
6378 /// returns the absolute offset -- relative to the beginning of the
6379 /// containing class of the anonymous data member.
6380 ///
6381 /// @param m the data member to consider.
6382 ///
6383 /// @return the aboslute offset of the data member @p m.
6384 uint64_t
get_absolute_data_member_offset(const var_decl_sptr & m)6385 get_absolute_data_member_offset(const var_decl_sptr& m)
6386 {
6387   if (!m)
6388     return 0;
6389   return get_absolute_data_member_offset(*m);
6390 }
6391 
6392 /// Get the size of a given variable.
6393 ///
6394 /// @param v the variable to consider.
6395 ///
6396 /// @return the size of variable @p v.
6397 uint64_t
get_var_size_in_bits(const var_decl_sptr & v)6398 get_var_size_in_bits(const var_decl_sptr& v)
6399 {
6400   type_base_sptr t = v->get_type();
6401   ABG_ASSERT(t);
6402 
6403   return t->get_size_in_bits();
6404 }
6405 
6406 /// Set a flag saying if a data member is laid out.
6407 ///
6408 /// @param m the data member to consider.
6409 ///
6410 /// @param l true if @p m is to be considered as laid out.
6411 void
set_data_member_is_laid_out(var_decl_sptr m,bool l)6412 set_data_member_is_laid_out(var_decl_sptr m, bool l)
6413 {
6414   ABG_ASSERT(is_data_member(m));
6415   dm_context_rel* ctxt_rel =
6416     dynamic_cast<dm_context_rel*>(m->get_context_rel());
6417   ctxt_rel->set_is_laid_out(l);
6418 }
6419 
6420 /// Test whether a data member is laid out.
6421 ///
6422 /// @param m the data member to consider.
6423 ///
6424 /// @return true if @p m is laid out, false otherwise.
6425 bool
get_data_member_is_laid_out(const var_decl & m)6426 get_data_member_is_laid_out(const var_decl& m)
6427 {
6428   ABG_ASSERT(is_data_member(m));
6429   const dm_context_rel* ctxt_rel =
6430     dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6431 
6432   return ctxt_rel->get_is_laid_out();
6433 }
6434 
6435 /// Test whether a data member is laid out.
6436 ///
6437 /// @param m the data member to consider.
6438 ///
6439 /// @return true if @p m is laid out, false otherwise.
6440 bool
get_data_member_is_laid_out(const var_decl_sptr m)6441 get_data_member_is_laid_out(const var_decl_sptr m)
6442 {return get_data_member_is_laid_out(*m);}
6443 
6444 /// Test whether a function_decl is a member function.
6445 ///
6446 /// @param f the function_decl to test.
6447 ///
6448 /// @return true if @p f is a member function, false otherwise.
6449 bool
is_member_function(const function_decl & f)6450 is_member_function(const function_decl& f)
6451 {return is_member_decl(f);}
6452 
6453 /// Test whether a function_decl is a member function.
6454 ///
6455 /// @param f the function_decl to test.
6456 ///
6457 /// @return true if @p f is a member function, false otherwise.
6458 bool
is_member_function(const function_decl * f)6459 is_member_function(const function_decl* f)
6460 {return is_member_decl(*f);}
6461 
6462 /// Test whether a function_decl is a member function.
6463 ///
6464 /// @param f the function_decl to test.
6465 ///
6466 /// @return true if @p f is a member function, false otherwise.
6467 bool
is_member_function(const function_decl_sptr & f)6468 is_member_function(const function_decl_sptr& f)
6469 {return is_member_decl(*f);}
6470 
6471 /// Test whether a member function is a constructor.
6472 ///
6473 /// @param f the member function to test.
6474 ///
6475 /// @return true if @p f is a constructor, false otherwise.
6476 bool
get_member_function_is_ctor(const function_decl & f)6477 get_member_function_is_ctor(const function_decl& f)
6478 {
6479   ABG_ASSERT(is_member_function(f));
6480 
6481   const method_decl* m = is_method_decl(&f);
6482   ABG_ASSERT(m);
6483 
6484   const mem_fn_context_rel* ctxt =
6485     dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6486 
6487   return ctxt->is_constructor();
6488 }
6489 
6490 /// Test whether a member function is a constructor.
6491 ///
6492 /// @param f the member function to test.
6493 ///
6494 /// @return true if @p f is a constructor, false otherwise.
6495 bool
get_member_function_is_ctor(const function_decl_sptr & f)6496 get_member_function_is_ctor(const function_decl_sptr& f)
6497 {return get_member_function_is_ctor(*f);}
6498 
6499 
6500 /// Setter for the is_ctor property of the member function.
6501 ///
6502 /// @param f the member function to set.
6503 ///
6504 /// @param f the new boolean value of the is_ctor property.  Is true
6505 /// if @p f is a constructor, false otherwise.
6506 void
set_member_function_is_ctor(function_decl & f,bool c)6507 set_member_function_is_ctor(function_decl& f, bool c)
6508 {
6509   ABG_ASSERT(is_member_function(f));
6510 
6511   method_decl* m = is_method_decl(&f);
6512   ABG_ASSERT(m);
6513 
6514   mem_fn_context_rel* ctxt =
6515     dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6516 
6517   ctxt->is_constructor(c);
6518 }
6519 
6520 /// Setter for the is_ctor property of the member function.
6521 ///
6522 /// @param f the member function to set.
6523 ///
6524 /// @param f the new boolean value of the is_ctor property.  Is true
6525 /// if @p f is a constructor, false otherwise.
6526 void
set_member_function_is_ctor(const function_decl_sptr & f,bool c)6527 set_member_function_is_ctor(const function_decl_sptr& f, bool c)
6528 {set_member_function_is_ctor(*f, c);}
6529 
6530 /// Test whether a member function is a destructor.
6531 ///
6532 /// @param f the function to test.
6533 ///
6534 /// @return true if @p f is a destructor, false otherwise.
6535 bool
get_member_function_is_dtor(const function_decl & f)6536 get_member_function_is_dtor(const function_decl& f)
6537 {
6538   ABG_ASSERT(is_member_function(f));
6539 
6540   const method_decl* m = is_method_decl(&f);
6541   ABG_ASSERT(m);
6542 
6543   const mem_fn_context_rel* ctxt =
6544     dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6545 
6546   return ctxt->is_destructor();
6547 }
6548 
6549 /// Test whether a member function is a destructor.
6550 ///
6551 /// @param f the function to test.
6552 ///
6553 /// @return true if @p f is a destructor, false otherwise.
6554 bool
get_member_function_is_dtor(const function_decl_sptr & f)6555 get_member_function_is_dtor(const function_decl_sptr& f)
6556 {return get_member_function_is_dtor(*f);}
6557 
6558 /// Set the destructor-ness property of a member function.
6559 ///
6560 /// @param f the function to set.
6561 ///
6562 /// @param d true if @p f is a destructor, false otherwise.
6563 void
set_member_function_is_dtor(function_decl & f,bool d)6564 set_member_function_is_dtor(function_decl& f, bool d)
6565 {
6566     ABG_ASSERT(is_member_function(f));
6567 
6568     method_decl* m = is_method_decl(&f);
6569   ABG_ASSERT(m);
6570 
6571   mem_fn_context_rel* ctxt =
6572     dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6573 
6574   ctxt->is_destructor(d);
6575 }
6576 
6577 /// Set the destructor-ness property of a member function.
6578 ///
6579 /// @param f the function to set.
6580 ///
6581 /// @param d true if @p f is a destructor, false otherwise.
6582 void
set_member_function_is_dtor(const function_decl_sptr & f,bool d)6583 set_member_function_is_dtor(const function_decl_sptr& f, bool d)
6584 {set_member_function_is_dtor(*f, d);}
6585 
6586 /// Test whether a member function is const.
6587 ///
6588 /// @param f the function to test.
6589 ///
6590 /// @return true if @p f is const, false otherwise.
6591 bool
get_member_function_is_const(const function_decl & f)6592 get_member_function_is_const(const function_decl& f)
6593 {
6594   ABG_ASSERT(is_member_function(f));
6595 
6596   const method_decl* m = is_method_decl(&f);
6597   ABG_ASSERT(m);
6598 
6599   const mem_fn_context_rel* ctxt =
6600     dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6601 
6602   return ctxt->is_const();
6603 }
6604 
6605 /// Test whether a member function is const.
6606 ///
6607 /// @param f the function to test.
6608 ///
6609 /// @return true if @p f is const, false otherwise.
6610 bool
get_member_function_is_const(const function_decl_sptr & f)6611 get_member_function_is_const(const function_decl_sptr& f)
6612 {return get_member_function_is_const(*f);}
6613 
6614 /// set the const-ness property of a member function.
6615 ///
6616 /// @param f the function to set.
6617 ///
6618 /// @param is_const the new value of the const-ness property of @p f
6619 void
set_member_function_is_const(function_decl & f,bool is_const)6620 set_member_function_is_const(function_decl& f, bool is_const)
6621 {
6622   ABG_ASSERT(is_member_function(f));
6623 
6624   method_decl* m = is_method_decl(&f);
6625   ABG_ASSERT(m);
6626 
6627   mem_fn_context_rel* ctxt =
6628     dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6629 
6630   ctxt->is_const(is_const);
6631 }
6632 
6633 /// set the const-ness property of a member function.
6634 ///
6635 /// @param f the function to set.
6636 ///
6637 /// @param is_const the new value of the const-ness property of @p f
6638 void
set_member_function_is_const(const function_decl_sptr & f,bool is_const)6639 set_member_function_is_const(const function_decl_sptr& f, bool is_const)
6640 {set_member_function_is_const(*f, is_const);}
6641 
6642 /// Test if a virtual member function has a vtable offset set.
6643 ///
6644 /// @param f the virtual member function to consider.
6645 ///
6646 /// @return true iff the virtual member function has its vtable offset
6647 /// set, i.e, if the vtable offset of @p is different from -1.
6648 bool
member_function_has_vtable_offset(const function_decl & f)6649 member_function_has_vtable_offset(const function_decl& f)
6650 {return get_member_function_vtable_offset(f) != -1;}
6651 
6652 /// Get the vtable offset of a member function.
6653 ///
6654 /// @param f the member function to consider.
6655 ///
6656 /// @return the vtable offset of @p f.  Note that a vtable offset of
6657 /// value -1 means that the member function does *NOT* yet have a
6658 /// vtable offset associated to it.
6659 ssize_t
get_member_function_vtable_offset(const function_decl & f)6660 get_member_function_vtable_offset(const function_decl& f)
6661 {
6662   ABG_ASSERT(is_member_function(f));
6663 
6664   const method_decl* m =
6665     dynamic_cast<const method_decl*>(&f);
6666   ABG_ASSERT(m);
6667 
6668   const mem_fn_context_rel* ctxt =
6669     dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6670 
6671   return ctxt->vtable_offset();
6672 }
6673 
6674 /// Get the vtable offset of a member function.
6675 ///
6676 /// @param f the member function to consider.
6677 ///
6678 /// @return the vtable offset of @p f.  Note that a vtable offset of
6679 /// value -1 means that the member function does *NOT* yet have a
6680 /// vtable offset associated to it.
6681 ssize_t
get_member_function_vtable_offset(const function_decl_sptr & f)6682 get_member_function_vtable_offset(const function_decl_sptr& f)
6683 {return get_member_function_vtable_offset(*f);}
6684 
6685 /// Set the vtable offset of a member function.
6686 ///
6687 /// @param f the member function to consider.
6688 ///
6689 /// @param s the new vtable offset.  Please note that a vtable offset
6690 /// of value -1 means that the virtual member function does not (yet)
6691 /// have any vtable offset associated to it.
6692 void
set_member_function_vtable_offset(function_decl & f,ssize_t s)6693 set_member_function_vtable_offset(function_decl& f, ssize_t s)
6694 {
6695   ABG_ASSERT(is_member_function(f));
6696 
6697   method_decl* m = is_method_decl(&f);
6698   ABG_ASSERT(m);
6699 
6700   mem_fn_context_rel* ctxt =
6701     dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6702 
6703   ctxt->vtable_offset(s);
6704 }
6705 
6706 /// Get the vtable offset of a member function.
6707 ///
6708 /// @param f the member function to consider.
6709 ///
6710 /// @param s the new vtable offset.  Please note that a vtable offset
6711 /// of value -1 means that the virtual member function does not (yet)
6712 /// have any vtable offset associated to it.
6713 void
set_member_function_vtable_offset(const function_decl_sptr & f,ssize_t s)6714 set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
6715 {return set_member_function_vtable_offset(*f, s);}
6716 
6717 /// Test if a given member function is virtual.
6718 ///
6719 /// @param mem_fn the member function to consider.
6720 ///
6721 /// @return true iff a @p mem_fn is virtual.
6722 bool
get_member_function_is_virtual(const function_decl & f)6723 get_member_function_is_virtual(const function_decl& f)
6724 {
6725   ABG_ASSERT(is_member_function(f));
6726 
6727   const method_decl* m =
6728     dynamic_cast<const method_decl*>(&f);
6729   ABG_ASSERT(m);
6730 
6731   const mem_fn_context_rel* ctxt =
6732     dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6733 
6734   return ctxt->is_virtual();
6735 }
6736 
6737 /// Test if a given member function is virtual.
6738 ///
6739 /// @param mem_fn the member function to consider.
6740 ///
6741 /// @return true iff a @p mem_fn is virtual.
6742 bool
get_member_function_is_virtual(const function_decl_sptr & mem_fn)6743 get_member_function_is_virtual(const function_decl_sptr& mem_fn)
6744 {return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6745 
6746 /// Test if a given member function is virtual.
6747 ///
6748 /// @param mem_fn the member function to consider.
6749 ///
6750 /// @return true iff a @p mem_fn is virtual.
6751 bool
get_member_function_is_virtual(const function_decl * mem_fn)6752 get_member_function_is_virtual(const function_decl* mem_fn)
6753 {return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6754 
6755 /// Set the virtual-ness of a member function.
6756 ///
6757 /// @param f the member function to consider.
6758 ///
6759 /// @param is_virtual set to true if the function is virtual.
6760 void
set_member_function_is_virtual(function_decl & f,bool is_virtual)6761 set_member_function_is_virtual(function_decl& f, bool is_virtual)
6762 {
6763   ABG_ASSERT(is_member_function(f));
6764 
6765   method_decl* m = is_method_decl(&f);
6766   ABG_ASSERT(m);
6767 
6768   mem_fn_context_rel* ctxt =
6769     dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6770 
6771   ctxt->is_virtual(is_virtual);
6772 }
6773 
6774 /// Set the virtual-ness of a member function.
6775 ///
6776 /// @param f the member function to consider.
6777 ///
6778 /// @param is_virtual set to true if the function is virtual.
6779 void
set_member_function_is_virtual(const function_decl_sptr & fn,bool is_virtual)6780 set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
6781 {
6782   if (fn)
6783     {
6784       set_member_function_is_virtual(*fn, is_virtual);
6785       fixup_virtual_member_function
6786 	(dynamic_pointer_cast<method_decl>(fn));
6787     }
6788 }
6789 
6790 /// Recursively returns the the underlying type of a typedef.  The
6791 /// return type should not be a typedef of anything anymore.
6792 ///
6793 ///
6794 /// Also recursively strip typedefs from the sub-types of the type
6795 /// given in arguments.
6796 ///
6797 /// Note that this function builds types in which typedefs are
6798 /// stripped off.  Usually, types are held by their scope, so their
6799 /// life time is bound to the life time of their scope.  But as this
6800 /// function cannot really insert the built type into it's scope, it
6801 /// must ensure that the newly built type stays live long enough.
6802 ///
6803 /// So, if the newly built type has a canonical type, this function
6804 /// returns the canonical type.  Otherwise, this function ensure that
6805 /// the newly built type has a life time that is the same as the life
6806 /// time of the entire libabigail library.
6807 ///
6808 /// @param type the type to strip the typedefs from.
6809 ///
6810 /// @return the resulting type stripped from its typedefs, or just
6811 /// return @p type if it has no typedef in any of its sub-types.
6812 type_base_sptr
strip_typedef(const type_base_sptr type)6813 strip_typedef(const type_base_sptr type)
6814 {
6815   if (!type)
6816     return type;
6817 
6818   // If type is a class type then do not try to strip typedefs from it.
6819   // And if it has no canonical type (which can mean that it's a
6820   // declaration-only class), then, make sure its live for ever and
6821   // return it.
6822   if (class_decl_sptr cl = is_class_type(type))
6823     {
6824       if (!cl->get_canonical_type())
6825 	keep_type_alive(type);
6826       return type;
6827     }
6828 
6829   const environment& env = type->get_environment();
6830   type_base_sptr t = type;
6831 
6832   if (const typedef_decl_sptr ty = is_typedef(t))
6833     t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6834   else if (const reference_type_def_sptr ty = is_reference_type(t))
6835     {
6836       type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6837 						    env));
6838       ABG_ASSERT(p);
6839       t.reset(new reference_type_def(p,
6840 				     ty->is_lvalue(),
6841 				     ty->get_size_in_bits(),
6842 				     ty->get_alignment_in_bits(),
6843 				     ty->get_location()));
6844     }
6845   else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6846     {
6847       type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6848 						    env));
6849       ABG_ASSERT(p);
6850       t.reset(new pointer_type_def(p,
6851 				   ty->get_size_in_bits(),
6852 				   ty->get_alignment_in_bits(),
6853 				   ty->get_location()));
6854     }
6855   else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6856     {
6857       type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6858 						    env));
6859       ABG_ASSERT(p);
6860       t.reset(new qualified_type_def(p,
6861 				     ty->get_cv_quals(),
6862 				     ty->get_location()));
6863     }
6864   else if (const array_type_def_sptr ty = is_array_type(t))
6865     {
6866       type_base_sptr p = strip_typedef(ty->get_element_type());
6867       ABG_ASSERT(p);
6868       t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6869     }
6870   else if (const method_type_sptr ty = is_method_type(t))
6871     {
6872       function_decl::parameters parm;
6873       for (function_decl::parameters::const_iterator i =
6874 	     ty->get_parameters().begin();
6875 	   i != ty->get_parameters().end();
6876 	   ++i)
6877 	{
6878 	  function_decl::parameter_sptr p = *i;
6879 	  type_base_sptr typ = strip_typedef(p->get_type());
6880 	  ABG_ASSERT(typ);
6881 	  function_decl::parameter_sptr stripped
6882 	    (new function_decl::parameter(typ,
6883 					  p->get_index(),
6884 					  p->get_name(),
6885 					  p->get_location(),
6886 					  p->get_variadic_marker(),
6887 					  p->get_is_artificial()));
6888 	  parm.push_back(stripped);
6889 	}
6890       type_base_sptr p = strip_typedef(ty->get_return_type());
6891       ABG_ASSERT(!!p == !!ty->get_return_type());
6892       t.reset(new method_type(p, ty->get_class_type(),
6893 			      parm, ty->get_is_const(),
6894 			      ty->get_size_in_bits(),
6895 			      ty->get_alignment_in_bits()));
6896     }
6897   else if (const function_type_sptr ty = is_function_type(t))
6898     {
6899       function_decl::parameters parm;
6900       for (function_decl::parameters::const_iterator i =
6901 	     ty->get_parameters().begin();
6902 	   i != ty->get_parameters().end();
6903 	   ++i)
6904 	{
6905 	  function_decl::parameter_sptr p = *i;
6906 	  type_base_sptr typ = strip_typedef(p->get_type());
6907 	  ABG_ASSERT(typ);
6908 	  function_decl::parameter_sptr stripped
6909 	    (new function_decl::parameter(typ,
6910 					  p->get_index(),
6911 					  p->get_name(),
6912 					  p->get_location(),
6913 					  p->get_variadic_marker(),
6914 					  p->get_is_artificial()));
6915 	  parm.push_back(stripped);
6916 	}
6917       type_base_sptr p = strip_typedef(ty->get_return_type());
6918       ABG_ASSERT(!!p == !!ty->get_return_type());
6919       t.reset(new function_type(p, parm,
6920 				ty->get_size_in_bits(),
6921 				ty->get_alignment_in_bits()));
6922     }
6923 
6924   if (!t->get_translation_unit())
6925     t->set_translation_unit(type->get_translation_unit());
6926 
6927   if (!(type->get_canonical_type() && canonicalize(t)))
6928     keep_type_alive(t);
6929 
6930   return t->get_canonical_type() ? t->get_canonical_type() : t;
6931 }
6932 
6933 /// Strip qualification from a qualified type, when it makes sense.
6934 ///
6935 /// DWARF constructs "const reference".  This is redundant because a
6936 /// reference is always const.  It also constructs the useless "const
6937 /// void" type.  The issue is these redundant types then leak into the
6938 /// IR and make for bad diagnostics.
6939 ///
6940 /// This function thus strips the const qualifier from the type in
6941 /// that case.  It might contain code to strip other cases like this
6942 /// in the future.
6943 ///
6944 /// @param t the type to strip const qualification from.
6945 ///
6946 /// @return the stripped type or just return @p t.
6947 decl_base_sptr
strip_useless_const_qualification(const qualified_type_def_sptr t)6948 strip_useless_const_qualification(const qualified_type_def_sptr t)
6949 {
6950   if (!t)
6951     return t;
6952 
6953   decl_base_sptr result = t;
6954   type_base_sptr u = t->get_underlying_type();
6955   const environment& env = t->get_environment();
6956 
6957   if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6958        && (is_reference_type(u)))
6959       || (t->get_cv_quals() & qualified_type_def::CV_CONST
6960 	  && env.is_void_type(u))
6961       || t->get_cv_quals() == qualified_type_def::CV_NONE)
6962     // Let's strip the const qualifier because a reference is always
6963     // 'const' and a const void doesn't make sense.  They will just
6964     // lead to spurious changes later down the pipeline, that we'll
6965     // have to deal with by doing painful and error-prone editing of
6966     // the diff IR.  Dropping that useless and inconsistent artefact
6967     // right here seems to be a good way to go.
6968     result = is_decl(u);
6969 
6970   return result;
6971 }
6972 
6973 /// Merge redundant qualifiers from a tree of qualified types.
6974 ///
6975 /// Suppose a tree of qualified types leads to:
6976 ///
6977 ///     const virtual const restrict const int;
6978 ///
6979 /// Suppose the IR tree of qualified types ressembles (with C meaning
6980 /// const, V meaning virtual and R meaning restrict):
6981 ///
6982 ///     [C|V]-->[C|R] -->[C] --> [int].
6983 ///
6984 /// This function walks the IR and remove the redundant CV qualifiers
6985 /// so the IR becomes:
6986 ///
6987 ///     [C|V] --> [R] --> []  -->[int].
6988 ///
6989 /// Note that the empty qualified type (noted []) represents a
6990 /// qualified type with no qualifier.  It's rare, but it can exist.
6991 /// I've put it here just for the sake of example.
6992 ///
6993 /// The resulting IR thus represents the (merged) type:
6994 ///
6995 ///    const virtual restrict int.
6996 ///
6997 /// This function is a sub-routine of the overload @ref
6998 /// strip_useless_const_qualification which doesn't return any value.
6999 ///
7000 /// @param t the qualified type to consider.
7001 ///
7002 /// @param redundant_quals the (redundant) qualifiers to be removed
7003 /// from the qualifiers of the underlying types of @p t.
7004 ///
7005 /// @return the underlying type of @p t which might have had its
7006 /// redundant qualifiers removed.
7007 static qualified_type_def_sptr
strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr & t,qualified_type_def::CV redundant_quals)7008 strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
7009 					    qualified_type_def::CV redundant_quals)
7010 {
7011   if (!t)
7012     return t;
7013 
7014   // We must NOT edit canonicalized types.
7015   ABG_ASSERT(!t->get_canonical_type());
7016 
7017   qualified_type_def_sptr underlying_qualified_type =
7018     is_qualified_type(t->get_underlying_type());
7019 
7020   // Let's build 'currated qualifiers' that are the qualifiers of the
7021   // current type from which redundant qualifiers are removed.
7022   qualified_type_def::CV currated_quals = t->get_cv_quals();
7023 
7024   // Remove the redundant qualifiers from these currated qualifiers
7025   currated_quals &= ~redundant_quals;
7026   t->set_cv_quals(currated_quals);
7027 
7028   // The redundant qualifiers, moving forward, is now the union of the
7029   // previous set of redundant qualifiers and the currated qualifiers.
7030   redundant_quals |= currated_quals;
7031 
7032   qualified_type_def_sptr result = t;
7033   if (underlying_qualified_type)
7034     // Now remove the redundant qualifiers from the qualified types
7035     // potentially carried by the underlying type.
7036     result =
7037       strip_redundant_quals_from_underyling_types(underlying_qualified_type,
7038 						  redundant_quals);
7039 
7040   return result;
7041 }
7042 
7043 /// Merge redundant qualifiers from a tree of qualified types.
7044 ///
7045 /// Suppose a tree of qualified types leads to:
7046 ///
7047 ///     const virtual const restrict const int;
7048 ///
7049 /// Suppose the IR tree of qualified types ressembles (with C meaning
7050 /// const, V meaning virtual and R meaning restrict):
7051 ///
7052 ///     [C|V]-->[C|R] -->[C] --> [int].
7053 ///
7054 /// This function walks the IR and remove the redundant CV qualifiers
7055 /// so the IR becomes:
7056 ///
7057 ///     [C|V] --> [R] --> []  -->[int].
7058 ///
7059 /// Note that the empty qualified type (noted []) represents a
7060 /// qualified type with no qualifier.  It's rare, but it can exist.
7061 /// I've put it here just for the sake of example.
7062 ///
7063 /// The resulting IR thus represents the (merged) type:
7064 ///
7065 ///    const virtual restrict int.
7066 ///
7067 /// @param t the qualified type to consider.  The IR below the
7068 /// argument to this parameter will be edited to remove redundant
7069 /// qualifiers where applicable.
7070 void
strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr & t)7071 strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
7072 {
7073   if (!t)
7074     return;
7075 
7076   qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
7077   strip_redundant_quals_from_underyling_types(t, redundant_quals);
7078 }
7079 
7080 /// Return the leaf underlying type node of a @ref typedef_decl node.
7081 ///
7082 /// If the underlying type of a @ref typedef_decl node is itself a
7083 /// @ref typedef_decl node, then recursively look at the underlying
7084 /// type nodes to get the first one that is not a a @ref typedef_decl
7085 /// node.  This is what a leaf underlying type node means.
7086 ///
7087 /// Otherwise, if the underlying type node of @ref typedef_decl is
7088 /// *NOT* a @ref typedef_decl node, then just return the underlying
7089 /// type node.
7090 ///
7091 /// And if the type node considered is not a @ref typedef_decl node,
7092 /// then just return it.
7093 ///
7094 /// @return the leaf underlying type node of a @p type.
7095 type_base_sptr
peel_typedef_type(const type_base_sptr & type)7096 peel_typedef_type(const type_base_sptr& type)
7097 {
7098   typedef_decl_sptr t = is_typedef(type);
7099   if (!t)
7100     return type;
7101 
7102   if (is_typedef(t->get_underlying_type()))
7103     return peel_typedef_type(t->get_underlying_type());
7104   return t->get_underlying_type();
7105 }
7106 
7107 /// Return the leaf underlying type node of a @ref typedef_decl node.
7108 ///
7109 /// If the underlying type of a @ref typedef_decl node is itself a
7110 /// @ref typedef_decl node, then recursively look at the underlying
7111 /// type nodes to get the first one that is not a a @ref typedef_decl
7112 /// node.  This is what a leaf underlying type node means.
7113 ///
7114 /// Otherwise, if the underlying type node of @ref typedef_decl is
7115 /// *NOT* a @ref typedef_decl node, then just return the underlying
7116 /// type node.
7117 ///
7118 /// And if the type node considered is not a @ref typedef_decl node,
7119 /// then just return it.
7120 ///
7121 /// @return the leaf underlying type node of a @p type.
7122 const type_base*
peel_typedef_type(const type_base * type)7123 peel_typedef_type(const type_base* type)
7124 {
7125   const typedef_decl* t = is_typedef(type);
7126   if (!t)
7127     return type;
7128 
7129   return peel_typedef_type(t->get_underlying_type()).get();
7130 }
7131 
7132 /// Return the leaf pointed-to type node of a @ref pointer_type_def
7133 /// node.
7134 ///
7135 /// If the pointed-to type of a @ref pointer_type_def node is itself a
7136 /// @ref pointer_type_def node, then recursively look at the
7137 /// pointed-to type nodes to get the first one that is not a a @ref
7138 /// pointer_type_def node.  This is what a leaf pointed-to type node
7139 /// means.
7140 ///
7141 /// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7142 /// *NOT* a @ref pointer_type_def node, then just return the
7143 /// pointed-to type node.
7144 ///
7145 /// And if the type node considered is not a @ref pointer_type_def
7146 /// node, then just return it.
7147 ///
7148 /// @return the leaf pointed-to type node of a @p type.
7149 type_base_sptr
peel_pointer_type(const type_base_sptr & type)7150 peel_pointer_type(const type_base_sptr& type)
7151 {
7152   pointer_type_def_sptr t = is_pointer_type(type);
7153   if (!t)
7154     return type;
7155 
7156   if (is_pointer_type(t->get_pointed_to_type()))
7157     return peel_pointer_type(t->get_pointed_to_type());
7158   return t->get_pointed_to_type();
7159 }
7160 
7161 /// Return the leaf pointed-to type node of a @ref pointer_type_def
7162 /// node.
7163 ///
7164 /// If the pointed-to type of a @ref pointer_type_def node is itself a
7165 /// @ref pointer_type_def node, then recursively look at the
7166 /// pointed-to type nodes to get the first one that is not a a @ref
7167 /// pointer_type_def node.  This is what a leaf pointed-to type node
7168 /// means.
7169 ///
7170 /// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7171 /// *NOT* a @ref pointer_type_def node, then just return the
7172 /// pointed-to type node.
7173 ///
7174 /// And if the type node considered is not a @ref pointer_type_def
7175 /// node, then just return it.
7176 ///
7177 /// @return the leaf pointed-to type node of a @p type.
7178 const type_base*
peel_pointer_type(const type_base * type)7179 peel_pointer_type(const type_base* type)
7180 {
7181   const pointer_type_def* t = is_pointer_type(type);
7182   if (!t)
7183     return type;
7184 
7185   return peel_pointer_type(t->get_pointed_to_type()).get();
7186 }
7187 
7188 /// Return the leaf pointed-to type node of a @ref reference_type_def
7189 /// node.
7190 ///
7191 /// If the pointed-to type of a @ref reference_type_def node is itself
7192 /// a @ref reference_type_def node, then recursively look at the
7193 /// pointed-to type nodes to get the first one that is not a a @ref
7194 /// reference_type_def node.  This is what a leaf pointed-to type node
7195 /// means.
7196 ///
7197 /// Otherwise, if the pointed-to type node of @ref reference_type_def
7198 /// is *NOT* a @ref reference_type_def node, then just return the
7199 /// pointed-to type node.
7200 ///
7201 /// And if the type node considered is not a @ref reference_type_def
7202 /// node, then just return it.
7203 ///
7204 /// @return the leaf pointed-to type node of a @p type.
7205 type_base_sptr
peel_reference_type(const type_base_sptr & type)7206 peel_reference_type(const type_base_sptr& type)
7207 {
7208   reference_type_def_sptr t = is_reference_type(type);
7209   if (!t)
7210     return type;
7211 
7212   if (is_reference_type(t->get_pointed_to_type()))
7213     return peel_reference_type(t->get_pointed_to_type());
7214   return t->get_pointed_to_type();
7215 }
7216 
7217 /// Return the leaf pointed-to type node of a @ref reference_type_def
7218 /// node.
7219 ///
7220 /// If the pointed-to type of a @ref reference_type_def node is itself
7221 /// a @ref reference_type_def node, then recursively look at the
7222 /// pointed-to type nodes to get the first one that is not a a @ref
7223 /// reference_type_def node.  This is what a leaf pointed-to type node
7224 /// means.
7225 ///
7226 /// Otherwise, if the pointed-to type node of @ref reference_type_def
7227 /// is *NOT* a @ref reference_type_def node, then just return the
7228 /// pointed-to type node.
7229 ///
7230 /// And if the type node considered is not a @ref reference_type_def
7231 /// node, then just return it.
7232 ///
7233 /// @return the leaf pointed-to type node of a @p type.
7234 const type_base*
peel_reference_type(const type_base * type)7235 peel_reference_type(const type_base* type)
7236 {
7237   const reference_type_def* t = is_reference_type(type);
7238   if (!t)
7239     return type;
7240 
7241   return peel_reference_type(t->get_pointed_to_type()).get();
7242 }
7243 
7244 /// Return the leaf element type of an array.
7245 ///
7246 /// If the element type is itself an array, then recursively return
7247 /// the element type of that array itself.
7248 ///
7249 /// @param type the array type to consider.  If this is not an array
7250 /// type, this type is returned by the function.
7251 ///
7252 /// @return the leaf element type of the array @p type, or, if it's
7253 /// not an array type, then just return @p.
7254 const type_base_sptr
peel_array_type(const type_base_sptr & type)7255 peel_array_type(const type_base_sptr& type)
7256 {
7257   const array_type_def_sptr t = is_array_type(type);
7258   if (!t)
7259     return type;
7260 
7261   return peel_array_type(t->get_element_type());
7262 }
7263 
7264 /// Return the leaf element type of an array.
7265 ///
7266 /// If the element type is itself an array, then recursively return
7267 /// the element type of that array itself.
7268 ///
7269 /// @param type the array type to consider.  If this is not an array
7270 /// type, this type is returned by the function.
7271 ///
7272 /// @return the leaf element type of the array @p type, or, if it's
7273 /// not an array type, then just return @p.
7274 const type_base*
peel_array_type(const type_base * type)7275 peel_array_type(const type_base* type)
7276 {
7277   const array_type_def* t = is_array_type(type);
7278   if (!t)
7279     return type;
7280 
7281   return peel_array_type(t->get_element_type()).get();
7282 }
7283 
7284 /// Return the leaf underlying type of a qualified type.
7285 ///
7286 /// If the underlying type is itself a qualified type, then
7287 /// recursively return the first underlying type of that qualified
7288 /// type to return the first underlying type that is not a qualified type.
7289 ///
7290 /// If the underlying type is NOT a qualified type, then just return
7291 /// that underlying type.
7292 ///
7293 /// @param type the qualified type to consider.
7294 ///
7295 /// @return the leaf underlying type.
7296 const type_base*
peel_qualified_type(const type_base * type)7297 peel_qualified_type(const type_base* type)
7298 {
7299   const qualified_type_def* t = is_qualified_type(type);
7300   if (!t)
7301     return type;
7302 
7303   return peel_qualified_type(t->get_underlying_type().get());
7304 }
7305 
7306 /// Return the leaf underlying type of a qualified type.
7307 ///
7308 /// If the underlying type is itself a qualified type, then
7309 /// recursively return the first underlying type of that qualified
7310 /// type to return the first underlying type that is not a qualified type.
7311 ///
7312 /// If the underlying type is NOT a qualified type, then just return
7313 /// that underlying type.
7314 ///
7315 /// @param type the qualified type to consider.
7316 ///
7317 /// @return the leaf underlying type.
7318 const type_base_sptr
peel_qualified_type(const type_base_sptr & type)7319 peel_qualified_type(const type_base_sptr& type)
7320 {
7321   const qualified_type_def_sptr t = is_qualified_type(type);
7322   if (!t)
7323     return type;
7324 
7325   return peel_qualified_type(t->get_underlying_type());
7326 }
7327 
7328 /// Return the leaf underlying type of a qualified or typedef type.
7329 ///
7330 /// If the underlying type is itself a qualified or typedef type, then
7331 /// recursively return the first underlying type of that qualified or
7332 /// typedef type to return the first underlying type that is not a
7333 /// qualified or typedef type.
7334 ///
7335 /// If the underlying type is NOT a qualified nor a typedef type, then
7336 /// just return that underlying type.
7337 ///
7338 /// @param type the qualified or typedef type to consider.
7339 ///
7340 /// @return the leaf underlying type.
7341 type_base*
peel_qualified_or_typedef_type(const type_base * type)7342 peel_qualified_or_typedef_type(const type_base* type)
7343 {
7344   while (is_typedef(type) || is_qualified_type(type))
7345     {
7346       if (const typedef_decl* t = is_typedef(type))
7347 	type = peel_typedef_type(t);
7348 
7349       if (const qualified_type_def* t = is_qualified_type(type))
7350 	type = peel_qualified_type(t);
7351     }
7352 
7353   return const_cast<type_base*>(type);
7354 }
7355 
7356 /// Return the leaf underlying type of a qualified or typedef type.
7357 ///
7358 /// If the underlying type is itself a qualified or typedef type, then
7359 /// recursively return the first underlying type of that qualified or
7360 /// typedef type to return the first underlying type that is not a
7361 /// qualified or typedef type.
7362 ///
7363 /// If the underlying type is NOT a qualified nor a typedef type, then
7364 /// just return that underlying type.
7365 ///
7366 /// @param type the qualified or typedef type to consider.
7367 ///
7368 /// @return the leaf underlying type.
7369 type_base_sptr
peel_qualified_or_typedef_type(const type_base_sptr & t)7370 peel_qualified_or_typedef_type(const type_base_sptr &t)
7371 {
7372   type_base_sptr type = t;
7373   while (is_typedef(type) || is_qualified_type(type))
7374     {
7375       if (typedef_decl_sptr t = is_typedef(type))
7376 	type = peel_typedef_type(t);
7377 
7378       if (qualified_type_def_sptr t = is_qualified_type(type))
7379 	type = peel_qualified_type(t);
7380     }
7381 
7382   return type;
7383 }
7384 
7385 /// Return the leaf underlying or pointed-to type node of a @ref
7386 /// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7387 /// or @ref array_type_def node.
7388 ///
7389 /// @param type the type to peel.
7390 ///
7391 /// @return the leaf underlying or pointed-to type node of @p type.
7392 type_base_sptr
peel_typedef_pointer_or_reference_type(const type_base_sptr type)7393 peel_typedef_pointer_or_reference_type(const type_base_sptr type)
7394 {
7395   type_base_sptr typ = type;
7396   while (is_typedef(typ)
7397 	 || is_pointer_type(typ)
7398 	 || is_reference_type(typ)
7399 	 || is_array_type(typ))
7400     {
7401       if (typedef_decl_sptr t = is_typedef(typ))
7402 	typ = peel_typedef_type(t);
7403 
7404       if (pointer_type_def_sptr t = is_pointer_type(typ))
7405 	typ = peel_pointer_type(t);
7406 
7407       if (reference_type_def_sptr t = is_reference_type(typ))
7408 	typ = peel_reference_type(t);
7409 
7410       if (const array_type_def_sptr t = is_array_type(typ))
7411 	typ = peel_array_type(t);
7412     }
7413 
7414   return typ;
7415 }
7416 
7417 /// Return the leaf underlying or pointed-to type node of a @ref
7418 /// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7419 /// node.
7420 ///
7421 /// @param type the type to peel.
7422 ///
7423 /// @return the leaf underlying or pointed-to type node of @p type.
7424 type_base*
peel_typedef_pointer_or_reference_type(const type_base * type)7425 peel_typedef_pointer_or_reference_type(const type_base* type)
7426 {
7427   while (is_typedef(type)
7428 	 || is_pointer_type(type)
7429 	 || is_reference_type(type)
7430 	 || is_array_type(type))
7431     {
7432       if (const typedef_decl* t = is_typedef(type))
7433 	type = peel_typedef_type(t);
7434 
7435       if (const pointer_type_def* t = is_pointer_type(type))
7436 	type = peel_pointer_type(t);
7437 
7438       if (const reference_type_def* t = is_reference_type(type))
7439 	type = peel_reference_type(t);
7440 
7441       if (const array_type_def* t = is_array_type(type))
7442 	type = peel_array_type(t);
7443     }
7444 
7445   return const_cast<type_base*>(type);
7446 }
7447 
7448 /// Return the leaf underlying or pointed-to type node of a @ref
7449 /// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7450 /// node.
7451 ///
7452 /// @param type the type to peel.
7453 ///
7454 /// @return the leaf underlying or pointed-to type node of @p type.
7455 type_base*
peel_typedef_pointer_or_reference_type(const type_base * type,bool peel_qual_type)7456 peel_typedef_pointer_or_reference_type(const type_base* type,
7457 				       bool peel_qual_type)
7458 {
7459   while (is_typedef(type)
7460 	 || is_pointer_type(type)
7461 	 || is_reference_type(type)
7462 	 || is_array_type(type)
7463 	 || (peel_qual_type && is_qualified_type(type)))
7464     {
7465       if (const typedef_decl* t = is_typedef(type))
7466 	type = peel_typedef_type(t);
7467 
7468       if (const pointer_type_def* t = is_pointer_type(type))
7469 	type = peel_pointer_type(t);
7470 
7471       if (const reference_type_def* t = is_reference_type(type))
7472 	type = peel_reference_type(t);
7473 
7474       if (const array_type_def* t = is_array_type(type))
7475 	type = peel_array_type(t);
7476 
7477       if (peel_qual_type)
7478 	if (const qualified_type_def* t = is_qualified_type(type))
7479 	  type = peel_qualified_type(t);
7480     }
7481 
7482   return const_cast<type_base*>(type);
7483 }
7484 
7485 /// Return the leaf underlying or pointed-to type node of a, @ref
7486 /// pointer_type_def, @ref reference_type_def or @ref
7487 /// qualified_type_def type node.
7488 ///
7489 /// @param type the type to peel.
7490 ///
7491 /// @param peel_qualified_type if true, also peel qualified types.
7492 ///
7493 /// @return the leaf underlying or pointed-to type node of @p type.
7494 type_base*
peel_pointer_or_reference_type(const type_base * type,bool peel_qual_type)7495 peel_pointer_or_reference_type(const type_base *type,
7496 			       bool peel_qual_type)
7497 {
7498   while (is_pointer_type(type)
7499 	 || is_reference_type(type)
7500 	 || is_array_type(type)
7501 	 || (peel_qual_type && is_qualified_type(type)))
7502     {
7503       if (const pointer_type_def* t = is_pointer_type(type))
7504 	type = peel_pointer_type(t);
7505 
7506       if (const reference_type_def* t = is_reference_type(type))
7507 	type = peel_reference_type(t);
7508 
7509       if (const array_type_def* t = is_array_type(type))
7510 	type = peel_array_type(t);
7511 
7512       if (peel_qual_type)
7513 	if (const qualified_type_def* t = is_qualified_type(type))
7514 	  type = peel_qualified_type(t);
7515     }
7516 
7517   return const_cast<type_base*>(type);
7518 }
7519 
7520 /// Clone an array type.
7521 ///
7522 /// Note that the element type of the new array is shared witht the
7523 /// old one.
7524 ///
7525 /// @param array the array type to clone.
7526 ///
7527 /// @return a newly built array type.  Note that it needs to be added
7528 /// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7529 /// bound to the one of that scope.  Otherwise, its lifetime is bound
7530 /// to the lifetime of its containing shared pointer.
7531 array_type_def_sptr
clone_array(const array_type_def_sptr & array)7532 clone_array(const array_type_def_sptr& array)
7533 {
7534   vector<array_type_def::subrange_sptr> subranges;
7535 
7536   for (vector<array_type_def::subrange_sptr>::const_iterator i =
7537 	 array->get_subranges().begin();
7538        i != array->get_subranges().end();
7539        ++i)
7540     {
7541       array_type_def::subrange_sptr subrange
7542 	(new array_type_def::subrange_type(array->get_environment(),
7543 					   (*i)->get_name(),
7544 					   (*i)->get_lower_bound(),
7545 					   (*i)->get_upper_bound(),
7546 					   (*i)->get_underlying_type(),
7547 					   (*i)->get_location(),
7548 					   (*i)->get_language()));
7549       subrange->is_infinite((*i)->is_infinite());
7550       if (scope_decl *scope = (*i)->get_scope())
7551 	add_decl_to_scope(subrange, scope);
7552       subranges.push_back(subrange);
7553     }
7554 
7555   array_type_def_sptr result
7556     (new array_type_def(array->get_element_type(),
7557 			subranges, array->get_location()));
7558 
7559   return result;
7560 }
7561 
7562 /// Clone a typedef type.
7563 ///
7564 /// Note that the underlying type of the newly constructed typedef is
7565 /// shared with the old one.
7566 ///
7567 /// @param t the typedef to clone.
7568 ///
7569 /// @return the newly constructed typedef.  Note that it needs to be
7570 /// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7571 /// to be bound to the one of that scope.  Otherwise, its lifetime is
7572 /// bound to the lifetime of its containing shared pointer.
7573 typedef_decl_sptr
clone_typedef(const typedef_decl_sptr & t)7574 clone_typedef(const typedef_decl_sptr& t)
7575 {
7576   if (!t)
7577     return t;
7578 
7579   typedef_decl_sptr result
7580     (new typedef_decl(t->get_name(), t->get_underlying_type(),
7581 		      t->get_location(), t->get_linkage_name(),
7582 		      t->get_visibility()));
7583   return result;
7584 }
7585 
7586 /// Clone a qualifiend type.
7587 ///
7588 /// Note that underlying type of the newly constructed qualified type
7589 /// is shared with the old one.
7590 ///
7591 /// @param t the qualified type to clone.
7592 ///
7593 /// @return the newly constructed qualified type.  Note that it needs
7594 /// to be added to a scope (e.g, using add_decl_to_scope) for its
7595 /// lifetime to be bound to the one of that scope.  Otherwise, its
7596 /// lifetime is bound to the lifetime of its containing shared
7597 /// pointer.
7598 qualified_type_def_sptr
clone_qualified_type(const qualified_type_def_sptr & t)7599 clone_qualified_type(const qualified_type_def_sptr& t)
7600 {
7601   if (!t)
7602     return t;
7603 
7604   qualified_type_def_sptr result
7605     (new qualified_type_def(t->get_underlying_type(),
7606 			    t->get_cv_quals(), t->get_location()));
7607 
7608   return result;
7609 }
7610 
7611 /// Clone a typedef, an array or a qualified tree.
7612 ///
7613 /// @param type the typedef, array or qualified tree to clone.  any
7614 /// order.
7615 ///
7616 /// @return the cloned type, or NULL if @type was neither a typedef,
7617 /// array nor a qualified type.
7618 static type_base_sptr
clone_typedef_array_qualified_type(type_base_sptr type)7619 clone_typedef_array_qualified_type(type_base_sptr type)
7620 {
7621   if (!type)
7622     return type;
7623 
7624   scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7625   type_base_sptr result;
7626 
7627   if (typedef_decl_sptr t = is_typedef(type))
7628     result = clone_typedef(is_typedef(t));
7629   else if (qualified_type_def_sptr t = is_qualified_type(type))
7630     result = clone_qualified_type(t);
7631   else if (array_type_def_sptr t = is_array_type(type))
7632     result = clone_array(t);
7633   else
7634     return type_base_sptr();
7635 
7636   if (scope)
7637     add_decl_to_scope(is_decl(result), scope);
7638 
7639   return result;
7640 }
7641 
7642 /// Clone a type tree made of an array or a typedef of array.
7643 ///
7644 /// Note that this can be a tree which root node is a typedef an which
7645 /// sub-tree can be any arbitrary combination of typedef, qualified
7646 /// type and arrays.
7647 ///
7648 /// @param t the array or typedef of qualified array to consider.
7649 ///
7650 /// @return a clone of @p t.
7651 type_base_sptr
clone_array_tree(const type_base_sptr t)7652 clone_array_tree(const type_base_sptr t)
7653 {
7654   ABG_ASSERT(is_typedef_of_array(t) || is_array_type(t));
7655 
7656   scope_decl* scope = is_decl(t)->get_scope();
7657   type_base_sptr result = clone_typedef_array_qualified_type(t);
7658   ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7659 
7660   type_base_sptr subtree;
7661   if (typedef_decl_sptr type = is_typedef(result))
7662     {
7663       type_base_sptr s =
7664 	clone_typedef_array_qualified_type(type->get_underlying_type());
7665       if (s)
7666 	{
7667 	  subtree = s;
7668 	  type->set_underlying_type(subtree);
7669 	}
7670     }
7671   else if (array_type_def_sptr type = is_array_type(result))
7672     {
7673       type_base_sptr s =
7674 	clone_typedef_array_qualified_type(type->get_element_type());
7675       if (s)
7676 	{
7677 	  subtree = s;
7678 	  type->set_element_type(subtree);
7679 	}
7680     }
7681   add_decl_to_scope(is_decl(subtree), scope);
7682 
7683   for (;;)
7684     {
7685       if (typedef_decl_sptr t = is_typedef(subtree))
7686 	{
7687 	  type_base_sptr s =
7688 	    clone_typedef_array_qualified_type(t->get_underlying_type());
7689 	  if (s)
7690 	    {
7691 	      scope_decl* scope =
7692 		is_decl(t->get_underlying_type())->get_scope();
7693 	      ABG_ASSERT(scope);
7694 	      add_decl_to_scope(is_decl(s), scope);
7695 	      t->set_underlying_type (s);
7696 	      subtree = s;
7697 	    }
7698 	  else
7699 	    break;
7700 	}
7701       else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7702 	{
7703 	  type_base_sptr s =
7704 	    clone_typedef_array_qualified_type(t->get_underlying_type());
7705 	  if (s)
7706 	    {
7707 	      scope_decl* scope =
7708 		is_decl(t->get_underlying_type())->get_scope();
7709 	      ABG_ASSERT(scope);
7710 	      add_decl_to_scope(is_decl(s), scope);
7711 	      t->set_underlying_type(s);
7712 	      subtree = s;
7713 	    }
7714 	  else
7715 	    break;
7716 	}
7717       else if (array_type_def_sptr t = is_array_type(subtree))
7718 	{
7719 	  type_base_sptr e = t->get_element_type();
7720 	  if (is_typedef(e) || is_qualified_type(e))
7721 	    {
7722 	      type_base_sptr s =
7723 		clone_typedef_array_qualified_type(e);
7724 	      if (s)
7725 		{
7726 		  scope_decl* scope = is_decl(e)->get_scope();
7727 		  ABG_ASSERT(scope);
7728 		  add_decl_to_scope(is_decl(s), scope);
7729 		  t->set_element_type(s);
7730 		}
7731 	      else
7732 		break;
7733 	    }
7734 	  break;
7735 	}
7736       else
7737 	break;
7738     }
7739   return result;
7740 }
7741 
7742 /// Update the qualified name of a given sub-tree.
7743 ///
7744 /// @param d the sub-tree for which to update the qualified name.
7745 static void
update_qualified_name(decl_base * d)7746 update_qualified_name(decl_base * d)
7747 {
7748   ::qualified_name_setter setter;
7749   d->traverse(setter);
7750 }
7751 
7752 /// Update the qualified name of a given sub-tree.
7753 ///
7754 /// @param d the sub-tree for which to update the qualified name.
7755 static void
update_qualified_name(decl_base_sptr d)7756 update_qualified_name(decl_base_sptr d)
7757 {return update_qualified_name(d.get());}
7758 
7759 // <scope_decl stuff>
7760 
7761 /// Hash a type by returning the pointer value of its canonical type.
7762 ///
7763 /// @param l the type to hash.
7764 ///
7765 /// @return the the pointer value of the canonical type of @p l.
7766 size_t
operator ()(const type_base_sptr & l) const7767 canonical_type_hash::operator()(const type_base_sptr& l) const
7768 {return operator()(l.get());}
7769 
7770 /// Hash a (canonical) type by returning its pointer value
7771 ///
7772 /// @param l the canonical type to hash.
7773 ///
7774 /// @return the pointer value of the canonical type of @p l.
7775 size_t
operator ()(const type_base * l) const7776 canonical_type_hash::operator()(const type_base *l) const
7777 {return reinterpret_cast<size_t>(l);}
7778 
7779 struct scope_decl::priv
7780 {
7781   declarations members_;
7782   declarations sorted_members_;
7783   type_base_sptrs_type member_types_;
7784   type_base_sptrs_type sorted_member_types_;
7785   scopes member_scopes_;
7786   canonical_type_sptr_set_type canonical_types_;
7787   type_base_sptrs_type sorted_canonical_types_;
7788 }; // end struct scope_decl::priv
7789 
7790 /// Constructor of the @ref scope_decl type.
7791 ///
7792 /// @param the environment to use for the new instance.
7793 ///
7794 /// @param the name of the scope decl.
7795 ///
7796 /// @param locus the source location where the scope_decl is defined.
7797 ///
7798 /// @param vis the visibility of the declaration.
scope_decl(const environment & env,const string & name,const location & locus,visibility vis)7799 scope_decl::scope_decl(const environment& env,
7800 		       const string& name,
7801 		       const location& locus,
7802 		       visibility vis)
7803   : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7804     decl_base(env, name, locus, /*mangled_name=*/name, vis),
7805     priv_(new priv)
7806 {}
7807 
7808 /// Constructor of the @ref scope_decl type.
7809 ///
7810 /// @param the environment to use for the new instance.
7811 ///
7812 /// @param l the source location where the scope_decl is defined.
7813 ///
7814 /// @param vis the visibility of the declaration.
scope_decl(const environment & env,location & l)7815 scope_decl::scope_decl(const environment& env, location& l)
7816   : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7817     decl_base(env, "", l),
7818     priv_(new priv)
7819 {}
7820 
7821 /// @eturn the set of canonical types of the the current scope.
7822 canonical_type_sptr_set_type&
get_canonical_types()7823 scope_decl::get_canonical_types()
7824 {return priv_->canonical_types_;}
7825 
7826 /// @eturn the set of canonical types of the the current scope.
7827 const canonical_type_sptr_set_type&
get_canonical_types() const7828 scope_decl::get_canonical_types() const
7829 {return const_cast<scope_decl*>(this)->get_canonical_types();}
7830 
7831 /// Return a vector of sorted canonical types of the current scope.
7832 ///
7833 /// The types are sorted "almost topologically". That means, they are
7834 /// sorted using the lexicographic order of the string representing
7835 /// the location their definition point.  If a type doesn't have a
7836 /// location, then its pretty representation is used.
7837 ///
7838 /// @return a vector of sorted canonical types of the current scope.
7839 const type_base_sptrs_type&
get_sorted_canonical_types() const7840 scope_decl::get_sorted_canonical_types() const
7841 {
7842   if (priv_->sorted_canonical_types_.empty())
7843     {
7844       for (canonical_type_sptr_set_type::const_iterator e =
7845 	     get_canonical_types().begin();
7846 	   e != get_canonical_types().end();
7847 	   ++e)
7848 	priv_->sorted_canonical_types_.push_back(*e);
7849 
7850       type_topo_comp comp;
7851       std::stable_sort(priv_->sorted_canonical_types_.begin(),
7852 		       priv_->sorted_canonical_types_.end(),
7853 		       comp);
7854     }
7855   return priv_->sorted_canonical_types_;
7856 }
7857 
7858 /// Getter for the member declarations carried by the current @ref
7859 /// scope_decl.
7860 ///
7861 /// @return the member declarations carried by the current @ref
7862 /// scope_decl.
7863 const scope_decl::declarations&
get_member_decls() const7864 scope_decl::get_member_decls() const
7865 {return priv_->members_;}
7866 
7867 /// Getter for the member declarations carried by the current @ref
7868 /// scope_decl.
7869 ///
7870 /// @return the member declarations carried by the current @ref
7871 /// scope_decl.
7872 scope_decl::declarations&
get_member_decls()7873 scope_decl::get_member_decls()
7874 {return priv_->members_;}
7875 
7876 /// Getter for the sorted member declarations carried by the current
7877 /// @ref scope_decl.
7878 ///
7879 /// @return the sorted member declarations carried by the current @ref
7880 /// scope_decl.  The declarations are sorted topologically.
7881 const scope_decl::declarations&
get_sorted_member_decls() const7882 scope_decl::get_sorted_member_decls() const
7883 {
7884   decl_topo_comp comp;
7885   if (priv_->sorted_members_.empty())
7886     {
7887       for (declarations::const_iterator i = get_member_decls().begin();
7888 	   i != get_member_decls().end();
7889 	   ++i)
7890 	priv_->sorted_members_.push_back(*i);
7891 
7892       std::stable_sort(priv_->sorted_members_.begin(),
7893 		       priv_->sorted_members_.end(),
7894 		       comp);
7895     }
7896   return priv_->sorted_members_;
7897 }
7898 
7899 /// Getter for the number of anonymous classes contained in this
7900 /// scope.
7901 ///
7902 /// @return the number of anonymous classes contained in this scope.
7903 size_t
get_num_anonymous_member_classes() const7904 scope_decl::get_num_anonymous_member_classes() const
7905 {
7906   int result = 0;
7907   for (declarations::const_iterator it = get_member_decls().begin();
7908        it != get_member_decls().end();
7909        ++it)
7910     if (class_decl_sptr t = is_class_type(*it))
7911       if (t->get_is_anonymous())
7912 	++result;
7913 
7914   return result;
7915 }
7916 
7917 /// Getter for the number of anonymous unions contained in this
7918 /// scope.
7919 ///
7920 /// @return the number of anonymous unions contained in this scope.
7921 size_t
get_num_anonymous_member_unions() const7922 scope_decl::get_num_anonymous_member_unions() const
7923 {
7924   int result = 0;
7925   for (declarations::const_iterator it = get_member_decls().begin();
7926        it != get_member_decls().end();
7927        ++it)
7928     if (union_decl_sptr t = is_union_type(*it))
7929       if (t->get_is_anonymous())
7930 	++result;
7931 
7932   return result;
7933 }
7934 
7935 /// Getter for the number of anonymous enums contained in this
7936 /// scope.
7937 ///
7938 /// @return the number of anonymous enums contained in this scope.
7939 size_t
get_num_anonymous_member_enums() const7940 scope_decl::get_num_anonymous_member_enums() const
7941 {
7942   int result = 0;
7943   for (declarations::const_iterator it = get_member_decls().begin();
7944        it != get_member_decls().end();
7945        ++it)
7946     if (enum_type_decl_sptr t = is_enum_type(*it))
7947       if (t->get_is_anonymous())
7948 	++result;
7949 
7950   return result;
7951 }
7952 
7953 /// Getter for the scopes carried by the current scope.
7954 ///
7955 /// @return the scopes carried by the current scope.
7956 scope_decl::scopes&
get_member_scopes()7957 scope_decl::get_member_scopes()
7958 {return priv_->member_scopes_;}
7959 
7960 /// Getter for the scopes carried by the current scope.
7961 ///
7962 /// @return the scopes carried by the current scope.
7963 const scope_decl::scopes&
get_member_scopes() const7964 scope_decl::get_member_scopes() const
7965 {return priv_->member_scopes_;}
7966 
7967 /// Test if the current scope is empty.
7968 ///
7969 /// @return true iff the current scope is empty.
7970 bool
is_empty() const7971 scope_decl::is_empty() const
7972 {
7973   return (get_member_decls().empty()
7974 	  && get_canonical_types().empty());
7975 }
7976 
7977 /// Add a member decl to this scope.  Note that user code should not
7978 /// use this, but rather use add_decl_to_scope.
7979 ///
7980 /// Note that this function updates the qualified name of the member
7981 /// decl that is added.  It also sets the scope of the member.  Thus,
7982 /// it ABG_ASSERTs that member should not have its scope set, prior to
7983 /// calling this function.
7984 ///
7985 /// @param member the new member decl to add to this scope.
7986 decl_base_sptr
add_member_decl(const decl_base_sptr & member)7987 scope_decl::add_member_decl(const decl_base_sptr& member)
7988 {
7989   ABG_ASSERT(!has_scope(member));
7990 
7991   member->set_scope(this);
7992   priv_->members_.push_back(member);
7993   if (is_type(member))
7994     priv_->member_types_.push_back(is_type(member));
7995 
7996   if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
7997     priv_->member_scopes_.push_back(m);
7998 
7999   update_qualified_name(member);
8000 
8001   if (translation_unit* tu = get_translation_unit())
8002     {
8003       if (translation_unit* existing_tu = member->get_translation_unit())
8004 	ABG_ASSERT(tu == existing_tu);
8005       else
8006 	member->set_translation_unit(tu);
8007     }
8008 
8009   maybe_update_types_lookup_map(member);
8010 
8011   return member;
8012 }
8013 
8014 /// Get the member types of this @ref scope_decl.
8015 ///
8016 /// @return a vector of the member types of this ref class_or_union.
8017 const type_base_sptrs_type&
get_member_types() const8018 scope_decl::get_member_types() const
8019 {return priv_->member_types_;}
8020 
8021 /// Find a member type of a given name, inside the current @ref
8022 /// scope_decl.
8023 ///
8024 /// @param name the name of the member type to look for.
8025 ///
8026 /// @return a pointer to the @ref type_base that represents the member
8027 /// type of name @p name, for the current scope.
8028 type_base_sptr
find_member_type(const string & name) const8029 scope_decl::find_member_type(const string& name) const
8030 {
8031   for (auto t : get_member_types())
8032     if (get_type_name(t, /*qualified*/false) == name)
8033       return t;
8034   return type_base_sptr();
8035 }
8036 
8037 /// Insert a member type.
8038 ///
8039 /// @param t the type to insert in the @ref scope_decl type.
8040 ///
8041 /// @param an iterator right before which @p t has to be inserted.
8042 void
insert_member_type(type_base_sptr t,declarations::iterator before)8043 scope_decl::insert_member_type(type_base_sptr t,
8044 			       declarations::iterator before)
8045 {
8046   decl_base_sptr d = get_type_declaration(t);
8047   ABG_ASSERT(d);
8048   ABG_ASSERT(!has_scope(d));
8049 
8050   priv_->member_types_.push_back(t);
8051   insert_member_decl(d, before);
8052 }
8053 
8054 /// Add a member type to the current instance of class_or_union.
8055 ///
8056 /// @param t the member type to add.  It must not have been added to a
8057 /// scope, otherwise this will violate an ABG_ASSERTion.
8058 void
add_member_type(type_base_sptr t)8059 scope_decl::add_member_type(type_base_sptr t)
8060 {insert_member_type(t, get_member_decls().end());}
8061 
8062 /// Add a member type to the current instance of class_or_union.
8063 ///
8064 /// @param t the type to be added as a member type to the current
8065 /// instance of class_or_union.  An instance of class_or_union::member_type
8066 /// will be created out of @p t and and added to the the class.
8067 ///
8068 /// @param a the access specifier for the member type to be created.
8069 type_base_sptr
add_member_type(type_base_sptr t,access_specifier a)8070 scope_decl::add_member_type(type_base_sptr t, access_specifier a)
8071 {
8072   decl_base_sptr d = get_type_declaration(t);
8073   ABG_ASSERT(d);
8074   ABG_ASSERT(!is_member_decl(d));
8075   add_member_type(t);
8076   set_member_access_specifier(d, a);
8077   return t;
8078 }
8079 
8080 /// Remove a member type from the current @ref class_or_union scope.
8081 ///
8082 /// @param t the type to remove.
8083 void
remove_member_type(type_base_sptr t)8084 scope_decl::remove_member_type(type_base_sptr t)
8085 {
8086   for (auto i = priv_->member_types_.begin();
8087        i != priv_->member_types_.end();
8088        ++i)
8089     {
8090       if (*((*i)) == *t)
8091 	{
8092 	  priv_->member_types_.erase(i);
8093 	  return;
8094 	}
8095     }
8096 }
8097 
8098 /// Get the sorted member types of this @ref scope_decl
8099 ///
8100 /// @return a vector of the sorted member types of this ref
8101 /// class_or_union.
8102 const type_base_sptrs_type&
get_sorted_member_types() const8103 scope_decl::get_sorted_member_types() const
8104 {
8105   if (priv_->sorted_member_types_.empty())
8106     {
8107       for (auto t : get_member_types())
8108 	priv_->sorted_member_types_.push_back(t);
8109 
8110       type_topo_comp comp;
8111       std::stable_sort(priv_->sorted_member_types_.begin(),
8112 		       priv_->sorted_member_types_.end(),
8113 		       comp);
8114     }
8115   return priv_->sorted_member_types_;
8116 }
8117 
8118 /// Insert a member decl to this scope, right before an element
8119 /// pointed to by a given iterator.  Note that user code should not
8120 /// use this, but rather use insert_decl_into_scope.
8121 ///
8122 /// Note that this function updates the qualified name of the inserted
8123 /// member.
8124 ///
8125 /// @param member the new member decl to add to this scope.
8126 ///
8127 /// @param before an interator pointing to the element before which
8128 /// the new member should be inserted.
8129 decl_base_sptr
insert_member_decl(decl_base_sptr member,declarations::iterator before)8130 scope_decl::insert_member_decl(decl_base_sptr member,
8131 			       declarations::iterator before)
8132 {
8133   ABG_ASSERT(!member->get_scope());
8134 
8135   member->set_scope(this);
8136   priv_->members_.insert(before, member);
8137 
8138   if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8139    priv_-> member_scopes_.push_back(m);
8140 
8141   update_qualified_name(member);
8142 
8143   if (translation_unit* tu = get_translation_unit())
8144     {
8145       if (translation_unit* existing_tu = member->get_translation_unit())
8146 	ABG_ASSERT(tu == existing_tu);
8147       else
8148 	member->set_translation_unit(tu);
8149     }
8150 
8151   maybe_update_types_lookup_map(member);
8152 
8153   return member;
8154 }
8155 
8156 /// Remove a declaration from the current scope.
8157 ///
8158 /// @param member the declaration to remove from the scope.
8159 void
remove_member_decl(decl_base_sptr member)8160 scope_decl::remove_member_decl(decl_base_sptr member)
8161 {
8162   for (declarations::iterator i = priv_->members_.begin();
8163        i != priv_->members_.end();
8164        ++i)
8165     {
8166       if (**i == *member)
8167 	{
8168 	  priv_->members_.erase(i);
8169 	  // Do not access i after this point as it's invalided by the
8170 	  // erase call.
8171 	  break;
8172 	}
8173     }
8174 
8175   scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
8176   if (scope)
8177     {
8178       for (scopes::iterator i = priv_->member_scopes_.begin();
8179 	   i != priv_->member_scopes_.end();
8180 	   ++i)
8181 	{
8182 	  if (**i == *member)
8183 	    {
8184 	      priv_->member_scopes_.erase(i);
8185 	      break;
8186 	    }
8187 	}
8188     }
8189 }
8190 
8191 /// Return the hash value for the current instance of scope_decl.
8192 ///
8193 /// This method can trigger the computing of the hash value, if need be.
8194 ///
8195 /// @return the hash value.
8196 size_t
get_hash() const8197 scope_decl::get_hash() const
8198 {
8199   scope_decl::hash hash_scope;
8200   return hash_scope(this);
8201 }
8202 
8203 /// Compares two instances of @ref scope_decl.
8204 ///
8205 /// If the two intances are different, set a bitfield to give some
8206 /// insight about the kind of differences there are.
8207 ///
8208 /// @param l the first artifact of the comparison.
8209 ///
8210 /// @param r the second artifact of the comparison.
8211 ///
8212 /// @param k a pointer to a bitfield that gives information about the
8213 /// kind of changes there are between @p l and @p r.  This one is set
8214 /// iff @p k is non-null and the function returns false.
8215 ///
8216 /// Please note that setting k to a non-null value does have a
8217 /// negative performance impact because even if @p l and @p r are not
8218 /// equal, the function keeps up the comparison in order to determine
8219 /// the different kinds of ways in which they are different.
8220 ///
8221 /// @return true if @p l equals @p r, false otherwise.
8222 bool
equals(const scope_decl & l,const scope_decl & r,change_kind * k)8223 equals(const scope_decl& l, const scope_decl& r, change_kind* k)
8224 {
8225   bool result = true;
8226 
8227   if (!l.decl_base::operator==(r))
8228     {
8229       result = false;
8230       if (k)
8231 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
8232       else
8233 	ABG_RETURN_FALSE;
8234     }
8235 
8236   scope_decl::declarations::const_iterator i, j;
8237   for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
8238        i != l.get_member_decls().end() && j != r.get_member_decls().end();
8239        ++i, ++j)
8240     {
8241       if (**i != **j)
8242 	{
8243 	  result = false;
8244 	  if (k)
8245 	    {
8246 	      *k |= SUBTYPE_CHANGE_KIND;
8247 	      break;
8248 	    }
8249 	  else
8250 	    ABG_RETURN_FALSE;
8251 	}
8252     }
8253 
8254   if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
8255     {
8256       result = false;
8257       if (k)
8258 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
8259       else
8260 	ABG_RETURN_FALSE;
8261     }
8262 
8263   ABG_RETURN(result);
8264 }
8265 
8266 /// Return true iff both scopes have the same names and have the same
8267 /// member decls.
8268 ///
8269 /// This function doesn't check for equality of the scopes of its
8270 /// arguments.
8271 bool
operator ==(const decl_base & o) const8272 scope_decl::operator==(const decl_base& o) const
8273 {
8274   const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
8275   if (!other)
8276     return false;
8277 
8278   return equals(*this, *other, 0);
8279 }
8280 
8281 /// Equality operator for @ref scope_decl_sptr.
8282 ///
8283 /// @param l the left hand side operand of the equality operator.
8284 ///
8285 /// @pram r the right hand side operand of the equalify operator.
8286 ///
8287 /// @return true iff @p l equals @p r.
8288 bool
operator ==(const scope_decl_sptr & l,const scope_decl_sptr & r)8289 operator==(const scope_decl_sptr& l, const scope_decl_sptr& r)
8290 {
8291   if (!!l != !!r)
8292     return false;
8293   if (l.get() == r.get())
8294     return true;
8295   return *l == *r;
8296 }
8297 
8298 /// Inequality operator for @ref scope_decl_sptr.
8299 ///
8300 /// @param l the left hand side operand of the equality operator.
8301 ///
8302 /// @pram r the right hand side operand of the equalify operator.
8303 ///
8304 /// @return true iff @p l equals @p r.
8305 bool
operator !=(const scope_decl_sptr & l,const scope_decl_sptr & r)8306 operator!=(const scope_decl_sptr& l, const scope_decl_sptr& r)
8307 {return !operator==(l, r);}
8308 
8309 /// Find a member of the current scope and return an iterator on it.
8310 ///
8311 /// @param decl the scope member to find.
8312 ///
8313 /// @param i the iterator to set to the member @p decl.  This is set
8314 /// iff the function returns true.
8315 ///
8316 /// @return true if the member decl was found, false otherwise.
8317 bool
find_iterator_for_member(const decl_base * decl,declarations::iterator & i)8318 scope_decl::find_iterator_for_member(const decl_base* decl,
8319 				     declarations::iterator& i)
8320 {
8321   if (!decl)
8322     return false;
8323 
8324   if (get_member_decls().empty())
8325     {
8326       i = get_member_decls().end();
8327       return false;
8328     }
8329 
8330   for (declarations::iterator it = get_member_decls().begin();
8331        it != get_member_decls().end();
8332        ++it)
8333     {
8334       if ((*it).get() == decl)
8335 	{
8336 	  i = it;
8337 	  return true;
8338 	}
8339     }
8340 
8341   return false;
8342 }
8343 
8344 /// Find a member of the current scope and return an iterator on it.
8345 ///
8346 /// @param decl the scope member to find.
8347 ///
8348 /// @param i the iterator to set to the member @p decl.  This is set
8349 /// iff the function returns true.
8350 ///
8351 /// @return true if the member decl was found, false otherwise.
8352 bool
find_iterator_for_member(const decl_base_sptr decl,declarations::iterator & i)8353 scope_decl::find_iterator_for_member(const decl_base_sptr decl,
8354 				     declarations::iterator& i)
8355 {return find_iterator_for_member(decl.get(), i);}
8356 
8357 /// This implements the ir_traversable_base::traverse pure virtual
8358 /// function.
8359 ///
8360 /// @param v the visitor used on the current instance of scope_decl
8361 /// and on its member nodes.
8362 ///
8363 /// @return true if the traversal of the tree should continue, false
8364 /// otherwise.
8365 bool
traverse(ir_node_visitor & v)8366 scope_decl::traverse(ir_node_visitor &v)
8367 {
8368   if (visiting())
8369     return true;
8370 
8371   if (v.visit_begin(this))
8372     {
8373       visiting(true);
8374       for (scope_decl::declarations::const_iterator i =
8375 	     get_member_decls().begin();
8376 	   i != get_member_decls ().end();
8377 	   ++i)
8378 	if (!(*i)->traverse(v))
8379 	  break;
8380       visiting(false);
8381     }
8382   return v.visit_end(this);
8383 }
8384 
~scope_decl()8385 scope_decl::~scope_decl()
8386 {}
8387 
8388 /// Appends a declaration to a given scope, if the declaration
8389 /// doesn't already belong to one and if the declaration is not for a
8390 /// type that is supposed to be unique.
8391 ///
8392 /// @param decl the declaration to add to the scope
8393 ///
8394 /// @param scope the scope to append the declaration to
8395 decl_base_sptr
add_decl_to_scope(decl_base_sptr decl,scope_decl * scope)8396 add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8397 {
8398   ABG_ASSERT(scope);
8399 
8400   if (scope && decl && !decl->get_scope())
8401     decl = scope->add_member_decl(decl);
8402 
8403   return decl;
8404 }
8405 
8406 /// Appends a declaration to a given scope, if the declaration doesn't
8407 /// already belong to a scope.
8408 ///
8409 /// @param decl the declaration to add append to the scope
8410 ///
8411 /// @param scope the scope to append the decl to
8412 decl_base_sptr
add_decl_to_scope(decl_base_sptr decl,const scope_decl_sptr & scope)8413 add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8414 {return add_decl_to_scope(decl, scope.get());}
8415 
8416 /// Remove a given decl from its scope
8417 ///
8418 /// @param decl the decl to remove from its scope.
8419 void
remove_decl_from_scope(decl_base_sptr decl)8420 remove_decl_from_scope(decl_base_sptr decl)
8421 {
8422   if (!decl)
8423     return;
8424 
8425   scope_decl* scope = decl->get_scope();
8426   scope->remove_member_decl(decl);
8427   decl->set_scope(0);
8428 }
8429 
8430 /// Inserts a declaration into a given scope, before a given IR child
8431 /// node of the scope.
8432 ///
8433 /// @param decl the declaration to insert into the scope.
8434 ///
8435 /// @param before an iterator pointing to the child IR node before
8436 /// which to insert the declaration.
8437 ///
8438 /// @param scope the scope into which to insert the declaration.
8439 decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,scope_decl::declarations::iterator before,scope_decl * scope)8440 insert_decl_into_scope(decl_base_sptr decl,
8441 		       scope_decl::declarations::iterator before,
8442 		       scope_decl* scope)
8443 {
8444   if (scope && decl && !decl->get_scope())
8445     {
8446       decl_base_sptr d = scope->insert_member_decl(decl, before);
8447       decl = d;
8448     }
8449   return decl;
8450 }
8451 
8452 /// Inserts a declaration into a given scope, before a given IR child
8453 /// node of the scope.
8454 ///
8455 /// @param decl the declaration to insert into the scope.
8456 ///
8457 /// @param before an iterator pointing to the child IR node before
8458 /// which to insert the declaration.
8459 ///
8460 /// @param scope the scope into which to insert the declaration.
8461 decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,scope_decl::declarations::iterator before,scope_decl_sptr scope)8462 insert_decl_into_scope(decl_base_sptr decl,
8463 		       scope_decl::declarations::iterator before,
8464 		       scope_decl_sptr scope)
8465 {return insert_decl_into_scope(decl, before, scope.get());}
8466 
8467 /// Constructor of the @ref global_scope type.
8468 ///
8469 /// @param tu the translation unit the scope belongs to.
global_scope(translation_unit * tu)8470 global_scope::global_scope(translation_unit *tu)
8471   : type_or_decl_base(tu->get_environment(),
8472 		      GLOBAL_SCOPE_DECL
8473 		      | ABSTRACT_DECL_BASE
8474 		      | ABSTRACT_SCOPE_DECL),
8475     decl_base(tu->get_environment(), "", location()),
8476     scope_decl(tu->get_environment(), "", location()),
8477     translation_unit_(tu)
8478 {
8479   runtime_type_instance(this);
8480 }
8481 
8482 /// return the global scope as seen by a given declaration.
8483 ///
8484 /// @param decl the declaration to consider.
8485 ///
8486 /// @return the global scope of the decl, or a null pointer if the
8487 /// decl is not yet added to a translation_unit.
8488 const global_scope*
get_global_scope(const decl_base & decl)8489 get_global_scope(const decl_base& decl)
8490 {
8491   if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8492     return s;
8493 
8494   scope_decl* scope = decl.get_scope();
8495   while (scope && !dynamic_cast<global_scope*>(scope))
8496     scope = scope->get_scope();
8497 
8498   return scope ? dynamic_cast<global_scope*> (scope) : 0;
8499 }
8500 
8501 /// return the global scope as seen by a given declaration.
8502 ///
8503 /// @param decl the declaration to consider.
8504 ///
8505 /// @return the global scope of the decl, or a null pointer if the
8506 /// decl is not yet added to a translation_unit.
8507 const global_scope*
get_global_scope(const decl_base * decl)8508 get_global_scope(const decl_base* decl)
8509 {return get_global_scope(*decl);}
8510 
8511 /// Return the global scope as seen by a given declaration.
8512 ///
8513 /// @param decl the declaration to consider.
8514 ///
8515 /// @return the global scope of the decl, or a null pointer if the
8516 /// decl is not yet added to a translation_unit.
8517 const global_scope*
get_global_scope(const shared_ptr<decl_base> decl)8518 get_global_scope(const shared_ptr<decl_base> decl)
8519 {return get_global_scope(decl.get());}
8520 
8521 /// Return the a scope S containing a given declaration and that is
8522 /// right under a given scope P.
8523 ///
8524 /// Note that @p scope must come before @p decl in topological
8525 /// order.
8526 ///
8527 /// @param decl the decl for which to find a scope.
8528 ///
8529 /// @param scope the scope under which the resulting scope must be.
8530 ///
8531 /// @return the resulting scope.
8532 const scope_decl*
get_top_most_scope_under(const decl_base * decl,const scope_decl * scope)8533 get_top_most_scope_under(const decl_base* decl,
8534 			 const scope_decl* scope)
8535 {
8536   if (!decl)
8537     return 0;
8538 
8539   if (scope == 0)
8540     return get_global_scope(decl);
8541 
8542   // Handle the case where decl is a scope itself.
8543   const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8544   if (!s)
8545     s = decl->get_scope();
8546 
8547   if (is_global_scope(s))
8548     return scope;
8549 
8550   // Here, decl is in the scope 'scope', or decl and 'scope' are the
8551   // same.  The caller needs to be prepared to deal with this case.
8552   if (s == scope)
8553     return s;
8554 
8555   while (s && !is_global_scope(s) && s->get_scope() != scope)
8556     s = s->get_scope();
8557 
8558   if (!s || is_global_scope(s))
8559     // SCOPE must come before decl in topological order, but I don't
8560     // know how to ensure that ...
8561     return scope;
8562   ABG_ASSERT(s);
8563 
8564   return s;
8565 }
8566 
8567 /// Return the a scope S containing a given declaration and that is
8568 /// right under a given scope P.
8569 ///
8570 /// @param decl the decl for which to find a scope.
8571 ///
8572 /// @param scope the scope under which the resulting scope must be.
8573 ///
8574 /// @return the resulting scope.
8575 const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,const scope_decl * scope)8576 get_top_most_scope_under(const decl_base_sptr decl,
8577 			 const scope_decl* scope)
8578 {return get_top_most_scope_under(decl.get(), scope);}
8579 
8580 /// Return the a scope S containing a given declaration and that is
8581 /// right under a given scope P.
8582 ///
8583 /// @param decl the decl for which to find a scope.
8584 ///
8585 /// @param scope the scope under which the resulting scope must be.
8586 ///
8587 /// @return the resulting scope.
8588 const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,const scope_decl_sptr scope)8589 get_top_most_scope_under(const decl_base_sptr decl,
8590 			 const scope_decl_sptr scope)
8591 {return get_top_most_scope_under(decl, scope.get());}
8592 
8593 // </scope_decl stuff>
8594 
8595 
8596 /// Get the string representation of a CV qualifier bitmap.
8597 ///
8598 /// @param cv_quals the bitmap of CV qualifiers to consider.
8599 ///
8600 /// @return the string representation.
8601 string
get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)8602 get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)
8603 {
8604   string repr;
8605   if (cv_quals & qualified_type_def::CV_RESTRICT)
8606     repr = "restrict";
8607   if (cv_quals & qualified_type_def::CV_CONST)
8608     {
8609       if (!repr.empty())
8610 	repr += ' ';
8611       repr += "const";
8612     }
8613   if (cv_quals & qualified_type_def::CV_VOLATILE)
8614     {
8615       if (!repr.empty())
8616 	repr += ' ';
8617       repr += "volatile";
8618     }
8619   return repr;
8620 }
8621 
8622 /// Build and return a copy of the name of an ABI artifact that is
8623 /// either a type or a decl.
8624 ///
8625 /// @param tod the ABI artifact to get the name for.
8626 ///
8627 /// @param qualified if yes, return the qualified name of @p tod;
8628 /// otherwise, return the non-qualified name;
8629 ///
8630 /// @return the name of @p tod.
8631 string
get_name(const type_or_decl_base * tod,bool qualified)8632 get_name(const type_or_decl_base *tod, bool qualified)
8633 {
8634   string result;
8635 
8636   type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8637 
8638   if (type_base* t = dynamic_cast<type_base*>(a))
8639     result = get_type_name(t, qualified);
8640   else if (decl_base *d = dynamic_cast<decl_base*>(a))
8641     {
8642       if (qualified)
8643 	result = d->get_qualified_name();
8644       else
8645 	result = d->get_name();
8646     }
8647   else
8648     // We should never reach this point.
8649     abort();
8650 
8651   return result;
8652 }
8653 
8654 /// Build and return a copy of the name of an ABI artifact that is
8655 /// either a type of a decl.
8656 ///
8657 /// @param tod the ABI artifact to get the name for.
8658 ///
8659 /// @param qualified if yes, return the qualified name of @p tod;
8660 /// otherwise, return the non-qualified name;
8661 ///
8662 /// @return the name of @p tod.
8663 string
get_name(const type_or_decl_base_sptr & tod,bool qualified)8664 get_name(const type_or_decl_base_sptr& tod, bool qualified)
8665 {return get_name(tod.get(), qualified);}
8666 
8667 /// Build and return a qualified name from a name and its scope.
8668 ///
8669 /// The name is supposed to be for an entity that is part of the
8670 /// scope.
8671 ///
8672 /// @param the scope to consider.
8673 ///
8674 /// @param name of the name to consider.
8675 ///
8676 /// @return a copy of the string that represents the qualified name.
8677 string
build_qualified_name(const scope_decl * scope,const string & name)8678 build_qualified_name(const scope_decl* scope, const string& name)
8679 {
8680   if (name.empty())
8681     return "";
8682 
8683   string qualified_name;
8684   if (scope)
8685     qualified_name = scope->get_qualified_name();
8686 
8687   if (qualified_name.empty())
8688     qualified_name = name;
8689   else
8690     qualified_name = qualified_name + "::" + name;
8691 
8692   return qualified_name;
8693 }
8694 
8695 /// Build and return the qualified name of a type in its scope.
8696 ///
8697 /// @param scope the scope of the type to consider.
8698 ///
8699 /// @param type the type to consider.
8700 string
build_qualified_name(const scope_decl * scope,const type_base_sptr & type)8701 build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8702 {return build_qualified_name(scope, get_name((type)));}
8703 
8704 // </scope_decl stuff>
8705 
8706 /// Get the location of the declaration of a given type.
8707 ///
8708 /// @param type the type to consider.
8709 ///
8710 /// @return the location of the declaration of type @p type.
8711 location
get_location(const type_base_sptr & type)8712 get_location(const type_base_sptr& type)
8713 {
8714   if (decl_base_sptr decl = get_type_declaration(type))
8715     return get_location(decl);
8716   return location();
8717 }
8718 
8719 /// Get the location of a given declaration.
8720 ///
8721 /// @param decl the declaration to consider.
8722 ///
8723 /// @return the location of the declaration @p decl.
8724 location
get_location(const decl_base_sptr & decl)8725 get_location(const decl_base_sptr& decl)
8726 {
8727   location loc = decl->get_location();
8728   if (!loc)
8729     {
8730       if (class_or_union_sptr c = is_class_or_union_type(decl))
8731 	if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8732 	  {
8733 	    c = is_class_or_union_type(c->get_definition_of_declaration());
8734 	    loc = c->get_location();
8735 	  }
8736     }
8737   return loc;
8738 }
8739 
8740 /// Get the scope of a given type.
8741 ///
8742 /// @param t the type to consider.
8743 ///
8744 /// @return the scope of type @p t or 0 if the type has no scope yet.
8745 scope_decl*
get_type_scope(type_base * t)8746 get_type_scope(type_base* t)
8747 {
8748   if (!t)
8749     return 0;
8750 
8751   decl_base* d = get_type_declaration(t);
8752   if (d)
8753     return d->get_scope();
8754   return 0;
8755 }
8756 
8757 /// Get the scope of a given type.
8758 ///
8759 /// @param t the type to consider.
8760 ///
8761 /// @return the scope of type @p t or 0 if the type has no scope yet.
8762 scope_decl*
get_type_scope(const type_base_sptr & t)8763 get_type_scope(const type_base_sptr& t)
8764 {return get_type_scope(t.get());}
8765 
8766 /// Get the name of a given type and return a copy of it.
8767 ///
8768 /// @param t the type to consider.
8769 ///
8770 /// @param qualified if true then return the qualified name of the
8771 /// type.
8772 ///
8773 /// @param internal set to true if the call is intended for an
8774 /// internal use (for technical use inside the library itself), false
8775 /// otherwise.  If you don't know what this is for, then set it to
8776 /// false.
8777 ///
8778 /// @return a copy of the type name if the type has a name, or the
8779 /// empty string if it does not.
8780 interned_string
get_type_name(const type_base_sptr & t,bool qualified,bool internal)8781 get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8782 {return get_type_name(t.get(), qualified, internal);}
8783 
8784 /// Return true iff a decl is for a type type that has a generic
8785 /// anonymous internal type name.
8786 ///
8787 /// @param d the decl to considier.
8788 ///
8789 /// @return true iff @p d is for a type type that has a generic
8790 /// anonymous internal type name.
8791 static bool
has_generic_anonymous_internal_type_name(const decl_base * d)8792 has_generic_anonymous_internal_type_name(const decl_base *d)
8793 {
8794   return (is_class_or_union_type(d)
8795 	  || is_enum_type(d)
8796 	  || is_subrange_type(d));
8797 }
8798 
8799 /// Return the generic internal name of an anonymous type.
8800 ///
8801 /// For internal purposes, we want to define a generic name for all
8802 /// anonymous types of a certain kind.  For instance, all anonymous
8803 /// structs will be have a generic name of "__anonymous_struct__", all
8804 /// anonymous unions will have a generic name of
8805 /// "__anonymous_union__", etc.
8806 ///
8807 /// That generic name can be used as a hash to put all anonymous types
8808 /// of a certain kind in the same hash table bucket, for instance.
8809 static interned_string
get_generic_anonymous_internal_type_name(const decl_base * d)8810 get_generic_anonymous_internal_type_name(const decl_base *d)
8811 {
8812   ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8813 
8814   const environment&env = d->get_environment();
8815 
8816   interned_string result;
8817   if (is_class_type(d))
8818     result =
8819       env.intern(tools_utils::get_anonymous_struct_internal_name_prefix());
8820   else if (is_union_type(d))
8821     result =
8822       env.intern(tools_utils::get_anonymous_union_internal_name_prefix());
8823   else if (is_enum_type(d))
8824     result =
8825       env.intern(tools_utils::get_anonymous_enum_internal_name_prefix());
8826   else if (is_subrange_type(d))
8827     result =
8828       env.intern(tools_utils::get_anonymous_subrange_internal_name_prefix());
8829   else
8830     ABG_ASSERT_NOT_REACHED;
8831 
8832   return result;
8833 }
8834 
8835 /// Get the internal name for a given integral type.
8836 ///
8837 /// All integral types that have the modifiers 'short, long or long
8838 /// long' have the same internal name.  This is so that they can all
8839 /// have the same canonical type if they are of the same size.
8840 /// Otherwise, 'long int' and 'long long int' would have different
8841 /// canonical types even though they are equivalent from an ABI point
8842 /// of view.
8843 ///
8844 /// @param t the integral type to consider
8845 ///
8846 /// @return the internal name for @p t if it's an integral type, or
8847 /// the empty string if @p t is not an integral type.
8848 static string
get_internal_integral_type_name(const type_base * t)8849 get_internal_integral_type_name(const type_base* t)
8850 {
8851   string name;
8852   type_decl *type = is_integral_type(t);
8853 
8854   if (!type)
8855     return name;
8856 
8857   integral_type int_type;
8858   if (parse_integral_type(type->get_name(), int_type))
8859     name = int_type.to_string(/*internal=*/true);
8860 
8861   return name;
8862 }
8863 
8864 /// Get the name of a given type and return a copy of it.
8865 ///
8866 /// @param t the type to consider.
8867 ///
8868 /// @param qualified if true then return the qualified name of the
8869 /// type.
8870 ///
8871 /// @param internal set to true if the call is intended for an
8872 /// internal use (for technical use inside the library itself), false
8873 /// otherwise.  If you don't know what this is for, then set it to
8874 /// false.
8875 ///
8876 /// @return a copy of the type name if the type has a name, or the
8877 /// empty string if it does not.
8878 interned_string
get_type_name(const type_base * t,bool qualified,bool internal)8879 get_type_name(const type_base* t, bool qualified, bool internal)
8880 {
8881   const decl_base* d = dynamic_cast<const decl_base*>(t);
8882   if (!d)
8883     {
8884       const function_type* fn_type = is_function_type(t);
8885       ABG_ASSERT(fn_type);
8886       return fn_type->get_cached_name(internal);
8887     }
8888 
8889   const environment&env = d->get_environment();
8890 
8891   // All anonymous types of a given kind get to have the same internal
8892   // name for internal purpose.  This to allow them to be compared
8893   // among themselves during type canonicalization.
8894   if (internal)
8895     {
8896       if (d->get_is_anonymous())
8897 	{
8898 	  string r;
8899 	  r += get_generic_anonymous_internal_type_name(d);
8900 	  return t->get_environment().intern(r);
8901 	}
8902 
8903       if (is_typedef(t))
8904 	return d->get_name();
8905 
8906       if (qualified)
8907 	return d->get_qualified_name(internal);
8908 
8909       return env.intern(get_internal_integral_type_name(t));
8910     }
8911 
8912   if (d->get_is_anonymous())
8913     {
8914       if (is_class_or_union_type(t) || is_enum_type(t))
8915 	return env.intern
8916 	  (get_class_or_enum_flat_representation (*t, "",
8917 						  /*one_line=*/true,
8918 						  internal, qualified));
8919     }
8920 
8921   if (qualified)
8922     return d->get_qualified_name(internal);
8923   return d->get_name();
8924 }
8925 
8926 /// Get the name of a given type and return a copy of it.
8927 ///
8928 /// @param t the type to consider.
8929 ///
8930 /// @param qualified if true then return the qualified name of the
8931 /// type.
8932 ///
8933 /// @param internal set to true if the call is intended for an
8934 /// internal use (for technical use inside the library itself), false
8935 /// otherwise.  If you don't know what this is for, then set it to
8936 /// false.
8937 ///
8938 /// @return a copy of the type name if the type has a name, or the
8939 /// empty string if it does not.
8940 interned_string
get_type_name(const type_base & t,bool qualified,bool internal)8941 get_type_name(const type_base& t, bool qualified, bool internal)
8942 {return get_type_name(&t, qualified, internal);}
8943 
8944 /// Get the name of the pointer to a given type.
8945 ///
8946 /// @param pointed_to_type the pointed-to-type to consider.
8947 ///
8948 /// @param qualified this is true if the resulting name should be of a
8949 /// pointer to a *fully-qualified* pointed-to-type.
8950 ///
8951 /// @param internal true if the name is for libabigail-internal
8952 /// purposes.
8953 ///
8954 /// @return the name (string representation) of the pointer.
8955 interned_string
get_name_of_pointer_to_type(const type_base & pointed_to_type,bool qualified,bool internal)8956 get_name_of_pointer_to_type(const type_base& pointed_to_type,
8957 			    bool qualified, bool internal)
8958 {
8959   const environment& env = pointed_to_type.get_environment();
8960   string tn = get_type_name(pointed_to_type, qualified, internal);
8961   tn =  tn + "*";
8962 
8963   return env.intern(tn);
8964 }
8965 
8966 /// Get the name of the reference to a given type.
8967 ///
8968 /// @param pointed_to_type the pointed-to-type to consider.
8969 ///
8970 /// @param qualified this is true if the resulting name should be of a
8971 /// reference to a *fully-qualified* pointed-to-type.
8972 ///
8973 /// @param internal true if the name is for libabigail-internal
8974 /// purposes.
8975 ///
8976 /// @return the name (string representation) of the reference.
8977 interned_string
get_name_of_reference_to_type(const type_base & pointed_to_type,bool lvalue_reference,bool qualified,bool internal)8978 get_name_of_reference_to_type(const type_base& pointed_to_type,
8979 			      bool lvalue_reference,
8980 			      bool qualified, bool internal)
8981 {
8982   const environment& env = pointed_to_type.get_environment();
8983 
8984   string name = get_type_name(pointed_to_type, qualified, internal);
8985   if (lvalue_reference)
8986     name = name + "&";
8987   else
8988     name = name + "&&";
8989 
8990   return env.intern(name);
8991 }
8992 
8993 /// Get the name of a qualified type, given the underlying type and
8994 /// its qualifiers.
8995 ///
8996 /// @param underlying_type the underlying type to consider.
8997 ///
8998 /// @param quals the CV qualifiers of the name.
8999 ///
9000 /// @param qualified true if we should consider the fully qualified
9001 /// name of @p underlying_type.
9002 ///
9003 /// @param internal true if the result is to be used for
9004 /// libabigail-internal purposes.
9005 ///
9006 /// @return the name (string representation) of the qualified type.
9007 interned_string
get_name_of_qualified_type(const type_base_sptr & underlying_type,qualified_type_def::CV quals,bool qualified,bool internal)9008 get_name_of_qualified_type(const type_base_sptr& underlying_type,
9009 			   qualified_type_def::CV quals,
9010 			   bool qualified, bool internal)
9011 {
9012   const environment& env = underlying_type->get_environment();
9013 
9014   string quals_repr = get_string_representation_of_cv_quals(quals);
9015   string name = get_type_name(underlying_type, qualified, internal);
9016 
9017   if (quals_repr.empty() && internal)
9018     // We are asked to return the internal name, that might be used
9019     // for type canonicalization.  For that canonicalization, we need
9020     // to make a difference between a no-op qualified type which
9021     // underlying type is foo (the qualified type is named "none
9022     // foo"), and the name of foo, which is just "foo".
9023     //
9024     // Please remember that this has to be kept in sync with what is
9025     // done in die_qualified_name, in abg-dwarf-reader.cc.  So if you
9026     // change this code here, please change that code there too.
9027     quals_repr = "";
9028 
9029   if (!quals_repr.empty())
9030     {
9031       if (is_pointer_type(peel_qualified_type(underlying_type))
9032 	  || is_reference_type(peel_qualified_type(underlying_type)))
9033 	{
9034 	  name += " ";
9035 	  name += quals_repr;
9036 	}
9037       else
9038 	name = quals_repr + " " + name;
9039     }
9040 
9041   return env.intern(name);
9042 }
9043 
9044 /// Get the name of a given function type and return a copy of it.
9045 ///
9046 /// @param fn_type the function type to consider.
9047 ///
9048 /// @param internal set to true if the call is intended for an
9049 /// internal use (for technical use inside the library itself), false
9050 /// otherwise.  If you don't know what this is for, then set it to
9051 /// false.
9052 ///
9053 /// @return a copy of the function type name
9054 interned_string
get_function_type_name(const function_type_sptr & fn_type,bool internal)9055 get_function_type_name(const function_type_sptr& fn_type,
9056 		       bool internal)
9057 {return get_function_type_name(fn_type.get(), internal);}
9058 
9059 /// Get the name of a given function type and return a copy of it.
9060 ///
9061 /// @param fn_type the function type to consider.
9062 ///
9063 /// @param internal set to true if the call is intended for an
9064 /// internal use (for technical use inside the library itself), false
9065 /// otherwise.  If you don't know what this is for, then set it to
9066 /// false.
9067 ///
9068 /// @return a copy of the function type name
9069 interned_string
get_function_type_name(const function_type * fn_type,bool internal)9070 get_function_type_name(const function_type* fn_type,
9071 		       bool internal)
9072 {
9073   ABG_ASSERT(fn_type);
9074 
9075   if (const method_type* method = is_method_type(fn_type))
9076     return get_method_type_name(method, internal);
9077 
9078   return get_function_type_name(*fn_type, internal);
9079 }
9080 
9081 /// Get the name of a given function type and return a copy of it.
9082 ///
9083 /// @param fn_type the function type to consider.
9084 ///
9085 /// @param internal set to true if the call is intended for an
9086 /// internal use (for technical use inside the library itself), false
9087 /// otherwise.  If you don't know what this is for, then set it to
9088 /// false.
9089 ///
9090 /// @return a copy of the function type name
9091 interned_string
get_function_type_name(const function_type & fn_type,bool internal)9092 get_function_type_name(const function_type& fn_type,
9093 		       bool internal)
9094 {
9095   std::ostringstream o;
9096   // When the function name is used for internal purposes (e.g, for
9097   // canonicalization), we want its representation to stay the same,
9098   // regardless of typedefs.  So let's strip typedefs from the return
9099   // type.
9100   type_base_sptr return_type =
9101     internal
9102     ? peel_typedef_type(fn_type.get_return_type())
9103     : fn_type.get_return_type();
9104   const environment& env = fn_type.get_environment();
9105 
9106   o <<  get_pretty_representation(return_type, internal);
9107 
9108   o << " (";
9109   type_base_sptr type;
9110   for (function_type::parameters::const_iterator i =
9111 	 fn_type.get_parameters().begin();
9112        i != fn_type.get_parameters().end();
9113        ++i)
9114     {
9115       if (i != fn_type.get_parameters().begin())
9116 	o << ", ";
9117       type = (*i)->get_type();
9118       if (internal)
9119 	type = peel_typedef_type(type);
9120       o << get_pretty_representation(type, internal);
9121     }
9122   o <<")";
9123 
9124   return env.intern(o.str());
9125 }
9126 
9127 /// Get the ID of a function, or, if the ID can designate several
9128 /// different functions, get its pretty representation.
9129 ///
9130 /// @param fn the function to consider
9131 ///
9132 /// @return the function ID of pretty representation of @p fn.
9133 interned_string
get_function_id_or_pretty_representation(function_decl * fn)9134 get_function_id_or_pretty_representation(function_decl *fn)
9135 {
9136   ABG_ASSERT(fn);
9137 
9138   interned_string result = fn->get_environment().intern(fn->get_id());
9139 
9140   if (corpus *c = fn->get_corpus())
9141     {
9142       corpus::exported_decls_builder_sptr b =
9143 	c->get_exported_decls_builder();
9144       if (b->fn_id_maps_to_several_fns(fn))
9145 	result = fn->get_environment().intern(fn->get_pretty_representation());
9146     }
9147 
9148   return result;
9149 }
9150 
9151 /// Get the name of a given method type and return a copy of it.
9152 ///
9153 /// @param fn_type the function type to consider.
9154 ///
9155 /// @param internal set to true if the call is intended for an
9156 /// internal use (for technical use inside the library itself), false
9157 /// otherwise.  If you don't know what this is for, then set it to
9158 /// false.
9159 ///
9160 /// @return a copy of the function type name
9161 interned_string
get_method_type_name(const method_type_sptr fn_type,bool internal)9162 get_method_type_name(const method_type_sptr fn_type,
9163 		     bool internal)
9164 {return get_method_type_name(fn_type.get(), internal);}
9165 
9166 /// Get the name of a given method type and return a copy of it.
9167 ///
9168 /// @param fn_type the function type to consider.
9169 ///
9170 /// @param internal set to true if the call is intended for an
9171 /// internal use (for technical use inside the library itself), false
9172 /// otherwise.  If you don't know what this is for, then set it to
9173 /// false.
9174 ///
9175 /// @return a copy of the function type name
9176 interned_string
get_method_type_name(const method_type * fn_type,bool internal)9177 get_method_type_name(const method_type* fn_type,
9178 		     bool internal)
9179 {
9180   if (fn_type)
9181     return get_method_type_name(*fn_type, internal);
9182 
9183   return interned_string();
9184 }
9185 
9186 /// Get the name of a given method type and return a copy of it.
9187 ///
9188 /// @param fn_type the function type to consider.
9189 ///
9190 /// @param internal set to true if the call is intended for an
9191 /// internal use (for technical use inside the library itself), false
9192 /// otherwise.  If you don't know what this is for, then set it to
9193 /// false.
9194 ///
9195 /// @return a copy of the function type name
9196 interned_string
get_method_type_name(const method_type & fn_type,bool internal)9197 get_method_type_name(const method_type& fn_type,
9198 		     bool internal)
9199 {
9200   std::ostringstream o;
9201   // When the function name is used for internal purposes (e.g, for
9202   // canonicalization), we want its representation to stay the same,
9203   // regardless of typedefs.  So let's strip typedefs from the return
9204   // type.
9205   type_base_sptr return_type =
9206     internal
9207     ? peel_typedef_type(fn_type.get_return_type())
9208     : fn_type.get_return_type();
9209   const environment& env = fn_type.get_environment();
9210 
9211   if (return_type)
9212     o << return_type->get_cached_pretty_representation(internal);
9213   else
9214     // There are still some abixml files out there in which "void"
9215     // can be expressed as an empty type.
9216     o << "void";
9217 
9218   class_or_union_sptr class_type = fn_type.get_class_type();
9219   ABG_ASSERT(class_type);
9220 
9221   o << " (" << class_type->get_qualified_name(internal) << "::*)"
9222     << " (";
9223 
9224   type_base_sptr type;
9225   for (function_type::parameters::const_iterator i =
9226 	 fn_type.get_parameters().begin();
9227        i != fn_type.get_parameters().end();
9228        ++i)
9229     {
9230       if (i != fn_type.get_parameters().begin())
9231 	o << ", ";
9232       type = (*i)->get_type();
9233       if (internal)
9234 	type = peel_typedef_type(type);
9235       if (*i)
9236 	o << type->get_cached_pretty_representation(internal);
9237       else
9238 	// There are still some abixml files out there in which "void"
9239 	// can be expressed as an empty type.
9240 	o << "void";
9241     }
9242   o <<")";
9243 
9244   return env.intern(o.str());
9245 }
9246 
9247 /// Build and return a copy of the pretty representation of an ABI
9248 /// artifact that could be either a type of a decl.
9249 ///
9250 /// param tod the ABI artifact to consider.
9251 ///
9252 /// @param internal set to true if the call is intended for an
9253 /// internal use (for technical use inside the library itself), false
9254 /// otherwise.  If you don't know what this is for, then set it to
9255 /// false.
9256 ///
9257 /// @return a copy of the pretty representation of an ABI artifact
9258 /// that could be either a type of a decl.
9259 string
get_pretty_representation(const type_or_decl_base * tod,bool internal)9260 get_pretty_representation(const type_or_decl_base* tod, bool internal)
9261 {
9262   string result;
9263 
9264   if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9265     result = get_pretty_representation(t, internal);
9266   else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9267     result =  get_pretty_representation(d, internal);
9268   else
9269     // We should never reach this point
9270     abort();
9271 
9272   return result;
9273 }
9274 
9275 /// Build and return a copy of the pretty representation of an ABI
9276 /// artifact that could be either a type of a decl.
9277 ///
9278 /// param tod the ABI artifact to consider.
9279 ///
9280 /// @param internal set to true if the call is intended for an
9281 /// internal use (for technical use inside the library itself), false
9282 /// otherwise.  If you don't know what this is for, then set it to
9283 /// false.
9284 ///
9285 /// @return a copy of the pretty representation of an ABI artifact
9286 /// that could be either a type of a decl.
9287 string
get_pretty_representation(const type_or_decl_base_sptr & tod,bool internal)9288 get_pretty_representation(const type_or_decl_base_sptr& tod, bool internal)
9289 {return get_pretty_representation(tod.get(), internal);}
9290 
9291 /// Get a copy of the pretty representation of a decl.
9292 ///
9293 /// @param d the decl to consider.
9294 ///
9295 /// @param internal set to true if the call is intended for an
9296 /// internal use (for technical use inside the library itself), false
9297 /// otherwise.  If you don't know what this is for, then set it to
9298 /// false.
9299 ///
9300 /// @return the pretty representation of the decl.
9301 string
get_pretty_representation(const decl_base * d,bool internal)9302 get_pretty_representation(const decl_base* d, bool internal)
9303 {
9304   if (!d)
9305     return "";
9306   return d->get_pretty_representation(internal);
9307 }
9308 
9309 /// Get a copy of the pretty representation of a type.
9310 ///
9311 /// @param d the type to consider.
9312 ///
9313 /// @param internal set to true if the call is intended for an
9314 /// internal use (for technical use inside the library itself), false
9315 /// otherwise.  If you don't know what this is for, then set it to
9316 /// false.
9317 ///
9318 /// @return the pretty representation of the type.
9319 string
get_pretty_representation(const type_base * t,bool internal)9320 get_pretty_representation(const type_base* t, bool internal)
9321 {
9322   if (!t)
9323     return "void";
9324   if (const function_type* fn_type = is_function_type(t))
9325     return get_pretty_representation(fn_type, internal);
9326 
9327   const decl_base* d = get_type_declaration(t);
9328   ABG_ASSERT(d);
9329   return get_pretty_representation(d, internal);
9330 }
9331 
9332 /// Get a copy of the pretty representation of a decl.
9333 ///
9334 /// @param d the decl to consider.
9335 ///
9336 /// @param internal set to true if the call is intended for an
9337 /// internal use (for technical use inside the library itself), false
9338 /// otherwise.  If you don't know what this is for, then set it to
9339 /// false.
9340 ///
9341 /// @return the pretty representation of the decl.
9342 string
get_pretty_representation(const decl_base_sptr & d,bool internal)9343 get_pretty_representation(const decl_base_sptr& d, bool internal)
9344 {return get_pretty_representation(d.get(), internal);}
9345 
9346 /// Get a copy of the pretty representation of a type.
9347 ///
9348 /// @param d the type to consider.
9349 ///
9350 /// @param internal set to true if the call is intended for an
9351 /// internal use (for technical use inside the library itself), false
9352 /// otherwise.  If you don't know what this is for, then set it to
9353 /// false.
9354 ///
9355 /// @return the pretty representation of the type.
9356 string
get_pretty_representation(const type_base_sptr & t,bool internal)9357 get_pretty_representation(const type_base_sptr& t, bool internal)
9358 {return get_pretty_representation(t.get(), internal);}
9359 
9360 /// Get the pretty representation of a function type.
9361 ///
9362 /// @param fn_type the function type to consider.
9363 ///
9364 /// @param internal set to true if the call is intended for an
9365 /// internal use (for technical use inside the library itself), false
9366 /// otherwise.  If you don't know what this is for, then set it to
9367 /// false.
9368 ///
9369 /// @return the string represenation of the function type.
9370 string
get_pretty_representation(const function_type_sptr & fn_type,bool internal)9371 get_pretty_representation(const function_type_sptr& fn_type,
9372 			  bool internal)
9373 {return get_pretty_representation(fn_type.get(), internal);}
9374 
9375 /// Get the pretty representation of a function type.
9376 ///
9377 /// @param fn_type the function type to consider.
9378 ///
9379 /// @param internal set to true if the call is intended for an
9380 /// internal use (for technical use inside the library itself), false
9381 /// otherwise.  If you don't know what this is for, then set it to
9382 /// false.
9383 ///
9384 /// @return the string represenation of the function type.
9385 string
get_pretty_representation(const function_type * fn_type,bool internal)9386 get_pretty_representation(const function_type* fn_type, bool internal)
9387 {
9388   if (!fn_type)
9389     return "void";
9390 
9391   if (const method_type* method = is_method_type(fn_type))
9392     return get_pretty_representation(method, internal);
9393 
9394   return get_pretty_representation(*fn_type, internal);
9395 }
9396 
9397 /// Get the pretty representation of a function type.
9398 ///
9399 /// @param fn_type the function type to consider.
9400 ///
9401 /// @param internal set to true if the call is intended for an
9402 /// internal use (for technical use inside the library itself), false
9403 /// otherwise.  If you don't know what this is for, then set it to
9404 /// false.
9405 ///
9406 /// @return the string represenation of the function type.
9407 string
get_pretty_representation(const function_type & fn_type,bool internal)9408 get_pretty_representation(const function_type& fn_type, bool internal)
9409 {
9410   std::ostringstream o;
9411   o << "function type " << get_function_type_name(fn_type, internal);
9412   return o.str();
9413 }
9414 
9415 /// Get the pretty representation of a method type.
9416 ///
9417 /// @param method the method type to consider.
9418 ///
9419 /// @param internal set to true if the call is intended for an
9420 /// internal use (for technical use inside the library itself), false
9421 /// otherwise.  If you don't know what this is for, then set it to
9422 /// false.
9423 ///
9424 /// @return the string represenation of the method type.
9425 string
get_pretty_representation(const method_type & method,bool internal)9426 get_pretty_representation(const method_type& method, bool internal)
9427 {
9428   std::ostringstream o;
9429   o << "method type " << get_method_type_name(method, internal);
9430   return o.str();
9431 }
9432 
9433 /// Get the pretty representation of a method type.
9434 ///
9435 /// @param method the method type to consider.
9436 ///
9437 /// @param internal set to true if the call is intended for an
9438 /// internal use (for technical use inside the library itself), false
9439 /// otherwise.  If you don't know what this is for, then set it to
9440 /// false.
9441 ///
9442 /// @return the string represenation of the method type.
9443 string
get_pretty_representation(const method_type * method,bool internal)9444 get_pretty_representation(const method_type* method, bool internal)
9445 {
9446   if (!method)
9447     return "void";
9448   return get_pretty_representation(*method, internal);
9449 }
9450 
9451 /// Get the pretty representation of a method type.
9452 ///
9453 /// @param method the method type to consider.
9454 ///
9455 /// @param internal set to true if the call is intended for an
9456 /// internal use (for technical use inside the library itself), false
9457 /// otherwise.  If you don't know what this is for, then set it to
9458 /// false.
9459 ///
9460 /// @return the string represenation of the method type.
9461 string
get_pretty_representation(const method_type_sptr method,bool internal)9462 get_pretty_representation(const method_type_sptr method, bool internal)
9463 {return get_pretty_representation(method.get(), internal);}
9464 
9465 /// Get the flat representation of an instance of @ref class_or_union
9466 /// type.
9467 ///
9468 /// The flat representation of a given @ref class_or_union type is the
9469 /// actual definition of the type, for instance:
9470 ///
9471 ///   struct foo {int a; char b;}
9472 ///
9473 ///@param cou the instance of @ref class_or_union to consider.
9474 ///
9475 ///@param indent the identation spaces to use in the representation.
9476 ///
9477 ///@param one_line if true, then the flat representation stands on one
9478 ///line.  Otherwise, it stands on multiple lines.
9479 ///
9480 ///@return the resulting flat representation.
9481 string
get_class_or_union_flat_representation(const class_or_union & cou,const string & indent,bool one_line,bool internal,bool qualified_names)9482 get_class_or_union_flat_representation(const class_or_union& cou,
9483 				       const string& indent,
9484 				       bool one_line,
9485 				       bool internal,
9486 				       bool qualified_names)
9487 {
9488   string repr;
9489   string local_indent = "  ";
9490 
9491   if (class_decl* clazz = is_class_type(&cou))
9492     {
9493       repr = indent;
9494       if (!internal && clazz->is_struct())
9495 	repr += "struct";
9496       else
9497 	repr += "class";
9498     }
9499   else if (is_union_type(cou))
9500     repr = indent + "union";
9501   else
9502     return "";
9503 
9504   repr += " ";
9505 
9506   string name = cou.get_qualified_name();
9507 
9508   if (!cou.get_is_anonymous())
9509     repr += name;
9510 
9511   repr += "{";
9512 
9513   if (!one_line)
9514     repr += "\n";
9515 
9516   string real_indent;
9517   const class_or_union::data_members &dmems = cou.get_data_members();
9518   for (class_or_union::data_members::const_iterator dm = dmems.begin();
9519        dm != dmems.end();
9520        ++dm)
9521     {
9522       if (dm != dmems.begin())
9523 	{
9524 	  if (one_line)
9525 	    real_indent = " ";
9526 	  else
9527 	    real_indent = "\n" + indent + local_indent;
9528 	}
9529 
9530       if (var_decl_sptr v = is_anonymous_data_member(*dm))
9531 	repr +=
9532 	  get_class_or_union_flat_representation
9533 	  (anonymous_data_member_to_class_or_union(*dm),
9534 	   real_indent, one_line, internal, qualified_names);
9535       else
9536 	{
9537 	  if (one_line)
9538 	    {
9539 	      if (dm != dmems.begin())
9540 		repr += real_indent;
9541 	      repr += (*dm)->get_pretty_representation(internal,
9542 						       qualified_names);
9543 	    }
9544 	  else
9545 	    repr +=
9546 	      real_indent+ (*dm)->get_pretty_representation(internal,
9547 							    qualified_names);
9548 	}
9549       repr += ";";
9550     }
9551 
9552   if (one_line)
9553     repr += "}";
9554   else
9555     repr += indent + "}";
9556 
9557   return repr;
9558 }
9559 
9560 /// Get the flat representation of an instance of @ref class_or_union
9561 /// type.
9562 ///
9563 /// The flat representation of a given @ref class_or_union type is the
9564 /// actual definition of the type, for instance:
9565 ///
9566 ///   struct foo {int a; char b;}
9567 ///
9568 ///@param cou the instance of @ref class_or_union to consider.
9569 ///
9570 ///@param indent the identation spaces to use in the representation.
9571 ///
9572 ///@param one_line if true, then the flat representation stands on one
9573 ///line.  Otherwise, it stands on multiple lines.
9574 ///
9575 ///@return the resulting flat representation.
9576 string
get_class_or_union_flat_representation(const class_or_union * cou,const string & indent,bool one_line,bool internal,bool qualified_names)9577 get_class_or_union_flat_representation(const class_or_union* cou,
9578 				       const string& indent,
9579 				       bool one_line,
9580 				       bool internal,
9581 				       bool qualified_names)
9582 {
9583   if (cou)
9584     return get_class_or_union_flat_representation(*cou, indent, one_line,
9585 						  internal, qualified_names);
9586   return "";
9587 }
9588 
9589 /// Get the flat representation of an instance of @ref class_or_union
9590 /// type.
9591 ///
9592 /// The flat representation of a given @ref class_or_union type is the
9593 /// actual definition of the type, for instance:
9594 ///
9595 ///   struct foo {int a; char b;}
9596 ///
9597 ///@param cou the instance of @ref class_or_union to consider.
9598 ///
9599 ///@param indent the identation spaces to use in the representation.
9600 ///
9601 ///@param one_line if true, then the flat representation stands on one
9602 ///line.  Otherwise, it stands on multiple lines.
9603 ///
9604 ///@return the resulting flat representation.
9605 string
get_class_or_union_flat_representation(const class_or_union_sptr & cou,const string & indent,bool one_line,bool internal,bool qualified_names)9606 get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9607 				       const string& indent,
9608 				       bool one_line,
9609 				       bool internal,
9610 				       bool qualified_names)
9611 {return get_class_or_union_flat_representation(cou.get(),
9612 					       indent,
9613 					       one_line,
9614 					       internal,
9615 					       qualified_names);}
9616 
9617 /// Get the flat representation of an instance of @ref enum_type_decl
9618 /// type.
9619 ///
9620 /// The flat representation of a given @ref enum_type_decl type is the
9621 /// actual definition of the type, for instance:
9622 ///
9623 ///   enum {E_0 =0, E_1 = 1}
9624 ///
9625 ///@param enum_type the enum type to consider.
9626 ///
9627 ///@param indent the identation spaces to use in the representation.
9628 ///
9629 ///@param one_line if true, then the flat representation stands on one
9630 ///line.  Otherwise, it stands on multiple lines.
9631 ///
9632 ///@param qualified_names use qualified names when applicable.
9633 ///Typically, if this is true, the name of the enum is going to be
9634 ///qualified.
9635 ///
9636 ///@return the resulting flat representation.
9637 string
get_enum_flat_representation(const enum_type_decl & enum_type,const string & indent,bool one_line,bool qualified_names)9638 get_enum_flat_representation(const enum_type_decl& enum_type,
9639 			     const string& indent, bool one_line,
9640 			     bool qualified_names)
9641 {
9642   string repr;
9643   std::ostringstream o;
9644   string local_indent = "  ";
9645 
9646   repr = indent + "enum ";
9647 
9648   if (!enum_type.get_is_anonymous())
9649     o << (qualified_names
9650 	  ? enum_type.get_qualified_name()
9651 	  : enum_type.get_name()) + " ";
9652 
9653   o << "{";
9654 
9655   if (!one_line)
9656     o << "\n";
9657 
9658   for (const auto &enumerator : enum_type.get_sorted_enumerators())
9659     {
9660       if (!one_line)
9661 	o << "\n" + indent;
9662 
9663       o << enumerator.get_name() + "="  << enumerator.get_value() << ", ";
9664     }
9665 
9666   if (!one_line)
9667     o << "\n" + indent << "}";
9668   else
9669     o << "}";
9670 
9671   repr =o.str();
9672 
9673   return repr;
9674 }
9675 
9676 /// Get the flat representation of an instance of @ref enum_type_decl
9677 /// type.
9678 ///
9679 /// The flat representation of a given @ref enum_type_decl type is the
9680 /// actual definition of the type, for instance:
9681 ///
9682 ///   enum {E_0 =0, E_1 = 1}
9683 ///
9684 ///@param enum_type the enum type to consider.
9685 ///
9686 ///@param indent the identation spaces to use in the representation.
9687 ///
9688 ///@param one_line if true, then the flat representation stands on one
9689 ///line.  Otherwise, it stands on multiple lines.
9690 ///
9691 ///@param qualified_names use qualified names when applicable.
9692 ///Typically, if this is true, the name of the enum is going to be
9693 ///qualified.
9694 ///
9695 ///@return the resulting flat representation.
9696 string
get_enum_flat_representation(const enum_type_decl * enum_type,const string & indent,bool one_line,bool qualified_names)9697 get_enum_flat_representation(const enum_type_decl* enum_type,
9698 			     const string& indent, bool one_line,
9699 			     bool qualified_names)
9700 {
9701   if (!enum_type)
9702     return "";
9703 
9704   return get_enum_flat_representation(*enum_type, indent,
9705 				      one_line, qualified_names);
9706 }
9707 
9708 /// Get the flat representation of an instance of @ref enum_type_decl
9709 /// type.
9710 ///
9711 /// The flat representation of a given @ref enum_type_decl type is the
9712 /// actual definition of the type, for instance:
9713 ///
9714 ///   enum {E_0 =0, E_1 = 1}
9715 ///
9716 ///@param enum_type the enum type to consider.
9717 ///
9718 ///@param indent the identation spaces to use in the representation.
9719 ///
9720 ///@param one_line if true, then the flat representation stands on one
9721 ///line.  Otherwise, it stands on multiple lines.
9722 ///
9723 ///@param qualified_names use qualified names when applicable.
9724 ///Typically, if this is true, the name of the enum is going to be
9725 ///qualified.
9726 ///
9727 ///@return the resulting flat representation.
9728 string
get_enum_flat_representation(const enum_type_decl_sptr & enum_type,const string & indent,bool one_line,bool qualified_names)9729 get_enum_flat_representation(const enum_type_decl_sptr& enum_type,
9730 			     const string& indent, bool one_line,
9731 			     bool qualified_names)
9732 {
9733   return get_enum_flat_representation(enum_type.get(),
9734 				      indent, one_line,
9735 				      qualified_names);
9736 }
9737 
9738 /// Get the flat representation of an instance of @ref enum_type_decl
9739 /// type.
9740 ///
9741 /// The flat representation of a given @ref enum_type_decl type is the
9742 /// actual definition of the type, for instance:
9743 ///
9744 ///   enum {E_0 =0, E_1 = 1}
9745 ///
9746 ///@param enum_type the enum type to consider.
9747 ///
9748 ///@param indent the identation spaces to use in the representation.
9749 ///
9750 ///@param one_line if true, then the flat representation stands on one
9751 ///line.  Otherwise, it stands on multiple lines.
9752 ///
9753 ///@param qualified_names use qualified names when applicable.
9754 ///Typically, if this is true, the name of the enum is going to be
9755 ///qualified.
9756 ///
9757 ///@return the resulting flat representation.
9758 string
get_class_or_enum_flat_representation(const type_base & coe,const string & indent,bool one_line,bool internal,bool qualified_name)9759 get_class_or_enum_flat_representation(const type_base& coe,
9760 				      const string& indent,
9761 				      bool one_line,
9762 				      bool internal,
9763 				      bool qualified_name)
9764 
9765 {
9766   string repr;
9767   if (const class_or_union* cou = is_class_or_union_type(&coe))
9768     repr = get_class_or_union_flat_representation(cou, indent, one_line,
9769 						  internal, qualified_name);
9770   else if (const enum_type_decl* enom = is_enum_type(&coe))
9771     repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
9772 
9773   return repr;
9774 }
9775 
9776 /// Get the textual representation of a type for debugging purposes.
9777 ///
9778 /// If the type is a class/union, this shows the data members, virtual
9779 /// member functions, size, pointer value of its canonical type, etc.
9780 /// Otherwise, this just shows the name of the artifact as returned by
9781 /// type_or_decl_base:get_pretty_representation().
9782 ///
9783 /// @param artifact the artifact to show a debugging representation of.
9784 ///
9785 /// @return a debugging string representation of @p artifact.
9786 string
get_debug_representation(const type_or_decl_base * artifact)9787 get_debug_representation(const type_or_decl_base* artifact)
9788 {
9789   if (!artifact)
9790     return string("");
9791 
9792   class_or_union * c = is_class_or_union_type(artifact);
9793   if (c)
9794     {
9795       class_decl *clazz = is_class_type(c);
9796       string name = c->get_qualified_name();
9797       std::ostringstream o;
9798       if (clazz)
9799 	{
9800 	  if (clazz->is_struct())
9801 	    o << "struct ";
9802 	  else
9803 	    o << "class ";
9804 	}
9805       else if (is_union_type(c))
9806 	o << "union ";
9807       o << name;
9808 
9809       if (clazz)
9810 	{
9811 	  if (!clazz->get_base_specifiers().empty())
9812 	    o << " :" << std::endl;
9813 	  for (auto &b : clazz->get_base_specifiers())
9814 	    {
9815 	      o << "  ";
9816 	      if (b->get_is_virtual())
9817 		o << "virtual ";
9818 	      o << b->get_base_class()->get_qualified_name()
9819 		<< std::endl;
9820 	    }
9821 	}
9822       o << std::endl
9823 	<< "{"
9824 	<< "   // size in bits: " << c->get_size_in_bits() << "\n"
9825 	<< "   // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9826 	<< "   // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9827 	<< "   // translation unit: " << c->get_translation_unit()->get_absolute_path() << std::endl
9828 	<< "   // @: " << std::hex << is_type(c)
9829 	<< ", @canonical: " << c->get_canonical_type().get() << std::dec
9830 	<< "\n\n";
9831 
9832       for (auto m : c->get_data_members())
9833 	{
9834 	  type_base_sptr t = m->get_type();
9835 	  t = peel_typedef_pointer_or_reference_type(t);
9836 
9837 	  o << "  "
9838 	    << m->get_pretty_representation(/*internal=*/false,
9839 					    /*qualified=*/false)
9840 	    << ";";
9841 
9842 	  if (t && t->get_canonical_type())
9843 	    o << " // uses canonical type '@"
9844 	      << std::hex << t->get_canonical_type().get() << std::dec;
9845 
9846 	  o << "'" << std::endl;
9847 	}
9848 
9849       if (clazz && clazz->has_vtable())
9850 	{
9851 	  o << "  // virtual member functions\n\n";
9852 	  for (auto f : clazz->get_virtual_mem_fns())
9853 	    o << "  " << f->get_pretty_representation(/*internal=*/false,
9854 						      /*qualified=*/false)
9855 	      << ";" << std::endl;
9856 	}
9857 
9858       o << "};" << std::endl;
9859 
9860       return o.str();
9861     }
9862   else if (const enum_type_decl* e = is_enum_type(artifact))
9863     {
9864       string name = e->get_qualified_name();
9865       std::ostringstream o;
9866       o << "enum " << name
9867 	<< " : "
9868 	<< e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9869 							       true)
9870 	<< "\n"
9871 	<< "{\n"
9872 	<< "  // size in bits: " << e->get_size_in_bits() << "\n"
9873 	<< "  // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9874 	<< " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9875 	<< "  // translation unit: "
9876 	<< e->get_translation_unit()->get_absolute_path() << "\n"
9877 	<< "  // @: " << std::hex << is_type(e)
9878 	<< ", @canonical: " << e->get_canonical_type().get() << std::dec
9879 	<< "\n\n";
9880 
9881       for (const auto &enom : e->get_enumerators())
9882 	o << "  " << enom.get_name() << " = " << enom.get_value() << ",\n";
9883 
9884       o << "};\n";
9885 
9886       return o.str();
9887     }
9888   return artifact->get_pretty_representation(/*internal=*/true,
9889 					     /*qualified=*/true);
9890 }
9891 
9892 /// Get a given data member, referred to by its name, of a class type.
9893 ///
9894 /// @param clazz the class to consider.
9895 ///
9896 /// @param member_name name of the data member to get.
9897 ///
9898 /// @return the resulting data member or nullptr if none was found.
9899 var_decl_sptr
get_data_member(class_or_union * clazz,const char * member_name)9900 get_data_member(class_or_union *clazz, const char* member_name)
9901 {
9902   if (!clazz)
9903     return var_decl_sptr();
9904   return clazz->find_data_member(member_name);
9905 }
9906 
9907 /// Get a given data member, referred to by its name, of a class type.
9908 ///
9909 /// @param clazz the class to consider.
9910 ///
9911 /// @param member_name name of the data member to get.
9912 ///
9913 /// @return the resulting data member or nullptr if none was found.
9914 var_decl_sptr
get_data_member(type_base * clazz,const char * member_name)9915 get_data_member(type_base *clazz, const char* member_name)
9916 {return get_data_member(is_class_or_union_type(clazz), member_name);}
9917 
9918 /// Get the non-artificial (natural) location of a decl.
9919 ///
9920 /// If the decl doesn't have a natural location then return its
9921 /// artificial one.
9922 ///
9923 /// @param decl the decl to consider.
9924 ///
9925 /// @return the natural location @p decl if it has one; otherwise,
9926 /// return its artificial one.
9927 const location&
get_natural_or_artificial_location(const decl_base * decl)9928 get_natural_or_artificial_location(const decl_base* decl)
9929 {
9930   ABG_ASSERT(decl);
9931 
9932   if (decl->get_location())
9933     return decl->get_location();
9934   return decl->get_artificial_location();
9935 }
9936 
9937 /// Get the artificial location of a decl.
9938 ///
9939 /// If the decl doesn't have an artificial location then return its
9940 /// natural one.
9941 ///
9942 /// @param decl the decl to consider.
9943 ///
9944 /// @return the artificial location @p decl if it has one; otherwise,
9945 /// return its natural one.
9946 const location&
get_artificial_or_natural_location(const decl_base * decl)9947 get_artificial_or_natural_location(const decl_base* decl)
9948 {
9949   ABG_ASSERT(decl);
9950 
9951   if (decl->has_artificial_location())
9952     return decl->get_artificial_location();
9953   return decl->get_location();
9954 }
9955 
9956 /// Emit a textual representation of an artifact to std error stream
9957 /// for debugging purposes.
9958 ///
9959 /// This is useful to invoke from within a command line debugger like
9960 /// GDB to help make sense of a given ABI artifact.
9961 ///
9962 /// @param artifact the ABI artifact to emit the debugging
9963 /// representation for.
9964 ///
9965 /// @return the artifact @p artifact.
9966 type_or_decl_base*
debug(const type_or_decl_base * artifact)9967 debug(const type_or_decl_base* artifact)
9968 {
9969   std::cerr << get_debug_representation(artifact) << std::endl;
9970   return const_cast<type_or_decl_base*>(artifact);
9971 }
9972 
9973 /// Emit a textual representation of an artifact to std error stream
9974 /// for debugging purposes.
9975 ///
9976 /// This is useful to invoke from within a command line debugger like
9977 /// GDB to help make sense of a given ABI artifact.
9978 ///
9979 /// @param artifact the ABI artifact to emit the debugging
9980 /// representation for.
9981 ///
9982 /// @return the artifact @p artifact.
9983 type_base*
debug(const type_base * artifact)9984 debug(const type_base* artifact)
9985 {
9986   debug(static_cast<const type_or_decl_base*>(artifact));
9987   return const_cast<type_base*>(artifact);
9988 }
9989 
9990 /// Emit a textual representation of an artifact to std error stream
9991 /// for debugging purposes.
9992 ///
9993 /// This is useful to invoke from within a command line debugger like
9994 /// GDB to help make sense of a given ABI artifact.
9995 ///
9996 /// @param artifact the ABI artifact to emit the debugging
9997 /// representation for.
9998 ///
9999 /// @return the artifact @p artifact.
10000 decl_base*
debug(const decl_base * artifact)10001 debug(const decl_base* artifact)
10002 {
10003   debug(static_cast<const type_or_decl_base*>(artifact));
10004   return const_cast<decl_base*>(artifact);
10005 }
10006 
10007 /// Test if two ABI artifacts are equal.
10008 ///
10009 /// This can be useful when used from the command line of a debugger
10010 /// like GDB.
10011 ///
10012 /// @param l the first ABI artifact to consider in the comparison.
10013 ///
10014 /// @param r the second ABI artifact to consider in the comparison.
10015 ///
10016 /// @return true iff @p l equals @p r.
10017 bool
debug_equals(const type_or_decl_base * l,const type_or_decl_base * r)10018 debug_equals(const type_or_decl_base *l, const type_or_decl_base *r)
10019 {
10020   if (!!l != !!r)
10021     return false;
10022   if (!l && !r)
10023     return true;
10024 
10025   return (*l == *r);
10026 }
10027 
10028 /// Emit a trace of a comparison operand stack.
10029 ///
10030 /// @param vect the operand stack to emit the trace for.
10031 ///
10032 /// @param o the output stream to emit the trace to.
10033 static void
debug_comp_vec(const vector<const type_base * > & vect,std::ostringstream & o)10034 debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
10035 {
10036   for (auto t : vect)
10037     {
10038       o << "|" << t->get_pretty_representation()
10039 	<< "@" << std::hex << t << std::dec;
10040     }
10041   if (!vect.empty())
10042     o << "|";
10043 }
10044 
10045 /// Construct a trace of the two comparison operand stacks.
10046 ///
10047 /// @param the environment in which the comparison operand stacks are.
10048 ///
10049 /// @return a string representing the trace.
10050 static string
print_comp_stack(const environment & env)10051 print_comp_stack(const environment& env)
10052 {
10053   std::ostringstream o;
10054   o << "left-operands: ";
10055   debug_comp_vec(env.priv_->left_type_comp_operands_, o);
10056   o << "\n" << "right-operands: ";
10057   debug_comp_vec(env.priv_->right_type_comp_operands_, o);
10058   o << "\n";
10059   return o.str();
10060 }
10061 
10062 /// Emit a trace of the two comparison operands stack on the standard
10063 /// error stream.
10064 ///
10065 /// @param env the environment the comparison operands stack belong
10066 /// to.
10067 void
debug_comp_stack(const environment & env)10068 debug_comp_stack(const environment& env)
10069 {
10070   std::cerr << print_comp_stack(env);
10071   std::cerr << std::endl;
10072 }
10073 
10074 /// By looking at the language of the TU a given ABI artifact belongs
10075 /// to, test if the ONE Definition Rule should apply.
10076 ///
10077 /// To date, it applies to c++, java and ada.
10078 ///
10079 /// @param artifact the ABI artifact to consider.
10080 ///
10081 /// @return true iff the One Definition Rule should apply.
10082 bool
odr_is_relevant(const type_or_decl_base & artifact)10083 odr_is_relevant(const type_or_decl_base& artifact)
10084 {
10085   translation_unit::language l =
10086     artifact.get_translation_unit()->get_language();
10087 
10088   if (is_cplus_plus_language(l)
10089       || is_java_language(l)
10090       || is_ada_language(l))
10091     return true;
10092 
10093   return false;
10094 }
10095 
10096 /// Get the declaration for a given type.
10097 ///
10098 /// @param t the type to consider.
10099 ///
10100 /// @return the declaration for the type to return.
10101 const decl_base*
get_type_declaration(const type_base * t)10102 get_type_declaration(const type_base* t)
10103 {return dynamic_cast<const decl_base*>(t);}
10104 
10105 /// Get the declaration for a given type.
10106 ///
10107 /// @param t the type to consider.
10108 ///
10109 /// @return the declaration for the type to return.
10110 decl_base*
get_type_declaration(type_base * t)10111 get_type_declaration(type_base* t)
10112 {return dynamic_cast<decl_base*>(t);}
10113 
10114 /// Get the declaration for a given type.
10115 ///
10116 /// @param t the type to consider.
10117 ///
10118 /// @return the declaration for the type to return.
10119 decl_base_sptr
get_type_declaration(const type_base_sptr t)10120 get_type_declaration(const type_base_sptr t)
10121 {return dynamic_pointer_cast<decl_base>(t);}
10122 
10123 /// Test if two types are equal modulo a typedef.
10124 ///
10125 /// Type A and B are compatible if
10126 ///
10127 ///	- A and B are equal
10128 ///	- or if one type is a typedef of the other one.
10129 ///
10130 /// @param type1 the first type to consider.
10131 ///
10132 /// @param type2 the second type to consider.
10133 ///
10134 /// @return true iff @p type1 and @p type2 are compatible.
10135 bool
types_are_compatible(const type_base_sptr type1,const type_base_sptr type2)10136 types_are_compatible(const type_base_sptr type1,
10137 		     const type_base_sptr type2)
10138 {
10139   if (!type1 || !type2)
10140     return false;
10141 
10142   if (type1 == type2)
10143     return true;
10144 
10145   // Normally we should strip typedefs entirely, but this is
10146   // potentially costly, especially on binaries with huge changesets
10147   // like the Linux Kernel.  So we just get the leaf types for now.
10148   //
10149   // Maybe there should be an option by which users accepts to pay the
10150   // CPU usage toll in exchange for finer filtering?
10151 
10152   // type_base_sptr t1 = strip_typedef(type1);
10153   // type_base_sptr t2 = strip_typedef(type2);
10154 
10155   type_base_sptr t1 = peel_typedef_type(type1);
10156   type_base_sptr t2 = peel_typedef_type(type2);
10157 
10158   return t1 == t2;
10159 }
10160 
10161 /// Test if two types are equal modulo a typedef.
10162 ///
10163 /// Type A and B are compatible if
10164 ///
10165 ///	- A and B are equal
10166 ///	- or if one type is a typedef of the other one.
10167 ///
10168 /// @param type1 the declaration of the first type to consider.
10169 ///
10170 /// @param type2 the declaration of the second type to consider.
10171 ///
10172 /// @return true iff @p type1 and @p type2 are compatible.
10173 bool
types_are_compatible(const decl_base_sptr d1,const decl_base_sptr d2)10174 types_are_compatible(const decl_base_sptr d1,
10175 		     const decl_base_sptr d2)
10176 {return types_are_compatible(is_type(d1), is_type(d2));}
10177 
10178 /// Return the translation unit a declaration belongs to.
10179 ///
10180 /// @param decl the declaration to consider.
10181 ///
10182 /// @return the resulting translation unit, or null if the decl is not
10183 /// yet added to a translation unit.
10184 translation_unit*
get_translation_unit(const decl_base & decl)10185 get_translation_unit(const decl_base& decl)
10186 {return const_cast<translation_unit*>(decl.get_translation_unit());}
10187 
10188 /// Return the translation unit a declaration belongs to.
10189 ///
10190 /// @param decl the declaration to consider.
10191 ///
10192 /// @return the resulting translation unit, or null if the decl is not
10193 /// yet added to a translation unit.
10194 translation_unit*
get_translation_unit(const decl_base * decl)10195 get_translation_unit(const decl_base* decl)
10196 {return decl ? get_translation_unit(*decl) : 0;}
10197 
10198 /// Return the translation unit a declaration belongs to.
10199 ///
10200 /// @param decl the declaration to consider.
10201 ///
10202 /// @return the resulting translation unit, or null if the decl is not
10203 /// yet added to a translation unit.
10204 translation_unit*
get_translation_unit(const shared_ptr<decl_base> decl)10205 get_translation_unit(const shared_ptr<decl_base> decl)
10206 {return get_translation_unit(decl.get());}
10207 
10208 /// Tests whether if a given scope is the global scope.
10209 ///
10210 /// @param scope the scope to consider.
10211 ///
10212 /// @return true iff the current scope is the global one.
10213 bool
is_global_scope(const scope_decl & scope)10214 is_global_scope(const scope_decl& scope)
10215 {return !!dynamic_cast<const global_scope*>(&scope);}
10216 
10217 /// Tests whether if a given scope is the global scope.
10218 ///
10219 /// @param scope the scope to consider.
10220 ///
10221 /// @return the @ref global_scope* representing the scope @p scope or
10222 /// 0 if @p scope is not a global scope.
10223 const global_scope*
is_global_scope(const scope_decl * scope)10224 is_global_scope(const scope_decl* scope)
10225 {return dynamic_cast<const global_scope*>(scope);}
10226 
10227 /// Tests whether if a given scope is the global scope.
10228 ///
10229 /// @param scope the scope to consider.
10230 ///
10231 /// @return true iff the current scope is the global one.
10232 bool
is_global_scope(const shared_ptr<scope_decl> scope)10233 is_global_scope(const shared_ptr<scope_decl>scope)
10234 {return is_global_scope(scope.get());}
10235 
10236 /// Tests whether a given declaration is at global scope.
10237 ///
10238 /// @param decl the decl to consider.
10239 ///
10240 /// @return true iff decl is at global scope.
10241 bool
is_at_global_scope(const decl_base & decl)10242 is_at_global_scope(const decl_base& decl)
10243 {return (is_global_scope(decl.get_scope()));}
10244 
10245 /// Tests whether a given declaration is at global scope.
10246 ///
10247 /// @param decl the decl to consider.
10248 ///
10249 /// @return true iff decl is at global scope.
10250 bool
is_at_global_scope(const decl_base_sptr decl)10251 is_at_global_scope(const decl_base_sptr decl)
10252 {return (decl && is_global_scope(decl->get_scope()));}
10253 
10254 /// Tests whether a given declaration is at global scope.
10255 ///
10256 /// @param decl the decl to consider.
10257 ///
10258 /// @return true iff decl is at global scope.
10259 bool
is_at_global_scope(const decl_base * decl)10260 is_at_global_scope(const decl_base* decl)
10261 {return is_at_global_scope(*decl);}
10262 
10263 /// Tests whether a given decl is at class scope.
10264 ///
10265 /// @param decl the decl to consider.
10266 ///
10267 /// @return true iff decl is at class scope.
10268 class_or_union*
is_at_class_scope(const decl_base_sptr decl)10269 is_at_class_scope(const decl_base_sptr decl)
10270 {return is_at_class_scope(decl.get());}
10271 
10272 /// Tests whether a given decl is at class scope.
10273 ///
10274 /// @param decl the decl to consider.
10275 ///
10276 /// @return true iff decl is at class scope.
10277 class_or_union*
is_at_class_scope(const decl_base * decl)10278 is_at_class_scope(const decl_base* decl)
10279 {
10280   if (!decl)
10281     return 0;
10282 
10283   return is_at_class_scope(*decl);
10284 }
10285 
10286 /// Tests whether a given decl is at class scope.
10287 ///
10288 /// @param decl the decl to consider.
10289 ///
10290 /// @return true iff decl is at class scope.
10291 class_or_union*
is_at_class_scope(const decl_base & decl)10292 is_at_class_scope(const decl_base& decl)
10293 {
10294   scope_decl* scope = decl.get_scope();
10295   if (class_or_union* cl = is_class_type(scope))
10296     return cl;
10297   if (class_or_union* cl = is_union_type(scope))
10298     return cl;
10299   return 0;
10300 }
10301 
10302 /// Find a data member inside an anonymous data member.
10303 ///
10304 /// An anonymous data member has a type which is a class or union.
10305 /// This function looks for a data member inside the type of that
10306 /// anonymous data member.
10307 ///
10308 /// @param anon_dm the anonymous data member to consider.
10309 ///
10310 /// @param name the name of the data member to look for.
10311 var_decl_sptr
find_data_member_from_anonymous_data_member(const var_decl_sptr & anon_dm,const string & name)10312 find_data_member_from_anonymous_data_member(const var_decl_sptr& anon_dm,
10313 					    const string& name)
10314 {
10315   const class_or_union* containing_class_or_union =
10316     anonymous_data_member_to_class_or_union(anon_dm.get());
10317 
10318   if (!containing_class_or_union)
10319     return var_decl_sptr();
10320 
10321   var_decl_sptr result = containing_class_or_union->find_data_member(name);
10322   return result;
10323 }
10324 
10325 /// Tests whether a given decl is at template scope.
10326 ///
10327 /// Note that only template parameters , types that are compositions,
10328 /// and template patterns (function or class) can be at template scope.
10329 ///
10330 /// @param decl the decl to consider.
10331 ///
10332 /// @return true iff the decl is at template scope.
10333 bool
is_at_template_scope(const shared_ptr<decl_base> decl)10334 is_at_template_scope(const shared_ptr<decl_base> decl)
10335 {return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10336 
10337 /// Tests whether a decl is a template parameter.
10338 ///
10339 /// @param decl the decl to consider.
10340 ///
10341 /// @return true iff decl is a template parameter.
10342 bool
is_template_parameter(const shared_ptr<decl_base> decl)10343 is_template_parameter(const shared_ptr<decl_base> decl)
10344 {
10345   return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10346 		   || dynamic_pointer_cast<non_type_tparameter>(decl)
10347 		   || dynamic_pointer_cast<template_tparameter>(decl)));
10348 }
10349 
10350 /// Test whether a declaration is a @ref function_decl.
10351 ///
10352 /// @param d the declaration to test for.
10353 ///
10354 /// @return a shared pointer to @ref function_decl if @p d is a @ref
10355 /// function_decl.  Otherwise, a nil shared pointer.
10356 function_decl*
is_function_decl(const type_or_decl_base * d)10357 is_function_decl(const type_or_decl_base* d)
10358 {return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10359 
10360 /// Test whether a declaration is a @ref function_decl.
10361 ///
10362 /// @param d the declaration to test for.
10363 ///
10364 /// @return true if @p d is a function_decl.
10365 bool
is_function_decl(const type_or_decl_base & d)10366 is_function_decl(const type_or_decl_base& d)
10367 {return is_function_decl(&d);}
10368 
10369 /// Test whether a declaration is a @ref function_decl.
10370 ///
10371 /// @param d the declaration to test for.
10372 ///
10373 /// @return a shared pointer to @ref function_decl if @p d is a @ref
10374 /// function_decl.  Otherwise, a nil shared pointer.
10375 function_decl_sptr
is_function_decl(const type_or_decl_base_sptr & d)10376 is_function_decl(const type_or_decl_base_sptr& d)
10377 {return dynamic_pointer_cast<function_decl>(d);}
10378 
10379 /// Test whether a declaration is a @ref function_decl.
10380 ///
10381 /// @param d the declaration to test for.
10382 ///
10383 /// @return a pointer to @ref function_decl if @p d is a @ref
10384 /// function_decl.  Otherwise, a nil shared pointer.
10385 function_decl::parameter*
is_function_parameter(const type_or_decl_base * tod)10386 is_function_parameter(const type_or_decl_base* tod)
10387 {
10388   return dynamic_cast<function_decl::parameter*>
10389     (const_cast<type_or_decl_base*>(tod));
10390 }
10391 
10392 /// Test whether an ABI artifact is a @ref function_decl.
10393 ///
10394 /// @param tod the declaration to test for.
10395 ///
10396 /// @return a pointer to @ref function_decl if @p d is a @ref
10397 /// function_decl.  Otherwise, a nil shared pointer.
10398 function_decl::parameter_sptr
is_function_parameter(const type_or_decl_base_sptr tod)10399 is_function_parameter(const type_or_decl_base_sptr tod)
10400 {return dynamic_pointer_cast<function_decl::parameter>(tod);}
10401 
10402 /// Test if an ABI artifact is a declaration.
10403 ///
10404 /// @param d the artifact to consider.
10405 ///
10406 /// @param return the declaration sub-object of @p d if it's a
10407 /// declaration, or NULL if it is not.
10408 decl_base*
is_decl(const type_or_decl_base * d)10409 is_decl(const type_or_decl_base* d)
10410 {
10411   if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10412     {
10413       if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10414 	// The artifact is a decl-only (like a function or a
10415 	// variable).  That is, it's not a type that also has a
10416 	// declaration.  In this case, we are in the fast path and we
10417 	// have a pointer to the decl sub-object handy.  Just return
10418 	// it ...
10419 	return reinterpret_cast<decl_base*>
10420 	  (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10421 
10422       // ... Otherwise, we are in the slow path, which is that the
10423       // artifact is a type which has a declaration.  In that case,
10424       // let's use the slow dynamic_cast because we don't have the
10425       // pointer to the decl sub-object handily present.
10426       return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10427     }
10428   return 0;
10429 }
10430 
10431 /// Test if an ABI artifact is a declaration.
10432 ///
10433 /// @param d the artifact to consider.
10434 ///
10435 /// @param return the declaration sub-object of @p d if it's a
10436 /// declaration, or NULL if it is not.
10437 decl_base_sptr
is_decl(const type_or_decl_base_sptr & d)10438 is_decl(const type_or_decl_base_sptr& d)
10439 {return dynamic_pointer_cast<decl_base>(d);}
10440 
10441 /// Test if an ABI artifact is a declaration.
10442 ///
10443 /// This is done using a slow path that uses dynamic_cast.
10444 ///
10445 /// @param d the artifact to consider.
10446 ///
10447 /// @param return the declaration sub-object of @p d if it's a
10448 decl_base*
is_decl_slow(const type_or_decl_base * t)10449 is_decl_slow(const type_or_decl_base* t)
10450 {return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10451 
10452 /// Test if an ABI artifact is a declaration.
10453 ///
10454 /// This is done using a slow path that uses dynamic_cast.
10455 ///
10456 /// @param d the artifact to consider.
10457 ///
10458 /// @param return the declaration sub-object of @p d if it's a
10459 decl_base_sptr
is_decl_slow(const type_or_decl_base_sptr & t)10460 is_decl_slow(const type_or_decl_base_sptr& t)
10461 {return dynamic_pointer_cast<decl_base>(t);}
10462 
10463 /// Test whether a declaration is a type.
10464 ///
10465 /// @param d the IR artefact to test for.
10466 ///
10467 /// @return true if the artifact is a type, false otherwise.
10468 bool
is_type(const type_or_decl_base & tod)10469 is_type(const type_or_decl_base& tod)
10470 {
10471   if (dynamic_cast<const type_base*>(&tod))
10472     return true;
10473   return false;
10474 }
10475 
10476 /// Test whether a declaration is a type.
10477 ///
10478 /// @param d the IR artefact to test for.
10479 ///
10480 /// @return true if the artifact is a type, false otherwise.
10481 type_base*
is_type(const type_or_decl_base * t)10482 is_type(const type_or_decl_base* t)
10483 {
10484   if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10485     return reinterpret_cast<type_base*>
10486       (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10487 
10488   return 0;
10489 }
10490 
10491 /// Test whether a declaration is a type.
10492 ///
10493 /// @param d the IR artefact to test for.
10494 ///
10495 /// @return true if the artifact is a type, false otherwise.
10496 type_base_sptr
is_type(const type_or_decl_base_sptr & tod)10497 is_type(const type_or_decl_base_sptr& tod)
10498 {return dynamic_pointer_cast<type_base>(tod);}
10499 
10500 /// Test whether a declaration is a type.
10501 ///
10502 /// @param d the declaration to test for.
10503 ///
10504 /// @return true if the declaration is a type, false otherwise.
10505 
10506 /// Test if a given type is anonymous.
10507 ///
10508 /// Note that this function considers that an anonymous class that is
10509 /// named by a typedef is not anonymous anymore.  This is the C idiom:
10510 ///
10511 ///       typedef struct {int member;} s_type;
10512 ///
10513 /// The typedef s_type becomes the name of the originally anonymous
10514 /// struct.
10515 ///
10516 /// @param t the type to consider.
10517 ///
10518 /// @return true iff @p t is anonymous.
10519 bool
is_anonymous_type(const type_base * t)10520 is_anonymous_type(const type_base* t)
10521 {
10522   const decl_base* d = get_type_declaration(t);
10523   if (d)
10524     if (d->get_is_anonymous())
10525       {
10526 	if (class_or_union *cou = is_class_or_union_type(t))
10527 	  {
10528 	    // An anonymous class that is named by a typedef is not
10529 	    // considered anonymous anymore.
10530 	    if (!cou->get_naming_typedef())
10531 	      return true;
10532 	  }
10533 	else
10534 	  return true;
10535       }
10536   return false;
10537 }
10538 
10539 /// Test if a given type is anonymous.
10540 ///
10541 /// @param t the type to consider.
10542 ///
10543 /// @return true iff @p t is anonymous.
10544 bool
is_anonymous_type(const type_base_sptr & t)10545 is_anonymous_type(const type_base_sptr& t)
10546 {return is_anonymous_type(t.get());}
10547 
10548 /// Test whether a type is a type_decl (a builtin type).
10549 ///
10550 /// @return the type_decl* for @t if it's type_decl, otherwise, return
10551 /// nil.
10552 const type_decl*
is_type_decl(const type_or_decl_base * t)10553 is_type_decl(const type_or_decl_base* t)
10554 {return dynamic_cast<const type_decl*>(t);}
10555 
10556 /// Test whether a type is a type_decl (a builtin type).
10557 ///
10558 /// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10559 /// return nil.
10560 type_decl_sptr
is_type_decl(const type_or_decl_base_sptr & t)10561 is_type_decl(const type_or_decl_base_sptr& t)
10562 {return dynamic_pointer_cast<type_decl>(t);}
10563 
10564 /// Test if a type is an integral type.
10565 ///
10566 /// @param t the type to test.
10567 ///
10568 /// @return the integral type @p t can be converted to, or nil if @p
10569 /// is not an integral type.
10570 type_decl*
is_integral_type(const type_or_decl_base * t)10571 is_integral_type(const type_or_decl_base* t)
10572 {
10573   type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10574   if (!type)
10575     return nullptr;
10576 
10577   integral_type int_type;
10578   if (!parse_integral_type(type->get_name(), int_type))
10579     return nullptr;
10580 
10581   return type;
10582 }
10583 
10584 /// Test if a type is an integral type.
10585 ///
10586 /// @param t the type to test.
10587 ///
10588 /// @return the integral type @p t can be converted to, or nil if @p
10589 /// is not an integral type.
10590 type_decl_sptr
is_integral_type(const type_or_decl_base_sptr & t)10591 is_integral_type(const type_or_decl_base_sptr& t)
10592 {
10593   const type_decl_sptr type = is_type_decl(t);
10594   if (!type)
10595     return type_decl_sptr();
10596 
10597   integral_type int_type;
10598   if (!parse_integral_type(type->get_name(), int_type))
10599     return type_decl_sptr();
10600 
10601   return type;
10602 }
10603 
10604 /// Test whether a type is a typedef.
10605 ///
10606 /// @param t the type to test for.
10607 ///
10608 /// @return the typedef declaration of the @p t, or NULL if it's not a
10609 /// typedef.
10610 typedef_decl_sptr
is_typedef(const type_or_decl_base_sptr t)10611 is_typedef(const type_or_decl_base_sptr t)
10612 {return dynamic_pointer_cast<typedef_decl>(t);}
10613 
10614 /// Test whether a type is a typedef.
10615 ///
10616 /// @param t the declaration of the type to test for.
10617 ///
10618 /// @return the typedef declaration of the @p t, or NULL if it's not a
10619 /// typedef.
10620 const typedef_decl*
is_typedef(const type_base * t)10621 is_typedef(const type_base* t)
10622 {return dynamic_cast<const typedef_decl*>(t);}
10623 
10624 /// Test whether a type is a typedef.
10625 ///
10626 /// @param t the declaration of the type to test for.
10627 ///
10628 /// @return the typedef declaration of the @p t, or NULL if it's not a
10629 /// typedef.
10630 typedef_decl*
is_typedef(type_base * t)10631 is_typedef(type_base* t)
10632 {return dynamic_cast<typedef_decl*>(t);}
10633 
10634 /// Test whether a type is a typedef.
10635 ///
10636 /// @param t the declaration of the type to test for.
10637 ///
10638 /// @return the typedef declaration of the @p t, or NULL if it's not a
10639 /// typedef.
10640 const typedef_decl*
is_typedef(const type_or_decl_base * t)10641 is_typedef(const type_or_decl_base* t)
10642 {return dynamic_cast<const typedef_decl*>(t);}
10643 /// Test if a type is an enum. This function looks through typedefs.
10644 ///
10645 /// @parm t the type to consider.
10646 ///
10647 /// @return the enum_decl if @p t is an @ref enum_decl or null
10648 /// otherwise.
10649 enum_type_decl_sptr
is_compatible_with_enum_type(const type_base_sptr & t)10650 is_compatible_with_enum_type(const type_base_sptr& t)
10651 {
10652   if (!t)
10653     return enum_type_decl_sptr();
10654 
10655   // Normally we should strip typedefs entirely, but this is
10656   // potentially costly, especially on binaries with huge changesets
10657   // like the Linux Kernel.  So we just get the leaf types for now.
10658   //
10659   // Maybe there should be an option by which users accepts to pay the
10660   // CPU usage toll in exchange for finer filtering?
10661 
10662   // type_base_sptr ty = strip_typedef(t);
10663   type_base_sptr ty = peel_typedef_type(t);;
10664   return is_enum_type(ty);
10665 }
10666 
10667 /// Test if a type is an enum. This function looks through typedefs.
10668 ///
10669 /// @parm t the type to consider.
10670 ///
10671 /// @return the enum_decl if @p t is an @ref enum_decl or null
10672 /// otherwise.
10673 enum_type_decl_sptr
is_compatible_with_enum_type(const decl_base_sptr & t)10674 is_compatible_with_enum_type(const decl_base_sptr& t)
10675 {return is_compatible_with_enum_type(is_type(t));}
10676 
10677 /// Test if a decl is an enum_type_decl
10678 ///
10679 /// @param d the decl to test for.
10680 ///
10681 /// @return the enum_type_decl* if @p d is an enum, nil otherwise.
10682 const enum_type_decl*
is_enum_type(const type_or_decl_base * d)10683 is_enum_type(const type_or_decl_base* d)
10684 {return dynamic_cast<const enum_type_decl*>(d);}
10685 
10686 /// Test if a decl is an enum_type_decl
10687 ///
10688 /// @param d the decl to test for.
10689 ///
10690 /// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
10691 enum_type_decl_sptr
is_enum_type(const type_or_decl_base_sptr & d)10692 is_enum_type(const type_or_decl_base_sptr& d)
10693 {return dynamic_pointer_cast<enum_type_decl>(d);}
10694 
10695 /// Test if a type is a class. This function looks through typedefs.
10696 ///
10697 /// @parm t the type to consider.
10698 ///
10699 /// @return the class_decl if @p t is a class_decl or null otherwise.
10700 class_decl_sptr
is_compatible_with_class_type(const type_base_sptr & t)10701 is_compatible_with_class_type(const type_base_sptr& t)
10702 {
10703   if (!t)
10704     return class_decl_sptr();
10705 
10706   // Normally we should strip typedefs entirely, but this is
10707   // potentially costly, especially on binaries with huge changesets
10708   // like the Linux Kernel.  So we just get the leaf types for now.
10709   //
10710   // Maybe there should be an option by which users accepts to pay the
10711   // CPU usage toll in exchange for finer filtering?
10712 
10713   // type_base_sptr ty = strip_typedef(t);
10714   type_base_sptr ty = peel_typedef_type(t);
10715   return is_class_type(ty);
10716 }
10717 
10718 /// Test if a type is a class. This function looks through typedefs.
10719 ///
10720 /// @parm t the type to consider.
10721 ///
10722 /// @return the class_decl if @p t is a class_decl or null otherwise.
10723 class_decl_sptr
is_compatible_with_class_type(const decl_base_sptr & t)10724 is_compatible_with_class_type(const decl_base_sptr& t)
10725 {return is_compatible_with_class_type(is_type(t));}
10726 
10727 /// Test whether a type is a class.
10728 ///
10729 /// @parm t the type to consider.
10730 ///
10731 /// @return true iff @p t is a class_decl.
10732 bool
is_class_type(const type_or_decl_base & t)10733 is_class_type(const type_or_decl_base& t)
10734 {return is_class_type(&t);}
10735 
10736 /// Test whether a type is a class.
10737 ///
10738 /// @parm t the type to consider.
10739 ///
10740 /// @return the class_decl if @p t is a class_decl or null otherwise.
10741 class_decl*
is_class_type(const type_or_decl_base * t)10742 is_class_type(const type_or_decl_base* t)
10743 {
10744   if (!t)
10745     return 0;
10746 
10747   if (t->kind() & type_or_decl_base::CLASS_TYPE)
10748     return reinterpret_cast<class_decl*>
10749       (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
10750 
10751   return 0;
10752 }
10753 
10754 /// Test whether a type is a class.
10755 ///
10756 /// @parm t the type to consider.
10757 ///
10758 /// @return the class_decl if @p t is a class_decl or null otherwise.
10759 class_decl_sptr
is_class_type(const type_or_decl_base_sptr & d)10760 is_class_type(const type_or_decl_base_sptr& d)
10761 {return dynamic_pointer_cast<class_decl>(d);}
10762 
10763 /// Test if the last data member of a class is an array with
10764 /// non-finite data member.
10765 ///
10766 /// The flexible data member idiom is a well known C idiom:
10767 /// https://en.wikipedia.org/wiki/Flexible_array_member.
10768 ///
10769 /// @param klass the class to consider.
10770 ///
10771 /// @return the data member which type is a flexible array, if any, or
10772 /// nil.
10773 var_decl_sptr
has_flexible_array_data_member(const class_decl & klass)10774 has_flexible_array_data_member(const class_decl& klass)
10775 {
10776   var_decl_sptr nil;
10777   const class_or_union::data_members& dms = klass.get_data_members();
10778   if (dms.empty())
10779     return nil;
10780 
10781   if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
10782     {// The type of the last data member is an array.
10783       if (array->is_infinite())
10784 	// The array has a non-finite size.  We are thus looking at a
10785 	// flexible array data member.  Let's return it.
10786 	return dms.back();
10787     }
10788 
10789   return nil;
10790 }
10791 
10792 /// Test if the last data member of a class is an array with
10793 /// non-finite data member.
10794 ///
10795 /// The flexible data member idiom is a well known C idiom:
10796 /// https://en.wikipedia.org/wiki/Flexible_array_member.
10797 ///
10798 /// @param klass the class to consider.
10799 ///
10800 /// @return the data member which type is a flexible array, if any, or
10801 /// nil.
10802 var_decl_sptr
has_flexible_array_data_member(const class_decl * klass)10803 has_flexible_array_data_member(const class_decl* klass)
10804 {
10805   if (!klass)
10806     return var_decl_sptr();
10807 
10808   return has_flexible_array_data_member(*klass);
10809 }
10810 
10811 /// Test if the last data member of a class is an array with
10812 /// non-finite data member.
10813 ///
10814 /// The flexible data member idiom is a well known C idiom:
10815 /// https://en.wikipedia.org/wiki/Flexible_array_member.
10816 ///
10817 /// @param klass the class to consider.
10818 ///
10819 /// @return the data member which type is a flexible array, if any, or
10820 /// nil.
10821 var_decl_sptr
has_flexible_array_data_member(const class_decl_sptr & klass)10822 has_flexible_array_data_member(const class_decl_sptr& klass)
10823 {return has_flexible_array_data_member(klass.get());}
10824 
10825 /// Test wheter a type is a declaration-only class.
10826 ///
10827 /// @param t the type to considier.
10828 ///
10829 /// @param look_through_decl_only if true, then look through the
10830 /// decl-only class to see if it actually has a class definition in
10831 /// the same ABI corpus.
10832 ///
10833 /// @return true iff @p t is a declaration-only class.
10834 bool
is_declaration_only_class_or_union_type(const type_base * t,bool look_through_decl_only)10835 is_declaration_only_class_or_union_type(const type_base *t,
10836 					bool look_through_decl_only)
10837 {
10838   if (class_or_union *klass = is_class_or_union_type(t))
10839     {
10840       if (look_through_decl_only)
10841 	klass = look_through_decl_only_class(klass);
10842       return klass->get_is_declaration_only();
10843     }
10844   return false;
10845 }
10846 
10847 
10848 /// Test wheter a type is a declaration-only class.
10849 ///
10850 /// @param t the type to considier.
10851 ///
10852 /// @param look_through_decl_only if true, then look through the
10853 /// decl-only class to see if it actually has a class definition in
10854 /// the same ABI corpus.
10855 ///
10856 /// @return true iff @p t is a declaration-only class.
10857 bool
is_declaration_only_class_or_union_type(const type_base_sptr & t,bool look_through_decl_only)10858 is_declaration_only_class_or_union_type(const type_base_sptr& t,
10859 					bool look_through_decl_only)
10860 {return is_declaration_only_class_or_union_type(t.get(), look_through_decl_only);}
10861 
10862 /// Test wheter a type is a declaration-only class.
10863 ///
10864 /// @param t the type to considier.
10865 ///
10866 /// @param look_through_decl_only if true, then look through the
10867 /// decl-only class to see if it actually has a class definition in
10868 /// the same ABI corpus.
10869 ///
10870 /// @return true iff @p t is a declaration-only class.
10871 bool
is_declaration_only_class_type(const type_base_sptr & t,bool look_through_decl_only)10872 is_declaration_only_class_type(const type_base_sptr& t,
10873 			       bool look_through_decl_only)
10874 {return is_declaration_only_class_or_union_type(t.get(), look_through_decl_only);}
10875 
10876 /// Test if a type is a @ref class_or_union.
10877 ///
10878 /// @param t the type to consider.
10879 ///
10880 /// @return the @ref class_or_union is @p is a @ref class_or_union, or
10881 /// nil otherwise.
10882 class_or_union*
is_class_or_union_type(const type_or_decl_base * t)10883 is_class_or_union_type(const type_or_decl_base* t)
10884 {return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
10885 
10886 /// Test if a type is a @ref class_or_union.
10887 ///
10888 /// @param t the type to consider.
10889 ///
10890 /// @return the @ref class_or_union is @p is a @ref class_or_union, or
10891 /// nil otherwise.
10892 shared_ptr<class_or_union>
is_class_or_union_type(const shared_ptr<type_or_decl_base> & t)10893 is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
10894 {return dynamic_pointer_cast<class_or_union>(t);}
10895 
10896 /// Test if two class or union types are of the same kind.
10897 ///
10898 /// @param first the first type to consider.
10899 ///
10900 /// @param second the second type to consider.
10901 ///
10902 /// @return true iff @p first is of the same kind as @p second.
10903 bool
class_or_union_types_of_same_kind(const class_or_union * first,const class_or_union * second)10904 class_or_union_types_of_same_kind(const class_or_union* first,
10905 				  const class_or_union* second)
10906 {
10907   if ((is_class_type(first) && is_class_type(second))
10908       || (is_union_type(first) && is_union_type(second)))
10909     return true;
10910 
10911   return false;
10912 }
10913 
10914 /// Test if two class or union types are of the same kind.
10915 ///
10916 /// @param first the first type to consider.
10917 ///
10918 /// @param second the second type to consider.
10919 ///
10920 /// @return true iff @p first is of the same kind as @p second.
10921 bool
class_or_union_types_of_same_kind(const class_or_union_sptr & first,const class_or_union_sptr & second)10922 class_or_union_types_of_same_kind(const class_or_union_sptr& first,
10923 				  const class_or_union_sptr& second)
10924 {return class_or_union_types_of_same_kind(first.get(), second.get());}
10925 
10926 /// Test if a type is a @ref union_decl.
10927 ///
10928 /// @param t the type to consider.
10929 ///
10930 /// @return true iff @p t is a union_decl.
10931 bool
is_union_type(const type_or_decl_base & t)10932 is_union_type(const type_or_decl_base& t)
10933 {return is_union_type(&t);}
10934 
10935 /// Test if a type is a @ref union_decl.
10936 ///
10937 /// @param t the type to consider.
10938 ///
10939 /// @return the @ref union_decl is @p is a @ref union_decl, or nil
10940 /// otherwise.
10941 union_decl*
is_union_type(const type_or_decl_base * t)10942 is_union_type(const type_or_decl_base* t)
10943 {return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
10944 
10945 /// Test if a type is a @ref union_decl.
10946 ///
10947 /// @param t the type to consider.
10948 ///
10949 /// @return the @ref union_decl is @p is a @ref union_decl, or nil
10950 /// otherwise.
10951 union_decl_sptr
is_union_type(const shared_ptr<type_or_decl_base> & t)10952 is_union_type(const shared_ptr<type_or_decl_base>& t)
10953 {return dynamic_pointer_cast<union_decl>(t);}
10954 
10955 /// Test whether a type is a pointer_type_def.
10956 ///
10957 /// @param t the type to test.
10958 ///
10959 /// @return the @ref pointer_type_def_sptr if @p t is a
10960 /// pointer_type_def, null otherwise.
10961 pointer_type_def*
is_pointer_type(type_or_decl_base * t)10962 is_pointer_type(type_or_decl_base* t)
10963 {
10964   if (!t)
10965     return 0;
10966 
10967   if (t->kind() & type_or_decl_base::POINTER_TYPE)
10968     return reinterpret_cast<pointer_type_def*>
10969       (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
10970 
10971   return 0;
10972 }
10973 
10974 /// Test whether a type is a pointer_type_def.
10975 ///
10976 /// @param t the type to test.
10977 ///
10978 /// @return the @ref pointer_type_def_sptr if @p t is a
10979 /// pointer_type_def, null otherwise.
10980 const pointer_type_def*
is_pointer_type(const type_or_decl_base * t)10981 is_pointer_type(const type_or_decl_base* t)
10982 {
10983   return is_pointer_type(const_cast<type_or_decl_base*>(t));
10984 }
10985 
10986 /// Test whether a type is a pointer_type_def.
10987 ///
10988 /// @param t the type to test.
10989 ///
10990 /// @return the @ref pointer_type_def_sptr if @p t is a
10991 /// pointer_type_def, null otherwise.
10992 pointer_type_def_sptr
is_pointer_type(const type_or_decl_base_sptr & t)10993 is_pointer_type(const type_or_decl_base_sptr &t)
10994 {return dynamic_pointer_cast<pointer_type_def>(t);}
10995 
10996 
10997 /// Test if a type is a typedef, pointer or reference to a decl-only
10998 /// class/union.
10999 ///
11000 /// This looks into qualified types too.
11001 ///
11002 /// @param t the type to consider.
11003 ///
11004 /// @return true iff @p t is a type is a typedef, pointer or reference
11005 /// to a decl-only class/union.
11006 bool
is_typedef_ptr_or_ref_to_decl_only_class_or_union_type(const type_base * t)11007 is_typedef_ptr_or_ref_to_decl_only_class_or_union_type(const type_base* t)
11008 {
11009   const type_base * type =
11010     peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
11011 
11012   if (is_declaration_only_class_or_union_type(type,
11013 					      /*look_through_decl_only=*/true))
11014     return true;
11015 
11016   return false;
11017 }
11018 
11019 /// Test whether a type is a reference_type_def.
11020 ///
11021 /// @param t the type to test.
11022 ///
11023 /// @return the @ref reference_type_def_sptr if @p t is a
11024 /// reference_type_def, null otherwise.
11025 reference_type_def*
is_reference_type(type_or_decl_base * t)11026 is_reference_type(type_or_decl_base* t)
11027 {return dynamic_cast<reference_type_def*>(t);}
11028 
11029 /// Test whether a type is a reference_type_def.
11030 ///
11031 /// @param t the type to test.
11032 ///
11033 /// @return the @ref reference_type_def_sptr if @p t is a
11034 /// reference_type_def, null otherwise.
11035 const reference_type_def*
is_reference_type(const type_or_decl_base * t)11036 is_reference_type(const type_or_decl_base* t)
11037 {return dynamic_cast<const reference_type_def*>(t);}
11038 
11039 /// Test whether a type is a reference_type_def.
11040 ///
11041 /// @param t the type to test.
11042 ///
11043 /// @return the @ref reference_type_def_sptr if @p t is a
11044 /// reference_type_def, null otherwise.
11045 reference_type_def_sptr
is_reference_type(const type_or_decl_base_sptr & t)11046 is_reference_type(const type_or_decl_base_sptr& t)
11047 {return dynamic_pointer_cast<reference_type_def>(t);}
11048 
11049 /// Test if a type is equivalent to a pointer to void type.
11050 ///
11051 /// Note that this looks trough typedefs or CV qualifiers to look for
11052 /// the void pointer.
11053 ///
11054 /// @param type the type to consider.
11055 ///
11056 /// @return the actual void pointer if @p is eqivalent to a void
11057 /// pointer or NULL if it's not.
11058 const type_base*
is_void_pointer_type_equivalent(const type_base * type)11059 is_void_pointer_type_equivalent(const type_base* type)
11060 {
11061   type = peel_qualified_or_typedef_type(type);
11062 
11063   const pointer_type_def * t = is_pointer_type(type);
11064   if (!t)
11065     return 0;
11066 
11067   // Look through typedefs in the pointed-to type as well.
11068   type_base * ty = t->get_pointed_to_type().get();
11069   ty = peel_qualified_or_typedef_type(ty);
11070   if (ty && ty->get_environment().is_void_type(ty))
11071     return ty;
11072 
11073   return 0;
11074 }
11075 
11076 /// Test if a type is equivalent to a pointer to void type.
11077 ///
11078 /// Note that this looks trough typedefs or CV qualifiers to look for
11079 /// the void pointer.
11080 ///
11081 /// @param type the type to consider.
11082 ///
11083 /// @return the actual void pointer if @p is eqivalent to a void
11084 /// pointer or NULL if it's not.
11085 const type_base*
is_void_pointer_type_equivalent(const type_base & type)11086 is_void_pointer_type_equivalent(const type_base& type)
11087 {return is_void_pointer_type_equivalent(&type);}
11088 
11089 /// Test if a type is a pointer to void type.
11090 ///
11091 /// @param type the type to consider.
11092 ///
11093 /// @return the actual void pointer if @p is a void pointer or NULL if
11094 /// it's not.
11095 const type_base*
is_void_pointer_type(const type_base * t)11096 is_void_pointer_type(const type_base* t)
11097 {
11098   if (!t)
11099     return nullptr;
11100 
11101   if (t->get_environment().get_void_pointer_type().get() == t)
11102     return t;
11103 
11104   const pointer_type_def* ptr = is_pointer_type(t);
11105   if (!ptr)
11106     return nullptr;
11107 
11108   if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11109     return t;
11110 
11111   return nullptr;
11112 }
11113 
11114 /// Test if a type is a pointer to void type.
11115 ///
11116 /// @param type the type to consider.
11117 ///
11118 /// @return the actual void pointer if @p is a void pointer or NULL if
11119 /// it's not.
11120 const type_base_sptr
is_void_pointer_type(const type_base_sptr & t)11121 is_void_pointer_type(const type_base_sptr& t)
11122 {
11123   type_base_sptr nil;
11124   if (!t)
11125     return nil;
11126 
11127   if (t->get_environment().get_void_pointer_type().get() == t.get())
11128     return t;
11129 
11130   pointer_type_def* ptr = is_pointer_type(t.get());
11131   if (!ptr)
11132     return nil;
11133 
11134   if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11135     return t;
11136 
11137   return nil;
11138 }
11139 
11140 /// Test whether a type is a reference_type_def.
11141 ///
11142 /// @param t the type to test.
11143 ///
11144 /// @return the @ref reference_type_def_sptr if @p t is a
11145 /// reference_type_def, null otherwise.
11146 qualified_type_def*
is_qualified_type(const type_or_decl_base * t)11147 is_qualified_type(const type_or_decl_base* t)
11148 {return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
11149 
11150 /// Test whether a type is a qualified_type_def.
11151 ///
11152 /// @param t the type to test.
11153 ///
11154 /// @return the @ref qualified_type_def_sptr if @p t is a
11155 /// qualified_type_def, null otherwise.
11156 qualified_type_def_sptr
is_qualified_type(const type_or_decl_base_sptr & t)11157 is_qualified_type(const type_or_decl_base_sptr& t)
11158 {return dynamic_pointer_cast<qualified_type_def>(t);}
11159 
11160 /// Test whether a type is a function_type.
11161 ///
11162 /// @param t the type to test.
11163 ///
11164 /// @return the @ref function_type_sptr if @p t is a
11165 /// function_type, null otherwise.
11166 function_type_sptr
is_function_type(const type_or_decl_base_sptr & t)11167 is_function_type(const type_or_decl_base_sptr& t)
11168 {return dynamic_pointer_cast<function_type>(t);}
11169 
11170 /// Test whether a type is a function_type.
11171 ///
11172 /// @param t the type to test.
11173 ///
11174 /// @return the @ref function_type_sptr if @p t is a
11175 /// function_type, null otherwise.
11176 function_type*
is_function_type(type_or_decl_base * t)11177 is_function_type(type_or_decl_base* t)
11178 {return dynamic_cast<function_type*>(t);}
11179 
11180 /// Test whether a type is a function_type.
11181 ///
11182 /// @param t the type to test.
11183 ///
11184 /// @return the @ref function_type_sptr if @p t is a
11185 /// function_type, null otherwise.
11186 const function_type*
is_function_type(const type_or_decl_base * t)11187 is_function_type(const type_or_decl_base* t)
11188 {return dynamic_cast<const function_type*>(t);}
11189 
11190 /// Test whether a type is a method_type.
11191 ///
11192 /// @param t the type to test.
11193 ///
11194 /// @return the @ref method_type_sptr if @p t is a
11195 /// method_type, null otherwise.
11196 method_type_sptr
is_method_type(const type_or_decl_base_sptr & t)11197 is_method_type(const type_or_decl_base_sptr& t)
11198 {return dynamic_pointer_cast<method_type>(t);}
11199 
11200 /// Test whether a type is a method_type.
11201 ///
11202 /// @param t the type to test.
11203 ///
11204 /// @return the @ref method_type_sptr if @p t is a
11205 /// method_type, null otherwise.
11206 const method_type*
is_method_type(const type_or_decl_base * t)11207 is_method_type(const type_or_decl_base* t)
11208 {return dynamic_cast<const method_type*>(t);}
11209 
11210 /// Test whether a type is a method_type.
11211 ///
11212 /// @param t the type to test.
11213 ///
11214 /// @return the @ref method_type_sptr if @p t is a
11215 /// method_type, null otherwise.
11216 method_type*
is_method_type(type_or_decl_base * t)11217 is_method_type(type_or_decl_base* t)
11218 {return dynamic_cast<method_type*>(t);}
11219 
11220 /// If a class (or union) is a decl-only class, get its definition.
11221 /// Otherwise, just return the initial class.
11222 ///
11223 /// @param the_class the class (or union) to consider.
11224 ///
11225 /// @return either the definition of the class, or the class itself.
11226 class_or_union*
look_through_decl_only_class(class_or_union * the_class)11227 look_through_decl_only_class(class_or_union* the_class)
11228 {return is_class_or_union_type(look_through_decl_only(the_class));}
11229 
11230 /// If a class (or union) is a decl-only class, get its definition.
11231 /// Otherwise, just return the initial class.
11232 ///
11233 /// @param the_class the class (or union) to consider.
11234 ///
11235 /// @return either the definition of the class, or the class itself.
11236 class_or_union_sptr
look_through_decl_only_class(const class_or_union & the_class)11237 look_through_decl_only_class(const class_or_union& the_class)
11238 {return is_class_or_union_type(look_through_decl_only(the_class));}
11239 
11240 /// If a class (or union) is a decl-only class, get its definition.
11241 /// Otherwise, just return the initial class.
11242 ///
11243 /// @param klass the class (or union) to consider.
11244 ///
11245 /// @return either the definition of the class, or the class itself.
11246 class_or_union_sptr
look_through_decl_only_class(class_or_union_sptr klass)11247 look_through_decl_only_class(class_or_union_sptr klass)
11248 {return is_class_or_union_type(look_through_decl_only(klass));}
11249 
11250 /// If an enum is a decl-only enum, get its definition.
11251 /// Otherwise, just return the initial enum.
11252 ///
11253 /// @param the_enum the enum to consider.
11254 ///
11255 /// @return either the definition of the enum, or the enum itself.
11256 enum_type_decl_sptr
look_through_decl_only_enum(const enum_type_decl & the_enum)11257 look_through_decl_only_enum(const enum_type_decl& the_enum)
11258 {return is_enum_type(look_through_decl_only(the_enum));}
11259 
11260 /// If an enum is a decl-only enum, get its definition.
11261 /// Otherwise, just return the initial enum.
11262 ///
11263 /// @param enom the enum to consider.
11264 ///
11265 /// @return either the definition of the enum, or the enum itself.
11266 enum_type_decl_sptr
look_through_decl_only_enum(enum_type_decl_sptr enom)11267 look_through_decl_only_enum(enum_type_decl_sptr enom)
11268 {return is_enum_type(look_through_decl_only(enom));}
11269 
11270 /// If a decl is decl-only get its definition.  Otherwise, just return nil.
11271 ///
11272 /// @param d the decl to consider.
11273 ///
11274 /// @return either the definition of the decl, or nil.
11275 decl_base_sptr
look_through_decl_only(const decl_base & d)11276 look_through_decl_only(const decl_base& d)
11277 {
11278   decl_base_sptr decl;
11279   if (d.get_is_declaration_only())
11280     decl = d.get_definition_of_declaration();
11281 
11282   if (!decl)
11283     return decl;
11284 
11285   while (decl->get_is_declaration_only()
11286 	 && decl->get_definition_of_declaration())
11287     decl = decl->get_definition_of_declaration();
11288 
11289   return decl;
11290 }
11291 
11292 /// If a decl is decl-only enum, get its definition.  Otherwise, just
11293 /// return the initial decl.
11294 ///
11295 /// @param d the decl to consider.
11296 ///
11297 /// @return either the definition of the enum, or the decl itself.
11298 decl_base*
look_through_decl_only(decl_base * d)11299 look_through_decl_only(decl_base* d)
11300 {
11301   if (!d)
11302     return d;
11303 
11304   decl_base* result = look_through_decl_only(*d).get();
11305   if (!result)
11306     result = d;
11307 
11308   return result;
11309 }
11310 
11311 /// If a decl is decl-only get its definition.  Otherwise, just return nil.
11312 ///
11313 /// @param d the decl to consider.
11314 ///
11315 /// @return either the definition of the decl, or nil.
11316 decl_base_sptr
look_through_decl_only(const decl_base_sptr & d)11317 look_through_decl_only(const decl_base_sptr& d)
11318 {
11319   if (!d)
11320     return d;
11321 
11322   decl_base_sptr result = look_through_decl_only(*d);
11323   if (!result)
11324     result = d;
11325 
11326   return result;
11327 }
11328 
11329 /// If a type is is decl-only, then get its definition.  Otherwise,
11330 /// just return the initial type.
11331 ///
11332 /// @param d the decl to consider.
11333 ///
11334 /// @return either the definition of the decl, or the initial type.
11335 type_base*
look_through_decl_only(type_base * t)11336 look_through_decl_only(type_base* t)
11337 {
11338   decl_base* d = is_decl(t);
11339   if (!d)
11340     return t;
11341   d = look_through_decl_only(d);
11342   return is_type(d);
11343 }
11344 
11345 /// If a type is is decl-only, then get its definition.  Otherwise,
11346 /// just return the initial type.
11347 ///
11348 /// @param d the decl to consider.
11349 ///
11350 /// @return either the definition of the decl, or the initial type.
11351 type_base_sptr
look_through_decl_only(const type_base_sptr & t)11352 look_through_decl_only(const type_base_sptr& t)
11353 {
11354   decl_base_sptr d = is_decl(t);
11355   if (!d)
11356     return t;
11357   d = look_through_decl_only(d);
11358   return is_type(d);
11359 }
11360 
11361 /// Tests if a declaration is a variable declaration.
11362 ///
11363 /// @param decl the decl to test.
11364 ///
11365 /// @return the var_decl_sptr iff decl is a variable declaration; nil
11366 /// otherwise.
11367 var_decl*
is_var_decl(const type_or_decl_base * tod)11368 is_var_decl(const type_or_decl_base* tod)
11369 {return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
11370 
11371 /// Tests if a declaration is a variable declaration.
11372 ///
11373 /// @param decl the decl to test.
11374 ///
11375 /// @return the var_decl_sptr iff decl is a variable declaration; nil
11376 /// otherwise.
11377 var_decl_sptr
is_var_decl(const type_or_decl_base_sptr & decl)11378 is_var_decl(const type_or_decl_base_sptr& decl)
11379 {return dynamic_pointer_cast<var_decl>(decl);}
11380 
11381 /// Tests if a declaration is a namespace declaration.
11382 ///
11383 /// @param d the decalration to consider.
11384 ///
11385 /// @return the namespace declaration if @p d is a namespace.
11386 namespace_decl_sptr
is_namespace(const decl_base_sptr & d)11387 is_namespace(const decl_base_sptr& d)
11388 {return dynamic_pointer_cast<namespace_decl>(d);}
11389 
11390 /// Tests if a declaration is a namespace declaration.
11391 ///
11392 /// @param d the decalration to consider.
11393 ///
11394 /// @return the namespace declaration if @p d is a namespace.
11395 namespace_decl*
is_namespace(const decl_base * d)11396 is_namespace(const decl_base* d)
11397 {return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
11398 
11399 /// Tests whether a decl is a template parameter composition type.
11400 ///
11401 /// @param decl the declaration to consider.
11402 ///
11403 /// @return true iff decl is a template parameter composition type.
11404 bool
is_template_parm_composition_type(const shared_ptr<decl_base> decl)11405 is_template_parm_composition_type(const shared_ptr<decl_base> decl)
11406 {
11407   return (decl
11408 	  && is_at_template_scope(decl)
11409 	  && is_type(decl)
11410 	  && !is_template_parameter(decl));
11411 }
11412 
11413 /// Test whether a decl is the pattern of a function template.
11414 ///
11415 /// @param decl the decl to consider.
11416 ///
11417 /// @return true iff decl is the pattern of a function template.
11418 bool
is_function_template_pattern(const shared_ptr<decl_base> decl)11419 is_function_template_pattern(const shared_ptr<decl_base> decl)
11420 {
11421   return (decl
11422 	  && dynamic_pointer_cast<function_decl>(decl)
11423 	  && dynamic_cast<template_decl*>(decl->get_scope()));
11424 }
11425 
11426 /// Test if a type is an array_type_def.
11427 ///
11428 /// @param type the type to consider.
11429 ///
11430 /// @return true iff @p type is an array_type_def.
11431 array_type_def*
is_array_type(const type_or_decl_base * type)11432 is_array_type(const type_or_decl_base* type)
11433 {return dynamic_cast<array_type_def*>(const_cast<type_or_decl_base*>(type));}
11434 
11435 /// Test if a type is an array_type_def.
11436 ///
11437 /// @param type the type to consider.
11438 ///
11439 /// @return true iff @p type is an array_type_def.
11440 array_type_def_sptr
is_array_type(const type_or_decl_base_sptr & type)11441 is_array_type(const type_or_decl_base_sptr& type)
11442 {return dynamic_pointer_cast<array_type_def>(type);}
11443 
11444 /// Tests if the element of a given array is a qualified type.
11445 ///
11446 /// @param array the array type to consider.
11447 ///
11448 /// @return the qualified element of the array iff it's a qualified
11449 /// type.  Otherwise, return a nil object.
11450 qualified_type_def_sptr
is_array_of_qualified_element(const array_type_def_sptr & array)11451 is_array_of_qualified_element(const array_type_def_sptr& array)
11452 {
11453   if (!array)
11454     return qualified_type_def_sptr();
11455 
11456   return is_qualified_type(array->get_element_type());
11457 }
11458 
11459 /// Test if an array type is an array to a qualified element type.
11460 ///
11461 /// @param type the array type to consider.
11462 ///
11463 /// @return true the array @p type iff it's an array to a qualified
11464 /// element type.
11465 array_type_def_sptr
is_array_of_qualified_element(const type_base_sptr & type)11466 is_array_of_qualified_element(const type_base_sptr& type)
11467 {
11468   if (array_type_def_sptr array = is_array_type(type))
11469     if (is_array_of_qualified_element(array))
11470       return array;
11471 
11472   return array_type_def_sptr();
11473 }
11474 
11475 /// Test if a type is a typedef of an array.
11476 ///
11477 /// Note that the function looks through qualified and typedefs types
11478 /// of the underlying type of the current typedef.  In other words, if
11479 /// we are looking at a typedef of a CV-qualified array, or at a
11480 /// typedef of a CV-qualified typedef of an array, this function will
11481 /// still return TRUE.
11482 ///
11483 /// @param t the type to consider.
11484 ///
11485 /// @return true if t is a typedef which underlying type is an array.
11486 /// That array might be either cv-qualified array or a typedef'ed
11487 /// array, or a combination of both.
11488 array_type_def_sptr
is_typedef_of_array(const type_base_sptr & t)11489 is_typedef_of_array(const type_base_sptr& t)
11490 {
11491   array_type_def_sptr result;
11492 
11493   if (typedef_decl_sptr typdef = is_typedef(t))
11494     {
11495       type_base_sptr u =
11496 	peel_qualified_or_typedef_type(typdef->get_underlying_type());
11497       result = is_array_type(u);
11498     }
11499 
11500   return result;
11501 }
11502 
11503 /// Test if a type is an array_type_def::subrange_type.
11504 ///
11505 /// @param type the type to consider.
11506 ///
11507 /// @return the array_type_def::subrange_type which @p type is a type
11508 /// of, or nil if it's not of that type.
11509 array_type_def::subrange_type*
is_subrange_type(const type_or_decl_base * type)11510 is_subrange_type(const type_or_decl_base *type)
11511 {
11512   return dynamic_cast<array_type_def::subrange_type*>
11513     (const_cast<type_or_decl_base*>(type));
11514 }
11515 
11516 /// Test if a type is an array_type_def::subrange_type.
11517 ///
11518 /// @param type the type to consider.
11519 ///
11520 /// @return the array_type_def::subrange_type which @p type is a type
11521 /// of, or nil if it's not of that type.
11522 array_type_def::subrange_sptr
is_subrange_type(const type_or_decl_base_sptr & type)11523 is_subrange_type(const type_or_decl_base_sptr &type)
11524 {return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
11525 
11526 /// Tests whether a decl is a template.
11527 ///
11528 /// @param decl the decl to consider.
11529 ///
11530 /// @return true iff decl is a function template, class template, or
11531 /// template template parameter.
11532 bool
is_template_decl(const decl_base_sptr & decl)11533 is_template_decl(const decl_base_sptr& decl)
11534 {return decl && dynamic_pointer_cast<template_decl>(decl);}
11535 
11536 /// This enum describe the kind of entity to lookup, while using the
11537 /// lookup API.
11538 enum lookup_entity_kind
11539 {
11540   LOOKUP_ENTITY_TYPE,
11541   LOOKUP_ENTITY_VAR,
11542 };
11543 
11544 /// Find the first relevant delimiter (the "::" string) in a fully
11545 /// qualified C++ type name, starting from a given position.  The
11546 /// delimiter returned separates a type name from the name of its
11547 /// context.
11548 ///
11549 /// This is supposed to work correctly on names in cases like this:
11550 ///
11551 ///    foo<ns1::name1, ns2::name2>
11552 ///
11553 /// In that case when called with with parameter @p begin set to 0, no
11554 /// delimiter is returned, because the type name in this case is:
11555 /// 'foo<ns1::name1, ns2::name2>'.
11556 ///
11557 /// But in this case:
11558 ///
11559 ///   foo<p1, bar::name>::some_type
11560 ///
11561 /// The "::" returned is the one right before 'some_type'.
11562 ///
11563 /// @param fqn the fully qualified name of the type to consider.
11564 ///
11565 /// @param begin the position from which to look for the delimiter.
11566 ///
11567 /// @param delim_pos out parameter. Is set to the position of the
11568 /// delimiter iff the function returned true.
11569 ///
11570 /// @return true iff the function found and returned the delimiter.
11571 static bool
find_next_delim_in_cplus_type(const string & fqn,size_t begin,size_t & delim_pos)11572 find_next_delim_in_cplus_type(const string&	fqn,
11573 			      size_t		begin,
11574 			      size_t&		delim_pos)
11575 {
11576   int angle_count = 0;
11577   bool found = false;
11578   size_t i = begin;
11579   for (; i < fqn.size(); ++i)
11580     {
11581       if (fqn[i] == '<')
11582 	++angle_count;
11583       else if (fqn[i] == '>')
11584 	--angle_count;
11585       else if (i + 1 < fqn.size()
11586 	       && !angle_count
11587 	       && fqn[i] == ':'
11588 	       && fqn[i+1] == ':')
11589 	{
11590 	  delim_pos = i;
11591 	  found = true;
11592 	  break;
11593 	}
11594     }
11595   return found;
11596 }
11597 
11598 /// Decompose a fully qualified name into the list of its components.
11599 ///
11600 /// @param fqn the fully qualified name to decompose.
11601 ///
11602 /// @param comps the resulting list of component to fill.
11603 void
fqn_to_components(const string & fqn,list<string> & comps)11604 fqn_to_components(const string& fqn,
11605 		  list<string>& comps)
11606 {
11607   string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
11608   do
11609     {
11610       if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
11611 	comp_end = fqn_size;
11612 
11613       string comp = fqn.substr(comp_begin, comp_end - comp_begin);
11614       comps.push_back(comp);
11615 
11616       comp_begin = comp_end + 2;
11617       if (comp_begin >= fqn_size)
11618 	break;
11619     } while (true);
11620 }
11621 
11622 /// Turn a set of qualified name components (that name a type) into a
11623 /// qualified name string.
11624 ///
11625 /// @param comps the name components
11626 ///
11627 /// @return the resulting string, which would be the qualified name of
11628 /// a type.
11629 string
components_to_type_name(const list<string> & comps)11630 components_to_type_name(const list<string>& comps)
11631 {
11632   string result;
11633   for (list<string>::const_iterator c = comps.begin();
11634        c != comps.end();
11635        ++c)
11636     if (c == comps.begin())
11637       result = *c;
11638     else
11639       result += "::" + *c;
11640   return result;
11641 }
11642 
11643 /// This predicate returns true if a given container iterator points
11644 /// to the last element of the container, false otherwise.
11645 ///
11646 /// @tparam T the type of the container of the iterator.
11647 ///
11648 /// @param container the container the iterator points into.
11649 ///
11650 /// @param i the iterator to consider.
11651 ///
11652 /// @return true iff the iterator points to the last element of @p
11653 /// container.
11654 template<typename T>
11655 static bool
iterator_is_last(T & container,typename T::const_iterator i)11656 iterator_is_last(T& container,
11657 		 typename T::const_iterator i)
11658 {
11659   typename T::const_iterator next = i;
11660   ++next;
11661   return (next == container.end());
11662 }
11663 
11664 //--------------------------------
11665 // <type and decls lookup stuff>
11666 // ------------------------------
11667 
11668 /// Lookup all the type*s* that have a given fully qualified name.
11669 ///
11670 /// @param type_name the fully qualified name of the type to
11671 /// lookup.
11672 ///
11673 /// @param type_map the map to look into.
11674 ///
11675 /// @return the vector containing the types named @p type_name.  If
11676 /// the lookup didn't yield any type, then this function returns nil.
11677 static const type_base_wptrs_type*
lookup_types_in_map(const interned_string & type_name,const istring_type_base_wptrs_map_type & type_map)11678 lookup_types_in_map(const interned_string& type_name,
11679 		    const istring_type_base_wptrs_map_type& type_map)
11680 {
11681   istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
11682   if (i != type_map.end())
11683     return &i->second;
11684   return 0;
11685 }
11686 
11687 /// Lookup a type (with a given name) in a map that associates a type
11688 /// name to a type.  If there are several types with a given name,
11689 /// then try to return the first one that is not decl-only.
11690 /// Otherwise, return the last of such types, that is, the last one
11691 /// that got registered.
11692 ///
11693 /// @tparam TypeKind the type of the type this function is supposed to
11694 /// return.
11695 ///
11696 /// @param type_name the name of the type to lookup.
11697 ///
11698 /// @param type_map the map in which to look.
11699 ///
11700 /// @return a shared_ptr to the type found.  If no type was found or
11701 /// if the type found was not of type @p TypeKind then the function
11702 /// returns nil.
11703 template <class TypeKind>
11704 static shared_ptr<TypeKind>
lookup_type_in_map(const interned_string & type_name,const istring_type_base_wptrs_map_type & type_map)11705 lookup_type_in_map(const interned_string& type_name,
11706 		   const istring_type_base_wptrs_map_type& type_map)
11707 {
11708   istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
11709   if (i != type_map.end())
11710     {
11711       // Walk the types that have the name "type_name" and return the
11712       // first one that is not declaration-only ...
11713       for (auto j : i->second)
11714 	{
11715 	  type_base_sptr t(j);
11716 	  decl_base_sptr d = is_decl(t);
11717 	  if (d && !d->get_is_declaration_only())
11718 	    return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
11719 	}
11720       // ... or return the last type with the name "type_name" that
11721       // was recorded.  It's likely to be declaration-only if we
11722       // reached this point.
11723       return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
11724     }
11725   return shared_ptr<TypeKind>();
11726 }
11727 
11728 /// Lookup a basic type from a translation unit.
11729 ///
11730 /// This is done by looking the type up in the type map that is
11731 /// maintained in the translation unit.  So this is as fast as
11732 /// possible.
11733 ///
11734 /// @param type_name the name of the basic type to look for.
11735 ///
11736 /// @param tu the translation unit to look into.
11737 ///
11738 /// @return the basic type found or nil if no basic type was found.
11739 type_decl_sptr
lookup_basic_type(const interned_string & type_name,const translation_unit & tu)11740 lookup_basic_type(const interned_string& type_name, const translation_unit& tu)
11741 {
11742   return lookup_type_in_map<type_decl>(type_name,
11743 				       tu.get_types().basic_types());
11744 }
11745 
11746 /// Lookup a basic type from a translation unit.
11747 ///
11748 /// This is done by looking the type up in the type map that is
11749 /// maintained in the translation unit.  So this is as fast as
11750 /// possible.
11751 ///
11752 /// @param type_name the name of the basic type to look for.
11753 ///
11754 /// @param tu the translation unit to look into.
11755 ///
11756 /// @return the basic type found or nil if no basic type was found.
11757 type_decl_sptr
lookup_basic_type(const string & type_name,const translation_unit & tu)11758 lookup_basic_type(const string& type_name, const translation_unit& tu)
11759 {
11760   const environment& env = tu.get_environment();
11761 
11762   interned_string s = env.intern(type_name);
11763   return lookup_basic_type(s, tu);
11764 }
11765 
11766 /// Lookup a class type from a translation unit.
11767 ///
11768 /// This is done by looking the type up in the type map that is
11769 /// maintained in the translation unit.  So this is as fast as
11770 /// possible.
11771 ///
11772 /// @param fqn the fully qualified name of the class type node to look
11773 /// up.
11774 ///
11775 /// @param tu the translation unit to perform lookup from.
11776 ///
11777 /// @return the declaration of the class type IR node found, NULL
11778 /// otherwise.
11779 class_decl_sptr
lookup_class_type(const string & fqn,const translation_unit & tu)11780 lookup_class_type(const string& fqn, const translation_unit& tu)
11781 {
11782   const environment& env = tu.get_environment();
11783   interned_string s = env.intern(fqn);
11784   return lookup_class_type(s, tu);
11785 }
11786 
11787 /// Lookup a class type from a translation unit.
11788 ///
11789 /// This is done by looking the type up in the type map that is
11790 /// maintained in the translation unit.  So this is as fast as
11791 /// possible.
11792 ///
11793 /// @param type_name the name of the class type to look for.
11794 ///
11795 /// @param tu the translation unit to look into.
11796 ///
11797 /// @return the class type found or nil if no class type was found.
11798 class_decl_sptr
lookup_class_type(const interned_string & type_name,const translation_unit & tu)11799 lookup_class_type(const interned_string& type_name, const translation_unit& tu)
11800 {
11801   return lookup_type_in_map<class_decl>(type_name,
11802 					tu.get_types().class_types());
11803 }
11804 
11805 /// Lookup a union type from a translation unit.
11806 ///
11807 /// This is done by looking the type up in the type map that is
11808 /// maintained in the translation unit.  So this is as fast as
11809 /// possible.
11810 ///
11811 /// @param type_name the name of the union type to look for.
11812 ///
11813 /// @param tu the translation unit to look into.
11814 ///
11815 /// @return the union type found or nil if no union type was found.
11816 union_decl_sptr
lookup_union_type(const interned_string & type_name,const translation_unit & tu)11817 lookup_union_type(const interned_string& type_name, const translation_unit& tu)
11818 {
11819   return lookup_type_in_map<union_decl>(type_name,
11820 					tu.get_types().union_types());
11821 }
11822 
11823 /// Lookup a union type from a translation unit.
11824 ///
11825 /// This is done by looking the type up in the type map that is
11826 /// maintained in the translation unit.  So this is as fast as
11827 /// possible.
11828 ///
11829 /// @param fqn the fully qualified name of the type to lookup.
11830 ///
11831 /// @param tu the translation unit to look into.
11832 ///
11833 /// @return the union type found or nil if no union type was found.
11834 union_decl_sptr
lookup_union_type(const string & fqn,const translation_unit & tu)11835 lookup_union_type(const string& fqn, const translation_unit& tu)
11836 {
11837   const environment& env = tu.get_environment();
11838   interned_string s = env.intern(fqn);
11839   return lookup_union_type(s, tu);
11840 }
11841 
11842 /// Lookup a union type in a given corpus, from its location.
11843 ///
11844 /// @param loc the location of the union type to look for.
11845 ///
11846 /// @param corp the corpus to look it from.
11847 ///
11848 /// @return the resulting union_decl.
11849 union_decl_sptr
lookup_union_type_per_location(const interned_string & loc,const corpus & corp)11850 lookup_union_type_per_location(const interned_string &loc, const corpus& corp)
11851 {
11852   const istring_type_base_wptrs_map_type& m =
11853     corp.get_type_per_loc_map().union_types();
11854   union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
11855 
11856   return result;
11857 }
11858 
11859 /// Lookup a union type in a given corpus, from its location.
11860 ///
11861 /// @param loc the location of the union type to look for.
11862 ///
11863 /// @param corp the corpus to look it from.
11864 ///
11865 /// @return the resulting union_decl.
11866 union_decl_sptr
lookup_union_type_per_location(const string & loc,const corpus & corp)11867 lookup_union_type_per_location(const string& loc, const corpus& corp)
11868 {
11869   const environment& env = corp.get_environment();
11870   return lookup_union_type_per_location(env.intern(loc), corp);
11871 }
11872 
11873 /// Lookup an enum type from a translation unit.
11874 ///
11875 /// This is done by looking the type up in the type map that is
11876 /// maintained in the translation unit.  So this is as fast as
11877 /// possible.
11878 ///
11879 /// @param type_name the name of the enum type to look for.
11880 ///
11881 /// @param tu the translation unit to look into.
11882 ///
11883 /// @return the enum type found or nil if no enum type was found.
11884 enum_type_decl_sptr
lookup_enum_type(const interned_string & type_name,const translation_unit & tu)11885 lookup_enum_type(const interned_string& type_name, const translation_unit& tu)
11886 {
11887   return lookup_type_in_map<enum_type_decl>(type_name,
11888 					    tu.get_types().enum_types());
11889 }
11890 
11891 /// Lookup an enum type from a translation unit.
11892 ///
11893 /// This is done by looking the type up in the type map that is
11894 /// maintained in the translation unit.  So this is as fast as
11895 /// possible.
11896 ///
11897 /// @param type_name the name of the enum type to look for.
11898 ///
11899 /// @param tu the translation unit to look into.
11900 ///
11901 /// @return the enum type found or nil if no enum type was found.
11902 enum_type_decl_sptr
lookup_enum_type(const string & type_name,const translation_unit & tu)11903 lookup_enum_type(const string& type_name, const translation_unit& tu)
11904 {
11905   const environment& env = tu.get_environment();
11906   interned_string s = env.intern(type_name);
11907   return lookup_enum_type(s, tu);
11908 }
11909 
11910 /// Lookup a typedef type from a translation unit.
11911 ///
11912 /// This is done by looking the type up in the type map that is
11913 /// maintained in the translation unit.  So this is as fast as
11914 /// possible.
11915 ///
11916 /// @param type_name the name of the typedef type to look for.
11917 ///
11918 /// @param tu the translation unit to look into.
11919 ///
11920 /// @return the typedef type found or nil if no typedef type was
11921 /// found.
11922 typedef_decl_sptr
lookup_typedef_type(const interned_string & type_name,const translation_unit & tu)11923 lookup_typedef_type(const interned_string& type_name,
11924 		    const translation_unit& tu)
11925 {
11926   return lookup_type_in_map<typedef_decl>(type_name,
11927 					  tu.get_types().typedef_types());
11928 }
11929 
11930 /// Lookup a typedef type from a translation unit.
11931 ///
11932 /// This is done by looking the type up in the type map that is
11933 /// maintained in the translation unit.  So this is as fast as
11934 /// possible.
11935 ///
11936 /// @param type_name the name of the typedef type to look for.
11937 ///
11938 /// @param tu the translation unit to look into.
11939 ///
11940 /// @return the typedef type found or nil if no typedef type was
11941 /// found.
11942 typedef_decl_sptr
lookup_typedef_type(const string & type_name,const translation_unit & tu)11943 lookup_typedef_type(const string& type_name, const translation_unit& tu)
11944 {
11945   const environment& env = tu.get_environment();
11946   interned_string s = env.intern(type_name);
11947   return lookup_typedef_type(s, tu);
11948 }
11949 
11950 /// Lookup a qualified type from a translation unit.
11951 ///
11952 /// This is done by looking the type up in the type map that is
11953 /// maintained in the translation unit.  So this is as fast as
11954 /// possible.
11955 ///
11956 /// @param type_name the name of the qualified type to look for.
11957 ///
11958 /// @param tu the translation unit to look into.
11959 ///
11960 /// @return the qualified type found or nil if no qualified type was
11961 /// found.
11962 qualified_type_def_sptr
lookup_qualified_type(const interned_string & type_name,const translation_unit & tu)11963 lookup_qualified_type(const interned_string& type_name,
11964 		      const translation_unit& tu)
11965 {
11966   const type_maps& m = tu.get_types();
11967   return lookup_type_in_map<qualified_type_def>(type_name,
11968 						m.qualified_types());
11969 }
11970 
11971 /// Lookup a qualified type from a translation unit.
11972 ///
11973 /// This is done by looking the type up in the type map that is
11974 /// maintained in the translation unit.  So this is as fast as
11975 /// possible.
11976 ///
11977 /// @param underlying_type the underying type of the qualified type to
11978 /// look up.
11979 ///
11980 /// @param quals the CV-qualifiers of the qualified type to look for.
11981 ///
11982 /// @param tu the translation unit to look into.
11983 ///
11984 /// @return the qualified type found or nil if no qualified type was
11985 /// found.
11986 qualified_type_def_sptr
lookup_qualified_type(const type_base_sptr & underlying_type,qualified_type_def::CV quals,const translation_unit & tu)11987 lookup_qualified_type(const type_base_sptr& underlying_type,
11988 		      qualified_type_def::CV quals,
11989 		      const translation_unit& tu)
11990 {
11991   interned_string type_name = get_name_of_qualified_type(underlying_type,
11992 							 quals);
11993   return lookup_qualified_type(type_name, tu);
11994 }
11995 
11996 /// Lookup a pointer type from a translation unit.
11997 ///
11998 /// This is done by looking the type up in the type map that is
11999 /// maintained in the translation unit.  So this is as fast as
12000 /// possible.
12001 ///
12002 /// @param type_name the name of the pointer type to look for.
12003 ///
12004 /// @param tu the translation unit to look into.
12005 ///
12006 /// @return the pointer type found or nil if no pointer type was
12007 /// found.
12008 pointer_type_def_sptr
lookup_pointer_type(const interned_string & type_name,const translation_unit & tu)12009 lookup_pointer_type(const interned_string& type_name,
12010 		    const translation_unit& tu)
12011 {
12012   const type_maps& m = tu.get_types();
12013   return lookup_type_in_map<pointer_type_def>(type_name,
12014 					      m.pointer_types());
12015 }
12016 
12017 /// Lookup a pointer type from a translation unit.
12018 ///
12019 /// This is done by looking the type up in the type map that is
12020 /// maintained in the translation unit.  So this is as fast as
12021 /// possible.
12022 ///
12023 /// @param type_name the name of the pointer type to look for.
12024 ///
12025 /// @param tu the translation unit to look into.
12026 ///
12027 /// @return the pointer type found or nil if no pointer type was
12028 /// found.
12029 pointer_type_def_sptr
lookup_pointer_type(const string & type_name,const translation_unit & tu)12030 lookup_pointer_type(const string& type_name, const translation_unit& tu)
12031 {
12032   const environment& env = tu.get_environment();
12033   interned_string s = env.intern(type_name);
12034   return lookup_pointer_type(s, tu);
12035 }
12036 
12037 /// Lookup a pointer type from a translation unit.
12038 ///
12039 /// This is done by looking the type up in the type map that is
12040 /// maintained in the translation unit.  So this is as fast as
12041 /// possible.
12042 ///
12043 /// @param pointed_to_type the pointed-to-type of the pointer to look for.
12044 ///
12045 /// @param tu the translation unit to look into.
12046 ///
12047 /// @return the pointer type found or nil if no pointer type was
12048 /// found.
12049 pointer_type_def_sptr
lookup_pointer_type(const type_base_sptr & pointed_to_type,const translation_unit & tu)12050 lookup_pointer_type(const type_base_sptr& pointed_to_type,
12051 		    const translation_unit& tu)
12052 {
12053   type_base_sptr t = look_through_decl_only(pointed_to_type);
12054   interned_string type_name = get_name_of_pointer_to_type(*t);
12055   return lookup_pointer_type(type_name, tu);
12056 }
12057 
12058 /// Lookup a reference type from a translation unit.
12059 ///
12060 /// This is done by looking the type up in the type map that is
12061 /// maintained in the translation unit.  So this is as fast as
12062 /// possible.
12063 ///
12064 /// @param type_name the name of the reference type to look for.
12065 ///
12066 /// @param tu the translation unit to look into.
12067 ///
12068 /// @return the reference type found or nil if no reference type was
12069 /// found.
12070 reference_type_def_sptr
lookup_reference_type(const interned_string & type_name,const translation_unit & tu)12071 lookup_reference_type(const interned_string& type_name,
12072 		      const translation_unit& tu)
12073 {
12074   const type_maps& m = tu.get_types();
12075   return lookup_type_in_map<reference_type_def>(type_name,
12076 						m.reference_types());
12077 }
12078 
12079 /// Lookup a reference type from a translation unit.
12080 ///
12081 /// This is done by looking the type up in the type map that is
12082 /// maintained in the translation unit.  So this is as fast as
12083 /// possible.
12084 ///
12085 /// @param pointed_to_type the pointed-to-type of the reference to
12086 /// look up.
12087 ///
12088 /// @param tu the translation unit to look into.
12089 ///
12090 /// @return the reference type found or nil if no reference type was
12091 /// found.
12092 const reference_type_def_sptr
lookup_reference_type(const type_base_sptr & pointed_to_type,bool lvalue_reference,const translation_unit & tu)12093 lookup_reference_type(const type_base_sptr& pointed_to_type,
12094 		      bool lvalue_reference,
12095 		      const translation_unit& tu)
12096 {
12097   interned_string type_name =
12098     get_name_of_reference_to_type(*look_through_decl_only(pointed_to_type),
12099 				  lvalue_reference);
12100   return lookup_reference_type(type_name, tu);
12101 }
12102 
12103 /// Lookup an array type from a translation unit.
12104 ///
12105 /// This is done by looking the type up in the type map that is
12106 /// maintained in the translation unit.  So this is as fast as
12107 /// possible.
12108 ///
12109 /// @param type_name the name of the array type to look for.
12110 ///
12111 /// @param tu the translation unit to look into.
12112 ///
12113 /// @return the array type found or nil if no array type was found.
12114 array_type_def_sptr
lookup_array_type(const interned_string & type_name,const translation_unit & tu)12115 lookup_array_type(const interned_string& type_name,
12116 		  const translation_unit& tu)
12117 {
12118   const type_maps& m = tu.get_types();
12119   return lookup_type_in_map<array_type_def>(type_name,
12120 					    m.array_types());
12121 }
12122 
12123 /// Lookup a function type from a translation unit.
12124 ///
12125 /// This is done by looking the type up in the type map that is
12126 /// maintained in the translation unit.  So this is as fast as
12127 /// possible.
12128 ///
12129 /// @param type_name the name of the type to lookup.
12130 ///
12131 /// @param tu the translation unit to look into.
12132 ///
12133 /// @return the function type found, or NULL of none was found.
12134 function_type_sptr
lookup_function_type(const interned_string & type_name,const translation_unit & tu)12135 lookup_function_type(const interned_string& type_name,
12136 		     const translation_unit& tu)
12137 {
12138   const type_maps& m = tu.get_types();
12139   return lookup_type_in_map<function_type>(type_name,
12140 					   m.function_types());
12141 }
12142 
12143 /// Lookup a function type from a translation unit.
12144 ///
12145 /// This walks all the function types held by the translation unit and
12146 /// compare their sub-type *names*.  If the names match then return
12147 /// the function type found in the translation unit.
12148 ///
12149 /// @param t the function type to look for.
12150 ///
12151 /// @param tu the translation unit to look into.
12152 ///
12153 /// @return the function type found, or NULL of none was found.
12154 function_type_sptr
lookup_function_type(const function_type & t,const translation_unit & tu)12155 lookup_function_type(const function_type& t,
12156 		     const translation_unit& tu)
12157 {
12158   interned_string type_name = get_type_name(t);
12159   return lookup_function_type(type_name, tu);
12160 }
12161 
12162 /// Lookup a function type from a translation unit.
12163 ///
12164 /// This is done by looking the type up in the type map that is
12165 /// maintained in the translation unit.  So this is as fast as
12166 /// possible.
12167 ///
12168 /// @param t the function type to look for.
12169 ///
12170 /// @param tu the translation unit to look into.
12171 ///
12172 /// @return the function type found, or NULL of none was found.
12173 function_type_sptr
lookup_function_type(const function_type_sptr & t,const translation_unit & tu)12174 lookup_function_type(const function_type_sptr& t,
12175 		     const translation_unit& tu)
12176 {return lookup_function_type(*t, tu);}
12177 
12178 /// Lookup a type in a translation unit.
12179 ///
12180 /// @param fqn the fully qualified name of the type to lookup.
12181 ///
12182 /// @param tu the translation unit to consider.
12183 ///
12184 /// @return the declaration of the type if found, NULL otherwise.
12185 const type_base_sptr
lookup_type(const interned_string & fqn,const translation_unit & tu)12186 lookup_type(const interned_string& fqn,
12187 	    const translation_unit& tu)
12188 {
12189   type_base_sptr result;
12190   ((result = lookup_typedef_type(fqn, tu))
12191    || (result = lookup_class_type(fqn, tu))
12192    || (result = lookup_union_type(fqn, tu))
12193    || (result = lookup_enum_type(fqn, tu))
12194    || (result = lookup_qualified_type(fqn, tu))
12195    || (result = lookup_pointer_type(fqn, tu))
12196    || (result = lookup_reference_type(fqn, tu))
12197    || (result = lookup_array_type(fqn, tu))
12198    || (result = lookup_function_type(fqn, tu))
12199    || (result = lookup_basic_type(fqn, tu)));
12200 
12201   return result;
12202 }
12203 
12204 /// Lookup a type in a translation unit, starting from the global
12205 /// namespace.
12206 ///
12207 /// @param fqn the fully qualified name of the type to lookup.
12208 ///
12209 /// @param tu the translation unit to consider.
12210 ///
12211 /// @return the declaration of the type if found, NULL otherwise.
12212 type_base_sptr
lookup_type(const string & fqn,const translation_unit & tu)12213 lookup_type(const string& fqn, const translation_unit& tu)
12214 {
12215   const environment&env = tu.get_environment();
12216   interned_string ifqn = env.intern(fqn);
12217   return lookup_type(ifqn, tu);
12218 }
12219 
12220 /// Lookup a type from a translation unit.
12221 ///
12222 /// @param fqn the components of the fully qualified name of the node
12223 /// to look up.
12224 ///
12225 /// @param tu the translation unit to perform lookup from.
12226 ///
12227 /// @return the declaration of the IR node found, NULL otherwise.
12228 const type_base_sptr
lookup_type(const type_base_sptr type,const translation_unit & tu)12229 lookup_type(const type_base_sptr type,
12230 	    const translation_unit& tu)
12231 {
12232   interned_string type_name = get_type_name(type);
12233   return lookup_type(type_name, tu);
12234 }
12235 
12236 /// Lookup a type in a scope.
12237 ///
12238 /// This is really slow as it walks the member types of the scope in
12239 /// sequence to find the type with a given name.
12240 ///
12241 /// If possible, users should prefer looking up types from the
12242 /// enclosing translation unit or even ABI corpus because both the
12243 /// translation unit and the corpus have a map of type, indexed by
12244 /// their name.  Looking up a type from those maps is thus much
12245 /// faster.
12246 ///
12247 /// @param fqn the fully qualified name of the type to lookup.
12248 ///
12249 /// @param skope the scope to look into.
12250 ///
12251 /// @return the declaration of the type if found, NULL otherwise.
12252 const type_base_sptr
lookup_type_in_scope(const string & fqn,const scope_decl_sptr & skope)12253 lookup_type_in_scope(const string& fqn,
12254 		     const scope_decl_sptr& skope)
12255 {
12256   list<string> comps;
12257   fqn_to_components(fqn, comps);
12258   return lookup_type_in_scope(comps, skope);
12259 }
12260 
12261 /// Lookup a @ref var_decl in a scope.
12262 ///
12263 /// @param fqn the fuly qualified name of the @var_decl to lookup.
12264 ///
12265 /// @param skope the scope to look into.
12266 ///
12267 /// @return the declaration of the @ref var_decl if found, NULL
12268 /// otherwise.
12269 const decl_base_sptr
lookup_var_decl_in_scope(const string & fqn,const scope_decl_sptr & skope)12270 lookup_var_decl_in_scope(const string& fqn,
12271 			 const scope_decl_sptr& skope)
12272 {
12273   list<string> comps;
12274   fqn_to_components(fqn, comps);
12275   return lookup_var_decl_in_scope(comps, skope);
12276 }
12277 
12278 /// A generic function (template) to get the name of a node, whatever
12279 /// node it is.  This has to be specialized for the kind of node we
12280 /// want.
12281 ///
12282 /// Note that a node is a member of a scope.
12283 ///
12284 /// @tparam NodeKind the kind of node to consider.
12285 ///
12286 /// @param node the node to get the name from.
12287 ///
12288 /// @return the name of the node.
12289 template<typename NodeKind>
12290 static const interned_string&
12291 get_node_name(shared_ptr<NodeKind> node);
12292 
12293 /// Gets the name of a class_decl node.
12294 ///
12295 /// @param node the decl_base node to get the name from.
12296 ///
12297 /// @return the name of the node.
12298 template<>
12299 const interned_string&
get_node_name(class_decl_sptr node)12300 get_node_name(class_decl_sptr node)
12301 {return node->get_name();}
12302 
12303 /// Gets the name of a type_base node.
12304 ///
12305 /// @param node the type_base node to get the name from.
12306 ///
12307 /// @return the name of the node.
12308 template<>
12309 const interned_string&
get_node_name(type_base_sptr node)12310 get_node_name(type_base_sptr node)
12311 {return get_type_declaration(node)->get_name();}
12312 
12313 /// Gets the name of a var_decl node.
12314 ///
12315 /// @param node the var_decl node to get the name from.
12316 ///
12317 /// @return the name of the node.
12318 template<>
12319 const interned_string&
get_node_name(var_decl_sptr node)12320 get_node_name(var_decl_sptr node)
12321 {return node->get_name();}
12322 
12323 /// Generic function to get the declaration of a given node, whatever
12324 /// it is.  There has to be specializations for the kind of the nodes
12325 /// we want to support.
12326 ///
12327 /// @tparam NodeKind the type of the node we are looking at.
12328 ///
12329 /// @return the declaration.
12330 template<typename NodeKind>
12331 static decl_base_sptr
12332 convert_node_to_decl(shared_ptr<NodeKind> node);
12333 
12334 /// Lookup a node in a given scope.
12335 ///
12336 /// @tparam the type of the node to lookup.
12337 ///
12338 /// @param fqn the components of the fully qualified name of the node
12339 /// to lookup.
12340 ///
12341 /// @param skope the scope to look into.
12342 ///
12343 /// @return the declaration of the looked up node, or NULL if it
12344 /// wasn't found.
12345 template<typename NodeKind>
12346 static const type_or_decl_base_sptr
lookup_node_in_scope(const list<string> & fqn,const scope_decl_sptr & skope)12347 lookup_node_in_scope(const list<string>& fqn,
12348 		     const scope_decl_sptr& skope)
12349 {
12350   type_or_decl_base_sptr resulting_decl;
12351   shared_ptr<NodeKind> node;
12352   bool it_is_last = false;
12353   scope_decl_sptr cur_scope = skope, new_scope, scope;
12354 
12355   for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
12356     {
12357       new_scope.reset();
12358       it_is_last = iterator_is_last(fqn, c);
12359       for (scope_decl::declarations::const_iterator m =
12360 	     cur_scope->get_member_decls().begin();
12361 	   m != cur_scope->get_member_decls().end();
12362 	   ++m)
12363 	{
12364 	  if (!it_is_last)
12365 	    {
12366 	      // looking for a scope
12367 	      scope = dynamic_pointer_cast<scope_decl>(*m);
12368 	      if (scope && scope->get_name() == *c)
12369 		{
12370 		  new_scope = scope;
12371 		  break;
12372 		}
12373 	    }
12374 	  else
12375 	    {
12376 	      //looking for a final type.
12377 	      node = dynamic_pointer_cast<NodeKind>(*m);
12378 	      if (node && get_node_name(node) == *c)
12379 		{
12380 		  if (class_decl_sptr cl =
12381 		      dynamic_pointer_cast<class_decl>(node))
12382 		    if (cl->get_is_declaration_only()
12383 			&& !cl->get_definition_of_declaration())
12384 		      continue;
12385 		  resulting_decl = node;
12386 		  break;
12387 		}
12388 	    }
12389 	}
12390       if (!new_scope && !resulting_decl)
12391 	return decl_base_sptr();
12392       cur_scope = new_scope;
12393     }
12394   ABG_ASSERT(resulting_decl);
12395   return resulting_decl;
12396 }
12397 
12398 /// lookup a type in a scope.
12399 ///
12400 ///
12401 /// This is really slow as it walks the member types of the scope in
12402 /// sequence to find the type with a given name.
12403 ///
12404 /// If possible, users should prefer looking up types from the
12405 /// enclosing translation unit or even ABI corpus because both the
12406 /// translation unit and the corpus have a map of type, indexed by
12407 /// their name.  Looking up a type from those maps is thus much
12408 /// faster.
12409 ///
12410 /// @param comps the components of the fully qualified name of the
12411 /// type to lookup.
12412 ///
12413 /// @param skope the scope to look into.
12414 ///
12415 /// @return the declaration of the type found.
12416 const type_base_sptr
lookup_type_in_scope(const list<string> & comps,const scope_decl_sptr & scope)12417 lookup_type_in_scope(const list<string>& comps,
12418 		     const scope_decl_sptr& scope)
12419 {return is_type(lookup_node_in_scope<type_base>(comps, scope));}
12420 
12421 /// lookup a type in a scope.
12422 ///
12423 /// This is really slow as it walks the member types of the scope in
12424 /// sequence to find the type with a given name.
12425 ///
12426 /// If possible, users should prefer looking up types from the
12427 /// enclosing translation unit or even ABI corpus because both the
12428 /// translation unit and the corpus have a map of type, indexed by
12429 /// their name.  Looking up a type from those maps is thus much
12430 /// faster.
12431 ///
12432 /// @param type the type to look for.
12433 ///
12434 /// @param access_path a vector of scopes the path of scopes to follow
12435 /// before reaching the scope into which to look for @p type.  Note
12436 /// that the deepest scope (the one immediately containing @p type) is
12437 /// at index 0 of this vector, and the top-most scope is the last
12438 /// element of the vector.
12439 ///
12440 /// @param scope the top-most scope into which to look for @p type.
12441 ///
12442 /// @return the scope found in @p scope, or NULL if it wasn't found.
12443 static const type_base_sptr
lookup_type_in_scope(const type_base & type,const vector<scope_decl * > & access_path,const scope_decl * scope)12444 lookup_type_in_scope(const type_base& type,
12445 		     const vector<scope_decl*>& access_path,
12446 		     const scope_decl* scope)
12447 {
12448   vector<scope_decl*> a = access_path;
12449   type_base_sptr result;
12450 
12451   scope_decl* first_scope = 0;
12452   if (!a.empty())
12453     {
12454       first_scope = a.back();
12455       ABG_ASSERT(first_scope->get_name() == scope->get_name());
12456       a.pop_back();
12457     }
12458 
12459   if (a.empty())
12460     {
12461       interned_string n = get_type_name(type, false);
12462       for (scope_decl::declarations::const_iterator i =
12463 	     scope->get_member_decls().begin();
12464 	   i != scope->get_member_decls().end();
12465 	   ++i)
12466 	if (is_type(*i) && (*i)->get_name() == n)
12467 	  {
12468 	    result = is_type(*i);
12469 	    break;
12470 	  }
12471     }
12472   else
12473     {
12474       first_scope = a.back();
12475       interned_string scope_name, cur_scope_name = first_scope->get_name();
12476       for (scope_decl::scopes::const_iterator i =
12477 	     scope->get_member_scopes().begin();
12478 	   i != scope->get_member_scopes().end();
12479 	   ++i)
12480 	{
12481 	  scope_name = (*i)->get_name();
12482 	  if (scope_name == cur_scope_name)
12483 	    {
12484 	      result = lookup_type_in_scope(type, a, (*i).get());
12485 	      break;
12486 	    }
12487 	}
12488     }
12489   return result;
12490 }
12491 
12492 /// lookup a type in a scope.
12493 ///
12494 /// This is really slow as it walks the member types of the scope in
12495 /// sequence to find the type with a given name.
12496 ///
12497 /// If possible, users should prefer looking up types from the
12498 /// enclosing translation unit or even ABI corpus because both the
12499 /// translation unit and the corpus have a map of type, indexed by
12500 /// their name.  Looking up a type from those maps is thus much
12501 /// faster.
12502 ///
12503 /// @param type the type to look for.
12504 ///
12505 /// @param scope the top-most scope into which to look for @p type.
12506 ///
12507 /// @return the scope found in @p scope, or NULL if it wasn't found.
12508 static const type_base_sptr
lookup_type_in_scope(const type_base_sptr type,const scope_decl * scope)12509 lookup_type_in_scope(const type_base_sptr type,
12510 		     const scope_decl* scope)
12511 {
12512   if (!type || is_function_type(type))
12513     return type_base_sptr();
12514 
12515   decl_base_sptr type_decl = get_type_declaration(type);
12516   ABG_ASSERT(type_decl);
12517   vector<scope_decl*> access_path;
12518   for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
12519     {
12520       access_path.push_back(s);
12521       if (is_global_scope(s))
12522 	break;
12523     }
12524   return lookup_type_in_scope(*type, access_path, scope);
12525 }
12526 
12527 /// Lookup a type from a translation unit by walking the scopes of the
12528 /// translation unit in sequence and looking into them.
12529 ///
12530 /// This is really slow as it walks the member types of the scopes in
12531 /// sequence to find the type with a given name.
12532 ///
12533 /// If possible, users should prefer looking up types from the
12534 /// translation unit or even ABI corpus in a more direct way, by using
12535 /// the lookup_type() functins.
12536 ///
12537 ///
12538 /// This is because both the translation unit and the corpus have a
12539 /// map of types, indexed by their name.  Looking up a type from those
12540 /// maps is thus much faster.  @param fqn the components of the fully
12541 /// qualified name of the node to look up.
12542 ///
12543 /// @param tu the translation unit to perform lookup from.
12544 ///
12545 /// @return the declaration of the IR node found, NULL otherwise.
12546 const type_base_sptr
lookup_type_through_scopes(const type_base_sptr type,const translation_unit & tu)12547 lookup_type_through_scopes(const type_base_sptr type,
12548 			   const translation_unit& tu)
12549 {
12550   if (function_type_sptr fn_type = is_function_type(type))
12551     return lookup_function_type(fn_type, tu);
12552   return lookup_type_in_scope(type, tu.get_global_scope().get());
12553 }
12554 
12555 /// lookup a var_decl in a scope.
12556 ///
12557 /// @param comps the components of the fully qualified name of the
12558 /// var_decl to lookup.
12559 ///
12560 /// @param skope the scope to look into.
12561 const decl_base_sptr
lookup_var_decl_in_scope(const std::list<string> & comps,const scope_decl_sptr & skope)12562 lookup_var_decl_in_scope(const std::list<string>& comps,
12563 			 const scope_decl_sptr& skope)
12564 {return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
12565 
12566 /// Lookup an IR node from a translation unit.
12567 ///
12568 /// @tparam NodeKind the type of the IR node to lookup from the
12569 /// translation unit.
12570 ///
12571 /// @param fqn the components of the fully qualified name of the node
12572 /// to look up.
12573 ///
12574 /// @param tu the translation unit to perform lookup from.
12575 ///
12576 /// @return the declaration of the IR node found, NULL otherwise.
12577 template<typename NodeKind>
12578 static const type_or_decl_base_sptr
lookup_node_in_translation_unit(const list<string> & fqn,const translation_unit & tu)12579 lookup_node_in_translation_unit(const list<string>& fqn,
12580 				const translation_unit& tu)
12581 {return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
12582 
12583 /// Lookup a type from a translation unit by walking its scopes in
12584 /// sequence and by looking into them.
12585 ///
12586 /// This is much slower than using the lookup_type() function.
12587 ///
12588 /// @param fqn the components of the fully qualified name of the node
12589 /// to look up.
12590 ///
12591 /// @param tu the translation unit to perform lookup from.
12592 ///
12593 /// @return the declaration of the IR node found, NULL otherwise.
12594 type_base_sptr
lookup_type_through_scopes(const list<string> & fqn,const translation_unit & tu)12595 lookup_type_through_scopes(const list<string>& fqn,
12596 			   const translation_unit& tu)
12597 {return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
12598 
12599 
12600 /// Lookup a class type from a translation unit by walking its scopes
12601 /// in sequence and by looking into them.
12602 ///
12603 /// This is much slower than using the lookup_class_type() function
12604 /// because it walks all the scopes of the translation unit in
12605 /// sequence and lookup the types to find one that has a given name.
12606 ///
12607 /// @param fqn the components of the fully qualified name of the class
12608 /// type node to look up.
12609 ///
12610 /// @param tu the translation unit to perform lookup from.
12611 ///
12612 /// @return the declaration of the class type IR node found, NULL
12613 /// otherwise.
12614 class_decl_sptr
lookup_class_type_through_scopes(const list<string> & fqn,const translation_unit & tu)12615 lookup_class_type_through_scopes(const list<string>& fqn,
12616 				 const translation_unit& tu)
12617 {return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
12618 
12619 /// Lookup a basic type from all the translation units of a given
12620 /// corpus.
12621 ///
12622 /// @param fqn the components of the fully qualified name of the basic
12623 /// type node to look up.
12624 ///
12625 /// @param tu the translation unit to perform lookup from.
12626 ///
12627 /// @return the declaration of the basic type IR node found, NULL
12628 /// otherwise.
12629 static type_decl_sptr
lookup_basic_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12630 lookup_basic_type_through_translation_units(const interned_string& type_name,
12631 					    const corpus& abi_corpus)
12632 {
12633   type_decl_sptr result;
12634 
12635   for (translation_units::const_iterator tu =
12636 	 abi_corpus.get_translation_units().begin();
12637        tu != abi_corpus.get_translation_units().end();
12638        ++tu)
12639     if ((result = lookup_basic_type(type_name, **tu)))
12640       break;
12641 
12642   return result;
12643 }
12644 
12645 /// Lookup a union type from all the translation units of a given
12646 /// corpus.
12647 ///
12648 /// @param fqn the components of the fully qualified name of the union
12649 /// type node to look up.
12650 ///
12651 /// @param tu the translation unit to perform lookup from.
12652 ///
12653 /// @return the declaration of the union type IR node found, NULL
12654 /// otherwise.
12655 static union_decl_sptr
lookup_union_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12656 lookup_union_type_through_translation_units(const interned_string& type_name,
12657 					    const corpus & abi_corpus)
12658 {
12659  union_decl_sptr result;
12660 
12661   for (translation_units::const_iterator tu =
12662 	 abi_corpus.get_translation_units().begin();
12663        tu != abi_corpus.get_translation_units().end();
12664        ++tu)
12665     if ((result = lookup_union_type(type_name, **tu)))
12666       break;
12667 
12668   return result;
12669 }
12670 
12671 /// Lookup an enum type from all the translation units of a given
12672 /// corpus.
12673 ///
12674 /// @param fqn the components of the fully qualified name of the enum
12675 /// type node to look up.
12676 ///
12677 /// @param tu the translation unit to perform lookup from.
12678 ///
12679 /// @return the declaration of the enum type IR node found, NULL
12680 /// otherwise.
12681 static enum_type_decl_sptr
lookup_enum_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12682 lookup_enum_type_through_translation_units(const interned_string& type_name,
12683 					   const corpus & abi_corpus)
12684 {
12685   enum_type_decl_sptr result;
12686 
12687   for (translation_units::const_iterator tu =
12688 	 abi_corpus.get_translation_units().begin();
12689        tu != abi_corpus.get_translation_units().end();
12690        ++tu)
12691     if ((result = lookup_enum_type(type_name, **tu)))
12692       break;
12693 
12694   return result;
12695 }
12696 
12697 /// Lookup a typedef type definition in all the translation units of a
12698 /// given ABI corpus.
12699 ///
12700 /// @param @param qn the fully qualified name of the typedef type to lookup.
12701 ///
12702 /// @param abi_corpus the ABI corpus which to look the type up in.
12703 ///
12704 /// @return the type definition if any was found, or a NULL pointer.
12705 static typedef_decl_sptr
lookup_typedef_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12706 lookup_typedef_type_through_translation_units(const interned_string& type_name,
12707 					      const corpus & abi_corpus)
12708 {
12709   typedef_decl_sptr result;
12710 
12711   for (translation_units::const_iterator tu =
12712 	 abi_corpus.get_translation_units().begin();
12713        tu != abi_corpus.get_translation_units().end();
12714        ++tu)
12715     if ((result = lookup_typedef_type(type_name, **tu)))
12716       break;
12717 
12718   return result;
12719 }
12720 
12721 /// Lookup a qualified type definition in all the translation units of a
12722 /// given ABI corpus.
12723 ///
12724 /// @param @param qn the fully qualified name of the qualified type to
12725 /// lookup.
12726 ///
12727 /// @param abi_corpus the ABI corpus which to look the type up in.
12728 ///
12729 /// @return the type definition if any was found, or a NULL pointer.
12730 static qualified_type_def_sptr
lookup_qualified_type_through_translation_units(const interned_string & t_name,const corpus & abi_corpus)12731 lookup_qualified_type_through_translation_units(const interned_string& t_name,
12732 						const corpus & abi_corpus)
12733 {
12734   qualified_type_def_sptr result;
12735 
12736   for (translation_units::const_iterator tu =
12737 	 abi_corpus.get_translation_units().begin();
12738        tu != abi_corpus.get_translation_units().end();
12739        ++tu)
12740     if ((result = lookup_qualified_type(t_name, **tu)))
12741       break;
12742 
12743   return result;
12744 }
12745 
12746 /// Lookup a pointer type definition in all the translation units of a
12747 /// given ABI corpus.
12748 ///
12749 /// @param @param qn the fully qualified name of the pointer type to
12750 /// lookup.
12751 ///
12752 /// @param abi_corpus the ABI corpus which to look the type up in.
12753 ///
12754 /// @return the type definition if any was found, or a NULL pointer.
12755 static pointer_type_def_sptr
lookup_pointer_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12756 lookup_pointer_type_through_translation_units(const interned_string& type_name,
12757 					      const corpus & abi_corpus)
12758 {
12759   pointer_type_def_sptr result;
12760 
12761   for (translation_units::const_iterator tu =
12762 	 abi_corpus.get_translation_units().begin();
12763        tu != abi_corpus.get_translation_units().end();
12764        ++tu)
12765     if ((result = lookup_pointer_type(type_name, **tu)))
12766       break;
12767 
12768   return result;
12769 }
12770 
12771 /// Lookup a reference type definition in all the translation units of a
12772 /// given ABI corpus.
12773 ///
12774 /// @param @param qn the fully qualified name of the reference type to
12775 /// lookup.
12776 ///
12777 /// @param abi_corpus the ABI corpus which to look the type up in.
12778 ///
12779 /// @return the type definition if any was found, or a NULL pointer.
12780 static reference_type_def_sptr
lookup_reference_type_through_translation_units(const interned_string & t_name,const corpus & abi_corpus)12781 lookup_reference_type_through_translation_units(const interned_string& t_name,
12782 						const corpus & abi_corpus)
12783 {
12784   reference_type_def_sptr result;
12785 
12786   for (translation_units::const_iterator tu =
12787 	 abi_corpus.get_translation_units().begin();
12788        tu != abi_corpus.get_translation_units().end();
12789        ++tu)
12790     if ((result = lookup_reference_type(t_name, **tu)))
12791       break;
12792 
12793   return result;
12794 }
12795 
12796 /// Lookup a array type definition in all the translation units of a
12797 /// given ABI corpus.
12798 ///
12799 /// @param @param qn the fully qualified name of the array type to
12800 /// lookup.
12801 ///
12802 /// @param abi_corpus the ABI corpus which to look the type up in.
12803 ///
12804 /// @return the type definition if any was found, or a NULL pointer.
12805 static array_type_def_sptr
lookup_array_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12806 lookup_array_type_through_translation_units(const interned_string& type_name,
12807 					    const corpus & abi_corpus)
12808 {
12809   array_type_def_sptr result;
12810 
12811   for (translation_units::const_iterator tu =
12812 	 abi_corpus.get_translation_units().begin();
12813        tu != abi_corpus.get_translation_units().end();
12814        ++tu)
12815     if ((result = lookup_array_type(type_name, **tu)))
12816       break;
12817 
12818   return result;
12819 }
12820 
12821 /// Lookup a function type definition in all the translation units of
12822 /// a given ABI corpus.
12823 ///
12824 /// @param @param qn the fully qualified name of the function type to
12825 /// lookup.
12826 ///
12827 /// @param abi_corpus the ABI corpus which to look the type up in.
12828 ///
12829 /// @return the type definition if any was found, or a NULL pointer.
12830 static function_type_sptr
lookup_function_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12831 lookup_function_type_through_translation_units(const interned_string& type_name,
12832 					       const corpus & abi_corpus)
12833 {
12834   function_type_sptr result;
12835 
12836   for (translation_units::const_iterator tu =
12837 	 abi_corpus.get_translation_units().begin();
12838        tu != abi_corpus.get_translation_units().end();
12839        ++tu)
12840     if ((result = lookup_function_type(type_name, **tu)))
12841       break;
12842 
12843   return result;
12844 }
12845 
12846 /// Lookup a type definition in all the translation units of a given
12847 /// ABI corpus.
12848 ///
12849 /// @param @param qn the fully qualified name of the type to lookup.
12850 ///
12851 /// @param abi_corpus the ABI corpus which to look the type up in.
12852 ///
12853 /// @return the type definition if any was found, or a NULL pointer.
12854 type_base_sptr
lookup_type_through_translation_units(const string & qn,const corpus & abi_corpus)12855 lookup_type_through_translation_units(const string& qn,
12856 				      const corpus& abi_corpus)
12857 {
12858   type_base_sptr result;
12859 
12860   for (translation_units::const_iterator tu =
12861 	 abi_corpus.get_translation_units().begin();
12862        tu != abi_corpus.get_translation_units().end();
12863        ++tu)
12864     if ((result = lookup_type(qn, **tu)))
12865       break;
12866 
12867   return result;
12868 }
12869 
12870 /// Lookup a type from a given translation unit present in a give corpus.
12871 ///
12872 /// @param type_name the name of the type to look for.
12873 ///
12874 /// @parm tu_path the path of the translation unit to consider.
12875 ///
12876 /// @param corp the corpus to consider.
12877 ///
12878 /// @return the resulting type, if any.
12879 type_base_sptr
lookup_type_from_translation_unit(const string & type_name,const string & tu_path,const corpus & corp)12880 lookup_type_from_translation_unit(const string& type_name,
12881 				  const string& tu_path,
12882 				  const corpus& corp)
12883 {
12884   string_tu_map_type::const_iterator i =  corp.priv_->path_tu_map.find(tu_path);
12885   if (i == corp.priv_->path_tu_map.end())
12886     return type_base_sptr();
12887 
12888   translation_unit_sptr tu = i->second;
12889   ABG_ASSERT(tu);
12890 
12891   type_base_sptr t = lookup_type(type_name, *tu);
12892   return t;
12893 }
12894 
12895 /// Look into an ABI corpus for a function type.
12896 ///
12897 /// @param fn_type the function type to be looked for in the ABI
12898 /// corpus.
12899 ///
12900 /// @param corpus the ABI corpus into which to look for the function
12901 /// type.
12902 ///
12903 /// @return the function type found in the corpus.
12904 function_type_sptr
lookup_or_synthesize_fn_type(const function_type_sptr & fn_t,const corpus & corpus)12905 lookup_or_synthesize_fn_type(const function_type_sptr& fn_t,
12906 			     const corpus& corpus)
12907 {
12908   ABG_ASSERT(fn_t);
12909 
12910   function_type_sptr result;
12911 
12912   if ((result = lookup_function_type(fn_t, corpus)))
12913     return result;
12914 
12915   for (translation_units::const_iterator i =
12916 	 corpus.get_translation_units().begin();
12917        i != corpus.get_translation_units().end();
12918        ++i)
12919     if ((result = synthesize_function_type_from_translation_unit(*fn_t,
12920 								 **i)))
12921       return result;
12922 
12923   return result;
12924 }
12925 
12926 /// Look into a given corpus to find a type which has the same
12927 /// qualified name as a giventype.
12928 ///
12929 /// If the per-corpus type map is non-empty (because the corpus allows
12930 /// the One Definition Rule) then the type islooked up in that
12931 /// per-corpus type map.  Otherwise, the type is looked-up in each
12932 /// translation unit.
12933 ///
12934 /// @param t the type which has the same qualified name as the type we
12935 /// are looking for.
12936 ///
12937 /// @param corp the ABI corpus to look into for the type.
12938 type_decl_sptr
lookup_basic_type(const type_decl & t,const corpus & corp)12939 lookup_basic_type(const type_decl& t, const corpus& corp)
12940 {return lookup_basic_type(t.get_name(), corp);}
12941 
12942 /// Look into a given corpus to find a basic type which has a given
12943 /// qualified name.
12944 ///
12945 /// If the per-corpus type map is non-empty (because the corpus allows
12946 /// the One Definition Rule) then the type islooked up in that
12947 /// per-corpus type map.  Otherwise, the type is looked-up in each
12948 /// translation unit.
12949 ///
12950 /// @param qualified_name the qualified name of the basic type to look
12951 /// for.
12952 ///
12953 /// @param corp the corpus to look into.
12954 type_decl_sptr
lookup_basic_type(const interned_string & qualified_name,const corpus & corp)12955 lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
12956 {
12957   const istring_type_base_wptrs_map_type& m = corp.get_types().basic_types();
12958   type_decl_sptr result;
12959 
12960   if (!m.empty())
12961     result = lookup_type_in_map<type_decl>(qualified_name, m);
12962   else
12963     result = lookup_basic_type_through_translation_units(qualified_name, corp);
12964 
12965   return result;
12966 }
12967 
12968 /// Lookup a @ref type_decl type from a given corpus, by its location.
12969 ///
12970 /// @param loc the location to consider.
12971 ///
12972 /// @param corp the corpus to consider.
12973 ///
12974 /// @return the resulting basic type, if any.
12975 type_decl_sptr
lookup_basic_type_per_location(const interned_string & loc,const corpus & corp)12976 lookup_basic_type_per_location(const interned_string &loc,
12977 			       const corpus &corp)
12978 {
12979   const istring_type_base_wptrs_map_type& m =
12980     corp.get_type_per_loc_map().basic_types();
12981   type_decl_sptr result;
12982 
12983   result = lookup_type_in_map<type_decl>(loc, m);
12984 
12985   return result;
12986 }
12987 
12988 /// Lookup a @ref type_decl type from a given corpus, by its location.
12989 ///
12990 /// @param loc the location to consider.
12991 ///
12992 /// @param corp the corpus to consider.
12993 ///
12994 /// @return the resulting basic type, if any.
12995 type_decl_sptr
lookup_basic_type_per_location(const string & loc,const corpus & corp)12996 lookup_basic_type_per_location(const string &loc, const corpus &corp)
12997 {
12998   const environment& env = corp.get_environment();
12999   return lookup_basic_type_per_location(env.intern(loc), corp);
13000 }
13001 
13002 /// Look into a given corpus to find a basic type which has a given
13003 /// qualified name.
13004 ///
13005 /// If the per-corpus type map is non-empty (because the corpus allows
13006 /// the One Definition Rule) then the type islooked up in that
13007 /// per-corpus type map.  Otherwise, the type is looked-up in each
13008 /// translation unit.
13009 ///
13010 /// @param qualified_name the qualified name of the basic type to look
13011 /// for.
13012 ///
13013 /// @param corp the corpus to look into.
13014 type_decl_sptr
lookup_basic_type(const string & qualified_name,const corpus & corp)13015 lookup_basic_type(const string& qualified_name, const corpus& corp)
13016 {
13017   return lookup_basic_type(corp.get_environment().intern(qualified_name),
13018 			   corp);
13019 }
13020 
13021 /// Look into a given corpus to find a class type which has the same
13022 /// qualified name as a given type.
13023 ///
13024 /// If the per-corpus type map is non-empty (because the corpus allows
13025 /// the One Definition Rule) then the type islooked up in that
13026 /// per-corpus type map.  Otherwise, the type is looked-up in each
13027 /// translation unit.
13028 ///
13029 /// @param t the class decl type which has the same qualified name as
13030 /// the type we are looking for.
13031 ///
13032 /// @param corp the corpus to look into.
13033 class_decl_sptr
lookup_class_type(const class_decl & t,const corpus & corp)13034 lookup_class_type(const class_decl& t, const corpus& corp)
13035 {
13036   interned_string s = get_type_name(t);
13037   return lookup_class_type(s, corp);
13038 }
13039 
13040 /// Look into a given corpus to find a class type which has a given
13041 /// qualified name.
13042 ///
13043 /// If the per-corpus type map is non-empty (because the corpus allows
13044 /// the One Definition Rule) then the type islooked up in that
13045 /// per-corpus type map.  Otherwise, the type is looked-up in each
13046 /// translation unit.
13047 ///
13048 /// @param qualified_name the qualified name of the type to look for.
13049 ///
13050 /// @param corp the corpus to look into.
13051 class_decl_sptr
lookup_class_type(const string & qualified_name,const corpus & corp)13052 lookup_class_type(const string& qualified_name, const corpus& corp)
13053 {
13054   interned_string s = corp.get_environment().intern(qualified_name);
13055   return lookup_class_type(s, corp);
13056 }
13057 
13058 /// Look into a given corpus to find a class type which has a given
13059 /// qualified name.
13060 ///
13061 /// If the per-corpus type map is non-empty (because the corpus allows
13062 /// the One Definition Rule) then the type islooked up in that
13063 /// per-corpus type map.  Otherwise, the type is looked-up in each
13064 /// translation unit.
13065 ///
13066 /// @param qualified_name the qualified name of the type to look for.
13067 ///
13068 /// @param corp the corpus to look into.
13069 class_decl_sptr
lookup_class_type(const interned_string & qualified_name,const corpus & corp)13070 lookup_class_type(const interned_string& qualified_name, const corpus& corp)
13071 {
13072   const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
13073 
13074   class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13075 
13076   return result;
13077 }
13078 
13079 /// Look into a given corpus to find the class type*s* that have a
13080 /// given qualified name.
13081 ///
13082 /// @param qualified_name the qualified name of the type to look for.
13083 ///
13084 /// @param corp the corpus to look into.
13085 ///
13086 /// @return the vector of class types named @p qualified_name.
13087 const type_base_wptrs_type *
lookup_class_types(const interned_string & qualified_name,const corpus & corp)13088 lookup_class_types(const interned_string& qualified_name, const corpus& corp)
13089 {
13090   const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
13091 
13092   return lookup_types_in_map(qualified_name, m);
13093 }
13094 
13095 /// Look into a given corpus to find the class type*s* that have a
13096 /// given qualified name and that are declaration-only.
13097 ///
13098 /// @param qualified_name the qualified name of the type to look for.
13099 ///
13100 /// @param corp the corpus to look into.
13101 ///
13102 /// @param result the vector of decl-only class types named @p
13103 /// qualified_name.  This is populated iff the function returns true.
13104 ///
13105 /// @return true iff @p result was populated with the decl-only
13106 /// classes named @p qualified_name.
13107 bool
lookup_decl_only_class_types(const interned_string & qualified_name,const corpus & corp,type_base_wptrs_type & result)13108 lookup_decl_only_class_types(const interned_string& qualified_name,
13109 			     const corpus& corp,
13110 			     type_base_wptrs_type& result)
13111 {
13112   const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
13113 
13114   const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
13115   if (!v)
13116     return false;
13117 
13118   for (auto type : *v)
13119     {
13120       type_base_sptr t(type);
13121       class_decl_sptr c = is_class_type(t);
13122       if (c->get_is_declaration_only()
13123 	  && !c->get_definition_of_declaration())
13124 	result.push_back(type);
13125     }
13126 
13127   return !result.empty();
13128 }
13129 
13130 /// Look into a given corpus to find the union type*s* that have a
13131 /// given qualified name.
13132 ///
13133 /// @param qualified_name the qualified name of the type to look for.
13134 ///
13135 /// @param corp the corpus to look into.
13136 ///
13137 /// @return the vector of union types named @p qualified_name.
13138 const type_base_wptrs_type *
lookup_union_types(const interned_string & qualified_name,const corpus & corp)13139 lookup_union_types(const interned_string& qualified_name, const corpus& corp)
13140 {
13141   const istring_type_base_wptrs_map_type& m = corp.get_types().union_types();
13142 
13143   return lookup_types_in_map(qualified_name, m);
13144 }
13145 
13146 /// Look into a given corpus to find the class type*s* that have a
13147 /// given qualified name.
13148 ///
13149 /// @param qualified_name the qualified name of the type to look for.
13150 ///
13151 /// @param corp the corpus to look into.
13152 ///
13153 /// @return the vector of class types which name is @p qualified_name.
13154 const type_base_wptrs_type*
lookup_class_types(const string & qualified_name,const corpus & corp)13155 lookup_class_types(const string& qualified_name, const corpus& corp)
13156 {
13157   interned_string s = corp.get_environment().intern(qualified_name);
13158   return lookup_class_types(s, corp);
13159 }
13160 
13161 /// Look into a given corpus to find the union types that have a given
13162 /// qualified name.
13163 ///
13164 /// @param qualified_name the qualified name of the type to look for.
13165 ///
13166 /// @param corp the corpus to look into.
13167 ///
13168 /// @return the vector of union types which name is @p qualified_name.
13169 const type_base_wptrs_type *
lookup_union_types(const string & qualified_name,const corpus & corp)13170 lookup_union_types(const string& qualified_name, const corpus& corp)
13171 {
13172   interned_string s = corp.get_environment().intern(qualified_name);
13173   return lookup_union_types(s, corp);
13174 }
13175 
13176 /// Look up a @ref class_decl from a given corpus by its location.
13177 ///
13178 /// @param loc the location to consider.
13179 ///
13180 /// @param corp the corpus to consider.
13181 ///
13182 /// @return the resulting class decl, if any.
13183 class_decl_sptr
lookup_class_type_per_location(const interned_string & loc,const corpus & corp)13184 lookup_class_type_per_location(const interned_string& loc,
13185 			       const corpus& corp)
13186 {
13187   const istring_type_base_wptrs_map_type& m =
13188     corp.get_type_per_loc_map().class_types();
13189   class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
13190 
13191   return result;
13192 }
13193 
13194 /// Look up a @ref class_decl from a given corpus by its location.
13195 ///
13196 /// @param loc the location to consider.
13197 ///
13198 /// @param corp the corpus to consider.
13199 ///
13200 /// @return the resulting class decl, if any.
13201 class_decl_sptr
lookup_class_type_per_location(const string & loc,const corpus & corp)13202 lookup_class_type_per_location(const string &loc, const corpus &corp)
13203 {
13204   const environment& env = corp.get_environment();
13205   return lookup_class_type_per_location(env.intern(loc), corp);
13206 }
13207 
13208 /// Look into a given corpus to find a union type which has a given
13209 /// qualified name.
13210 ///
13211 /// If the per-corpus type map is non-empty (because the corpus allows
13212 /// the One Definition Rule) then the type islooked up in that
13213 /// per-corpus type map.  Otherwise, the type is looked-up in each
13214 /// translation unit.
13215 ///
13216 /// @param qualified_name the qualified name of the type to look for.
13217 ///
13218 /// @param corp the corpus to look into.
13219 union_decl_sptr
lookup_union_type(const interned_string & type_name,const corpus & corp)13220 lookup_union_type(const interned_string& type_name, const corpus& corp)
13221 {
13222   const istring_type_base_wptrs_map_type& m = corp.get_types().union_types();
13223 
13224   union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13225   if (!result)
13226     result = lookup_union_type_through_translation_units(type_name, corp);
13227 
13228   return result;
13229 }
13230 
13231 /// Look into a given corpus to find a union type which has a given
13232 /// qualified name.
13233 ///
13234 /// If the per-corpus type map is non-empty (because the corpus allows
13235 /// the One Definition Rule) then the type islooked up in that
13236 /// per-corpus type map.  Otherwise, the type is looked-up in each
13237 /// translation unit.
13238 ///
13239 /// @param qualified_name the qualified name of the type to look for.
13240 ///
13241 /// @param corp the corpus to look into.
13242 union_decl_sptr
lookup_union_type(const string & type_name,const corpus & corp)13243 lookup_union_type(const string& type_name, const corpus& corp)
13244 {
13245   interned_string s = corp.get_environment().intern(type_name);
13246   return lookup_union_type(s, corp);
13247 }
13248 
13249 /// Look into a given corpus to find an enum type which has the same
13250 /// qualified name as a given enum type.
13251 ///
13252 /// If the per-corpus type map is non-empty (because the corpus allows
13253 /// the One Definition Rule) then the type islooked up in that
13254 /// per-corpus type map.  Otherwise, the type is looked-up in each
13255 /// translation unit.
13256 ///
13257 /// @param t the enum type which has the same qualified name as the
13258 /// type we are looking for.
13259 ///
13260 /// @param corp the corpus to look into.
13261 enum_type_decl_sptr
lookup_enum_type(const enum_type_decl & t,const corpus & corp)13262 lookup_enum_type(const enum_type_decl& t, const corpus& corp)
13263 {
13264   interned_string s = get_type_name(t);
13265   return lookup_enum_type(s, corp);
13266 }
13267 
13268 /// Look into a given corpus to find an enum type which has a given
13269 /// qualified name.
13270 ///
13271 /// If the per-corpus type map is non-empty (because the corpus allows
13272 /// the One Definition Rule) then the type islooked up in that
13273 /// per-corpus type map.  Otherwise, the type is looked-up in each
13274 /// translation unit.
13275 ///
13276 /// @param qualified_name the qualified name of the enum type to look
13277 /// for.
13278 ///
13279 /// @param corp the corpus to look into.
13280 enum_type_decl_sptr
lookup_enum_type(const string & qualified_name,const corpus & corp)13281 lookup_enum_type(const string& qualified_name, const corpus& corp)
13282 {
13283   interned_string s = corp.get_environment().intern(qualified_name);
13284   return lookup_enum_type(s, corp);
13285 }
13286 
13287 /// Look into a given corpus to find an enum type which has a given
13288 /// qualified name.
13289 ///
13290 /// If the per-corpus type map is non-empty (because the corpus allows
13291 /// the One Definition Rule) then the type islooked up in that
13292 /// per-corpus type map.  Otherwise, the type is looked-up in each
13293 /// translation unit.
13294 ///
13295 /// @param qualified_name the qualified name of the enum type to look
13296 /// for.
13297 ///
13298 /// @param corp the corpus to look into.
13299 enum_type_decl_sptr
lookup_enum_type(const interned_string & qualified_name,const corpus & corp)13300 lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
13301 {
13302   const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();
13303 
13304   enum_type_decl_sptr result =
13305     lookup_type_in_map<enum_type_decl>(qualified_name, m);
13306   if (!result)
13307     result = lookup_enum_type_through_translation_units(qualified_name, corp);
13308 
13309   return result;
13310 }
13311 
13312 /// Look into a given corpus to find the enum type*s* that have a
13313 /// given qualified name.
13314 ///
13315 /// @param qualified_name the qualified name of the type to look for.
13316 ///
13317 /// @param corp the corpus to look into.
13318 ///
13319 /// @return the vector of enum types that which name is @p qualified_name.
13320 const type_base_wptrs_type *
lookup_enum_types(const interned_string & qualified_name,const corpus & corp)13321 lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
13322 {
13323   const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();
13324 
13325   return lookup_types_in_map(qualified_name, m);
13326 }
13327 
13328 /// Look into a given corpus to find the enum type*s* that have a
13329 /// given qualified name.
13330 ///
13331 /// @param qualified_name the qualified name of the type to look for.
13332 ///
13333 /// @param corp the corpus to look into.
13334 ///
13335 /// @return the vector of enum types that which name is @p qualified_name.
13336 const type_base_wptrs_type*
lookup_enum_types(const string & qualified_name,const corpus & corp)13337 lookup_enum_types(const string& qualified_name, const corpus& corp)
13338 {
13339   interned_string s = corp.get_environment().intern(qualified_name);
13340   return lookup_enum_types(s, corp);
13341 }
13342 
13343 /// Look up an @ref enum_type_decl from a given corpus, by its location.
13344 ///
13345 /// @param loc the location to consider.
13346 ///
13347 /// @param corp the corpus to look the type from.
13348 ///
13349 /// @return the resulting enum type, if any.
13350 enum_type_decl_sptr
lookup_enum_type_per_location(const interned_string & loc,const corpus & corp)13351 lookup_enum_type_per_location(const interned_string &loc, const corpus& corp)
13352 {
13353   const istring_type_base_wptrs_map_type& m =
13354     corp.get_type_per_loc_map().enum_types();
13355   enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
13356 
13357   return result;
13358 }
13359 
13360 /// Look up an @ref enum_type_decl from a given corpus, by its location.
13361 ///
13362 /// @param loc the location to consider.
13363 ///
13364 /// @param corp the corpus to look the type from.
13365 ///
13366 /// @return the resulting enum type, if any.
13367 enum_type_decl_sptr
lookup_enum_type_per_location(const string & loc,const corpus & corp)13368 lookup_enum_type_per_location(const string &loc, const corpus &corp)
13369 {
13370   const environment& env = corp.get_environment();
13371   return lookup_enum_type_per_location(env.intern(loc), corp);
13372 }
13373 
13374 /// Look into a given corpus to find a typedef type which has the
13375 /// same qualified name as a given typedef type.
13376 ///
13377 /// If the per-corpus type map is non-empty (because the corpus allows
13378 /// the One Definition Rule) then the type islooked up in that
13379 /// per-corpus type map.  Otherwise, the type is looked-up in each
13380 /// translation unit.
13381 ///
13382 /// @param t the typedef type which has the same qualified name as the
13383 /// typedef type we are looking for.
13384 ///
13385 /// @param corp the corpus to look into.
13386 typedef_decl_sptr
lookup_typedef_type(const typedef_decl & t,const corpus & corp)13387 lookup_typedef_type(const typedef_decl& t, const corpus& corp)
13388 {
13389   interned_string s = get_type_name(t);
13390   return lookup_typedef_type(s, corp);
13391 }
13392 
13393 /// Look into a given corpus to find a typedef type which has the
13394 /// same qualified name as a given typedef type.
13395 ///
13396 /// If the per-corpus type map is non-empty (because the corpus allows
13397 /// the One Definition Rule) then the type islooked up in that
13398 /// per-corpus type map.  Otherwise, the type is looked-up in each
13399 /// translation unit.
13400 ///
13401 /// @param t the typedef type which has the same qualified name as the
13402 /// typedef type we are looking for.
13403 ///
13404 /// @param corp the corpus to look into.
13405 typedef_decl_sptr
lookup_typedef_type(const string & qualified_name,const corpus & corp)13406 lookup_typedef_type(const string& qualified_name, const corpus& corp)
13407 {
13408   interned_string s = corp.get_environment().intern(qualified_name);
13409   return lookup_typedef_type(s, corp);
13410 }
13411 
13412 /// Look into a given corpus to find a typedef type which has a
13413 /// given qualified name.
13414 ///
13415 /// If the per-corpus type map is non-empty (because the corpus allows
13416 /// the One Definition Rule) then the type islooked up in that
13417 /// per-corpus type map.  Otherwise, the type is looked-up in each
13418 /// translation unit.
13419 ///
13420 /// @param qualified_name the qualified name of the typedef type to
13421 /// look for.
13422 ///
13423 /// @param corp the corpus to look into.
13424 typedef_decl_sptr
lookup_typedef_type(const interned_string & qualified_name,const corpus & corp)13425 lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
13426 {
13427   const istring_type_base_wptrs_map_type& m = corp.get_types().typedef_types();
13428 
13429   typedef_decl_sptr result =
13430     lookup_type_in_map<typedef_decl>(qualified_name, m);
13431   if (!result)
13432     result = lookup_typedef_type_through_translation_units(qualified_name,
13433 							   corp);
13434 
13435   return result;
13436 }
13437 
13438 /// Lookup a @ref typedef_decl from a corpus, by its location.
13439 ///
13440 /// @param loc the location to consider.
13441 ///
13442 /// @param corp the corpus to consider.
13443 ///
13444 /// @return the typedef_decl found, if any.
13445 typedef_decl_sptr
lookup_typedef_type_per_location(const interned_string & loc,const corpus & corp)13446 lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
13447 {
13448   const istring_type_base_wptrs_map_type& m =
13449     corp.get_type_per_loc_map().typedef_types();
13450   typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
13451 
13452   return result;
13453 }
13454 
13455 /// Lookup a @ref typedef_decl from a corpus, by its location.
13456 ///
13457 /// @param loc the location to consider.
13458 ///
13459 /// @param corp the corpus to consider.
13460 ///
13461 /// @return the typedef_decl found, if any.
13462 typedef_decl_sptr
lookup_typedef_type_per_location(const string & loc,const corpus & corp)13463 lookup_typedef_type_per_location(const string &loc, const corpus &corp)
13464 {
13465   const environment& env = corp.get_environment();
13466   return lookup_typedef_type_per_location(env.intern(loc), corp);
13467 }
13468 
13469 /// Look into a corpus to find a class, union or typedef type which
13470 /// has a given qualified name.
13471 ///
13472 /// If the per-corpus type map is non-empty (because the corpus allows
13473 /// the One Definition Rule) then the type islooked up in that
13474 /// per-corpus type map.  Otherwise, the type is looked-up in each
13475 /// translation unit.
13476 ///
13477 /// @param qualified_name the name of the type to find.
13478 ///
13479 /// @param corp the corpus to look into.
13480 ///
13481 /// @return the typedef or class type found.
13482 type_base_sptr
lookup_class_or_typedef_type(const string & qualified_name,const corpus & corp)13483 lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
13484 {
13485   type_base_sptr result = lookup_class_type(qualified_name, corp);
13486   if (!result)
13487     result = lookup_union_type(qualified_name, corp);
13488 
13489   if (!result)
13490     result = lookup_typedef_type(qualified_name, corp);
13491   return result;
13492 }
13493 
13494 /// Look into a corpus to find a class, typedef or enum type which has
13495 /// a given qualified name.
13496 ///
13497 /// If the per-corpus type map is non-empty (because the corpus allows
13498 /// the One Definition Rule) then the type islooked up in that
13499 /// per-corpus type map.  Otherwise, the type is looked-up in each
13500 /// translation unit.
13501 ///
13502 /// @param qualified_name the qualified name of the type to look for.
13503 ///
13504 /// @param corp the corpus to look into.
13505 ///
13506 /// @return the typedef, class or enum type found.
13507 type_base_sptr
lookup_class_typedef_or_enum_type(const string & qualified_name,const corpus & corp)13508 lookup_class_typedef_or_enum_type(const string& qualified_name,
13509 				  const corpus& corp)
13510 {
13511   type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
13512   if (!result)
13513     result = lookup_enum_type(qualified_name, corp);
13514 
13515   return result;
13516 }
13517 
13518 /// Look into a given corpus to find a qualified type which has the
13519 /// same qualified name as a given type.
13520 ///
13521 /// @param t the type which has the same qualified name as the
13522 /// qualified type we are looking for.
13523 ///
13524 /// @param corp the corpus to look into.
13525 ///
13526 /// @return the qualified type found.
13527 qualified_type_def_sptr
lookup_qualified_type(const qualified_type_def & t,const corpus & corp)13528 lookup_qualified_type(const qualified_type_def& t, const corpus& corp)
13529 {
13530   interned_string s = get_type_name(t);
13531   return lookup_qualified_type(s, corp);
13532 }
13533 
13534 /// Look into a given corpus to find a qualified type which has a
13535 /// given qualified name.
13536 ///
13537 /// @param qualified_name the qualified name of the type to look for.
13538 ///
13539 /// @param corp the corpus to look into.
13540 ///
13541 /// @return the type found.
13542 qualified_type_def_sptr
lookup_qualified_type(const interned_string & qualified_name,const corpus & corp)13543 lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
13544 {
13545   const istring_type_base_wptrs_map_type& m =
13546     corp.get_types().qualified_types();
13547 
13548   qualified_type_def_sptr result =
13549     lookup_type_in_map<qualified_type_def>(qualified_name, m);
13550 
13551   if (!result)
13552     result = lookup_qualified_type_through_translation_units(qualified_name,
13553 							     corp);
13554 
13555   return result;
13556 }
13557 
13558 /// Look into a given corpus to find a pointer type which has the same
13559 /// qualified name as a given pointer type.
13560 ///
13561 /// @param t the pointer type which has the same qualified name as the
13562 /// type we are looking for.
13563 ///
13564 /// @param corp the corpus to look into.
13565 ///
13566 /// @return the pointer type found.
13567 pointer_type_def_sptr
lookup_pointer_type(const pointer_type_def & t,const corpus & corp)13568 lookup_pointer_type(const pointer_type_def& t, const corpus& corp)
13569 {
13570   interned_string s = get_type_name(t);
13571   return lookup_pointer_type(s, corp);
13572 }
13573 
13574 /// Look into a given corpus to find a pointer type which has a given
13575 /// qualified name.
13576 ///
13577 /// If the per-corpus type map is non-empty (because the corpus allows
13578 /// the One Definition Rule) then the type islooked up in that
13579 /// per-corpus type map.  Otherwise, the type is looked-up in each
13580 /// translation unit.
13581 ///
13582 /// @param qualified_name the qualified name of the pointer type to
13583 /// look for.
13584 ///
13585 /// @param corp the corpus to look into.
13586 ///
13587 /// @return the pointer type found.
13588 pointer_type_def_sptr
lookup_pointer_type(const interned_string & qualified_name,const corpus & corp)13589 lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
13590 {
13591   const istring_type_base_wptrs_map_type& m = corp.get_types().pointer_types();
13592 
13593   pointer_type_def_sptr result =
13594     lookup_type_in_map<pointer_type_def>(qualified_name, m);
13595   if (!result)
13596     result = lookup_pointer_type_through_translation_units(qualified_name,
13597 							   corp);
13598 
13599   return result;
13600 }
13601 
13602 /// Look into a given corpus to find a reference type which has the
13603 /// same qualified name as a given reference type.
13604 ///
13605 /// If the per-corpus type map is non-empty (because the corpus allows
13606 /// the One Definition Rule) then the type islooked up in that
13607 /// per-corpus type map.  Otherwise, the type is looked-up in each
13608 /// translation unit.
13609 ///
13610 /// @param t the reference type which has the same qualified name as
13611 /// the reference type we are looking for.
13612 ///
13613 /// @param corp the corpus to look into.
13614 ///
13615 /// @return the reference type found.
13616 reference_type_def_sptr
lookup_reference_type(const reference_type_def & t,const corpus & corp)13617 lookup_reference_type(const reference_type_def& t, const corpus& corp)
13618 {
13619   interned_string s = get_type_name(t);
13620   return lookup_reference_type(s, corp);
13621 }
13622 
13623 /// Look into a given corpus to find a reference type which has a
13624 /// given qualified name.
13625 ///
13626 /// If the per-corpus type map is non-empty (because the corpus allows
13627 /// the One Definition Rule) then the type islooked up in that
13628 /// per-corpus type map.  Otherwise, the type is looked-up in each
13629 /// translation unit.
13630 ///
13631 /// @param qualified_name the qualified name of the reference type to
13632 /// look for.
13633 ///
13634 /// @param corp the corpus to look into.
13635 ///
13636 /// @return the reference type found.
13637 reference_type_def_sptr
lookup_reference_type(const interned_string & qualified_name,const corpus & corp)13638 lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
13639 {
13640   const istring_type_base_wptrs_map_type& m =
13641     corp.get_types().reference_types();
13642 
13643   reference_type_def_sptr result =
13644     lookup_type_in_map<reference_type_def>(qualified_name, m);
13645   if (!result)
13646     result = lookup_reference_type_through_translation_units(qualified_name,
13647 							     corp);
13648 
13649   return result;
13650 }
13651 
13652 /// Look into a given corpus to find an array type which has a given
13653 /// qualified name.
13654 ///
13655 /// If the per-corpus type map is non-empty (because the corpus allows
13656 /// the One Definition Rule) then the type islooked up in that
13657 /// per-corpus type map.  Otherwise, the type is looked-up in each
13658 /// translation unit.
13659 ///
13660 /// @param qualified_name the qualified name of the array type to look
13661 /// for.
13662 ///
13663 /// @param corp the corpus to look into.
13664 ///
13665 /// @return the array type found.
13666 array_type_def_sptr
lookup_array_type(const array_type_def & t,const corpus & corp)13667 lookup_array_type(const array_type_def& t, const corpus& corp)
13668 {
13669   interned_string s = get_type_name(t);
13670   return lookup_array_type(s, corp);
13671 }
13672 
13673 /// Look into a given corpus to find an array type which has the same
13674 /// qualified name as a given array type.
13675 ///
13676 /// If the per-corpus type map is non-empty (because the corpus allows
13677 /// the One Definition Rule) then the type islooked up in that
13678 /// per-corpus type map.  Otherwise, the type is looked-up in each
13679 /// translation unit.
13680 ///
13681 /// @param t the type which has the same qualified name as the type we
13682 /// are looking for.
13683 ///
13684 /// @param corp the corpus to look into.
13685 ///
13686 /// @return the type found.
13687 array_type_def_sptr
lookup_array_type(const interned_string & qualified_name,const corpus & corp)13688 lookup_array_type(const interned_string& qualified_name, const corpus& corp)
13689 {
13690   const istring_type_base_wptrs_map_type& m = corp.get_types().array_types();
13691 
13692   array_type_def_sptr result =
13693     lookup_type_in_map<array_type_def>(qualified_name, m);
13694   if (!result)
13695     result = lookup_array_type_through_translation_units(qualified_name, corp);
13696 
13697   return result;
13698 }
13699 
13700 /// Look into a given corpus to find a function type which has the same
13701 /// qualified name as a given function type.
13702 ///
13703 /// If the per-corpus type map is non-empty (because the corpus allows
13704 /// the One Definition Rule) then the type islooked up in that
13705 /// per-corpus type map.  Otherwise, the type is looked-up in each
13706 /// translation unit.
13707 ///
13708 /// @param t the function type which has the same qualified name as
13709 /// the function type we are looking for.
13710 ///
13711 /// @param corp the corpus to look into.
13712 ///
13713 /// @return the function type found.
13714 function_type_sptr
lookup_function_type(const function_type & t,const corpus & corp)13715 lookup_function_type(const function_type&t, const corpus& corp)
13716 {
13717   interned_string type_name = get_type_name(t);
13718   return lookup_function_type(type_name, corp);
13719 }
13720 
13721 /// Look into a given corpus to find a function type which has the same
13722 /// qualified name as a given function type.
13723 ///
13724 /// If the per-corpus type map is non-empty (because the corpus allows
13725 /// the One Definition Rule) then the type islooked up in that
13726 /// per-corpus type map.  Otherwise, the type is looked-up in each
13727 /// translation unit.
13728 ///
13729 /// @param t the function type which has the same qualified name as
13730 /// the function type we are looking for.
13731 ///
13732 /// @param corp the corpus to look into.
13733 ///
13734 /// @return the function type found.
13735 function_type_sptr
lookup_function_type(const function_type_sptr & fn_t,const corpus & corpus)13736 lookup_function_type(const function_type_sptr& fn_t,
13737 		     const corpus& corpus)
13738 {
13739   if (fn_t)
13740     return lookup_function_type(*fn_t, corpus);
13741   return function_type_sptr();
13742 }
13743 
13744 /// Look into a given corpus to find a function type which has a given
13745 /// qualified name.
13746 ///
13747 /// If the per-corpus type map is non-empty (because the corpus allows
13748 /// the One Definition Rule) then the type islooked up in that
13749 /// per-corpus type map.  Otherwise, the type is looked-up in each
13750 /// translation unit.
13751 ///
13752 /// @param qualified_name the qualified name of the function type to
13753 /// look for.
13754 ///
13755 /// @param corp the corpus to look into.
13756 ///
13757 /// @return the function type found.
13758 function_type_sptr
lookup_function_type(const interned_string & qualified_name,const corpus & corp)13759 lookup_function_type(const interned_string& qualified_name, const corpus& corp)
13760 {
13761   const istring_type_base_wptrs_map_type& m = corp.get_types().function_types();
13762 
13763   function_type_sptr result =
13764     lookup_type_in_map<function_type>(qualified_name, m);
13765   if (!result)
13766     result = lookup_function_type_through_translation_units(qualified_name,
13767 							    corp);
13768 
13769   return result;
13770 }
13771 
13772 /// Look into a given corpus to find a type which has a given
13773 /// qualified name.
13774 ///
13775 /// If the per-corpus type map is non-empty (because the corpus allows
13776 /// the One Definition Rule) then the type islooked up in that
13777 /// per-corpus type map.  Otherwise, the type is looked-up in each
13778 /// translation unit.
13779 ///
13780 /// @param qualified_name the qualified name of the function type to
13781 /// look for.
13782 ///
13783 /// @param corp the corpus to look into.
13784 ///
13785 /// @return the function type found.
13786 type_base_sptr
lookup_type(const interned_string & n,const corpus & corp)13787 lookup_type(const interned_string& n, const corpus& corp)
13788 {
13789   type_base_sptr result;
13790 
13791   ((result = lookup_basic_type(n, corp))
13792    || (result = lookup_class_type(n, corp))
13793    || (result = lookup_union_type(n, corp))
13794    || (result = lookup_enum_type(n, corp))
13795    || (result = lookup_typedef_type(n, corp))
13796    || (result = lookup_qualified_type(n, corp))
13797    || (result = lookup_pointer_type(n, corp))
13798    || (result = lookup_reference_type(n, corp))
13799    || (result = lookup_array_type(n, corp))
13800    || (result= lookup_function_type(n, corp)));
13801 
13802   return result;
13803 }
13804 
13805 /// Lookup a type from a corpus, by its location.
13806 ///
13807 /// @param loc the location to consider.
13808 ///
13809 /// @param corp the corpus to look the type from.
13810 ///
13811 /// @return the resulting type, if any found.
13812 type_base_sptr
lookup_type_per_location(const interned_string & loc,const corpus & corp)13813 lookup_type_per_location(const interned_string& loc, const corpus& corp)
13814 {
13815   // TODO: finish this.
13816 
13817   //TODO: when we fully support types indexed by their location, this
13818   //function should return a vector of types because at each location,
13819   //there can be several types that are defined (yay, C and C++,
13820   //*sigh*).
13821 
13822   type_base_sptr result;
13823   ((result = lookup_basic_type_per_location(loc, corp))
13824    || (result = lookup_class_type_per_location(loc, corp))
13825    || (result = lookup_union_type_per_location(loc, corp))
13826    || (result = lookup_enum_type_per_location(loc, corp))
13827    || (result = lookup_typedef_type_per_location(loc, corp)));
13828 
13829   return result;
13830 }
13831 
13832 /// Look into a given corpus to find a type
13833 ///
13834 /// If the per-corpus type map is non-empty (because the corpus allows
13835 /// the One Definition Rule) then the type islooked up in that
13836 /// per-corpus type map.  Otherwise, the type is looked-up in each
13837 /// translation unit.
13838 ///
13839 /// @param qualified_name the qualified name of the function type to
13840 /// look for.
13841 ///
13842 /// @param corp the corpus to look into.
13843 ///
13844 /// @return the function type found.
13845 type_base_sptr
lookup_type(const type_base & t,const corpus & corp)13846 lookup_type(const type_base&t, const corpus& corp)
13847 {
13848   interned_string n = get_type_name(t);
13849   return lookup_type(n, corp);
13850 }
13851 
13852 /// Look into a given corpus to find a type
13853 ///
13854 /// If the per-corpus type map is non-empty (because the corpus allows
13855 /// the One Definition Rule) then the type islooked up in that
13856 /// per-corpus type map.  Otherwise, the type is looked-up in each
13857 /// translation unit.
13858 ///
13859 /// @param qualified_name the qualified name of the function type to
13860 /// look for.
13861 ///
13862 /// @param corp the corpus to look into.
13863 ///
13864 /// @return the function type found.
13865 type_base_sptr
lookup_type(const type_base_sptr & t,const corpus & corp)13866 lookup_type(const type_base_sptr&t, const corpus& corp)
13867 {
13868   if (t)
13869     return lookup_type(*t, corp);
13870   return type_base_sptr();
13871 }
13872 
13873 /// Update the map that associates a fully qualified name of a given
13874 /// type to that type.
13875 ///
13876 ///
13877 /// @param type the type we are considering.
13878 ///
13879 /// @param types_map the map to update.  It's a map that assciates a
13880 /// fully qualified name of a type to the type itself.
13881 ///
13882 /// @param use_type_name_as_key if true, use the name of the type as
13883 /// the key to look it up later.  If false, then use the location of
13884 /// the type as a key to look it up later.
13885 ///
13886 /// @return true iff the type was added to the map.
13887 template<typename TypeKind>
13888 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)13889 maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
13890 			      istring_type_base_wptrs_map_type& types_map,
13891 			      bool use_type_name_as_key = true)
13892 {
13893   interned_string s;
13894 
13895   if (use_type_name_as_key)
13896     s = get_type_name(type);
13897   else if (location l = type->get_location())
13898     {
13899       string str = l.expand();
13900       s = type->get_environment().intern(str);
13901     }
13902 
13903   istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
13904   bool result = false;
13905 
13906   if (i == types_map.end())
13907     {
13908       types_map[s].push_back(type);
13909       result = true;
13910     }
13911   else
13912     i->second.push_back(type);
13913 
13914   return result;
13915 }
13916 
13917 /// This is the specialization for type @ref class_decl of the
13918 /// function template:
13919 ///
13920 ///    maybe_update_types_lookup_map<T>(scope_decl*,
13921 ///					const shared_ptr<T>&,
13922 ///					istring_type_base_wptrs_map_type&)
13923 ///
13924 /// @param class_type the type to consider.
13925 ///
13926 /// @param types_map the type map to update.
13927 ///
13928 /// @return true iff the type was added to the map.
13929 template<>
13930 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)13931 maybe_update_types_lookup_map<class_decl>(const class_decl_sptr& class_type,
13932 					  istring_type_base_wptrs_map_type& map,
13933 					  bool use_type_name_as_key)
13934 {
13935   class_decl_sptr type = class_type;
13936 
13937   bool update_qname_map = true;
13938   if (type->get_is_declaration_only())
13939     {
13940       // Let's try to look through decl-only classes to get their
13941       // definition.  But if the class doesn't have a definition then
13942       // we'll keep it.
13943       if (class_decl_sptr def =
13944 	  is_class_type(class_type->get_definition_of_declaration()))
13945 	type = def;
13946     }
13947 
13948   if (!update_qname_map)
13949     return false;
13950 
13951   interned_string s;
13952   if (use_type_name_as_key)
13953     {
13954       string qname = type->get_qualified_name();
13955       s = type->get_environment().intern(qname);
13956     }
13957   else if (location l = type->get_location())
13958     {
13959       string str = l.expand();
13960       s = type->get_environment().intern(str);
13961     }
13962 
13963   bool result = false;
13964   istring_type_base_wptrs_map_type::iterator i = map.find(s);
13965   if (i == map.end())
13966     {
13967       map[s].push_back(type);
13968       result = true;
13969     }
13970   else
13971     i->second.push_back(type);
13972 
13973   return result;
13974 }
13975 
13976 /// This is the specialization for type @ref function_type of the
13977 /// function template:
13978 ///
13979 ///    maybe_update_types_lookup_map<T>(scope_decl*,
13980 ///					const shared_ptr<T>&,
13981 ///					istring_type_base_wptrs_map_type&)
13982 ///
13983 /// @param scope the scope of the type to consider.
13984 ///
13985 /// @param class_type the type to consider.
13986 ///
13987 /// @param types_map the type map to update.
13988 ///
13989 /// @return true iff the type was added to the map.
13990 template<>
13991 bool
maybe_update_types_lookup_map(const function_type_sptr & type,istring_type_base_wptrs_map_type & types_map,bool)13992 maybe_update_types_lookup_map<function_type>
13993 (const function_type_sptr& type,
13994  istring_type_base_wptrs_map_type& types_map,
13995  bool /*use_type_name_as_key*/)
13996 {
13997   bool result = false;
13998   interned_string s = get_type_name(type);
13999   istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14000   if (i == types_map.end())
14001     {
14002       types_map[s].push_back(type);
14003       result = true;
14004     }
14005   else
14006     i->second.push_back(type);
14007 
14008   return result;
14009 }
14010 
14011 /// Update the map that associates the fully qualified name of a basic
14012 /// type with the type itself.
14013 ///
14014 /// The per-translation unit type map is updated if no type with this
14015 /// name was already existing in that map.
14016 ///
14017 /// If no type with this name did already exist in the per-corpus type
14018 /// map, then that per-corpus type map is updated. Otherwise, that
14019 /// type is erased from that per-corpus map.
14020 ///
14021 /// @param basic_type the basic type to consider.
14022 void
maybe_update_types_lookup_map(const type_decl_sptr & basic_type)14023 maybe_update_types_lookup_map(const type_decl_sptr& basic_type)
14024 {
14025   if (translation_unit *tu = basic_type->get_translation_unit())
14026     maybe_update_types_lookup_map<type_decl>
14027       (basic_type, tu->get_types().basic_types());
14028 
14029   if (corpus *type_corpus = basic_type->get_corpus())
14030     {
14031       maybe_update_types_lookup_map<type_decl>
14032 	(basic_type,
14033 	 type_corpus->priv_->get_types().basic_types());
14034 
14035       maybe_update_types_lookup_map<type_decl>
14036 	(basic_type,
14037 	 type_corpus->get_type_per_loc_map().basic_types(),
14038 	 /*use_type_name_as_key*/false);
14039 
14040       if (corpus *group = type_corpus->get_group())
14041 	{
14042 	  maybe_update_types_lookup_map<type_decl>
14043 	    (basic_type,
14044 	     group->priv_->get_types().basic_types());
14045 
14046 	  maybe_update_types_lookup_map<type_decl>
14047 	    (basic_type,
14048 	     group->get_type_per_loc_map().basic_types(),
14049 	     /*use_type_name_as_key*/false);
14050 	}
14051     }
14052 
14053 }
14054 
14055 /// Update the map that associates the fully qualified name of a class
14056 /// type with the type itself.
14057 ///
14058 /// The per-translation unit type map is updated if no type with this
14059 /// name was already existing in that map.
14060 ///
14061 /// If no type with this name did already exist in the per-corpus type
14062 /// map, then that per-corpus type map is updated. Otherwise, that
14063 /// type is erased from that per-corpus map.
14064 ///
14065 /// @param class_type the class type to consider.
14066 void
maybe_update_types_lookup_map(const class_decl_sptr & class_type)14067 maybe_update_types_lookup_map(const class_decl_sptr& class_type)
14068 {
14069   if (translation_unit *tu = class_type->get_translation_unit())
14070     maybe_update_types_lookup_map<class_decl>
14071       (class_type, tu->get_types().class_types());
14072 
14073   if (corpus *type_corpus = class_type->get_corpus())
14074     {
14075       maybe_update_types_lookup_map<class_decl>
14076 	(class_type,
14077 	 type_corpus->priv_->get_types().class_types());
14078 
14079       maybe_update_types_lookup_map<class_decl>
14080 	(class_type,
14081 	 type_corpus->get_type_per_loc_map().class_types(),
14082 	 /*use_type_name_as_key*/false);
14083 
14084       if (corpus *group = type_corpus->get_group())
14085 	{
14086 	  maybe_update_types_lookup_map<class_decl>
14087 	    (class_type,
14088 	     group->priv_->get_types().class_types());
14089 
14090 	  maybe_update_types_lookup_map<class_decl>
14091 	    (class_type,
14092 	     group->get_type_per_loc_map().class_types(),
14093 	     /*use_type_name_as_key*/false);
14094 	}
14095     }
14096 }
14097 
14098 /// Update the map that associates the fully qualified name of a union
14099 /// type with the type itself.
14100 ///
14101 /// The per-translation unit type map is updated if no type with this
14102 /// name was already existing in that map.
14103 ///
14104 /// If no type with this name did already exist in the per-corpus type
14105 /// map, then that per-corpus type map is updated. Otherwise, that
14106 /// type is erased from that per-corpus map.
14107 ///
14108 /// @param union_type the union type to consider.
14109 void
maybe_update_types_lookup_map(const union_decl_sptr & union_type)14110 maybe_update_types_lookup_map(const union_decl_sptr& union_type)
14111 {
14112   if (translation_unit *tu = union_type->get_translation_unit())
14113     maybe_update_types_lookup_map<union_decl>
14114       (union_type, tu->get_types().union_types());
14115 
14116   if (corpus *type_corpus = union_type->get_corpus())
14117     {
14118       maybe_update_types_lookup_map<union_decl>
14119 	(union_type,
14120 	 type_corpus->priv_->get_types().union_types());
14121 
14122       maybe_update_types_lookup_map<union_decl>
14123 	(union_type,
14124 	 type_corpus->get_type_per_loc_map().union_types(),
14125 	 /*use_type_name_as_key*/false);
14126 
14127       if (corpus *group = type_corpus->get_group())
14128 	{
14129 	  maybe_update_types_lookup_map<union_decl>
14130 	    (union_type,
14131 	     group->priv_->get_types().union_types());
14132 
14133 	  maybe_update_types_lookup_map<union_decl>
14134 	    (union_type,
14135 	     group->get_type_per_loc_map().union_types(),
14136 	     /*use_type_name_as_key*/false);
14137 	}
14138     }
14139 }
14140 
14141 /// Update the map that associates the fully qualified name of an enum
14142 /// type with the type itself.
14143 ///
14144 /// The per-translation unit type map is updated if no type with this
14145 /// name was already existing in that map.
14146 ///
14147 /// If no type with this name did already exist in the per-corpus type
14148 /// map, then that per-corpus type map is updated. Otherwise, that
14149 /// type is erased from that per-corpus map.
14150 ///
14151 /// @param enum_type the type to consider.
14152 void
maybe_update_types_lookup_map(const enum_type_decl_sptr & enum_type)14153 maybe_update_types_lookup_map(const enum_type_decl_sptr& enum_type)
14154 {
14155   if (translation_unit *tu = enum_type->get_translation_unit())
14156     maybe_update_types_lookup_map<enum_type_decl>
14157       (enum_type, tu->get_types().enum_types());
14158 
14159   if (corpus *type_corpus = enum_type->get_corpus())
14160     {
14161       maybe_update_types_lookup_map<enum_type_decl>
14162 	(enum_type,
14163 	 type_corpus->priv_->get_types().enum_types());
14164 
14165       maybe_update_types_lookup_map<enum_type_decl>
14166 	(enum_type,
14167 	 type_corpus->get_type_per_loc_map().enum_types(),
14168 	 /*use_type_name_as_key*/false);
14169 
14170       if (corpus *group = type_corpus->get_group())
14171 	{
14172 	  maybe_update_types_lookup_map<enum_type_decl>
14173 	    (enum_type,
14174 	     group->priv_->get_types().enum_types());
14175 
14176 	  maybe_update_types_lookup_map<enum_type_decl>
14177 	    (enum_type,
14178 	     group->get_type_per_loc_map().enum_types(),
14179 	     /*use_type_name_as_key*/false);
14180 	}
14181     }
14182 
14183 }
14184 
14185 /// Update the map that associates the fully qualified name of a
14186 /// typedef type with the type itself.
14187 ///
14188 /// The per-translation unit type map is updated if no type with this
14189 /// name was already existing in that map.
14190 ///
14191 /// If no type with this name did already exist in the per-corpus type
14192 /// map, then that per-corpus type map is updated. Otherwise, that
14193 /// type is erased from that per-corpus map.
14194 ///
14195 /// @param typedef_type the type to consider.
14196 void
maybe_update_types_lookup_map(const typedef_decl_sptr & typedef_type)14197 maybe_update_types_lookup_map(const typedef_decl_sptr& typedef_type)
14198 {
14199   if (translation_unit *tu = typedef_type->get_translation_unit())
14200     maybe_update_types_lookup_map<typedef_decl>
14201       (typedef_type, tu->get_types().typedef_types());
14202 
14203   if (corpus *type_corpus = typedef_type->get_corpus())
14204     {
14205       maybe_update_types_lookup_map<typedef_decl>
14206 	(typedef_type,
14207 	 type_corpus->priv_->get_types().typedef_types());
14208 
14209       maybe_update_types_lookup_map<typedef_decl>
14210 	(typedef_type,
14211 	 type_corpus->get_type_per_loc_map().typedef_types(),
14212 	 /*use_type_name_as_key*/false);
14213 
14214       if (corpus *group = type_corpus->get_group())
14215 	{
14216 	  maybe_update_types_lookup_map<typedef_decl>
14217 	    (typedef_type,
14218 	     group->priv_->get_types().typedef_types());
14219 
14220 	  maybe_update_types_lookup_map<typedef_decl>
14221 	    (typedef_type,
14222 	     group->get_type_per_loc_map().typedef_types(),
14223 	     /*use_type_name_as_key*/false);
14224 	}
14225     }
14226 }
14227 
14228 /// Update the map that associates the fully qualified name of a
14229 /// qualified type with the type itself.
14230 ///
14231 /// The per-translation unit type map is updated if no type with this
14232 /// name was already existing in that map.
14233 ///
14234 /// If no type with this name did already exist in the per-corpus type
14235 /// map, then that per-corpus type map is updated. Otherwise, that
14236 /// type is erased from that per-corpus map.
14237 ///
14238 /// @param qualified_type the type to consider.
14239 void
maybe_update_types_lookup_map(const qualified_type_def_sptr & qualified_type)14240 maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
14241 {
14242   if (translation_unit *tu = qualified_type->get_translation_unit())
14243     maybe_update_types_lookup_map<qualified_type_def>
14244       (qualified_type, tu->get_types().qualified_types());
14245 
14246   if (corpus *type_corpus = qualified_type->get_corpus())
14247     {
14248       maybe_update_types_lookup_map<qualified_type_def>
14249 	(qualified_type,
14250 	 type_corpus->priv_->get_types().qualified_types());
14251 
14252       if (corpus *group = type_corpus->get_group())
14253 	{
14254 	  maybe_update_types_lookup_map<qualified_type_def>
14255 	    (qualified_type,
14256 	     group->priv_->get_types().qualified_types());
14257 	}
14258     }
14259 }
14260 
14261 /// Update the map that associates the fully qualified name of a
14262 /// pointer type with the type itself.
14263 ///
14264 /// The per-translation unit type map is updated if no type with this
14265 /// name was already existing in that map.
14266 ///
14267 /// If no type with this name did already exist in the per-corpus type
14268 /// map, then that per-corpus type map is updated. Otherwise, that
14269 /// type is erased from that per-corpus map.
14270 ///
14271 /// @param pointer_type the type to consider.
14272 void
maybe_update_types_lookup_map(const pointer_type_def_sptr & pointer_type)14273 maybe_update_types_lookup_map(const pointer_type_def_sptr& pointer_type)
14274 {
14275   if (translation_unit *tu = pointer_type->get_translation_unit())
14276     maybe_update_types_lookup_map<pointer_type_def>
14277       (pointer_type, tu->get_types().pointer_types());
14278 
14279   if (corpus *type_corpus = pointer_type->get_corpus())
14280     {
14281       maybe_update_types_lookup_map<pointer_type_def>
14282 	(pointer_type,
14283 	 type_corpus->priv_->get_types().pointer_types());
14284 
14285       if (corpus *group = type_corpus->get_group())
14286 	{
14287 	  maybe_update_types_lookup_map<pointer_type_def>
14288 	    (pointer_type,
14289 	     group->priv_->get_types().pointer_types());
14290 	}
14291     }
14292 }
14293 
14294 /// Update the map that associates the fully qualified name of a
14295 /// reference type with the type itself.
14296 ///
14297 /// The per-translation unit type map is updated if no type with this
14298 /// name was already existing in that map.
14299 ///
14300 /// If no type with this name did already exist in the per-corpus type
14301 /// map, then that per-corpus type map is updated. Otherwise, that
14302 /// type is erased from that per-corpus map.
14303 ///
14304 /// @param reference_type the type to consider.
14305 void
maybe_update_types_lookup_map(const reference_type_def_sptr & reference_type)14306 maybe_update_types_lookup_map(const reference_type_def_sptr& reference_type)
14307 {
14308   if (translation_unit *tu = reference_type->get_translation_unit())
14309     maybe_update_types_lookup_map<reference_type_def>
14310       (reference_type, tu->get_types().reference_types());
14311 
14312   if (corpus *type_corpus = reference_type->get_corpus())
14313     {
14314       maybe_update_types_lookup_map<reference_type_def>
14315 	(reference_type,
14316 	 type_corpus->priv_->get_types().reference_types());
14317 
14318       if (corpus *group = type_corpus->get_group())
14319 	{
14320 	  maybe_update_types_lookup_map<reference_type_def>
14321 	    (reference_type,
14322 	     group->priv_->get_types().reference_types());
14323 	}
14324     }
14325 }
14326 
14327 /// Update the map that associates the fully qualified name of a type
14328 /// with the type itself.
14329 ///
14330 /// The per-translation unit type map is updated if no type with this
14331 /// name was already existing in that map.
14332 ///
14333 /// If no type with this name did already exist in the per-corpus type
14334 /// map, then that per-corpus type map is updated. Otherwise, that
14335 /// type is erased from that per-corpus map.
14336 ///
14337 /// @param array_type the type to consider.
14338 void
maybe_update_types_lookup_map(const array_type_def_sptr & array_type)14339 maybe_update_types_lookup_map(const array_type_def_sptr& array_type)
14340 {
14341   if (translation_unit *tu = array_type->get_translation_unit())
14342     maybe_update_types_lookup_map<array_type_def>
14343       (array_type, tu->get_types().array_types());
14344 
14345   if (corpus *type_corpus = array_type->get_corpus())
14346     {
14347       maybe_update_types_lookup_map<array_type_def>
14348 	(array_type,
14349 	 type_corpus->priv_->get_types().array_types());
14350 
14351       maybe_update_types_lookup_map<array_type_def>
14352 	(array_type,
14353 	 type_corpus->get_type_per_loc_map().array_types(),
14354 	 /*use_type_name_as_key*/false);
14355 
14356       if (corpus *group = type_corpus->get_group())
14357 	{
14358 	  maybe_update_types_lookup_map<array_type_def>
14359 	    (array_type,
14360 	     group->priv_->get_types().array_types());
14361 
14362 	  maybe_update_types_lookup_map<array_type_def>
14363 	    (array_type,
14364 	     group->get_type_per_loc_map().array_types(),
14365 	     /*use_type_name_as_key*/false);
14366 	}
14367     }
14368 }
14369 
14370 /// Update the map that associates the fully qualified name of a type
14371 /// with the type itself.
14372 ///
14373 /// The per-translation unit type map is updated if no type with this
14374 /// name was already existing in that map.
14375 ///
14376 /// If no type with this name did already exist in the per-corpus type
14377 /// map, then that per-corpus type map is updated. Otherwise, that
14378 /// type is erased from that per-corpus map.
14379 ///
14380 /// @param subrange_type the type to consider.
14381 void
maybe_update_types_lookup_map(const array_type_def::subrange_sptr & subrange_type)14382 maybe_update_types_lookup_map
14383 (const array_type_def::subrange_sptr& subrange_type)
14384 {
14385   if (translation_unit *tu = subrange_type->get_translation_unit())
14386     maybe_update_types_lookup_map<array_type_def::subrange_type>
14387       (subrange_type, tu->get_types().subrange_types());
14388 
14389   if (corpus *type_corpus = subrange_type->get_corpus())
14390     {
14391       maybe_update_types_lookup_map<array_type_def::subrange_type>
14392 	(subrange_type,
14393 	 type_corpus->priv_->get_types().subrange_types());
14394 
14395       maybe_update_types_lookup_map<array_type_def::subrange_type>
14396 	(subrange_type,
14397 	 type_corpus->get_type_per_loc_map().subrange_types(),
14398 	 /*use_type_name_as_key*/false);
14399 
14400       if (corpus *group = subrange_type->get_corpus())
14401 	{
14402 	  maybe_update_types_lookup_map<array_type_def::subrange_type>
14403 	    (subrange_type,
14404 	     group->priv_->get_types().subrange_types());
14405 
14406 	  maybe_update_types_lookup_map<array_type_def::subrange_type>
14407 	    (subrange_type,
14408 	     group->get_type_per_loc_map().subrange_types(),
14409 	     /*use_type_name_as_key*/false);
14410 	}
14411     }
14412 }
14413 
14414 /// Update the map that associates the fully qualified name of a
14415 /// function type with the type itself.
14416 ///
14417 /// The per-translation unit type map is updated if no type with this
14418 /// name was already existing in that map.
14419 ///
14420 /// If no type with this name did already exist in the per-corpus type
14421 /// map, then that per-corpus type map is updated. Otherwise, that
14422 /// type is erased from that per-corpus map.
14423 ///
14424 /// @param scope the scope of the function type.
14425 /// @param fn_type the type to consider.
14426 void
maybe_update_types_lookup_map(const function_type_sptr & fn_type)14427 maybe_update_types_lookup_map(const function_type_sptr& fn_type)
14428 {
14429   if (translation_unit *tu = fn_type->get_translation_unit())
14430     maybe_update_types_lookup_map<function_type>
14431       (fn_type, tu->get_types().function_types());
14432 
14433   if (corpus *type_corpus = fn_type->get_corpus())
14434     {
14435       maybe_update_types_lookup_map<function_type>
14436 	(fn_type,
14437 	 type_corpus->priv_->get_types().function_types());
14438 
14439       if (corpus *group = fn_type->get_corpus())
14440 	{
14441 	  maybe_update_types_lookup_map<function_type>
14442 	    (fn_type,
14443 	     group->priv_->get_types().function_types());
14444 	}
14445     }
14446 }
14447 
14448 /// Update the map that associates the fully qualified name of a type
14449 /// declaration with the type itself.
14450 ///
14451 /// The per-translation unit type map is updated if no type with this
14452 /// name was already existing in that map.
14453 ///
14454 /// If no type with this name did already exist in the per-corpus type
14455 /// map, then that per-corpus type map is updated. Otherwise, that
14456 /// type is erased from that per-corpus map.
14457 ///
14458 /// @param decl the declaration of the type to consider.
14459 void
maybe_update_types_lookup_map(const decl_base_sptr & decl)14460 maybe_update_types_lookup_map(const decl_base_sptr& decl)
14461 {
14462   if (!is_type(decl))
14463     return;
14464 
14465   if (type_decl_sptr basic_type = is_type_decl(decl))
14466     maybe_update_types_lookup_map(basic_type);
14467   else if (class_decl_sptr class_type = is_class_type(decl))
14468     maybe_update_types_lookup_map(class_type);
14469   else if (union_decl_sptr union_type = is_union_type(decl))
14470     maybe_update_types_lookup_map(union_type);
14471   else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
14472     maybe_update_types_lookup_map(enum_type);
14473   else if (typedef_decl_sptr typedef_type = is_typedef(decl))
14474     maybe_update_types_lookup_map(typedef_type);
14475   else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
14476     maybe_update_types_lookup_map(qualified_type);
14477   else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
14478     maybe_update_types_lookup_map(pointer_type);
14479   else if (reference_type_def_sptr reference_type = is_reference_type(decl))
14480     maybe_update_types_lookup_map(reference_type);
14481   else if (array_type_def_sptr array_type = is_array_type(decl))
14482     maybe_update_types_lookup_map(array_type);
14483   else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
14484     maybe_update_types_lookup_map(subrange_type);
14485   else if (function_type_sptr fn_type = is_function_type(decl))
14486     maybe_update_types_lookup_map(fn_type);
14487   else
14488     ABG_ASSERT_NOT_REACHED;
14489 }
14490 
14491 /// Update the map that associates the fully qualified name of a type
14492 /// with the type itself.
14493 ///
14494 /// The per-translation unit type map is updated if no type with this
14495 /// name was already existing in that map.
14496 ///
14497 /// If no type with this name did already exist in the per-corpus type
14498 /// map, then that per-corpus type map is updated. Otherwise, that
14499 /// type is erased from that per-corpus map.
14500 ///
14501 /// @param type the type to consider.
14502 void
maybe_update_types_lookup_map(const type_base_sptr & type)14503 maybe_update_types_lookup_map(const type_base_sptr& type)
14504 {
14505   if (decl_base_sptr decl = get_type_declaration(type))
14506     maybe_update_types_lookup_map(decl);
14507   else if (function_type_sptr fn_type = is_function_type(type))
14508     maybe_update_types_lookup_map(fn_type);
14509   else
14510     ABG_ASSERT_NOT_REACHED;
14511 }
14512 
14513 //--------------------------------
14514 // </type and decls lookup stuff>
14515 // ------------------------------
14516 
14517 /// In a translation unit, lookup a given type or synthesize it if
14518 /// it's a qualified type.
14519 ///
14520 /// So this function first looks the type up in the translation unit.
14521 /// If it's found, then OK, it's returned.  Otherwise, if it's a
14522 /// qualified, reference or pointer or function type (a composite
14523 /// type), lookup the underlying type, synthesize the type we want
14524 /// from it and return it.
14525 ///
14526 /// If the underlying types is not not found, then give up and return
14527 /// nil.
14528 ///
14529 /// @return the type that was found or the synthesized type.
14530 type_base_sptr
synthesize_type_from_translation_unit(const type_base_sptr & type,translation_unit & tu)14531 synthesize_type_from_translation_unit(const type_base_sptr& type,
14532 				      translation_unit& tu)
14533 {
14534   type_base_sptr result;
14535 
14536    result = lookup_type(type, tu);
14537 
14538   if (!result)
14539     {
14540       if (qualified_type_def_sptr qual = is_qualified_type(type))
14541 	{
14542 	  type_base_sptr underlying_type =
14543 	    synthesize_type_from_translation_unit(qual->get_underlying_type(),
14544 						  tu);
14545 	  if (underlying_type)
14546 	    {
14547 	      result.reset(new qualified_type_def(underlying_type,
14548 						  qual->get_cv_quals(),
14549 						  qual->get_location()));
14550 	    }
14551 	}
14552       else if (pointer_type_def_sptr p = is_pointer_type(type))
14553 	{
14554 	  type_base_sptr pointed_to_type =
14555 	    synthesize_type_from_translation_unit(p->get_pointed_to_type(),
14556 						  tu);
14557 	  if (pointed_to_type)
14558 	    {
14559 	      result.reset(new pointer_type_def(pointed_to_type,
14560 						p->get_size_in_bits(),
14561 						p->get_alignment_in_bits(),
14562 						p->get_location()));
14563 	    }
14564 	}
14565       else if (reference_type_def_sptr r = is_reference_type(type))
14566 	{
14567 	  type_base_sptr pointed_to_type =
14568 	    synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
14569 	  if (pointed_to_type)
14570 	    {
14571 	      result.reset(new reference_type_def(pointed_to_type,
14572 						  r->is_lvalue(),
14573 						  r->get_size_in_bits(),
14574 						  r->get_alignment_in_bits(),
14575 						  r->get_location()));
14576 	    }
14577 	}
14578       else if (function_type_sptr f = is_function_type(type))
14579 	result = synthesize_function_type_from_translation_unit(*f, tu);
14580 
14581       if (result)
14582 	{
14583 	  add_decl_to_scope(is_decl(result), tu.get_global_scope());
14584 	  canonicalize(result);
14585 	}
14586     }
14587 
14588   if (result)
14589     tu.priv_->synthesized_types_.push_back(result);
14590 
14591   return result;
14592 }
14593 
14594 /// In a translation unit, lookup the sub-types that make up a given
14595 /// function type and if the sub-types are all found, synthesize and
14596 /// return a function_type with them.
14597 ///
14598 /// This function is like lookup_function_type_in_translation_unit()
14599 /// execept that it constructs the function type from the sub-types
14600 /// found in the translation, rather than just looking for the
14601 /// function types held by the translation unit.  This can be useful
14602 /// if the translation unit doesnt hold the function type we are
14603 /// looking for (i.e, lookup_function_type_in_translation_unit()
14604 /// returned NULL) but we still want to see if the sub-types of the
14605 /// function types are present in the translation unit.
14606 ///
14607 /// @param fn_type the function type to consider.
14608 ///
14609 /// @param tu the translation unit to look into.
14610 ///
14611 /// @return the resulting synthesized function type if all its
14612 /// sub-types have been found, NULL otherwise.
14613 function_type_sptr
synthesize_function_type_from_translation_unit(const function_type & fn_type,translation_unit & tu)14614 synthesize_function_type_from_translation_unit(const function_type& fn_type,
14615 					       translation_unit& tu)
14616 {
14617   function_type_sptr nil = function_type_sptr();
14618 
14619   const environment& env = tu.get_environment();
14620 
14621   type_base_sptr return_type = fn_type.get_return_type();
14622   type_base_sptr result_return_type;
14623   if (!return_type || env.is_void_type(return_type))
14624     result_return_type = env.get_void_type();
14625   else
14626     result_return_type = synthesize_type_from_translation_unit(return_type, tu);
14627   if (!result_return_type)
14628     return nil;
14629 
14630   function_type::parameters parms;
14631   type_base_sptr parm_type;
14632   function_decl::parameter_sptr parm;
14633   for (function_type::parameters::const_iterator i =
14634 	 fn_type.get_parameters().begin();
14635        i != fn_type.get_parameters().end();
14636        ++i)
14637     {
14638       type_base_sptr t = (*i)->get_type();
14639       parm_type = synthesize_type_from_translation_unit(t, tu);
14640       if (!parm_type)
14641 	return nil;
14642       parm.reset(new function_decl::parameter(parm_type,
14643 					      (*i)->get_index(),
14644 					      (*i)->get_name(),
14645 					      (*i)->get_location(),
14646 					      (*i)->get_variadic_marker(),
14647 					      (*i)->get_is_artificial()));
14648       parms.push_back(parm);
14649     }
14650 
14651   class_or_union_sptr class_type;
14652   const method_type* method = is_method_type(&fn_type);
14653   if (method)
14654     {
14655       class_type = is_class_or_union_type
14656 	(synthesize_type_from_translation_unit(method->get_class_type(), tu));
14657       ABG_ASSERT(class_type);
14658     }
14659 
14660   function_type_sptr result_fn_type;
14661 
14662   if (class_type)
14663     result_fn_type.reset(new method_type(result_return_type,
14664 					 class_type,
14665 					 parms,
14666 					 method->get_is_const(),
14667 					 fn_type.get_size_in_bits(),
14668 					 fn_type.get_alignment_in_bits()));
14669   else
14670     result_fn_type.reset(new function_type(result_return_type,
14671 					   parms,
14672 					   fn_type.get_size_in_bits(),
14673 					   fn_type.get_alignment_in_bits()));
14674 
14675   tu.priv_->synthesized_types_.push_back(result_fn_type);
14676   tu.bind_function_type_life_time(result_fn_type);
14677 
14678   canonicalize(result_fn_type);
14679   return result_fn_type;
14680 }
14681 
14682 /// Demangle a C++ mangled name and return the resulting string
14683 ///
14684 /// @param mangled_name the C++ mangled name to demangle.
14685 ///
14686 /// @return the resulting mangled name.
14687 string
demangle_cplus_mangled_name(const string & mangled_name)14688 demangle_cplus_mangled_name(const string& mangled_name)
14689 {
14690   if (mangled_name.empty())
14691     return "";
14692 
14693   size_t l = 0;
14694   int status = 0;
14695   char * str = abi::__cxa_demangle(mangled_name.c_str(),
14696 				   NULL, &l, &status);
14697   string demangled_name = mangled_name;
14698   if (str)
14699     {
14700       ABG_ASSERT(status == 0);
14701       demangled_name = str;
14702       free(str);
14703       str = 0;
14704     }
14705   return demangled_name;
14706 }
14707 
14708 /// Return either the type given in parameter if it's non-null, or the
14709 /// void type.
14710 ///
14711 /// @param t the type to consider.
14712 ///
14713 /// @param env the environment to use.  If NULL, just abort the
14714 /// process.
14715 ///
14716 /// @return either @p t if it is non-null, or the void type.
14717 type_base_sptr
type_or_void(const type_base_sptr t,const environment & env)14718 type_or_void(const type_base_sptr t, const environment& env)
14719 {
14720   type_base_sptr r;
14721 
14722   if (t)
14723     r = t;
14724   else
14725     r = type_base_sptr(env.get_void_type());
14726 
14727   return r;
14728 }
14729 
~global_scope()14730 global_scope::~global_scope()
14731 {
14732 }
14733 
14734 static bool
14735 maybe_propagate_canonical_type(const type_base& lhs_type,
14736 			       const type_base& rhs_type);
14737 
14738 /// Test if two types are eligible to the "Linux Kernel Fast Type
14739 /// Comparison Optimization", a.k.a LKFTCO.
14740 ///
14741 /// Two types T1 and T2 (who are presumably of the same name and kind)
14742 /// are eligible to the LKFTCO if they fulfill the following criteria/
14743 ///
14744 /// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
14745 /// either class, union or enums.
14746 ///
14747 /// 2/ They are defined in the same translation unit.
14748 ///
14749 /// @param t1 the first type to consider.
14750 ///
14751 /// @param t2 the second type to consider.
14752 ///
14753 /// @return true iff t1 and t2 are eligible to the LKFTCO.
14754 static bool
types_defined_same_linux_kernel_corpus_public(const type_base & t1,const type_base & t2)14755 types_defined_same_linux_kernel_corpus_public(const type_base& t1,
14756 					      const type_base& t2)
14757 {
14758   const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
14759   string t1_file_path, t2_file_path;
14760 
14761   /// If the t1 (and t2) are classes/unions/enums from the same linux
14762   /// kernel corpus, let's move on.  Otherwise bail out.
14763   if (!(t1_corpus && t2_corpus
14764 	&& t1_corpus == t2_corpus
14765 	&& (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
14766 	&& (is_class_or_union_type(&t1)
14767 	    || is_enum_type(&t1))))
14768     return false;
14769 
14770   class_or_union *c1 = 0, *c2 = 0;
14771   c1 = is_class_or_union_type(&t1);
14772   c2 = is_class_or_union_type(&t2);
14773 
14774   // Two anonymous class types with no naming typedefs cannot be
14775   // eligible to this optimization.
14776   if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
14777       || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
14778     return false;
14779 
14780   // Two anonymous classes with naming typedefs should have the same
14781   // typedef name.
14782   if (c1
14783       && c2
14784       && c1->get_is_anonymous() && c1->get_naming_typedef()
14785       && c2->get_is_anonymous() && c2->get_naming_typedef())
14786     if (c1->get_naming_typedef()->get_name()
14787 	!= c2->get_naming_typedef()->get_name())
14788       return false;
14789 
14790   // Two anonymous enum types cannot be eligible to this optimization.
14791   if (const enum_type_decl *e1 = is_enum_type(&t1))
14792     if (const enum_type_decl *e2 = is_enum_type(&t2))
14793       if (e1->get_is_anonymous() || e2->get_is_anonymous())
14794 	return false;
14795 
14796   // Look through declaration-only types.  That is, get the associated
14797   // definition type.
14798   c1 = look_through_decl_only_class(c1);
14799   c2 = look_through_decl_only_class(c2);
14800 
14801   if (c1 && c2)
14802     {
14803       if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
14804 	{
14805 	  if (c1->get_environment().decl_only_class_equals_definition())
14806 	    // At least one of classes/union is declaration-only.
14807 	    // Because we are in a context in which a declaration-only
14808 	    // class/union is equal to all definitions of that
14809 	    // class/union, we can assume that the two types are
14810 	    // equal.
14811 	    return true;
14812 	}
14813     }
14814 
14815   if (t1.get_size_in_bits() != t2.get_size_in_bits())
14816     return false;
14817 
14818   // Look at the file names of the locations of t1 and t2.  If they
14819   // are equal, then t1 and t2 are defined in the same file.
14820   {
14821     location l;
14822 
14823     if (c1)
14824       l = c1->get_location();
14825     else
14826       l = dynamic_cast<const decl_base&>(t1).get_location();
14827 
14828     unsigned line = 0, col = 0;
14829     if (l)
14830       l.expand(t1_file_path, line, col);
14831     if (c2)
14832       l = c2->get_location();
14833     else
14834       l = dynamic_cast<const decl_base&>(t2).get_location();
14835     if (l)
14836       l.expand(t2_file_path, line, col);
14837   }
14838 
14839   if (t1_file_path.empty() || t2_file_path.empty())
14840     return false;
14841 
14842   if (t1_file_path == t2_file_path)
14843     return true;
14844 
14845   return false;
14846 }
14847 
14848 
14849 /// Compare a type T against a canonical type.
14850 ///
14851 /// This function is called during the canonicalization process of the
14852 /// type T.  T is called the "candidate type" because it's in the
14853 /// process of being canonicalized.  Meaning, it's going to be
14854 /// compared to a canonical type C.  If T equals C, then the canonical
14855 /// type of T is C.
14856 ///
14857 /// The purpose of this function is to allow the debugging of the
14858 /// canonicalization of T, if that debugging is activated by
14859 /// configuring the libabigail package with
14860 /// --enable-debug-type-canonicalization and by running "abidw
14861 /// --debug-tc".  In that case, T is going to be compared to C twice:
14862 /// once with canonical equality and once with structural equality.
14863 /// The two comparisons must be equal.  Otherwise, the
14864 /// canonicalization process is said to be faulty and this function
14865 /// aborts.
14866 ///
14867 /// This is a sub-routine of type_base::get_canonical_type_for.
14868 ///
14869 /// @param canonical_type the canonical type to compare the candidate
14870 /// type against.
14871 ///
14872 /// @param candidate_type the candidate type to compare against the
14873 /// canonical type.
14874 ///
14875 /// @return true iff @p canonical_type equals @p candidate_type.
14876 ///
14877 static bool
compare_types_during_canonicalization(const type_base & canonical_type,const type_base & candidate_type)14878 compare_types_during_canonicalization(const type_base& canonical_type,
14879 				      const type_base& candidate_type)
14880 {
14881 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
14882   const environment& env = canonical_type.get_environment();
14883   if (env.debug_type_canonicalization_is_on())
14884     {
14885       bool canonical_equality = false, structural_equality = false;
14886       env.priv_->use_canonical_type_comparison_ = false;
14887       structural_equality = canonical_type == candidate_type;
14888       env.priv_->use_canonical_type_comparison_ = true;
14889       canonical_equality = canonical_type == candidate_type;
14890       if (canonical_equality != structural_equality)
14891 	{
14892 	  std::cerr << "structural & canonical equality different for type: "
14893 		    << canonical_type.get_pretty_representation(true, true)
14894 		    << std::endl;
14895 	  ABG_ASSERT_NOT_REACHED;
14896 	}
14897       return structural_equality;
14898     }
14899 #endif //end WITH_DEBUG_TYPE_CANONICALIZATION
14900   return canonical_type == candidate_type;
14901 }
14902 
14903 /// Compare a canonical type against a candidate canonical type.
14904 ///
14905 /// This is ultimately a sub-routine of the
14906 /// type_base::get_canonical_type_for().
14907 ///
14908 /// The goal of this function is to ease debugging because it can be
14909 /// called from within type_base::get_canonical_type_for() from the
14910 /// prompt of the debugger (with some breakpoint appropriately set) to
14911 /// debug the comparison that happens during type canonicalization,
14912 /// between a candidate type being canonicalized, and an existing
14913 /// canonical type that is registered in the system, in as returned by
14914 /// environment::get_canonical_types()
14915 ///
14916 /// @param canonical_type the canonical type to consider.
14917 ///
14918 /// @param candidate_type the candidate type that is being
14919 /// canonicalized, and thus compared to @p canonical_type.
14920 ///
14921 /// @return true iff @p canonical_type compares equal to @p
14922 /// candidate_type.
14923 static bool
compare_canonical_type_against_candidate(const type_base & canonical_type,const type_base & candidate_type)14924 compare_canonical_type_against_candidate(const type_base& canonical_type,
14925 					 const type_base& candidate_type)
14926 {
14927   environment& env = const_cast<environment&>(canonical_type.get_environment());
14928 
14929   // Before the "*it == it" comparison below is done, let's
14930   // perform on-the-fly-canonicalization.  For C types, let's
14931   // consider that an unresolved struct declaration 'struct S'
14932   // is different from a definition 'struct S'.  This is
14933   // because normally, at this point all the declarations of
14934   // struct S that are compatible with the definition of
14935   // struct S have already been resolved to that definition,
14936   // during the DWARF parsing.  The remaining unresolved
14937   // declaration are thus considered different.  With this
14938   // setup we can properly handle cases of two *different*
14939   // struct S being defined in the same binary (in different
14940   // translation units), and a third struct S being only
14941   // declared as an opaque type in a third translation unit of
14942   // its own, with no definition in there.  In that case, the
14943   // declaration-only struct S should be left alone and not
14944   // resolved to any of the two definitions of struct S.
14945   bool saved_decl_only_class_equals_definition =
14946     env.decl_only_class_equals_definition();
14947   env.do_on_the_fly_canonicalization(true);
14948   // Compare types by considering that decl-only classes don't
14949   // equal their definition.
14950   env.decl_only_class_equals_definition(false);
14951   env.priv_->allow_type_comparison_results_caching(true);
14952   bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
14953 							      candidate_type)
14954 		|| compare_types_during_canonicalization(canonical_type,
14955 							 candidate_type));
14956   // Restore the state of the on-the-fly-canonicalization and
14957   // the decl-only-class-being-equal-to-a-matching-definition
14958   // flags.
14959   env.priv_->clear_type_comparison_results_cache();
14960   env.priv_->allow_type_comparison_results_caching(false);
14961   env.do_on_the_fly_canonicalization(false);
14962   env.decl_only_class_equals_definition
14963     (saved_decl_only_class_equals_definition);
14964   return equal;
14965 }
14966 
14967 /// Compare a canonical type against a candidate canonical type.
14968 ///
14969 /// This is ultimately a sub-routine of the
14970 /// type_base::get_canonical_type_for().
14971 ///
14972 /// The goal of this function is to ease debugging because it can be
14973 /// called from within type_base::get_canonical_type_for() from the
14974 /// prompt of the debugger (with some breakpoint appropriately set) to
14975 /// debug the comparison that happens during type canonicalization,
14976 /// between a candidate type being canonicalized, and an existing
14977 /// canonical type that is registered in the system, in as returned by
14978 /// environment::get_canonical_types()
14979 ///
14980 /// @param canonical_type the canonical type to consider.
14981 ///
14982 /// @param candidate_type the candidate type that is being
14983 /// canonicalized, and thus compared to @p canonical_type.
14984 ///
14985 /// @return true iff @p canonical_type compares equal to @p
14986 /// candidate_type.
14987 static bool
compare_canonical_type_against_candidate(const type_base * canonical_type,const type_base * candidate_type)14988 compare_canonical_type_against_candidate(const type_base* canonical_type,
14989 					 const type_base* candidate_type)
14990 {
14991   return compare_canonical_type_against_candidate(*canonical_type,
14992 						  *candidate_type);
14993 }
14994 
14995 /// Compare a canonical type against a candidate canonical type.
14996 ///
14997 /// This is ultimately a sub-routine of the
14998 /// type_base::get_canonical_type_for().
14999 ///
15000 /// The goal of this function is to ease debugging because it can be
15001 /// called from within type_base::get_canonical_type_for() from the
15002 /// prompt of the debugger (with some breakpoint appropriately set) to
15003 /// debug the comparison that happens during type canonicalization,
15004 /// between a candidate type being canonicalized, and an existing
15005 /// canonical type that is registered in the system, in as returned by
15006 /// environment::get_canonical_types()
15007 ///
15008 /// @param canonical_type the canonical type to consider.
15009 ///
15010 /// @param candidate_type the candidate type that is being
15011 /// canonicalized, and thus compared to @p canonical_type.
15012 ///
15013 /// @return true iff @p canonical_type compares equal to @p
15014 /// candidate_type.
15015 static bool
compare_canonical_type_against_candidate(const type_base_sptr & canonical_type,const type_base_sptr & candidate_type)15016 compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
15017 					 const type_base_sptr& candidate_type)
15018 {
15019   return compare_canonical_type_against_candidate(canonical_type.get(),
15020 						  candidate_type.get());
15021 }
15022 
15023 /// Compute the canonical type for a given instance of @ref type_base.
15024 ///
15025 /// Consider two types T and T'.  The canonical type of T, denoted
15026 /// C(T) is a type such as T == T' if and only if C(T) == C(T').  Said
15027 /// otherwise, to compare two types, one just needs to compare their
15028 /// canonical types using pointer equality.  That makes type
15029 /// comparison faster than the structural comparison performed by the
15030 /// abigail::ir::equals() overloads.
15031 ///
15032 /// If there is not yet any canonical type for @p t, then @p t is its
15033 /// own canonical type.  Otherwise, this function returns the
15034 /// canonical type of @p t which is the canonical type that has the
15035 /// same hash value as @p t and that structurally equals @p t.  Note
15036 /// that after invoking this function, the life time of the returned
15037 /// canonical time is then equals to the life time of the current
15038 /// process.
15039 ///
15040 /// @param t a smart pointer to instance of @ref type_base we want to
15041 /// compute a canonical type for.
15042 ///
15043 /// @return the canonical type for the current instance of @ref
15044 /// type_base.
15045 type_base_sptr
get_canonical_type_for(type_base_sptr t)15046 type_base::get_canonical_type_for(type_base_sptr t)
15047 {
15048   if (!t)
15049     return t;
15050 
15051   environment& env = const_cast<environment&>(t->get_environment());
15052 
15053   if (is_non_canonicalized_type(t))
15054     // This type should not be canonicalized!
15055     return type_base_sptr();
15056 
15057   if (is_decl(t))
15058     t = is_type(look_through_decl_only(is_decl(t)));
15059 
15060   // Look through decl-only types (classes, unions and enums)
15061   bool decl_only_class_equals_definition =
15062     (odr_is_relevant(*t) || env.decl_only_class_equals_definition());
15063 
15064   class_or_union_sptr class_or_union = is_class_or_union_type(t);
15065 
15066   // In the context of types from C++ or languages where we assume the
15067   // "One Definition Rule", we assume that a declaration-only
15068   // non-anonymous class equals all fully defined classes of the same
15069   // name.
15070   //
15071   // Otherwise, all classes, including declaration-only classes are
15072   // canonicalized and only canonical comparison is going to be used
15073   // in the system.
15074   if (decl_only_class_equals_definition)
15075     if (class_or_union)
15076       if (class_or_union->get_is_declaration_only())
15077 	return type_base_sptr();
15078 
15079   class_decl_sptr is_class = is_class_type(t);
15080   if (t->get_canonical_type())
15081     return t->get_canonical_type();
15082 
15083   // For classes and union, ensure that an anonymous class doesn't
15084   // have a linkage name.  If it does in the future, then me must be
15085   // mindful that the linkage name respects the type identity
15086   // constraints which states that "if two linkage names are different
15087   // then the two types are different".
15088   ABG_ASSERT(!class_or_union
15089 	     || !class_or_union->get_is_anonymous()
15090 	     || class_or_union->get_linkage_name().empty());
15091 
15092   // We want the pretty representation of the type, but for an
15093   // internal use, not for a user-facing purpose.
15094   //
15095   // If two classe types Foo are declared, one as a class and the
15096   // other as a struct, but are otherwise equivalent, we want their
15097   // pretty representation to be the same.  Hence the 'internal'
15098   // argument of ir::get_pretty_representation() is set to true here.
15099   // So in this case, the pretty representation of Foo is going to be
15100   // "class Foo", regardless of its struct-ness. This also applies to
15101   // composite types which would have "class Foo" as a sub-type.
15102   string repr = t->get_cached_pretty_representation(/*internal=*/true);
15103 
15104   // If 't' already has a canonical type 'inside' its corpus
15105   // (t_corpus), then this variable is going to contain that canonical
15106   // type.
15107   type_base_sptr canonical_type_present_in_corpus;
15108   environment::canonical_types_map_type& types =
15109     env.get_canonical_types_map();
15110 
15111   type_base_sptr result;
15112   environment::canonical_types_map_type::iterator i = types.find(repr);
15113   if (i == types.end())
15114     {
15115       vector<type_base_sptr> v;
15116       v.push_back(t);
15117       types[repr] = v;
15118       result = t;
15119     }
15120   else
15121     {
15122       vector<type_base_sptr> &v = i->second;
15123       // Let's compare 't' structurally (i.e, compare its sub-types
15124       // recursively) against the canonical types of the system. If it
15125       // equals a given canonical type C, then it means C is the
15126       // canonical type of 't'.  Otherwise, if 't' is different from
15127       // all the canonical types of the system, then it means 't' is a
15128       // canonical type itself.
15129       for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15130 	   it != v.rend();
15131 	   ++it)
15132 	{
15133 	  bool equal = compare_canonical_type_against_candidate(*it, t);
15134 	  if (equal)
15135 	    {
15136 	      result = *it;
15137 	      break;
15138 	    }
15139 	}
15140 #ifdef WITH_DEBUG_SELF_COMPARISON
15141       if (env.self_comparison_debug_is_on())
15142 	{
15143 	  // So we are debugging the canonicalization process,
15144 	  // possibly via the use of 'abidw --debug-abidiff <binary>'.
15145 	  corpus_sptr corp1, corp2;
15146 	  env.get_self_comparison_debug_inputs(corp1, corp2);
15147 	  if (corp1 && corp2 && t->get_corpus() == corp2.get())
15148 	    {
15149 	      // If 't' comes from the second corpus, then it *must*
15150 	      // be equal to its matching canonical type coming from
15151 	      // the first corpus because the second corpus is the
15152 	      // abixml representation of the first corpus.  In other
15153 	      // words, all types coming from the second corpus must
15154 	      // have canonical types coming from the first corpus.
15155 	      if (result)
15156 		{
15157 		  if (!env.priv_->
15158 		      check_canonical_type_from_abixml_during_self_comp(t,
15159 									result))
15160 		    {
15161 		      // The canonical type of the type re-read from abixml
15162 		      // type doesn't match the canonical type that was
15163 		      // initially serialized down.
15164 		      uintptr_t should_have_canonical_type = 0;
15165 		      string type_id = env.get_type_id_from_type(t.get());
15166 		      if (type_id.empty())
15167 			type_id = "type-id-<not-found>";
15168 		      else
15169 			should_have_canonical_type =
15170 			  env.get_canonical_type_from_type_id(type_id.c_str());
15171 		      std::cerr << "error: wrong canonical type for '"
15172 				<< repr
15173 				<< "' / type: @"
15174 				<< std::hex
15175 				<< t.get()
15176 				<< "/ canon: @"
15177 				<< result.get()
15178 				<< ", type-id: '"
15179 				<< type_id
15180 				<< "'.  Should have had canonical type: "
15181 				<< std::hex
15182 				<< should_have_canonical_type
15183 				<< std::endl;
15184 		    }
15185 		}
15186 	      else //!result
15187 		{
15188 		  uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
15189 		  string type_id = env.get_type_id_from_pointer(ptr_val);
15190 		  if (type_id.empty())
15191 		    type_id = "type-id-<not-found>";
15192 		  // We are in the case where 't' is different from all
15193 		  // the canonical types of the same name that come from
15194 		  // the first corpus.
15195 		  //
15196 		  // If 't' indeed comes from the second corpus then this
15197 		  // clearly is a canonicalization failure.
15198 		  //
15199 		  // There was a problem either during the serialization
15200 		  // of 't' into abixml, or during the de-serialization
15201 		  // from abixml into abigail::ir.  Further debugging is
15202 		  // needed to determine what that root cause problem is.
15203 		  //
15204 		  // Note that the first canonicalization problem of this
15205 		  // kind must be fixed before looking at the subsequent
15206 		  // ones, because the later might well just be
15207 		  // consequences of the former.
15208 		  std::cerr << "error: wrong induced canonical type for '"
15209 			    << repr
15210 			    << "' from second corpus"
15211 			    << ", ptr: " << std::hex << t.get()
15212 			    << " type-id: " << type_id
15213 			    << std::endl;
15214 		}
15215 	    }
15216 	}
15217 #endif //WITH_DEBUG_SELF_COMPARISON
15218 
15219       if (!result)
15220 	{
15221 	  v.push_back(t);
15222 	  result = t;
15223 	}
15224     }
15225 
15226   return result;
15227 }
15228 
15229 /// This method is invoked automatically right after the current
15230 /// instance of @ref class_decl has been canonicalized.
15231 void
on_canonical_type_set()15232 type_base::on_canonical_type_set()
15233 {}
15234 
15235 /// This is a subroutine of the canonicalize() function.
15236 ///
15237 /// When the canonical type C of type T has just been computed, there
15238 /// can be cases where T has member functions that C doesn't have.
15239 ///
15240 /// This is possible because non virtual member functions are not
15241 /// taken in account when comparing two types.
15242 ///
15243 /// In that case, this function updates C so that it contains the
15244 /// member functions.
15245 ///
15246 /// There can also be cases where C has a method M which is not linked
15247 /// to any underlying symbol, whereas in T, M is to link to an
15248 /// underlying symbol.  In that case, this function updates M in C so
15249 /// that it's linked to the same underlying symbol as for M in T.
15250 static void
maybe_adjust_canonical_type(const type_base_sptr & canonical,const type_base_sptr & type)15251 maybe_adjust_canonical_type(const type_base_sptr& canonical,
15252 			    const type_base_sptr& type)
15253 {
15254   if (!canonical
15255       // If 'type' is *NOT* a newly canonicalized type ...
15256       || type->get_naked_canonical_type()
15257       // ... or if 'type' is it's own canonical type, then get out.
15258       || type.get() == canonical.get())
15259     return;
15260 
15261   if (class_decl_sptr cl = is_class_type(type))
15262     {
15263       class_decl_sptr canonical_class = is_class_type(canonical);
15264 
15265       if (canonical_class)
15266 	{
15267 	  // Set symbols of member functions that might be missing
15268 	  // theirs.
15269 	  for (class_decl::member_functions::const_iterator i =
15270 		 cl->get_member_functions().begin();
15271 	       i != cl->get_member_functions().end();
15272 	       ++i)
15273 	    if ((*i)->get_symbol())
15274 	      {
15275 		if (method_decl *m = canonical_class->
15276 		    find_member_function((*i)->get_linkage_name()))
15277 		  {
15278 		    elf_symbol_sptr s1 = (*i)->get_symbol();
15279 		    if (s1 && !m->get_symbol())
15280 		      // Method 'm' in the canonical type is not
15281 		      // linked to the underlying symbol of '*i'.
15282 		      // Let's link it now.  have th
15283 		      m->set_symbol(s1);
15284 		  }
15285 		else
15286 		  // There is a member function defined and publicly
15287 		  // exported in the other class, and the canonical
15288 		  // class doesn't have that member function.  Let's
15289 		  // copy that member function to the canonical class
15290 		  // then.
15291 		  {
15292 		    method_decl_sptr method =
15293 		      copy_member_function (canonical_class, *i);
15294 		    canonicalize(method->get_type());
15295 		  }
15296 	      }
15297 	}
15298     }
15299 
15300   // If an artificial function type equals a non-artfificial one in
15301   // the system, then the canonical type of both should be deemed
15302   // non-artificial.  This is important because only non-artificial
15303   // canonical function types are emitted out into abixml, so if don't
15304   // do this we risk missing to emit some function types.
15305   if (is_function_type(type))
15306     if (type->get_is_artificial() != canonical->get_is_artificial())
15307       canonical->set_is_artificial(false);
15308 }
15309 
15310 /// Compute the canonical type of a given type.
15311 ///
15312 /// It means that after invoking this function, comparing the intance
15313 /// instance @ref type_base and another one (on which
15314 /// type_base::enable_canonical_equality() would have been invoked as
15315 /// well) is performed by just comparing the pointer values of the
15316 /// canonical types of both types.  That equality comparison is
15317 /// supposedly faster than structural comparison of the types.
15318 ///
15319 /// @param t a smart pointer to the instance of @ref type_base for
15320 /// which to compute the canonical type.  After this call,
15321 /// t->get_canonical_type() will return the newly computed canonical
15322 /// type.
15323 ///
15324 /// @return the canonical type computed for @p t.
15325 type_base_sptr
canonicalize(type_base_sptr t)15326 canonicalize(type_base_sptr t)
15327 {
15328   if (!t)
15329     return t;
15330 
15331   if (t->get_canonical_type())
15332     return t->get_canonical_type();
15333 
15334   if (t->get_environment().priv_->do_log())
15335     std::cerr << "Canonicalization of type '"
15336 	      << t->get_pretty_representation(true, true)
15337 	      << "/@#" << std::hex << t.get() << ": ";
15338 
15339   tools_utils::timer tmr;
15340 
15341   if (t->get_environment().priv_->do_log())
15342     tmr.start();
15343   type_base_sptr canonical = type_base::get_canonical_type_for(t);
15344 
15345   if (t->get_environment().priv_->do_log())
15346     tmr.stop();
15347 
15348   if (t->get_environment().priv_->do_log())
15349     std::cerr << tmr << "\n";
15350 
15351   maybe_adjust_canonical_type(canonical, t);
15352 
15353   t->priv_->canonical_type = canonical;
15354   t->priv_->naked_canonical_type = canonical.get();
15355 
15356   // So this type is now canonicalized.
15357   //
15358   // It means that:
15359   //
15360   //   1/ Either the canonical type was not propagated during the
15361   //      comparison of another type that was being canonicalized
15362   //
15363   //   2/ Or the canonical type has been propagated during the
15364   //      comparison of another type that was being canonicalized and
15365   //      that propagated canonical type has been confirmed, because
15366   //      it was depending on a recursive type which comparison
15367   //      succeeded.
15368   ABG_ASSERT(!t->priv_->canonical_type_propagated()
15369 	     || t->priv_->propagated_canonical_type_confirmed());
15370 
15371   if (class_decl_sptr cl = is_class_type(t))
15372     if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
15373       if ((canonical = d->get_canonical_type()))
15374 	{
15375 	  d->priv_->canonical_type = canonical;
15376 	  d->priv_->naked_canonical_type = canonical.get();
15377 	}
15378 
15379   if (canonical)
15380     {
15381       if (decl_base_sptr d = is_decl_slow(canonical))
15382 	{
15383 	  scope_decl *scope = d->get_scope();
15384 	  // Add the canonical type to the set of canonical types
15385 	  // belonging to its scope.
15386 	  if (scope)
15387 	    {
15388 	      if (is_type(scope))
15389 		// The scope in question is itself a type (e.g, a class
15390 		// or union).  Let's call that type ST.  We want to add
15391 		// 'canonical' to the set of canonical types belonging
15392 		// to ST.
15393 		if (type_base_sptr c = is_type(scope)->get_canonical_type())
15394 		  // We want to add 'canonical' to set of canonical
15395 		  // types belonging to the canonical type of ST.  That
15396 		  // way, just looking at the canonical type of ST is
15397 		  // enough to get the types that belong to the scope of
15398 		  // the class of equivalence of ST.
15399 		  scope = is_scope_decl(is_decl(c)).get();
15400 	      scope->get_canonical_types().insert(canonical);
15401 	    }
15402 	  // else, if the type doesn't have a scope, it's not meant to be
15403 	  // emitted.  This can be the case for the result of the
15404 	  // function strip_typedef, for instance.
15405 	}
15406 
15407 #ifdef WITH_DEBUG_CT_PROPAGATION
15408       // Update the book-keeping of the set of the types which
15409       // propagated canonical type has been cleared.
15410       //
15411       // If this type 't' which has just been canonicalized was
15412       // previously in the set of types which propagated canonical
15413       // type has been cleared, then remove it from that set because
15414       // its canonical type is now computed and definitely set.
15415       const environment& env = t->get_environment();
15416       env.priv_->erase_type_with_cleared_propagated_canonical_type(t.get());
15417 #endif
15418     }
15419 
15420   t->on_canonical_type_set();
15421   return canonical;
15422 }
15423 
15424 /// Set the definition of this declaration-only @ref decl_base.
15425 ///
15426 /// @param d the new definition to set.
15427 void
set_definition_of_declaration(const decl_base_sptr & d)15428 decl_base::set_definition_of_declaration(const decl_base_sptr& d)
15429 {
15430   ABG_ASSERT(get_is_declaration_only());
15431   priv_->definition_of_declaration_ = d;
15432   if (type_base *t = is_type(this))
15433     if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
15434       t->priv_->canonical_type = canonical_type;
15435 
15436   priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
15437 }
15438 
15439 /// The constructor of @ref type_base.
15440 ///
15441 /// @param s the size of the type, in bits.
15442 ///
15443 /// @param a the alignment of the type, in bits.
type_base(const environment & e,size_t s,size_t a)15444 type_base::type_base(const environment& e, size_t s, size_t a)
15445   : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
15446     priv_(new priv(s, a))
15447 {}
15448 
15449 /// Getter of the canonical type of the current instance of @ref
15450 /// type_base.
15451 ///
15452 /// @return a smart pointer to the canonical type of the current
15453 /// intance of @ref type_base, or an empty smart pointer if the
15454 /// current instance of @ref type_base doesn't have any canonical
15455 /// type.
15456 type_base_sptr
get_canonical_type() const15457 type_base::get_canonical_type() const
15458 {return priv_->canonical_type.lock();}
15459 
15460 /// Getter of the canonical type pointer.
15461 ///
15462 /// Note that this function doesn't return a smart pointer, but rather
15463 /// the underlying pointer managed by the smart pointer.  So it's as
15464 /// fast as possible.  This getter is to be used in code paths that
15465 /// are proven to be performance hot spots; especially, when comparing
15466 /// sensitive types like class, function, pointers and reference
15467 /// types.  Those are compared extremely frequently and thus, their
15468 /// accessing the canonical type must be fast.
15469 ///
15470 /// @return the canonical type pointer, not managed by a smart
15471 /// pointer.
15472 type_base*
get_naked_canonical_type() const15473 type_base::get_naked_canonical_type() const
15474 {return priv_->naked_canonical_type;}
15475 
15476 /// Get the pretty representation of the current type.
15477 ///
15478 /// The pretty representation is retrieved from a cache.  If the cache
15479 /// is empty, this function computes the pretty representation, put it
15480 /// in the cache and returns it.
15481 ///
15482 /// Note that if the type is *NOT* canonicalized, the pretty
15483 /// representation is never cached.
15484 ///
15485 /// @param internal if true, then the pretty representation is to be
15486 /// used for purpuses that are internal to the libabigail library
15487 /// itself.  If you don't know what this means, then you probably
15488 /// should set this parameter to "false".
15489 const interned_string&
get_cached_pretty_representation(bool internal) const15490 type_base::get_cached_pretty_representation(bool internal) const
15491 {
15492   if (internal)
15493     {
15494       if (!get_naked_canonical_type() || priv_->internal_cached_repr_.empty())
15495 	{
15496 	  string r = ir::get_pretty_representation(this, internal);
15497 	  priv_->internal_cached_repr_ = get_environment().intern(r);
15498 	}
15499       return priv_->internal_cached_repr_;
15500     }
15501 
15502   if (!get_naked_canonical_type() || priv_->cached_repr_.empty())
15503     {
15504       string r = ir::get_pretty_representation(this, internal);
15505       priv_->cached_repr_ = get_environment().intern(r);
15506     }
15507 
15508   return priv_->cached_repr_;
15509 }
15510 
15511 /// Compares two instances of @ref type_base.
15512 ///
15513 /// If the two intances are different, set a bitfield to give some
15514 /// insight about the kind of differences there are.
15515 ///
15516 /// @param l the first artifact of the comparison.
15517 ///
15518 /// @param r the second artifact of the comparison.
15519 ///
15520 /// @param k a pointer to a bitfield that gives information about the
15521 /// kind of changes there are between @p l and @p r.  This one is set
15522 /// iff @p is non-null and if the function returns false.
15523 ///
15524 /// Please note that setting k to a non-null value does have a
15525 /// negative performance impact because even if @p l and @p r are not
15526 /// equal, the function keeps up the comparison in order to determine
15527 /// the different kinds of ways in which they are different.
15528 ///
15529 /// @return true if @p l equals @p r, false otherwise.
15530 bool
equals(const type_base & l,const type_base & r,change_kind * k)15531 equals(const type_base& l, const type_base& r, change_kind* k)
15532 {
15533   bool result = (l.get_size_in_bits() == r.get_size_in_bits()
15534 		 && l.get_alignment_in_bits() == r.get_alignment_in_bits());
15535   if (!result)
15536     if (k)
15537       *k |= LOCAL_TYPE_CHANGE_KIND;
15538   ABG_RETURN(result);
15539 }
15540 
15541 /// Return true iff both type declarations are equal.
15542 ///
15543 /// Note that this doesn't test if the scopes of both types are equal.
15544 bool
operator ==(const type_base & other) const15545 type_base::operator==(const type_base& other) const
15546 {return equals(*this, other, 0);}
15547 
15548 /// Inequality operator.
15549 ///
15550 ///@param other the instance of @ref type_base to compare the current
15551 /// instance against.
15552 ///
15553 /// @return true iff the current instance is different from @p other.
15554 bool
operator !=(const type_base & other) const15555 type_base::operator!=(const type_base& other) const
15556 {return !operator==(other);}
15557 
15558 /// Setter for the size of the type.
15559 ///
15560 /// @param s the new size -- in bits.
15561 void
set_size_in_bits(size_t s)15562 type_base::set_size_in_bits(size_t s)
15563 {priv_->size_in_bits = s;}
15564 
15565 /// Getter for the size of the type.
15566 ///
15567 /// @return the size in bits of the type.
15568 size_t
get_size_in_bits() const15569 type_base::get_size_in_bits() const
15570 {return priv_->size_in_bits;}
15571 
15572 /// Setter for the alignment of the type.
15573 ///
15574 /// @param a the new alignment -- in bits.
15575 void
set_alignment_in_bits(size_t a)15576 type_base::set_alignment_in_bits(size_t a)
15577 {priv_->alignment_in_bits = a;}
15578 
15579 /// Getter for the alignment of the type.
15580 ///
15581 /// @return the alignment of the type in bits.
15582 size_t
get_alignment_in_bits() const15583 type_base::get_alignment_in_bits() const
15584 {return priv_->alignment_in_bits;}
15585 
15586 /// Default implementation of traversal for types.  This function does
15587 /// nothing.  It must be implemented by every single new type that is
15588 /// written.
15589 ///
15590 /// Please look at e.g, class_decl::traverse() for an example of how
15591 /// to implement this.
15592 ///
15593 /// @param v the visitor used to visit the type.
15594 bool
traverse(ir_node_visitor & v)15595 type_base::traverse(ir_node_visitor& v)
15596 {
15597   if (v.type_node_has_been_visited(this))
15598     return true;
15599 
15600   v.visit_begin(this);
15601   bool result = v.visit_end(this);
15602   v.mark_type_node_as_visited(this);
15603 
15604   return result;
15605 }
15606 
~type_base()15607 type_base::~type_base()
15608 {delete priv_;}
15609 
15610 // </type_base definitions>
15611 
15612 // <integral_type definitions>
15613 
15614 /// Bitwise OR operator for integral_type::modifiers_type.
15615 ///
15616 /// @param l the left-hand side operand.
15617 ///
15618 /// @param r the right-hand side operand.
15619 ///
15620 /// @return the result of the bitwise OR.
15621 integral_type::modifiers_type
operator |(integral_type::modifiers_type l,integral_type::modifiers_type r)15622 operator|(integral_type::modifiers_type l, integral_type::modifiers_type r)
15623 {
15624   return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
15625 						    |
15626 						    static_cast<unsigned>(r));
15627 }
15628 
15629 /// Bitwise AND operator for integral_type::modifiers_type.
15630 ///
15631 /// @param l the left-hand side operand.
15632 ///
15633 /// @param r the right-hand side operand.
15634 ///
15635 /// @return the result of the bitwise AND.
15636 integral_type::modifiers_type
operator &(integral_type::modifiers_type l,integral_type::modifiers_type r)15637 operator&(integral_type::modifiers_type l, integral_type::modifiers_type r)
15638 {
15639   return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
15640 						    &
15641 						    static_cast<unsigned>(r));
15642 }
15643 
15644 /// Bitwise one's complement operator for integral_type::modifiers_type.
15645 ///
15646 /// @param l the left-hand side operand.
15647 ///
15648 /// @param r the right-hand side operand.
15649 ///
15650 /// @return the result of the bitwise one's complement operator.
15651 integral_type::modifiers_type
operator ~(integral_type::modifiers_type l)15652 operator~(integral_type::modifiers_type l)
15653 {
15654   return static_cast<integral_type::modifiers_type>(~static_cast<unsigned>(l));
15655 }
15656 
15657 /// Bitwise |= operator for integral_type::modifiers_type.
15658 ///
15659 /// @param l the left-hand side operand.
15660 ///
15661 /// @param r the right-hand side operand.
15662 ///
15663 /// @return the result of the bitwise |=.
15664 integral_type::modifiers_type&
operator |=(integral_type::modifiers_type & l,integral_type::modifiers_type r)15665 operator|=(integral_type::modifiers_type& l, integral_type::modifiers_type r)
15666 {
15667   l = l | r;
15668   return l;
15669 }
15670 
15671 /// Bitwise &= operator for integral_type::modifiers_type.
15672 ///
15673 /// @param l the left-hand side operand.
15674 ///
15675 /// @param r the right-hand side operand.
15676 ///
15677 /// @return the result of the bitwise &=.
15678 integral_type::modifiers_type&
operator &=(integral_type::modifiers_type & l,integral_type::modifiers_type r)15679 operator&=(integral_type::modifiers_type& l, integral_type::modifiers_type r)
15680 {
15681   l = l & r;
15682   return l;
15683 }
15684 
15685 /// Parse a word containing one integral type modifier.
15686 ///
15687 /// A word is considered to be a string of characters that doesn't
15688 /// contain any white space.
15689 ///
15690 /// @param word the word to parse.  It is considered to be a string of
15691 /// characters that doesn't contain any white space.
15692 ///
15693 /// @param modifiers out parameter.  It's set by this function to the
15694 /// parsed modifier iff the function returned true.
15695 ///
15696 /// @return true iff @word was successfully parsed.
15697 static bool
parse_integral_type_modifier(const string & word,integral_type::modifiers_type & modifiers)15698 parse_integral_type_modifier(const string& word,
15699 			     integral_type::modifiers_type &modifiers)
15700 {
15701     if (word == "signed")
15702       modifiers |= integral_type::SIGNED_MODIFIER;
15703     else if (word == "unsigned")
15704       modifiers |= integral_type::UNSIGNED_MODIFIER;
15705     else if (word == "short")
15706       modifiers |= integral_type::SHORT_MODIFIER;
15707     else if (word == "long")
15708       modifiers |= integral_type::LONG_MODIFIER;
15709     else if (word == "long long")
15710       modifiers |= integral_type::LONG_LONG_MODIFIER;
15711     else
15712       return false;
15713 
15714     return true;
15715 }
15716 
15717 /// Parse a base type of an integral type from a string.
15718 ///
15719 /// @param type_name the type name to parse.
15720 ///
15721 /// @param base out parameter.  This is set to the resulting base type
15722 /// parsed, iff the function returned true.
15723 ///
15724 /// @return true iff the function could successfully parse the base
15725 /// type.
15726 static bool
parse_base_integral_type(const string & type_name,integral_type::base_type & base)15727 parse_base_integral_type(const string& type_name,
15728 			 integral_type::base_type& base)
15729 {
15730   if (type_name == "int")
15731     base = integral_type::INT_BASE_TYPE;
15732   else if (type_name == "char")
15733     base = integral_type::CHAR_BASE_TYPE;
15734   else if (type_name == "bool" || type_name == "_Bool")
15735     base = integral_type::BOOL_BASE_TYPE;
15736   else if (type_name == "double")
15737     base = integral_type::DOUBLE_BASE_TYPE;
15738   else if (type_name =="float")
15739     base = integral_type::FLOAT_BASE_TYPE;
15740   else if (type_name == "char16_t")
15741     base = integral_type::CHAR16_T_BASE_TYPE;
15742   else if (type_name == "char32_t")
15743     base = integral_type::CHAR32_T_BASE_TYPE;
15744   else if (type_name == "wchar_t")
15745     base = integral_type::WCHAR_T_BASE_TYPE;
15746   else
15747     return false;
15748 
15749   return true;
15750 }
15751 
15752 /// Parse an integral type from a string.
15753 ///
15754 /// @param type_name the string containing the integral type to parse.
15755 ///
15756 /// @param base out parameter.  Is set by this function to the base
15757 /// type of the integral type, iff the function returned true.
15758 ///
15759 /// @param modifiers out parameter  If set by this function to the
15760 /// modifier of the integral type, iff the function returned true.
15761 ///
15762 /// @return true iff the function could parse an integral type from @p
15763 /// type_name.
15764 static bool
parse_integral_type(const string & type_name,integral_type::base_type & base,integral_type::modifiers_type & modifiers)15765 parse_integral_type(const string&			type_name,
15766 		    integral_type::base_type&		base,
15767 		    integral_type::modifiers_type&	modifiers)
15768 {
15769   string input = type_name;
15770   string::size_type len = input.length();
15771   string::size_type cur_pos = 0, prev_pos = 0;
15772   string cur_word, prev_word;
15773   bool ok = false;
15774 
15775   while (cur_pos < len)
15776     {
15777       if (cur_pos < len && isspace(input[cur_pos]))
15778 	do
15779 	  ++cur_pos;
15780 	while (cur_pos < len && isspace(input[cur_pos]));
15781 
15782       prev_pos = cur_pos;
15783       cur_pos = input.find(' ', prev_pos);
15784       prev_word = cur_word;
15785       cur_word = input.substr(prev_pos, cur_pos - prev_pos);
15786 
15787       if (cur_pos < len
15788 	  && cur_word == "long"
15789 	  && prev_word != "long")
15790 	{
15791 	  if (cur_pos < len && isspace(input[cur_pos]))
15792 	    do
15793 	      ++cur_pos;
15794 	    while (cur_pos < len && isspace(input[cur_pos]));
15795 	  prev_pos = cur_pos;
15796 
15797 	  cur_pos = input.find(' ', prev_pos);
15798 	  string saved_prev_word = prev_word;
15799 	  prev_word = cur_word;
15800 	  cur_word = input.substr(prev_pos, cur_pos - prev_pos);
15801 	  if (cur_word == "long")
15802 	    cur_word = "long long";
15803 	  else
15804 	    {
15805 	      cur_pos = prev_pos;
15806 	      cur_word = prev_word;
15807 	      prev_word = saved_prev_word;
15808 	    }
15809 	}
15810 
15811       if (!parse_integral_type_modifier(cur_word, modifiers))
15812 	{
15813 	  if (!parse_base_integral_type(cur_word, base))
15814 	    return false;
15815 	  else
15816 	    ok = true;
15817 	}
15818       else
15819 	ok = true;
15820     }
15821 
15822   return ok;
15823 }
15824 
15825 /// Parse an integral type from a string.
15826 ///
15827 /// @param str the string containing the integral type to parse.
15828 ///
15829 ///@param type the resulting @ref integral_type.  Is set to the result
15830 ///of the parse, iff the function returns true.
15831 ///
15832 /// @return true iff the function could parse an integral type from @p
15833 /// str.
15834 bool
parse_integral_type(const string & str,integral_type & type)15835 parse_integral_type(const string& str, integral_type& type)
15836 {
15837   integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
15838   integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
15839 
15840   if (!parse_integral_type(str, base_type, modifiers))
15841     return false;
15842 
15843   // So this is an integral type.
15844   integral_type int_type(base_type, modifiers);
15845   type = int_type;
15846   return true;
15847 }
15848 
15849 /// Default constructor of the @ref integral_type.
integral_type()15850 integral_type::integral_type()
15851   : base_(INT_BASE_TYPE),
15852     modifiers_(NO_MODIFIER)
15853 {}
15854 
15855 /// Constructor of the @ref integral_type.
15856 ///
15857 /// @param b the base type of the integral type.
15858 ///
15859 /// @param m the modifiers of the integral type.
integral_type(base_type b,modifiers_type m)15860 integral_type::integral_type(base_type b, modifiers_type m)
15861   : base_(b), modifiers_(m)
15862 {}
15863 
15864 /// Constructor of the @ref integral_type.
15865 ///
15866 /// @param the name of the integral type to parse to initialize the
15867 /// current instance of @ref integral_type.
integral_type(const string & type_name)15868 integral_type::integral_type(const string& type_name)
15869   : base_(INT_BASE_TYPE),
15870     modifiers_(NO_MODIFIER)
15871 {
15872   bool could_parse = parse_integral_type(type_name, base_, modifiers_);
15873   ABG_ASSERT(could_parse);
15874 }
15875 
15876 /// Getter of the base type of the @ref integral_type.
15877 ///
15878 /// @return the base type of the @ref integral_type.
15879 integral_type::base_type
get_base_type() const15880 integral_type::get_base_type() const
15881 {return base_;}
15882 
15883 /// Getter of the modifiers bitmap of the @ref integral_type.
15884 ///
15885 /// @return the modifiers bitmap of the @ref integral_type.
15886 integral_type::modifiers_type
get_modifiers() const15887 integral_type::get_modifiers() const
15888 {return modifiers_;}
15889 
15890 /// Setter of the modifiers bitmap of the @ref integral_type.
15891 ///
15892 /// @param m the new modifiers.
15893 void
set_modifiers(modifiers_type m)15894 integral_type::set_modifiers(modifiers_type m)
15895 {modifiers_ = m;}
15896 
15897 /// Equality operator for the @ref integral_type.
15898 ///
15899 /// @param other the other integral type to compare against.
15900 ///
15901 /// @return true iff @p other equals the current instance of @ref
15902 /// integral_type.
15903 bool
operator ==(const integral_type & other) const15904 integral_type::operator==(const integral_type&other) const
15905 {return base_ == other.base_ && modifiers_ == other.modifiers_;}
15906 
15907 /// Return the string representation of the current instance of @ref
15908 /// integral_type.
15909 ///
15910 /// @param internal if true the string representation is to be used
15911 /// for internal purposes.  In general, it means it's for type
15912 /// canonicalization purposes.
15913 ///
15914 /// @return the string representation of the current instance of @ref
15915 /// integral_type.
15916 string
to_string(bool internal) const15917 integral_type::to_string(bool internal) const
15918 {
15919   string result;
15920 
15921   // Look at modifiers ...
15922   if (modifiers_ & SIGNED_MODIFIER)
15923     result += "signed ";
15924   if (modifiers_ & UNSIGNED_MODIFIER)
15925     result += "unsigned ";
15926   if (!internal)
15927     {
15928       // For canonicalization purposes, we won't emit the "short, long, or
15929       // long long" modifiers.  This is because on some platforms, "long
15930       // int" and "long long int" might have the same size.  In those
15931       // cases, we want the two types to be equivalent if they have the
15932       // same size.  If they don't have the same internal string
15933       // representation, they'd automatically have different canonical
15934       // types and thus be canonically different.
15935       if (modifiers_ & SHORT_MODIFIER)
15936 	result += "short ";
15937       if (modifiers_ & LONG_MODIFIER)
15938 	result += "long ";
15939       if (modifiers_ & LONG_LONG_MODIFIER)
15940 	result += "long long ";
15941     }
15942 
15943   // ... and look at base types.
15944   if (base_ == INT_BASE_TYPE)
15945     result += "int";
15946   else if (base_ == CHAR_BASE_TYPE)
15947     result += "char";
15948   else if (base_ == BOOL_BASE_TYPE)
15949     result += "bool";
15950   else if (base_ == DOUBLE_BASE_TYPE)
15951     result += "double";
15952   else if (base_ == FLOAT_BASE_TYPE)
15953     result += "float";
15954   else if (base_ == CHAR16_T_BASE_TYPE)
15955     result += "char16_t";
15956     else if (base_ == CHAR32_T_BASE_TYPE)
15957     result += "char32_t";
15958     else if (base_ == WCHAR_T_BASE_TYPE)
15959     result += "wchar_t";
15960 
15961   return result;
15962 }
15963 
15964 /// Convert the current instance of @ref integral_type into its string
15965 /// representation.
15966 ///
15967 /// @return the string representation of the current instance of @ref
15968 /// integral_type.
operator string() const15969 integral_type::operator string() const
15970 {return to_string();}
15971 
15972 // </integral_type definitions>
15973 
15974 //<type_decl definitions>
15975 
15976 /// Constructor.
15977 ///
15978 /// @param env the environment we are operating from.
15979 ///
15980 /// @param name the name of the type declaration.
15981 ///
15982 /// @param size_in_bits the size of the current type_decl, in bits.
15983 ///
15984 /// @param alignment_in_bits the alignment of the current typ, in
15985 /// bits.
15986 ///
15987 /// @param locus the source location of the current type declaration.
15988 ///
15989 /// @param linkage_name the linkage_name of the current type declaration.
15990 ///
15991 /// @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)15992 type_decl::type_decl(const environment& env,
15993 		     const string&	name,
15994 		     size_t		size_in_bits,
15995 		     size_t		alignment_in_bits,
15996 		     const location&	locus,
15997 		     const string&	linkage_name,
15998 		     visibility	vis)
15999 
16000   : type_or_decl_base(env,
16001 		      BASIC_TYPE
16002 		      | ABSTRACT_TYPE_BASE
16003 		      | ABSTRACT_DECL_BASE),
16004     decl_base(env, name, locus, linkage_name, vis),
16005     type_base(env, size_in_bits, alignment_in_bits)
16006 {
16007   runtime_type_instance(this);
16008 
16009   integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
16010   integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
16011   integral_type int_type(base_type, modifiers);
16012   if (parse_integral_type(name, int_type))
16013     {
16014       // Convert the integral_type into its canonical string
16015       // representation.
16016       string integral_type_name = int_type;
16017 
16018       // Set the name of this type_decl to the canonical string
16019       // representation above
16020       set_name(integral_type_name);
16021       set_qualified_name(get_name());
16022 
16023       if (!get_linkage_name().empty())
16024 	set_linkage_name(integral_type_name);
16025     }
16026 }
16027 
16028 /// Compares two instances of @ref type_decl.
16029 ///
16030 /// If the two intances are different, set a bitfield to give some
16031 /// insight about the kind of differences there are.
16032 ///
16033 /// @param l the first artifact of the comparison.
16034 ///
16035 /// @param r the second artifact of the comparison.
16036 ///
16037 /// @param k a pointer to a bitfield that gives information about the
16038 /// kind of changes there are between @p l and @p r.  This one is set
16039 /// iff @p k is non-null and the function returns false.
16040 ///
16041 /// Please note that setting k to a non-null value does have a
16042 /// negative performance impact because even if @p l and @p r are not
16043 /// equal, the function keeps up the comparison in order to determine
16044 /// the different kinds of ways in which they are different.
16045 ///
16046 /// @return true if @p l equals @p r, false otherwise.
16047 bool
equals(const type_decl & l,const type_decl & r,change_kind * k)16048 equals(const type_decl& l, const type_decl& r, change_kind* k)
16049 {
16050   bool result = false;
16051 
16052   // Consider the types as decls to compare their decls-related
16053   // properties.
16054   result = equals(static_cast<const decl_base&>(l),
16055 		  static_cast<const decl_base&>(r),
16056 		  k);
16057   if (!k && !result)
16058     ABG_RETURN_FALSE;
16059 
16060   // Now consider the types a "types' to compare their size-related
16061   // properties.
16062   result &= equals(static_cast<const type_base&>(l),
16063 		   static_cast<const type_base&>(r),
16064 		   k);
16065   ABG_RETURN(result);
16066 }
16067 
16068 /// Return true if both types equals.
16069 ///
16070 /// This operator re-uses the overload that takes a decl_base.
16071 ///
16072 /// Note that this does not check the scopes of any of the types.
16073 ///
16074 /// @param o the other type_decl to check agains.
16075 bool
operator ==(const type_base & o) const16076 type_decl::operator==(const type_base& o) const
16077 {
16078   const decl_base* other = dynamic_cast<const decl_base*>(&o);
16079   if (!other)
16080     return false;
16081   return *this == *other;
16082 }
16083 
16084 /// Return true if both types equals.
16085 ///
16086 /// Note that this does not check the scopes of any of the types.
16087 ///
16088 /// @param o the other type_decl to check against.
16089 bool
operator ==(const decl_base & o) const16090 type_decl::operator==(const decl_base& o) const
16091 {
16092   const type_decl* other = dynamic_cast<const type_decl*>(&o);
16093   if (!other)
16094     return false;
16095   return try_canonical_compare(this, other);
16096 }
16097 
16098 /// Return true if both types equals.
16099 ///
16100 /// Note that this does not check the scopes of any of the types.
16101 ///
16102 /// @param o the other type_decl to check against.
16103 ///
16104 /// @return true iff the current isntance equals @p o
16105 bool
operator ==(const type_decl & o) const16106 type_decl::operator==(const type_decl& o) const
16107 {
16108   const decl_base& other = o;
16109   return *this == other;
16110 }
16111 
16112 /// Return true if both types equals.
16113 ///
16114 /// Note that this does not check the scopes of any of the types.
16115 ///
16116 /// @param o the other type_decl to check against.
16117 ///
16118 /// @return true iff the current isntance equals @p o
16119 bool
operator !=(const type_base & o) const16120 type_decl::operator!=(const type_base&o)const
16121 {return !operator==(o);}
16122 
16123 /// Return true if both types equals.
16124 ///
16125 /// Note that this does not check the scopes of any of the types.
16126 ///
16127 /// @param o the other type_decl to check against.
16128 ///
16129 /// @return true iff the current isntance equals @p o
16130 bool
operator !=(const decl_base & o) const16131 type_decl::operator!=(const decl_base&o)const
16132 {return !operator==(o);}
16133 
16134 /// Inequality operator.
16135 ///
16136 /// @param o the other type to compare against.
16137 ///
16138 /// @return true iff the current instance is different from @p o.
16139 bool
operator !=(const type_decl & o) const16140 type_decl::operator!=(const type_decl& o) const
16141 {return !operator==(o);}
16142 
16143 /// Equality operator for @ref type_decl_sptr.
16144 ///
16145 /// @param l the first operand to compare.
16146 ///
16147 /// @param r the second operand to compare.
16148 ///
16149 /// @return true iff @p l equals @p r.
16150 bool
operator ==(const type_decl_sptr & l,const type_decl_sptr & r)16151 operator==(const type_decl_sptr& l, const type_decl_sptr& r)
16152 {
16153   if (!!l != !!r)
16154     return false;
16155   if (l.get() == r.get())
16156     return true;
16157   return *l == *r;
16158 }
16159 
16160 /// Inequality operator for @ref type_decl_sptr.
16161 ///
16162 /// @param l the first operand to compare.
16163 ///
16164 /// @param r the second operand to compare.
16165 ///
16166 /// @return true iff @p l is different from @p r.
16167 bool
operator !=(const type_decl_sptr & l,const type_decl_sptr & r)16168 operator!=(const type_decl_sptr& l, const type_decl_sptr& r)
16169 {return !operator==(l, r);}
16170 
16171 /// Implementation for the virtual qualified name builder for @ref
16172 /// type_decl.
16173 ///
16174 /// @param qualified_name the output parameter to hold the resulting
16175 /// qualified name.
16176 ///
16177 /// @param internal set to true if the call is intended for an
16178 /// internal use (for technical use inside the library itself), false
16179 /// otherwise.  If you don't know what this is for, then set it to
16180 /// false.
16181 void
get_qualified_name(interned_string & qualified_name,bool internal) const16182 type_decl::get_qualified_name(interned_string& qualified_name,
16183 			      bool internal) const
16184 {qualified_name = get_qualified_name(internal);}
16185 
16186 /// Implementation for the virtual qualified name builder for @ref
16187 /// type_decl.
16188 ///
16189 /// @param qualified_name the output parameter to hold the resulting
16190 /// qualified name.
16191 ///
16192 /// @param internal set to true if the call is intended for an
16193 /// internal use (for technical use inside the library itself), false
16194 /// otherwise.  If you don't know what this is for, then set it to
16195 /// false.
16196 const interned_string&
get_qualified_name(bool internal) const16197 type_decl::get_qualified_name(bool internal) const
16198 {
16199   const environment& env = get_environment();
16200 
16201 
16202   if (internal)
16203     if (is_integral_type(this))
16204       {
16205 	if (get_naked_canonical_type())
16206 	  {
16207 	    if (decl_base::priv_->internal_qualified_name_.empty())
16208 	      decl_base::priv_->internal_qualified_name_ =
16209 		env.intern(get_internal_integral_type_name(this));
16210 	    return decl_base::priv_->internal_qualified_name_;
16211 	  }
16212 	else
16213 	  {
16214 	    decl_base::priv_->temporary_internal_qualified_name_ =
16215 	      env.intern(get_internal_integral_type_name(this));
16216 	    return decl_base::priv_->temporary_internal_qualified_name_;
16217 	  }
16218       }
16219 
16220   return decl_base::get_qualified_name(/*internal=*/false);
16221 }
16222 
16223 /// Get the pretty representation of the current instance of @ref
16224 /// type_decl.
16225 ///
16226 /// @param internal set to true if the call is intended to get a
16227 /// representation of the decl (or type) for the purpose of canonical
16228 /// type comparison.  This is mainly used in the function
16229 /// type_base::get_canonical_type_for().
16230 ///
16231 /// In other words if the argument for this parameter is true then the
16232 /// call is meant for internal use (for technical use inside the
16233 /// library itself), false otherwise.  If you don't know what this is
16234 /// for, then set it to false.
16235 ///
16236 /// @param qualified_name if true, names emitted in the pretty
16237 /// representation are fully qualified.
16238 ///
16239 /// @return the pretty representatin of the @ref type_decl.
16240 string
get_pretty_representation(bool internal,bool qualified_name) const16241 type_decl::get_pretty_representation(bool internal,
16242 				     bool qualified_name) const
16243 {
16244   if (internal)
16245     if (is_integral_type(this))
16246       return get_internal_integral_type_name(this);
16247 
16248   if (qualified_name)
16249     return get_qualified_name(internal);
16250   return get_name();
16251 }
16252 
16253 /// This implements the ir_traversable_base::traverse pure virtual
16254 /// function.
16255 ///
16256 /// @param v the visitor used on the current instance.
16257 ///
16258 /// @return true if the entire IR node tree got traversed, false
16259 /// otherwise.
16260 bool
traverse(ir_node_visitor & v)16261 type_decl::traverse(ir_node_visitor& v)
16262 {
16263   if (v.type_node_has_been_visited(this))
16264     return true;
16265 
16266   v.visit_begin(this);
16267   bool result = v.visit_end(this);
16268   v.mark_type_node_as_visited(this);
16269 
16270   return result;
16271 }
16272 
~type_decl()16273 type_decl::~type_decl()
16274 {}
16275 //</type_decl definitions>
16276 
16277 // <scope_type_decl definitions>
16278 
16279 /// Constructor.
16280 ///
16281 /// @param env the environment we are operating from.
16282 ///
16283 /// @param name the name of the type.
16284 ///
16285 /// @param size_in_bits the size of the type, in bits.
16286 ///
16287 /// @param alignment_in_bits the alignment of the type, in bits.
16288 ///
16289 /// @param locus the source location where the type is defined.
16290 ///
16291 /// @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)16292 scope_type_decl::scope_type_decl(const environment&	env,
16293 				 const string&		name,
16294 				 size_t		size_in_bits,
16295 				 size_t		alignment_in_bits,
16296 				 const location&	locus,
16297 				 visibility		vis)
16298   : type_or_decl_base(env,
16299 		      ABSTRACT_SCOPE_TYPE_DECL
16300 		      | ABSTRACT_TYPE_BASE
16301 		      | ABSTRACT_DECL_BASE),
16302     decl_base(env, name, locus, "", vis),
16303     type_base(env, size_in_bits, alignment_in_bits),
16304     scope_decl(env, name, locus)
16305 {}
16306 
16307 /// Compares two instances of @ref scope_type_decl.
16308 ///
16309 /// If the two intances are different, set a bitfield to give some
16310 /// insight about the kind of differences there are.
16311 ///
16312 /// @param l the first artifact of the comparison.
16313 ///
16314 /// @param r the second artifact of the comparison.
16315 ///
16316 /// @param k a pointer to a bitfield that gives information about the
16317 /// kind of changes there are between @p l and @p r.  This one is set
16318 /// iff @p k is non-null and the function returns false.
16319 ///
16320 /// Please note that setting k to a non-null value does have a
16321 /// negative performance impact because even if @p l and @p r are not
16322 /// equal, the function keeps up the comparison in order to determine
16323 /// the different kinds of ways in which they are different.
16324 ///
16325 /// @return true if @p l equals @p r, false otherwise.
16326 bool
equals(const scope_type_decl & l,const scope_type_decl & r,change_kind * k)16327 equals(const scope_type_decl& l, const scope_type_decl& r, change_kind* k)
16328 {
16329   bool result = equals(static_cast<const scope_decl&>(l),
16330 		  static_cast<const scope_decl&>(r),
16331 		  k);
16332 
16333   if (!k && !result)
16334     ABG_RETURN_FALSE;
16335 
16336   result &= equals(static_cast<const type_base&>(l),
16337 		   static_cast<const type_base&>(r),
16338 		   k);
16339 
16340   ABG_RETURN(result);
16341 }
16342 
16343 /// Equality operator between two scope_type_decl.
16344 ///
16345 /// Note that this function does not consider the scope of the scope
16346 /// types themselves.
16347 ///
16348 /// @return true iff both scope types are equal.
16349 bool
operator ==(const decl_base & o) const16350 scope_type_decl::operator==(const decl_base& o) const
16351 {
16352   const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
16353   if (!other)
16354     return false;
16355   return try_canonical_compare(this, other);
16356 }
16357 
16358 /// Equality operator between two scope_type_decl.
16359 ///
16360 /// This re-uses the equality operator that takes a decl_base.
16361 ///
16362 /// @param o the other scope_type_decl to compare against.
16363 ///
16364 /// @return true iff both scope types are equal.
16365 bool
operator ==(const type_base & o) const16366 scope_type_decl::operator==(const type_base& o) const
16367 {
16368   const decl_base* other = dynamic_cast<const decl_base*>(&o);
16369   if (!other)
16370     return false;
16371 
16372   return *this == *other;
16373 }
16374 
16375 /// Traverses an instance of @ref scope_type_decl, visiting all the
16376 /// sub-types and decls that it might contain.
16377 ///
16378 /// @param v the visitor that is used to visit every IR sub-node of
16379 /// the current node.
16380 ///
16381 /// @return true if either
16382 ///  - all the children nodes of the current IR node were traversed
16383 ///    and the calling code should keep going with the traversing.
16384 ///  - or the current IR node is already being traversed.
16385 /// Otherwise, returning false means that the calling code should not
16386 /// keep traversing the tree.
16387 bool
traverse(ir_node_visitor & v)16388 scope_type_decl::traverse(ir_node_visitor& v)
16389 {
16390   if (visiting())
16391     return true;
16392 
16393   if (v.type_node_has_been_visited(this))
16394     return true;
16395 
16396   if (v.visit_begin(this))
16397     {
16398       visiting(true);
16399       for (scope_decl::declarations::const_iterator i =
16400 	     get_member_decls().begin();
16401 	   i != get_member_decls ().end();
16402 	   ++i)
16403 	if (!(*i)->traverse(v))
16404 	  break;
16405       visiting(false);
16406     }
16407 
16408   bool result = v.visit_end(this);
16409   v.mark_type_node_as_visited(this);
16410 
16411   return result;
16412 }
16413 
~scope_type_decl()16414 scope_type_decl::~scope_type_decl()
16415 {}
16416 // </scope_type_decl definitions>
16417 
16418 // <namespace_decl>
16419 
16420 /// Constructor.
16421 ///
16422 /// @param the environment we are operatin from.
16423 ///
16424 /// @param name the name of the namespace.
16425 ///
16426 /// @param locus the source location where the namespace is defined.
16427 ///
16428 /// @param vis the visibility of the namespace.
namespace_decl(const environment & env,const string & name,const location & locus,visibility vis)16429 namespace_decl::namespace_decl(const environment&	env,
16430 			       const string&		name,
16431 			       const location&		locus,
16432 			       visibility		vis)
16433     // We need to call the constructor of decl_base directly here
16434     // because it is virtually inherited by scope_decl.  Note that we
16435     // just implicitely call the default constructor for scope_decl
16436     // here, as what we really want is to initialize the decl_base
16437     // subobject.  Wow, virtual inheritance is		useful, but setting it
16438     // up is ugly.
16439   : type_or_decl_base(env,
16440 		      NAMESPACE_DECL
16441 		      | ABSTRACT_DECL_BASE
16442 		      | ABSTRACT_SCOPE_DECL),
16443     decl_base(env, name, locus, "", vis),
16444     scope_decl(env, name, locus)
16445 {
16446   runtime_type_instance(this);
16447 }
16448 
16449 /// Build and return a copy of the pretty representation of the
16450 /// namespace.
16451 ///
16452 /// @param internal set to true if the call is intended to get a
16453 /// representation of the decl (or type) for the purpose of canonical
16454 /// type comparison.  This is mainly used in the function
16455 /// type_base::get_canonical_type_for().
16456 ///
16457 /// In other words if the argument for this parameter is true then the
16458 /// call is meant for internal use (for technical use inside the
16459 /// library itself), false otherwise.  If you don't know what this is
16460 /// for, then set it to false.
16461 ///
16462 /// @param qualified_name if true, names emitted in the pretty
16463 /// representation are fully qualified.
16464 ///
16465 /// @return a copy of the pretty representation of the namespace.
16466 string
get_pretty_representation(bool internal,bool qualified_name) const16467 namespace_decl::get_pretty_representation(bool internal,
16468 					  bool qualified_name) const
16469 {
16470   string r =
16471     "namespace " + scope_decl::get_pretty_representation(internal,
16472 							 qualified_name);
16473   return r;
16474 }
16475 
16476 /// Return true iff both namespaces and their members are equal.
16477 ///
16478 /// Note that this function does not check if the scope of these
16479 /// namespaces are equal.
16480 bool
operator ==(const decl_base & o) const16481 namespace_decl::operator==(const decl_base& o) const
16482 {
16483   const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
16484   if (!other)
16485     return false;
16486   return scope_decl::operator==(*other);
16487 }
16488 
16489 /// Test if the current namespace_decl is empty or contains empty
16490 /// namespaces itself.
16491 ///
16492 /// @return true iff the current namespace_decl is empty or contains
16493 /// empty itself.
16494 bool
is_empty_or_has_empty_sub_namespaces() const16495 namespace_decl::is_empty_or_has_empty_sub_namespaces() const
16496 {
16497   if (is_empty())
16498     return true;
16499 
16500   for (declarations::const_iterator i = get_member_decls().begin();
16501        i != get_member_decls().end();
16502        ++i)
16503     {
16504       if (!is_namespace(*i))
16505 	return false;
16506 
16507       namespace_decl_sptr ns = is_namespace(*i);
16508       ABG_ASSERT(ns);
16509 
16510       if (!ns->is_empty_or_has_empty_sub_namespaces())
16511 	return false;
16512     }
16513 
16514   return true;
16515 }
16516 
16517 /// This implements the ir_traversable_base::traverse pure virtual
16518 /// function.
16519 ///
16520 /// @param v the visitor used on the current instance and on its
16521 /// member nodes.
16522 ///
16523 /// @return true if the entire IR node tree got traversed, false
16524 /// otherwise.
16525 bool
traverse(ir_node_visitor & v)16526 namespace_decl::traverse(ir_node_visitor& v)
16527 {
16528   if (visiting())
16529     return true;
16530 
16531   if (v.visit_begin(this))
16532     {
16533       visiting(true);
16534       scope_decl::declarations::const_iterator i;
16535       for (i = get_member_decls().begin();
16536 	   i != get_member_decls ().end();
16537 	   ++i)
16538 	{
16539 	  ir_traversable_base_sptr t =
16540 	    dynamic_pointer_cast<ir_traversable_base>(*i);
16541 	  if (t)
16542 	    if (!t->traverse (v))
16543 	      break;
16544 	}
16545       visiting(false);
16546     }
16547   return v.visit_end(this);
16548 }
16549 
~namespace_decl()16550 namespace_decl::~namespace_decl()
16551 {
16552 }
16553 
16554 // </namespace_decl>
16555 
16556 // <qualified_type_def>
16557 
16558 /// Type of the private data of qualified_type_def.
16559 class qualified_type_def::priv
16560 {
16561   friend class qualified_type_def;
16562 
16563   qualified_type_def::CV	cv_quals_;
16564   // Before the type is canonicalized, this is used as a temporary
16565   // internal name.
16566   interned_string		temporary_internal_name_;
16567   // Once the type is canonicalized, this is used as the internal
16568   // name.
16569   interned_string		internal_name_;
16570   weak_ptr<type_base>		underlying_type_;
16571 
priv()16572   priv()
16573     : cv_quals_(CV_NONE)
16574   {}
16575 
priv(qualified_type_def::CV quals,type_base_sptr t)16576   priv(qualified_type_def::CV quals,
16577        type_base_sptr t)
16578     : cv_quals_(quals),
16579       underlying_type_(t)
16580   {}
16581 
priv(qualified_type_def::CV quals)16582     priv(qualified_type_def::CV quals)
16583     : cv_quals_(quals)
16584   {}
16585 };// end class qualified_type_def::priv
16586 
16587 /// Build the name of the current instance of qualified type.
16588 ///
16589 /// @param fully_qualified if true, build a fully qualified name.
16590 ///
16591 /// @param internal set to true if the call is intended for an
16592 /// internal use (for technical use inside the library itself), false
16593 /// otherwise.  If you don't know what this is for, then set it to
16594 /// false.
16595 ///
16596 /// @return a copy of the newly-built name.
16597 string
build_name(bool fully_qualified,bool internal) const16598 qualified_type_def::build_name(bool fully_qualified, bool internal) const
16599 {
16600   type_base_sptr t = get_underlying_type();
16601   if (!t)
16602     // The qualified type might temporarily have no underlying type,
16603     // especially during the construction of the type, while the
16604     // underlying type is not yet constructed.  In that case, let's do
16605     // like if the underlying type is the 'void' type.
16606     t = get_environment().get_void_type();
16607 
16608   return get_name_of_qualified_type(t, get_cv_quals(),
16609 				    fully_qualified,
16610 				    internal);
16611 }
16612 
16613 /// This function is automatically invoked whenever an instance of
16614 /// this type is canonicalized.
16615 ///
16616 /// It's an overload of the virtual type_base::on_canonical_type_set.
16617 ///
16618 /// We put here what is thus meant to be executed only at the point of
16619 /// type canonicalization.
16620 void
on_canonical_type_set()16621 qualified_type_def::on_canonical_type_set()
16622 {clear_qualified_name();}
16623 
16624 /// Constructor of the qualified_type_def
16625 ///
16626 /// @param type the underlying type
16627 ///
16628 /// @param quals a bitfield representing the const/volatile qualifiers
16629 ///
16630 /// @param locus the location of the qualified type definition
qualified_type_def(type_base_sptr type,CV quals,const location & locus)16631 qualified_type_def::qualified_type_def(type_base_sptr		type,
16632 				       CV			quals,
16633 				       const location&		locus)
16634   : type_or_decl_base(type->get_environment(),
16635 		      QUALIFIED_TYPE
16636 		      | ABSTRACT_TYPE_BASE
16637 		      | ABSTRACT_DECL_BASE),
16638     type_base(type->get_environment(), type->get_size_in_bits(),
16639 	      type->get_alignment_in_bits()),
16640     decl_base(type->get_environment(), "", locus, "",
16641 	      dynamic_pointer_cast<decl_base>(type)->get_visibility()),
16642     priv_(new priv(quals, type))
16643 {
16644   runtime_type_instance(this);
16645   interned_string name = type->get_environment().intern(build_name(false));
16646   set_name(name);
16647 }
16648 
16649 /// Constructor of the qualified_type_def
16650 ///
16651 /// @param env the environment of the type.
16652 ///
16653 /// @param quals a bitfield representing the const/volatile qualifiers
16654 ///
16655 /// @param locus the location of the qualified type definition
qualified_type_def(const environment & env,CV quals,const location & locus)16656 qualified_type_def::qualified_type_def(const environment& env,
16657 				       CV quals,
16658 				       const location& locus)
16659   : type_or_decl_base(env,
16660 		      QUALIFIED_TYPE
16661 		      | ABSTRACT_TYPE_BASE
16662 		      | ABSTRACT_DECL_BASE),
16663     type_base(env, /*size_in_bits=*/0,
16664 	      /*alignment_in_bits=*/0),
16665     decl_base(env, "", locus, ""),
16666     priv_(new priv(quals))
16667 {
16668   runtime_type_instance(this);
16669   // We don't yet have an underlying type.  So for naming purpose,
16670   // let's temporarily pretend the underlying type is 'void'.
16671   interned_string name = env.intern("void");
16672   set_name(name);
16673 }
16674 
16675 /// Get the size of the qualified type def.
16676 ///
16677 /// This is an overload for type_base::get_size_in_bits().
16678 ///
16679 /// @return the size of the qualified type.
16680 size_t
get_size_in_bits() const16681 qualified_type_def::get_size_in_bits() const
16682 {
16683   size_t s = 0;
16684   if (type_base_sptr ut = get_underlying_type())
16685     {
16686       // We do have the underlying type properly set, so let's make
16687       // the size of the qualified type match the size of its
16688       // underlying type.
16689       s = ut->get_size_in_bits();
16690       if (s != type_base::get_size_in_bits())
16691 	const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
16692     }
16693   return type_base::get_size_in_bits();
16694 }
16695 
16696 /// Compares two instances of @ref qualified_type_def.
16697 ///
16698 /// If the two intances are different, set a bitfield to give some
16699 /// insight about the kind of differences there are.
16700 ///
16701 /// @param l the first artifact of the comparison.
16702 ///
16703 /// @param r the second artifact of the comparison.
16704 ///
16705 /// @param k a pointer to a bitfield that gives information about the
16706 /// kind of changes there are between @p l and @p r.  This one is set
16707 /// iff @p k is non-null and the function returns false.
16708 ///
16709 /// Please note that setting k to a non-null value does have a
16710 /// negative performance impact because even if @p l and @p r are not
16711 /// equal, the function keeps up the comparison in order to determine
16712 /// the different kinds of ways in which they are different.
16713 ///
16714 /// @return true if @p l equals @p r, false otherwise.
16715 bool
equals(const qualified_type_def & l,const qualified_type_def & r,change_kind * k)16716 equals(const qualified_type_def& l, const qualified_type_def& r, change_kind* k)
16717 {
16718   bool result = true;
16719   if (l.get_cv_quals() != r.get_cv_quals())
16720     {
16721       result = false;
16722       if (k)
16723 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
16724       else
16725 	ABG_RETURN_FALSE;
16726     }
16727 
16728   if (l.get_underlying_type() != r.get_underlying_type())
16729     {
16730       result = false;
16731       if (k)
16732 	{
16733 	  if (!types_have_similar_structure(l.get_underlying_type().get(),
16734 					    r.get_underlying_type().get()))
16735 	    // Underlying type changes in which the structure of the
16736 	    // type changed are considered local changes to the
16737 	    // qualified type.
16738 	    *k |= LOCAL_TYPE_CHANGE_KIND;
16739 	  else
16740 	    *k |= SUBTYPE_CHANGE_KIND;
16741 	}
16742       else
16743 	// okay strictly speaking this is not necessary, but I am
16744 	// putting it here to maintenance; that is, so that adding
16745 	// subsequent clauses needed to compare two qualified types
16746 	// later still works.
16747 	ABG_RETURN_FALSE;
16748     }
16749 
16750   ABG_RETURN(result);
16751 }
16752 
16753 /// Equality operator for qualified types.
16754 ///
16755 /// Note that this function does not check for equality of the scopes.
16756 ///
16757 ///@param o the other qualified type to compare against.
16758 ///
16759 /// @return true iff both qualified types are equal.
16760 bool
operator ==(const decl_base & o) const16761 qualified_type_def::operator==(const decl_base& o) const
16762 {
16763   const qualified_type_def* other =
16764     dynamic_cast<const qualified_type_def*>(&o);
16765   if (!other)
16766     return false;
16767   return try_canonical_compare(this, other);
16768 }
16769 
16770 /// Equality operator for qualified types.
16771 ///
16772 /// Note that this function does not check for equality of the scopes.
16773 /// Also, this re-uses the equality operator above that takes a
16774 /// decl_base.
16775 ///
16776 ///@param o the other qualified type to compare against.
16777 ///
16778 /// @return true iff both qualified types are equal.
16779 bool
operator ==(const type_base & o) const16780 qualified_type_def::operator==(const type_base& o) const
16781 {
16782   const decl_base* other = dynamic_cast<const decl_base*>(&o);
16783   if (!other)
16784     return false;
16785   return *this == *other;
16786 }
16787 
16788 /// Equality operator for qualified types.
16789 ///
16790 /// Note that this function does not check for equality of the scopes.
16791 /// Also, this re-uses the equality operator above that takes a
16792 /// decl_base.
16793 ///
16794 ///@param o the other qualified type to compare against.
16795 ///
16796 /// @return true iff both qualified types are equal.
16797 bool
operator ==(const qualified_type_def & o) const16798 qualified_type_def::operator==(const qualified_type_def& o) const
16799 {
16800   const decl_base* other = dynamic_cast<const decl_base*>(&o);
16801   if (!other)
16802     return false;
16803   return *this == *other;
16804 }
16805 
16806 /// Implementation for the virtual qualified name builder for @ref
16807 /// qualified_type_def.
16808 ///
16809 /// @param qualified_name the output parameter to hold the resulting
16810 /// qualified name.
16811 ///
16812 /// @param internal set to true if the call is intended for an
16813 /// internal use (for technical use inside the library itself), false
16814 /// otherwise.  If you don't know what this is for, then set it to
16815 /// false.
16816 void
get_qualified_name(interned_string & qualified_name,bool internal) const16817 qualified_type_def::get_qualified_name(interned_string& qualified_name,
16818 				       bool internal) const
16819 {qualified_name = get_qualified_name(internal);}
16820 
16821 /// Implementation of the virtual qualified name builder/getter.
16822 ///
16823 /// @param internal set to true if the call is intended for an
16824 /// internal use (for technical use inside the library itself), false
16825 /// otherwise.  If you don't know what this is for, then set it to
16826 /// false.
16827 ///
16828 /// @return the resulting qualified name.
16829 const interned_string&
get_qualified_name(bool internal) const16830 qualified_type_def::get_qualified_name(bool internal) const
16831 {
16832   const environment& env = get_environment();
16833 
16834 
16835   if (!get_canonical_type())
16836     {
16837       // The type hasn't been canonicalized yet. We want to return a
16838       // temporary name that is not cached because the structure of
16839       // this type (and so its name) can change until its
16840       // canonicalized.
16841       if (internal)
16842 	{
16843 	  // We are asked to return a temporary *internal* name.
16844 	  // Lets compute it and return a reference to where it's
16845 	  // stored.
16846 	  priv_->temporary_internal_name_ =
16847 	      env.intern(build_name(true, /*internal=*/true));
16848 	  return priv_->temporary_internal_name_;
16849 	}
16850       else
16851 	{
16852 	  // We are asked to return a temporary non-internal name.
16853 	    set_temporary_qualified_name
16854 	      (env.intern(build_name(true, /*internal=*/false)));
16855 	  return peek_temporary_qualified_name();
16856 	}
16857     }
16858   else
16859     {
16860       // The type has already been canonicalized. We want to return
16861       // the definitive name and cache it.
16862       if (internal)
16863 	{
16864 	  if (priv_->internal_name_.empty())
16865 	    priv_->internal_name_ =
16866 	      env.intern(build_name(/*qualified=*/true,
16867 				     /*internal=*/true));
16868 	  return priv_->internal_name_;
16869 	}
16870       else
16871 	{
16872 	  if (peek_qualified_name().empty())
16873 	    set_qualified_name
16874 	      (env.intern(build_name(/*qualified=*/true,
16875 				      /*internal=*/false)));
16876 	  return peek_qualified_name();
16877 	}
16878     }
16879 }
16880 
16881 /// This implements the ir_traversable_base::traverse pure virtual
16882 /// function.
16883 ///
16884 /// @param v the visitor used on the current instance.
16885 ///
16886 /// @return true if the entire IR node tree got traversed, false
16887 /// otherwise.
16888 bool
traverse(ir_node_visitor & v)16889 qualified_type_def::traverse(ir_node_visitor& v)
16890 {
16891   if (v.type_node_has_been_visited(this))
16892     return true;
16893 
16894   if (visiting())
16895     return true;
16896 
16897   if (v.visit_begin(this))
16898     {
16899       visiting(true);
16900       if (type_base_sptr t = get_underlying_type())
16901 	t->traverse(v);
16902       visiting(false);
16903     }
16904   bool result = v.visit_end(this);
16905   v.mark_type_node_as_visited(this);
16906   return result;
16907 }
16908 
~qualified_type_def()16909 qualified_type_def::~qualified_type_def()
16910 {
16911 }
16912 
16913 /// Getter of the const/volatile qualifier bit field
16914 qualified_type_def::CV
get_cv_quals() const16915 qualified_type_def::get_cv_quals() const
16916 {return priv_->cv_quals_;}
16917 
16918 /// Setter of the const/value qualifiers bit field
16919 void
set_cv_quals(CV cv_quals)16920 qualified_type_def::set_cv_quals(CV cv_quals)
16921 {priv_->cv_quals_ = cv_quals;}
16922 
16923 /// Compute and return the string prefix or suffix representing the
16924 /// qualifiers hold by the current instance of @ref
16925 /// qualified_type_def.
16926 ///
16927 /// @return the newly-built cv string.
16928 string
get_cv_quals_string_prefix() const16929 qualified_type_def::get_cv_quals_string_prefix() const
16930 {return get_string_representation_of_cv_quals(priv_->cv_quals_);}
16931 
16932 /// Getter of the underlying type
16933 type_base_sptr
get_underlying_type() const16934 qualified_type_def::get_underlying_type() const
16935 {return priv_->underlying_type_.lock();}
16936 
16937 /// Setter of the underlying type.
16938 ///
16939 /// @param t the new underlying type.
16940 void
set_underlying_type(const type_base_sptr & t)16941 qualified_type_def::set_underlying_type(const type_base_sptr& t)
16942 {
16943   ABG_ASSERT(t);
16944   priv_->underlying_type_ = t;
16945   // Now we need to update other properties that depend on the new underlying type.
16946   set_size_in_bits(t->get_size_in_bits());
16947   set_alignment_in_bits(t->get_alignment_in_bits());
16948   interned_string name = get_environment().intern(build_name(false));
16949   set_name(name);
16950   if (scope_decl* s = get_scope())
16951       {
16952 	// Now that the name has been updated, we need to update the
16953 	// lookup maps accordingly.
16954 	scope_decl::declarations::iterator i;
16955 	if (s->find_iterator_for_member(this, i))
16956 	  maybe_update_types_lookup_map(*i);
16957 	else
16958 	  ABG_ASSERT_NOT_REACHED;
16959       }
16960 }
16961 
16962 /// Non-member equality operator for @ref qualified_type_def
16963 ///
16964 /// @param l the left-hand side of the equality operator
16965 ///
16966 /// @param r the right-hand side of the equality operator
16967 ///
16968 /// @return true iff @p l and @p r equals.
16969 bool
operator ==(const qualified_type_def_sptr & l,const qualified_type_def_sptr & r)16970 operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
16971 {
16972   if (l.get() == r.get())
16973     return true;
16974   if (!!l != !!r)
16975     return false;
16976 
16977   return *l == *r;
16978 }
16979 
16980 /// Non-member inequality operator for @ref qualified_type_def
16981 ///
16982 /// @param l the left-hand side of the equality operator
16983 ///
16984 /// @param r the right-hand side of the equality operator
16985 ///
16986 /// @return true iff @p l and @p r equals.
16987 bool
operator !=(const qualified_type_def_sptr & l,const qualified_type_def_sptr & r)16988 operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
16989 {return ! operator==(l, r);}
16990 
16991 /// Overloaded bitwise OR operator for cv qualifiers.
16992 qualified_type_def::CV
operator |(qualified_type_def::CV lhs,qualified_type_def::CV rhs)16993 operator|(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
16994 {
16995   return static_cast<qualified_type_def::CV>
16996     (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
16997 }
16998 
16999 /// Overloaded bitwise |= operator for cv qualifiers.
17000 qualified_type_def::CV&
operator |=(qualified_type_def::CV & l,qualified_type_def::CV r)17001 operator|=(qualified_type_def::CV& l, qualified_type_def::CV r)
17002 {
17003   l = l | r;
17004   return l;
17005 }
17006 
17007 /// Overloaded bitwise &= operator for cv qualifiers.
17008 qualified_type_def::CV&
operator &=(qualified_type_def::CV & l,qualified_type_def::CV r)17009 operator&=(qualified_type_def::CV& l, qualified_type_def::CV r)
17010 {
17011   l = l & r;
17012   return l;
17013 }
17014 
17015 /// Overloaded bitwise AND operator for CV qualifiers.
17016 qualified_type_def::CV
operator &(qualified_type_def::CV lhs,qualified_type_def::CV rhs)17017 operator&(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
17018 {
17019     return static_cast<qualified_type_def::CV>
17020     (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
17021 }
17022 
17023 /// Overloaded bitwise inverting operator for CV qualifiers.
17024 qualified_type_def::CV
operator ~(qualified_type_def::CV q)17025 operator~(qualified_type_def::CV q)
17026 {return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
17027 
17028 /// Streaming operator for qualified_type_decl::CV
17029 ///
17030 /// @param o the output stream to serialize the cv qualifier to.
17031 ///
17032 /// @param cv the cv qualifier to serialize.
17033 ///
17034 /// @return the output stream used.
17035 std::ostream&
operator <<(std::ostream & o,qualified_type_def::CV cv)17036 operator<<(std::ostream& o, qualified_type_def::CV cv)
17037 {
17038   string str;
17039 
17040   switch (cv)
17041     {
17042     case qualified_type_def::CV_NONE:
17043       str = "none";
17044       break;
17045     case qualified_type_def::CV_CONST:
17046       str = "const";
17047       break;
17048     case qualified_type_def::CV_VOLATILE:
17049       str = "volatile";
17050       break;
17051     case qualified_type_def::CV_RESTRICT:
17052       str = "restrict";
17053       break;
17054     }
17055 
17056   o << str;
17057   return o;
17058 }
17059 
17060 // </qualified_type_def>
17061 
17062 //<pointer_type_def definitions>
17063 
17064 /// Private data structure of the @ref pointer_type_def.
17065 struct pointer_type_def::priv
17066 {
17067   type_base_wptr pointed_to_type_;
17068   type_base* naked_pointed_to_type_;
17069   interned_string internal_qualified_name_;
17070   interned_string temp_internal_qualified_name_;
17071 
privabigail::ir::pointer_type_def::priv17072   priv(const type_base_sptr& t)
17073     : pointed_to_type_(type_or_void(t, t->get_environment())),
17074       naked_pointed_to_type_(t.get())
17075   {}
17076 
privabigail::ir::pointer_type_def::priv17077   priv()
17078     : naked_pointed_to_type_()
17079   {}
17080 }; //end struct pointer_type_def
17081 
17082 /// This function is automatically invoked whenever an instance of
17083 /// this type is canonicalized.
17084 ///
17085 /// It's an overload of the virtual type_base::on_canonical_type_set.
17086 ///
17087 /// We put here what is thus meant to be executed only at the point of
17088 /// type canonicalization.
17089 void
on_canonical_type_set()17090 pointer_type_def::on_canonical_type_set()
17091 {clear_qualified_name();}
17092 
17093 
17094 ///Constructor of @ref pointer_type_def.
17095 ///
17096 /// @param pointed_to the pointed-to type.
17097 ///
17098 /// @param size_in_bits the size of the type, in bits.
17099 ///
17100 /// @param align_in_bits the alignment of the type, in bits.
17101 ///
17102 /// @param locus the source location where the type was defined.
pointer_type_def(const type_base_sptr & pointed_to,size_t size_in_bits,size_t align_in_bits,const location & locus)17103 pointer_type_def::pointer_type_def(const type_base_sptr&	pointed_to,
17104 				   size_t			size_in_bits,
17105 				   size_t			align_in_bits,
17106 				   const location&		locus)
17107   : type_or_decl_base(pointed_to->get_environment(),
17108 		      POINTER_TYPE
17109 		      | ABSTRACT_TYPE_BASE
17110 		      | ABSTRACT_DECL_BASE),
17111     type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
17112     decl_base(pointed_to->get_environment(), "", locus, ""),
17113     priv_(new priv(pointed_to))
17114 {
17115   runtime_type_instance(this);
17116   try
17117     {
17118       ABG_ASSERT(pointed_to);
17119       const environment& env = pointed_to->get_environment();
17120       decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
17121       string name = (pto ? pto->get_name() : string("void")) + "*";
17122       set_name(env.intern(name));
17123       if (pto)
17124 	set_visibility(pto->get_visibility());
17125     }
17126   catch (...)
17127     {}
17128 }
17129 
17130 ///Constructor of @ref pointer_type_def.
17131 ///
17132 /// @param env the environment of the type.
17133 ///
17134 /// @param size_in_bits the size of the type, in bits.
17135 ///
17136 /// @param align_in_bits the alignment of the type, in bits.
17137 ///
17138 /// @param locus the source location where the type was defined.
pointer_type_def(const environment & env,size_t size_in_bits,size_t alignment_in_bits,const location & locus)17139 pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
17140 				   size_t alignment_in_bits,
17141 				   const location& locus)
17142   : type_or_decl_base(env,
17143 		      POINTER_TYPE
17144 		      | ABSTRACT_TYPE_BASE
17145 		      | ABSTRACT_DECL_BASE),
17146     type_base(env, size_in_bits, alignment_in_bits),
17147     decl_base(env, "", locus, ""),
17148     priv_(new priv())
17149 {
17150   runtime_type_instance(this);
17151   string name = string("void") + "*";
17152   set_name(env.intern(name));
17153 }
17154 
17155 /// Set the pointed-to type of the pointer.
17156 ///
17157 /// @param t the new pointed-to type.
17158 void
set_pointed_to_type(const type_base_sptr & t)17159 pointer_type_def::set_pointed_to_type(const type_base_sptr& t)
17160 {
17161   ABG_ASSERT(t);
17162   priv_->pointed_to_type_ = t;
17163   priv_->naked_pointed_to_type_ = t.get();
17164 
17165   try
17166     {
17167       const environment& env = t->get_environment();
17168       decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
17169       string name = (pto ? pto->get_name() : string("void")) + "*";
17170       set_name(env.intern(name));
17171       if (pto)
17172 	set_visibility(pto->get_visibility());
17173     }
17174   catch (...)
17175     {}
17176 }
17177 
17178 /// Compares two instances of @ref pointer_type_def.
17179 ///
17180 /// If the two intances are different, set a bitfield to give some
17181 /// insight about the kind of differences there are.
17182 ///
17183 /// @param l the first artifact of the comparison.
17184 ///
17185 /// @param r the second artifact of the comparison.
17186 ///
17187 /// @param k a pointer to a bitfield that gives information about the
17188 /// kind of changes there are between @p l and @p r.  This one is set
17189 /// iff @p k is non-null and the function returns false.
17190 ///
17191 /// Please note that setting k to a non-null value does have a
17192 /// negative performance impact because even if @p l and @p r are not
17193 /// equal, the function keeps up the comparison in order to determine
17194 /// the different kinds of ways in which they are different.
17195 ///
17196 /// @return true if @p l equals @p r, false otherwise.
17197 bool
equals(const pointer_type_def & l,const pointer_type_def & r,change_kind * k)17198 equals(const pointer_type_def& l, const pointer_type_def& r, change_kind* k)
17199 {
17200   // In C and C++ languages, a pointer to void equals all other
17201   // pointers.
17202   if (l.get_translation_unit()
17203       && r.get_translation_unit()
17204       && is_c_language(l.get_translation_unit()->get_language())
17205       && is_c_language(r.get_translation_unit()->get_language())
17206       && (is_void_pointer_type_equivalent(&l)
17207 	  || is_void_pointer_type_equivalent(&r)))
17208     return true;
17209 
17210   bool result = l.get_pointed_to_type() == r.get_pointed_to_type();
17211   if (!result)
17212     if (k)
17213       {
17214 	if (!types_have_similar_structure(&l, &r))
17215 	  // pointed-to type changes in which the structure of the
17216 	  // type changed are considered local changes to the pointer
17217 	  // type.
17218 	  *k |= LOCAL_TYPE_CHANGE_KIND;
17219 	*k |= SUBTYPE_CHANGE_KIND;
17220       }
17221 
17222   ABG_RETURN(result);
17223 }
17224 
17225 /// Return true iff both instances of pointer_type_def are equal.
17226 ///
17227 /// Note that this function does not check for the scopes of the this
17228 /// types.
17229 bool
operator ==(const decl_base & o) const17230 pointer_type_def::operator==(const decl_base& o) const
17231 {
17232   const pointer_type_def* other = is_pointer_type(&o);
17233   if (!other)
17234     return false;
17235   return try_canonical_compare(this, other);
17236 }
17237 
17238 /// Return true iff both instances of pointer_type_def are equal.
17239 ///
17240 /// Note that this function does not check for the scopes of the
17241 /// types.
17242 ///
17243 /// @param other the other type to compare against.
17244 ///
17245 /// @return true iff @p other equals the current instance.
17246 bool
operator ==(const type_base & other) const17247 pointer_type_def::operator==(const type_base& other) const
17248 {
17249   const decl_base* o = is_decl(&other);
17250   if (!o)
17251     return false;
17252   return *this == *o;
17253 }
17254 
17255 /// Return true iff both instances of pointer_type_def are equal.
17256 ///
17257 /// Note that this function does not check for the scopes of the
17258 /// types.
17259 ///
17260 /// @param other the other type to compare against.
17261 ///
17262 /// @return true iff @p other equals the current instance.
17263 bool
operator ==(const pointer_type_def & other) const17264 pointer_type_def::operator==(const pointer_type_def& other) const
17265 {
17266   const decl_base& o = other;
17267   return *this == o;
17268 }
17269 
17270 /// Getter of the pointed-to type.
17271 ///
17272 /// @return the pointed-to type.
17273 const type_base_sptr
get_pointed_to_type() const17274 pointer_type_def::get_pointed_to_type() const
17275 {return priv_->pointed_to_type_.lock();}
17276 
17277 /// Getter of a naked pointer to the pointed-to type.
17278 ///
17279 /// @return a naked pointed to the pointed-to type.
17280 type_base*
get_naked_pointed_to_type() const17281 pointer_type_def::get_naked_pointed_to_type() const
17282 {return priv_->naked_pointed_to_type_;}
17283 
17284 /// Build and return the qualified name of the current instance of
17285 /// @ref pointer_type_def.
17286 ///
17287 /// @param qn output parameter.  The resulting qualified name.
17288 ///
17289 /// @param internal set to true if the call is intended for an
17290 /// internal use (for technical use inside the library itself), false
17291 /// otherwise.  If you don't know what this is for, then set it to
17292 /// false.
17293 void
get_qualified_name(interned_string & qn,bool internal) const17294 pointer_type_def::get_qualified_name(interned_string& qn, bool internal) const
17295 {qn = get_qualified_name(internal);}
17296 
17297 /// Build, cache and return the qualified name of the current instance
17298 /// of @ref pointer_type_def.  Subsequent invocations of this function
17299 /// return the cached value.
17300 ///
17301 /// Note that this function should work even if the underlying type is
17302 /// momentarily empty.
17303 ///
17304 /// @param internal set to true if the call is intended for an
17305 /// internal use (for technical use inside the library itself), false
17306 /// otherwise.  If you don't know what this is for, then set it to
17307 /// false.
17308 ///
17309 /// @return the resulting qualified name.
17310 const interned_string&
get_qualified_name(bool internal) const17311 pointer_type_def::get_qualified_name(bool internal) const
17312 {
17313   type_base* pointed_to_type = get_naked_pointed_to_type();
17314   pointed_to_type = look_through_decl_only(pointed_to_type);
17315 
17316   if (internal)
17317     {
17318       if (get_canonical_type())
17319 	{
17320 	  if (priv_->internal_qualified_name_.empty())
17321 	    if (pointed_to_type)
17322 	      priv_->internal_qualified_name_ =
17323 		get_name_of_pointer_to_type(*pointed_to_type,
17324 					    /*qualified_name=*/
17325 					    is_typedef(pointed_to_type)
17326 					    ? false
17327 					    : true,
17328 					    /*internal=*/true);
17329 	  return priv_->internal_qualified_name_;
17330 	}
17331       else
17332 	{
17333 	  // As the type hasn't yet been canonicalized, its structure
17334 	  // (and so its name) can change.  So let's invalidate the
17335 	  // cache where we store its name at each invocation of this
17336 	  // function.
17337 	  if (pointed_to_type)
17338 	    priv_->temp_internal_qualified_name_ =
17339 	      get_name_of_pointer_to_type(*pointed_to_type,
17340 					  /*qualified_name=*/
17341 					  is_typedef(pointed_to_type)
17342 					  ? false
17343 					  : true,
17344 					  /*internal=*/true);
17345 	  return priv_->temp_internal_qualified_name_;
17346 	}
17347     }
17348   else
17349     {
17350       if (get_naked_canonical_type())
17351 	{
17352 	  if (decl_base::peek_qualified_name().empty())
17353 	    set_qualified_name
17354 	      (get_name_of_pointer_to_type(*pointed_to_type,
17355 					   /*qualified_name=*/true,
17356 					   /*internal=*/false));
17357 	  return decl_base::peek_qualified_name();
17358 	}
17359       else
17360 	{
17361 	  // As the type hasn't yet been canonicalized, its structure
17362 	  // (and so its name) can change.  So let's invalidate the
17363 	  // cache where we store its name at each invocation of this
17364 	  // function.
17365 	  if (pointed_to_type)
17366 	    set_qualified_name
17367 	      (get_name_of_pointer_to_type(*pointed_to_type,
17368 					   /*qualified_name=*/true,
17369 					   /*internal=*/false));
17370 	  return decl_base::peek_qualified_name();
17371 	}
17372     }
17373 }
17374 
17375 /// This implements the ir_traversable_base::traverse pure virtual
17376 /// function.
17377 ///
17378 /// @param v the visitor used on the current instance.
17379 ///
17380 /// @return true if the entire IR node tree got traversed, false
17381 /// otherwise.
17382 bool
traverse(ir_node_visitor & v)17383 pointer_type_def::traverse(ir_node_visitor& v)
17384 {
17385   if (v.type_node_has_been_visited(this))
17386     return true;
17387 
17388   if (visiting())
17389     return true;
17390 
17391   if (v.visit_begin(this))
17392     {
17393       visiting(true);
17394       if (type_base_sptr t = get_pointed_to_type())
17395 	t->traverse(v);
17396       visiting(false);
17397     }
17398 
17399   bool result = v.visit_end(this);
17400   v.mark_type_node_as_visited(this);
17401   return result;
17402 }
17403 
~pointer_type_def()17404 pointer_type_def::~pointer_type_def()
17405 {}
17406 
17407 /// Turn equality of shared_ptr of @ref pointer_type_def into a deep
17408 /// equality; that is, make it compare the pointed to objects too.
17409 ///
17410 /// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
17411 /// of the equality.
17412 ///
17413 /// @param r the shared_ptr of @ref pointer_type_def on
17414 /// right-hand-side of the equality.
17415 ///
17416 /// @return true if the @ref pointer_type_def pointed to by the
17417 /// shared_ptrs are equal, false otherwise.
17418 bool
operator ==(const pointer_type_def_sptr & l,const pointer_type_def_sptr & r)17419 operator==(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
17420 {
17421   if (l.get() == r.get())
17422     return true;
17423   if (!!l != !!r)
17424     return false;
17425 
17426   return *l == *r;
17427 }
17428 
17429 /// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
17430 /// equality; that is, make it compare the pointed to objects too.
17431 ///
17432 /// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
17433 /// of the equality.
17434 ///
17435 /// @param r the shared_ptr of @ref pointer_type_def on
17436 /// right-hand-side of the equality.
17437 ///
17438 /// @return true iff the @ref pointer_type_def pointed to by the
17439 /// shared_ptrs are different.
17440 bool
operator !=(const pointer_type_def_sptr & l,const pointer_type_def_sptr & r)17441 operator!=(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
17442 {return !operator==(l, r);}
17443 
17444 // </pointer_type_def definitions>
17445 
17446 // <reference_type_def definitions>
17447 
17448 /// Private data structure of the @ref reference_type_def type.
17449 struct reference_type_def::priv
17450 {
17451 
17452   type_base_wptr	pointed_to_type_;
17453   bool			is_lvalue_;
17454   interned_string	internal_qualified_name_;
17455   interned_string	temp_internal_qualified_name_;
17456 
privabigail::ir::reference_type_def::priv17457   priv(const type_base_sptr& t, bool is_lvalue)
17458     : pointed_to_type_(type_or_void(t, t->get_environment())),
17459       is_lvalue_(is_lvalue)
17460   {}
17461 
privabigail::ir::reference_type_def::priv17462   priv(bool is_lvalue)
17463     : is_lvalue_(is_lvalue)
17464   {}
17465 
17466   priv() = delete;
17467 };
17468 
17469 /// This function is automatically invoked whenever an instance of
17470 /// this type is canonicalized.
17471 ///
17472 /// It's an overload of the virtual type_base::on_canonical_type_set.
17473 ///
17474 /// We put here what is thus meant to be executed only at the point of
17475 /// type canonicalization.
17476 void
on_canonical_type_set()17477 reference_type_def::on_canonical_type_set()
17478 {clear_qualified_name();}
17479 
17480 /// Constructor of the reference_type_def type.
17481 ///
17482 /// @param pointed_to the pointed to type.
17483 ///
17484 /// @param lvalue wether the reference is an lvalue reference.  If
17485 /// false, the reference is an rvalue one.
17486 ///
17487 /// @param size_in_bits the size of the type, in bits.
17488 ///
17489 /// @param align_in_bits the alignment of the type, in bits.
17490 ///
17491 /// @param locus the source location of the type.
reference_type_def(const type_base_sptr pointed_to,bool lvalue,size_t size_in_bits,size_t align_in_bits,const location & locus)17492 reference_type_def::reference_type_def(const type_base_sptr	pointed_to,
17493 				       bool			lvalue,
17494 				       size_t			size_in_bits,
17495 				       size_t			align_in_bits,
17496 				       const location&		locus)
17497   : type_or_decl_base(pointed_to->get_environment(),
17498 		      REFERENCE_TYPE
17499 		      | ABSTRACT_TYPE_BASE
17500 		      | ABSTRACT_DECL_BASE),
17501     type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
17502     decl_base(pointed_to->get_environment(), "", locus, ""),
17503     priv_(new priv(pointed_to, lvalue))
17504 {
17505   runtime_type_instance(this);
17506 
17507   try
17508     {
17509       decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
17510       string name;
17511       if (pto)
17512 	{
17513 	  set_visibility(pto->get_visibility());
17514 	  name = string(pto->get_name()) + "&";
17515 	}
17516       else
17517 	name = string(get_type_name(is_function_type(pointed_to),
17518 				    /*qualified_name=*/true)) + "&";
17519 
17520       if (!is_lvalue())
17521 	name += "&";
17522       const environment& env = pointed_to->get_environment();
17523       set_name(env.intern(name));
17524     }
17525   catch (...)
17526     {}
17527 }
17528 
17529 /// Constructor of the reference_type_def type.
17530 ///
17531 /// This one creates a type that has no pointed-to type, temporarily.
17532 /// This is useful for cases where the underlying type is not yet
17533 /// available.  It can be set later using
17534 /// reference_type_def::set_pointed_to_type().
17535 ///
17536 /// @param env the environment of the type.
17537 ///
17538 /// @param lvalue wether the reference is an lvalue reference.  If
17539 /// false, the reference is an rvalue one.
17540 ///
17541 /// @param size_in_bits the size of the type, in bits.
17542 ///
17543 /// @param align_in_bits the alignment of the type, in bits.
17544 ///
17545 /// @param locus the source location of the type.
reference_type_def(const environment & env,bool lvalue,size_t size_in_bits,size_t alignment_in_bits,const location & locus)17546 reference_type_def::reference_type_def(const environment& env, bool lvalue,
17547 				       size_t size_in_bits,
17548 				       size_t alignment_in_bits,
17549 				       const location& locus)
17550   : type_or_decl_base(env,
17551 		      REFERENCE_TYPE
17552 		      | ABSTRACT_TYPE_BASE
17553 		      | ABSTRACT_DECL_BASE),
17554     type_base(env, size_in_bits, alignment_in_bits),
17555     decl_base(env, "", locus, ""),
17556     priv_(new priv(lvalue))
17557 {
17558   runtime_type_instance(this);
17559   string name = "void&";
17560   if (!is_lvalue())
17561     name += "&";
17562 
17563   set_name(env.intern(name));
17564   priv_->pointed_to_type_ = type_base_wptr(env.get_void_type());
17565 }
17566 
17567 /// Setter of the pointed_to type of the current reference type.
17568 ///
17569 /// @param pointed_to the new pointed to type.
17570 void
set_pointed_to_type(type_base_sptr & pointed_to_type)17571 reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
17572 {
17573   ABG_ASSERT(pointed_to_type);
17574   priv_->pointed_to_type_ = pointed_to_type;
17575 
17576   decl_base_sptr pto;
17577   try
17578     {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
17579   catch (...)
17580     {}
17581 
17582   if (pto)
17583     {
17584       set_visibility(pto->get_visibility());
17585       string name = string(pto->get_name()) + "&";
17586       if (!is_lvalue())
17587 	name += "&";
17588       const environment& env = pto->get_environment();
17589       set_name(env.intern(name));
17590     }
17591 }
17592 
17593 /// Compares two instances of @ref reference_type_def.
17594 ///
17595 /// If the two intances are different, set a bitfield to give some
17596 /// insight about the kind of differences there are.
17597 ///
17598 /// @param l the first artifact of the comparison.
17599 ///
17600 /// @param r the second artifact of the comparison.
17601 ///
17602 /// @param k a pointer to a bitfield that gives information about the
17603 /// kind of changes there are between @p l and @p r.  This one is set
17604 /// iff @p k is non-null and the function returns false.
17605 ///
17606 /// Please note that setting k to a non-null value does have a
17607 /// negative performance impact because even if @p l and @p r are not
17608 /// equal, the function keeps up the comparison in order to determine
17609 /// the different kinds of ways in which they are different.
17610 ///
17611 /// @return true if @p l equals @p r, false otherwise.
17612 bool
equals(const reference_type_def & l,const reference_type_def & r,change_kind * k)17613 equals(const reference_type_def& l, const reference_type_def& r, change_kind* k)
17614 {
17615   if (l.is_lvalue() != r.is_lvalue())
17616     {
17617       if (k)
17618 	*k |= LOCAL_TYPE_CHANGE_KIND;
17619       ABG_RETURN_FALSE;
17620     }
17621 
17622   // Compare the pointed-to-types modulo the typedefs they might have
17623   bool result = (l.get_pointed_to_type() == r.get_pointed_to_type());
17624   if (!result)
17625     if (k)
17626       {
17627 	if (!types_have_similar_structure(&l, &r))
17628 	  *k |= LOCAL_TYPE_CHANGE_KIND;
17629 	*k |= SUBTYPE_CHANGE_KIND;
17630       }
17631   ABG_RETURN(result);
17632 }
17633 
17634 /// Equality operator of the @ref reference_type_def type.
17635 ///
17636 /// @param o the other instance of @ref reference_type_def to compare
17637 /// against.
17638 ///
17639 /// @return true iff the two instances are equal.
17640 bool
operator ==(const decl_base & o) const17641 reference_type_def::operator==(const decl_base& o) const
17642 {
17643   const reference_type_def* other =
17644     dynamic_cast<const reference_type_def*>(&o);
17645   if (!other)
17646     return false;
17647   return try_canonical_compare(this, other);
17648 }
17649 
17650 /// Equality operator of the @ref reference_type_def type.
17651 ///
17652 /// @param o the other instance of @ref reference_type_def to compare
17653 /// against.
17654 ///
17655 /// @return true iff the two instances are equal.
17656 bool
operator ==(const type_base & o) const17657 reference_type_def::operator==(const type_base& o) const
17658 {
17659   const decl_base* other = dynamic_cast<const decl_base*>(&o);
17660   if (!other)
17661     return false;
17662   return *this == *other;
17663 }
17664 
17665 /// Equality operator of the @ref reference_type_def type.
17666 ///
17667 /// @param o the other instance of @ref reference_type_def to compare
17668 /// against.
17669 ///
17670 /// @return true iff the two instances are equal.
17671 bool
operator ==(const reference_type_def & o) const17672 reference_type_def::operator==(const reference_type_def& o) const
17673 {
17674   const decl_base* other = dynamic_cast<const decl_base*>(&o);
17675   if (!other)
17676     return false;
17677   return *this == *other;
17678 }
17679 
17680 type_base_sptr
get_pointed_to_type() const17681 reference_type_def::get_pointed_to_type() const
17682 {return priv_->pointed_to_type_.lock();}
17683 
17684 bool
is_lvalue() const17685 reference_type_def::is_lvalue() const
17686 {return priv_->is_lvalue_;}
17687 
17688 /// Build and return the qualified name of the current instance of the
17689 /// @ref reference_type_def.
17690 ///
17691 /// @param qn output parameter.  Is set to the newly-built qualified
17692 /// name of the current instance of @ref reference_type_def.
17693 ///
17694 /// @param internal set to true if the call is intended for an
17695 /// internal use (for technical use inside the library itself), false
17696 /// otherwise.  If you don't know what this is for, then set it to
17697 /// false.
17698 void
get_qualified_name(interned_string & qn,bool internal) const17699 reference_type_def::get_qualified_name(interned_string& qn, bool internal) const
17700 {qn = get_qualified_name(internal);}
17701 
17702 /// Build, cache and return the qualified name of the current instance
17703 /// of the @ref reference_type_def.  Subsequent invocations of this
17704 /// function return the cached value.
17705 ///
17706 /// @param internal set to true if the call is intended for an
17707 /// internal use (for technical use inside the library itself), false
17708 /// otherwise.  If you don't know what this is for, then set it to
17709 /// false.
17710 ///
17711 /// @return the newly-built qualified name of the current instance of
17712 /// @ref reference_type_def.
17713 const interned_string&
get_qualified_name(bool internal) const17714 reference_type_def::get_qualified_name(bool internal) const
17715 {
17716   type_base_sptr pointed_to_type = get_pointed_to_type();
17717   pointed_to_type = look_through_decl_only(pointed_to_type);
17718 
17719   if (internal)
17720     {
17721       if (get_canonical_type())
17722 	{
17723 	  if (priv_->internal_qualified_name_.empty())
17724 	    if (pointed_to_type)
17725 	      priv_->internal_qualified_name_ =
17726 		get_name_of_reference_to_type(*pointed_to_type,
17727 					      is_lvalue(),
17728 					      /*qualified_name=*/
17729 					      is_typedef(pointed_to_type)
17730 					      ? false
17731 					      : true,
17732 					      /*internal=*/true);
17733 	  return priv_->internal_qualified_name_;
17734 	}
17735       else
17736 	{
17737 	  // As the type hasn't yet been canonicalized, its structure
17738 	  // (and so its name) can change.  So let's invalidate the
17739 	  // cache where we store its name at each invocation of this
17740 	  // function.
17741 	  if (pointed_to_type)
17742 	    priv_->temp_internal_qualified_name_ =
17743 	      get_name_of_reference_to_type(*pointed_to_type,
17744 					    is_lvalue(),
17745 					    /*qualified_name=*/
17746 					    is_typedef(pointed_to_type)
17747 					    ? false
17748 					    : true,
17749 					    /*internal=*/true);
17750 	  return priv_->temp_internal_qualified_name_;
17751 	}
17752     }
17753   else
17754     {
17755       if (get_naked_canonical_type())
17756 	{
17757 	  set_qualified_name
17758 	    (get_name_of_reference_to_type(*pointed_to_type,
17759 					   is_lvalue(),
17760 					   /*qualified_name=*/true,
17761 					   /*internal=*/false));
17762 	  return decl_base::peek_qualified_name();
17763 	}
17764       else
17765 	{
17766 	  // As the type hasn't yet been canonicalized, its structure
17767 	  // (and so its name) can change.  So let's invalidate the
17768 	  // cache where we store its name at each invocation of this
17769 	  // function.
17770 	  if (pointed_to_type)
17771 	    set_qualified_name
17772 	      (get_name_of_reference_to_type(*pointed_to_type,
17773 					     is_lvalue(),
17774 					     /*qualified_name=*/true,
17775 					     /*internal=*/false));
17776 	  return decl_base::peek_qualified_name();
17777 	}
17778     }
17779 }
17780 
17781 /// Get the pretty representation of the current instance of @ref
17782 /// reference_type_def.
17783 ///
17784 /// @param internal set to true if the call is intended to get a
17785 /// representation of the decl (or type) for the purpose of canonical
17786 /// type comparison.  This is mainly used in the function
17787 /// type_base::get_canonical_type_for().
17788 ///
17789 /// In other words if the argument for this parameter is true then the
17790 /// call is meant for internal use (for technical use inside the
17791 /// library itself), false otherwise.  If you don't know what this is
17792 /// for, then set it to false.
17793 ///
17794 /// @param qualified_name if true, names emitted in the pretty
17795 /// representation are fully qualified.
17796 ///
17797 /// @return the pretty representatin of the @ref reference_type_def.
17798 string
get_pretty_representation(bool internal,bool qualified_name) const17799 reference_type_def::get_pretty_representation(bool internal,
17800 					      bool qualified_name) const
17801 {
17802   string result =
17803     get_name_of_reference_to_type(*look_through_decl_only
17804 				  (get_pointed_to_type()),
17805 				  is_lvalue(),
17806 				  qualified_name,
17807 				  internal);
17808 
17809   return result;
17810 }
17811 
17812 /// This implements the ir_traversable_base::traverse pure virtual
17813 /// function.
17814 ///
17815 /// @param v the visitor used on the current instance.
17816 ///
17817 /// @return true if the entire IR node tree got traversed, false
17818 /// otherwise.
17819 bool
traverse(ir_node_visitor & v)17820 reference_type_def::traverse(ir_node_visitor& v)
17821 {
17822   if (v.type_node_has_been_visited(this))
17823     return true;
17824 
17825   if (visiting())
17826     return true;
17827 
17828   if (v.visit_begin(this))
17829     {
17830       visiting(true);
17831       if (type_base_sptr t = get_pointed_to_type())
17832 	t->traverse(v);
17833       visiting(false);
17834     }
17835 
17836   bool result = v.visit_end(this);
17837   v.mark_type_node_as_visited(this);
17838   return result;
17839 }
17840 
~reference_type_def()17841 reference_type_def::~reference_type_def()
17842 {}
17843 
17844 /// Turn equality of shared_ptr of @ref reference_type_def into a deep
17845 /// equality; that is, make it compare the pointed to objects too.
17846 ///
17847 /// @param l the shared_ptr of @ref reference_type_def on left-hand-side
17848 /// of the equality.
17849 ///
17850 /// @param r the shared_ptr of @ref reference_type_def on
17851 /// right-hand-side of the equality.
17852 ///
17853 /// @return true if the @ref reference_type_def pointed to by the
17854 /// shared_ptrs are equal, false otherwise.
17855 bool
operator ==(const reference_type_def_sptr & l,const reference_type_def_sptr & r)17856 operator==(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
17857 {
17858   if (l.get() == r.get())
17859     return true;
17860   if (!!l != !!r)
17861     return false;
17862 
17863   return *l == *r;
17864 }
17865 
17866 /// Turn inequality of shared_ptr of @ref reference_type_def into a deep
17867 /// equality; that is, make it compare the pointed to objects too.
17868 ///
17869 /// @param l the shared_ptr of @ref reference_type_def on left-hand-side
17870 /// of the equality.
17871 ///
17872 /// @param r the shared_ptr of @ref reference_type_def on
17873 /// right-hand-side of the equality.
17874 ///
17875 /// @return true iff the @ref reference_type_def pointed to by the
17876 /// shared_ptrs are different.
17877 bool
operator !=(const reference_type_def_sptr & l,const reference_type_def_sptr & r)17878 operator!=(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
17879 {return !operator==(l, r);}
17880 
17881 // </reference_type_def definitions>
17882 
17883 // <array_type_def definitions>
17884 
17885 // <array_type_def::subrange_type>
17886 array_type_def::subrange_type::~subrange_type() = default;
17887 
17888 // <array_type_def::subrante_type::bound_value>
17889 
17890 /// Default constructor of the @ref
17891 /// array_type_def::subrange_type::bound_value class.
17892 ///
17893 /// Constructs an unsigned bound_value of value zero.
bound_value()17894 array_type_def::subrange_type::bound_value::bound_value()
17895   : s_(UNSIGNED_SIGNEDNESS)
17896 {
17897   v_.unsigned_ = 0;
17898 }
17899 
17900 /// Initialize an unsigned bound_value with a given value.
17901 ///
17902 /// @param v the initial bound value.
bound_value(uint64_t v)17903 array_type_def::subrange_type::bound_value::bound_value(uint64_t v)
17904   : s_(UNSIGNED_SIGNEDNESS)
17905 {
17906   v_.unsigned_ = v;
17907 }
17908 
17909 /// Initialize a signed bound_value with a given value.
17910 ///
17911 /// @param v the initial bound value.
bound_value(int64_t v)17912 array_type_def::subrange_type::bound_value::bound_value(int64_t v)
17913   : s_(SIGNED_SIGNEDNESS)
17914 {
17915   v_.signed_ = v;
17916 }
17917 
17918 /// Getter of the signedness (unsigned VS signed) of the bound value.
17919 ///
17920 /// @return the signedness of the bound value.
17921 enum array_type_def::subrange_type::bound_value::signedness
get_signedness() const17922 array_type_def::subrange_type::bound_value::get_signedness() const
17923 {return s_;}
17924 
17925 /// Setter of the signedness (unsigned VS signed) of the bound value.
17926 ///
17927 /// @param s the new signedness of the bound value.
17928 void
set_signedness(enum signedness s)17929 array_type_def::subrange_type::bound_value::set_signedness(enum signedness s)
17930 { s_ = s;}
17931 
17932 /// Getter of the bound value as a signed value.
17933 ///
17934 /// @return the bound value as signed.
17935 int64_t
get_signed_value() const17936 array_type_def::subrange_type::bound_value::get_signed_value() const
17937 {return v_.signed_;
17938 }
17939 
17940 /// Getter of the bound value as an unsigned value.
17941 ///
17942 /// @return the bound value as unsigned.
17943 uint64_t
get_unsigned_value()17944 array_type_def::subrange_type::bound_value::get_unsigned_value()
17945 {return v_.unsigned_;}
17946 
17947 /// Setter of the bound value as unsigned.
17948 ///
17949 /// @param v the new unsigned value.
17950 void
set_unsigned(uint64_t v)17951 array_type_def::subrange_type::bound_value::set_unsigned(uint64_t v)
17952 {
17953     s_ = UNSIGNED_SIGNEDNESS;
17954   v_.unsigned_ = v;
17955 }
17956 
17957 /// Setter of the bound value as signed.
17958 ///
17959 /// @param v the new signed value.
17960 void
set_signed(int64_t v)17961 array_type_def::subrange_type::bound_value::set_signed(int64_t v)
17962 {
17963   s_ = SIGNED_SIGNEDNESS;
17964   v_.signed_ = v;
17965 }
17966 
17967 /// Equality operator of the bound value.
17968 ///
17969 /// @param v the other bound value to compare with.
17970 ///
17971 /// @return true iff the current bound value equals @p v.
17972 bool
operator ==(const bound_value & v) const17973 array_type_def::subrange_type::bound_value::operator==(const bound_value& v) const
17974 {
17975   return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
17976 }
17977 
17978 // </array_type_def::subrante_type::bound_value>
17979 
17980 struct array_type_def::subrange_type::priv
17981 {
17982   bound_value		lower_bound_;
17983   bound_value		upper_bound_;
17984   type_base_wptr	underlying_type_;
17985   translation_unit::language language_;
17986   bool			infinite_;
17987 
privabigail::ir::array_type_def::subrange_type::priv17988   priv(bound_value ub,
17989        translation_unit::language l = translation_unit::LANG_C11)
17990     : upper_bound_(ub), language_(l), infinite_(false)
17991   {}
17992 
privabigail::ir::array_type_def::subrange_type::priv17993   priv(bound_value lb, bound_value ub,
17994        translation_unit::language l = translation_unit::LANG_C11)
17995     : lower_bound_(lb), upper_bound_(ub),
17996       language_(l), infinite_(false)
17997   {}
17998 
privabigail::ir::array_type_def::subrange_type::priv17999   priv(bound_value lb, bound_value ub, const type_base_sptr &u,
18000        translation_unit::language l = translation_unit::LANG_C11)
18001     : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
18002       language_(l), infinite_(false)
18003   {}
18004 };
18005 
18006 /// Constructor of an array_type_def::subrange_type type.
18007 ///
18008 /// @param env the environment this type was created from.
18009 ///
18010 /// @param name the name of the subrange type.
18011 ///
18012 /// @param lower_bound the lower bound of the array.  This is
18013 /// generally zero (at least for C and C++).
18014 ///
18015 /// @param upper_bound the upper bound of the array.
18016 ///
18017 /// @param underlying_type the underlying type of the subrange type.
18018 ///
18019 /// @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)18020 array_type_def::subrange_type::subrange_type(const environment& env,
18021 					     const string&	name,
18022 					     bound_value	lower_bound,
18023 					     bound_value	upper_bound,
18024 					     const type_base_sptr& utype,
18025 					     const location&	loc,
18026 					     translation_unit::language l)
18027   : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18028     type_base(env,
18029 	      upper_bound.get_unsigned_value()
18030 	      - lower_bound.get_unsigned_value(),
18031 	      0),
18032     decl_base(env, name, loc, ""),
18033     priv_(new priv(lower_bound, upper_bound, utype, l))
18034 {
18035   runtime_type_instance(this);
18036 }
18037 
18038 /// Constructor of the array_type_def::subrange_type type.
18039 ///
18040 /// @param env the environment this type is being created in.
18041 ///
18042 /// @param name the name of the subrange type.
18043 ///
18044 /// @param lower_bound the lower bound of the array.  This is
18045 /// generally zero (at least for C and C++).
18046 ///
18047 /// @param upper_bound the upper bound of the array.
18048 ///
18049 /// @param loc the source location where the type is defined.
18050 ///
18051 /// @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)18052 array_type_def::subrange_type::subrange_type(const environment& env,
18053 					     const string&	name,
18054 					     bound_value	lower_bound,
18055 					     bound_value	upper_bound,
18056 					     const location&	loc,
18057 					     translation_unit::language l)
18058   : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18059     type_base(env,
18060 	      upper_bound.get_unsigned_value()
18061 	      - lower_bound.get_unsigned_value(), 0),
18062     decl_base(env, name, loc, ""),
18063     priv_(new priv(lower_bound, upper_bound, l))
18064 {
18065   runtime_type_instance(this);
18066 }
18067 
18068 /// Constructor of the array_type_def::subrange_type type.
18069 ///
18070 /// @param env the environment this type is being created from.
18071 ///
18072 /// @param name of the name of type.
18073 ///
18074 /// @param upper_bound the upper bound of the array.  The lower bound
18075 /// is considered to be zero.
18076 ///
18077 /// @param loc the source location of the type.
18078 ///
18079 /// @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)18080 array_type_def::subrange_type::subrange_type(const environment& env,
18081 					     const string&	name,
18082 					     bound_value	upper_bound,
18083 					     const location&	loc,
18084 					     translation_unit::language l)
18085   : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18086     type_base(env, upper_bound.get_unsigned_value(), 0),
18087     decl_base(env, name, loc, ""),
18088     priv_(new priv(upper_bound, l))
18089 {
18090   runtime_type_instance(this);
18091 }
18092 
18093 /// Getter of the underlying type of the subrange, that is, the type
18094 /// that defines the range.
18095 ///
18096 /// @return the underlying type.
18097 type_base_sptr
get_underlying_type() const18098 array_type_def::subrange_type::get_underlying_type() const
18099 {return priv_->underlying_type_.lock();}
18100 
18101 /// Setter of the underlying type of the subrange, that is, the type
18102 /// that defines the range.
18103 ///
18104 /// @param u the new underlying type.
18105 void
set_underlying_type(const type_base_sptr & u)18106 array_type_def::subrange_type::set_underlying_type(const type_base_sptr &u)
18107 {
18108   ABG_ASSERT(priv_->underlying_type_.expired());
18109   priv_->underlying_type_ = u;
18110 }
18111 
18112 /// Getter of the upper bound of the subrange type.
18113 ///
18114 /// @return the upper bound of the subrange type.
18115 int64_t
get_upper_bound() const18116 array_type_def::subrange_type::get_upper_bound() const
18117 {return priv_->upper_bound_.get_signed_value();}
18118 
18119 /// Getter of the lower bound of the subrange type.
18120 ///
18121 /// @return the lower bound of the subrange type.
18122 int64_t
get_lower_bound() const18123 array_type_def::subrange_type::get_lower_bound() const
18124 {return priv_->lower_bound_.get_signed_value();}
18125 
18126 /// Setter of the upper bound of the subrange type.
18127 ///
18128 /// @param ub the new value of the upper bound.
18129 void
set_upper_bound(int64_t ub)18130 array_type_def::subrange_type::set_upper_bound(int64_t ub)
18131 {priv_->upper_bound_ = ub;}
18132 
18133 /// Setter of the lower bound.
18134 ///
18135 /// @param lb the new value of the lower bound.
18136 void
set_lower_bound(int64_t lb)18137 array_type_def::subrange_type::set_lower_bound(int64_t lb)
18138 {priv_->lower_bound_ = lb;}
18139 
18140 /// Getter of the length of the subrange type.
18141 ///
18142 /// Note that a length of zero means the array has an infinite (or
18143 /// rather a non-known) size.
18144 ///
18145 /// @return the length of the subrange type.
18146 uint64_t
get_length() const18147 array_type_def::subrange_type::get_length() const
18148 {
18149   if (is_infinite())
18150     return 0;
18151 
18152   // A subrange can have an upper bound that is lower than its lower
18153   // bound.  This is possible in Ada for instance.  In that case, the
18154   // length of the subrange is considered to be zero.
18155   if (get_upper_bound() >= get_lower_bound())
18156     return get_upper_bound() - get_lower_bound() + 1;
18157   return 0;
18158 }
18159 
18160 /// Test if the length of the subrange type is infinite.
18161 ///
18162 /// @return true iff the length of the subrange type is infinite.
18163 bool
is_infinite() const18164 array_type_def::subrange_type::is_infinite() const
18165 {return priv_->infinite_;}
18166 
18167 /// Set the infinite-ness status of the subrange type.
18168 ///
18169 /// @param f true iff the length of the subrange type should be set to
18170 /// being infinite.
18171 void
is_infinite(bool f)18172 array_type_def::subrange_type::is_infinite(bool f)
18173 {priv_->infinite_ = f;}
18174 
18175 /// Getter of the language that generated this type.
18176 ///
18177 /// @return the language of this type.
18178 translation_unit::language
get_language() const18179 array_type_def::subrange_type::get_language() const
18180 {return priv_->language_;}
18181 
18182 /// Return a string representation of the sub range.
18183 ///
18184 /// @return the string representation of the sub range.
18185 string
as_string() const18186 array_type_def::subrange_type::as_string() const
18187 {
18188   std::ostringstream o;
18189 
18190   if (is_ada_language(get_language()))
18191     {
18192       type_base_sptr underlying_type = get_underlying_type();
18193       if (underlying_type)
18194 	o << ir::get_pretty_representation(underlying_type, false) << " ";
18195       o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
18196     }
18197   else if (is_infinite())
18198     o << "[]";
18199   else
18200     o << "["  << get_length() << "]";
18201 
18202   return o.str();
18203 }
18204 
18205 /// Return a string representation of a vector of subranges
18206 ///
18207 /// @return the string representation of a vector of sub ranges.
18208 string
vector_as_string(const vector<subrange_sptr> & v)18209 array_type_def::subrange_type::vector_as_string(const vector<subrange_sptr>& v)
18210 {
18211   if (v.empty())
18212     return "[]";
18213 
18214   string r;
18215   for (vector<subrange_sptr>::const_iterator i = v.begin();
18216        i != v.end();
18217        ++i)
18218     r += (*i)->as_string();
18219 
18220   return r;
18221 }
18222 
18223 /// Compares two isntances of @ref array_type_def::subrange_type.
18224 ///
18225 /// If the two intances are different, set a bitfield to give some
18226 /// insight about the kind of differences there are.
18227 ///
18228 /// @param l the first artifact of the comparison.
18229 ///
18230 /// @param r the second artifact of the comparison.
18231 ///
18232 /// @param k a pointer to a bitfield that gives information about the
18233 /// kind of changes there are between @p l and @p r.  This one is set
18234 /// iff @p k is non-null and the function returns false.
18235 ///
18236 /// Please note that setting k to a non-null value does have a
18237 /// negative performance impact because even if @p l and @p r are not
18238 /// equal, the function keeps up the comparison in order to determine
18239 /// the different kinds of ways in which they are different.
18240 ///
18241 /// @return true if @p l equals @p r, false otherwise.
18242 bool
equals(const array_type_def::subrange_type & l,const array_type_def::subrange_type & r,change_kind * k)18243 equals(const array_type_def::subrange_type& l,
18244        const array_type_def::subrange_type& r,
18245        change_kind* k)
18246 {
18247   bool result = true;
18248 
18249   if (l.get_lower_bound() != r.get_lower_bound()
18250       || l.get_upper_bound() != r.get_upper_bound()
18251       || l.get_name() != r.get_name())
18252     {
18253       result = false;
18254       if (k)
18255 	*k |= LOCAL_TYPE_CHANGE_KIND;
18256       else
18257 	ABG_RETURN(result);
18258     }
18259 
18260   ABG_RETURN(result);
18261 }
18262 
18263 /// Equality operator.
18264 ///
18265 /// @param o the other subrange to test against.
18266 ///
18267 /// @return true iff @p o equals the current instance of
18268 /// array_type_def::subrange_type.
18269 bool
operator ==(const decl_base & o) const18270 array_type_def::subrange_type::operator==(const decl_base& o) const
18271 {
18272   const subrange_type* other =
18273     dynamic_cast<const subrange_type*>(&o);
18274   if (!other)
18275     return false;
18276   return try_canonical_compare(this, other);
18277 }
18278 
18279 /// Equality operator.
18280 ///
18281 /// @param o the other subrange to test against.
18282 ///
18283 /// @return true iff @p o equals the current instance of
18284 /// array_type_def::subrange_type.
18285 bool
operator ==(const type_base & o) const18286 array_type_def::subrange_type::operator==(const type_base& o) const
18287 {
18288   const decl_base* other = dynamic_cast<const decl_base*>(&o);
18289   if (!other)
18290     return false;
18291   return *this == *other;
18292 }
18293 
18294 /// Equality operator.
18295 ///
18296 /// @param o the other subrange to test against.
18297 ///
18298 /// @return true iff @p o equals the current instance of
18299 /// array_type_def::subrange_type.
18300 bool
operator ==(const subrange_type & o) const18301 array_type_def::subrange_type::operator==(const subrange_type& o) const
18302 {
18303   const type_base &t = o;
18304   return operator==(t);
18305 }
18306 
18307 /// Equality operator.
18308 ///
18309 /// @param o the other subrange to test against.
18310 ///
18311 /// @return true iff @p o equals the current instance of
18312 /// array_type_def::subrange_type.
18313 bool
operator !=(const decl_base & o) const18314 array_type_def::subrange_type::operator!=(const decl_base& o) const
18315 {return !operator==(o);}
18316 
18317 /// Equality operator.
18318 ///
18319 /// @param o the other subrange to test against.
18320 ///
18321 /// @return true iff @p o equals the current instance of
18322 /// array_type_def::subrange_type.
18323 bool
operator !=(const type_base & o) const18324 array_type_def::subrange_type::operator!=(const type_base& o) const
18325 {return !operator==(o);}
18326 
18327 /// Inequality operator.
18328 ///
18329 /// @param o the other subrange to test against.
18330 ///
18331 /// @return true iff @p o is different from the current instance of
18332 /// array_type_def::subrange_type.
18333 bool
operator !=(const subrange_type & o) const18334 array_type_def::subrange_type::operator!=(const subrange_type& o) const
18335 {return !operator==(o);}
18336 
18337 /// Build a pretty representation for an
18338 /// array_type_def::subrange_type.
18339 ///
18340 /// @param internal set to true if the call is intended to get a
18341 /// representation of the decl (or type) for the purpose of canonical
18342 /// type comparison.  This is mainly used in the function
18343 /// type_base::get_canonical_type_for().
18344 ///
18345 /// In other words if the argument for this parameter is true then the
18346 /// call is meant for internal use (for technical use inside the
18347 /// library itself), false otherwise.  If you don't know what this is
18348 /// for, then set it to false.
18349 ///
18350 /// @return a copy of the pretty representation of the current
18351 /// instance of typedef_decl.
18352 string
get_pretty_representation(bool,bool) const18353 array_type_def::subrange_type::get_pretty_representation(bool, bool) const
18354 {
18355   string name = get_name();
18356   string repr;
18357 
18358   if (name.empty())
18359     repr += "<anonymous range>";
18360   else
18361     repr += "<range " + get_name() + ">";
18362   repr += as_string();
18363 
18364   return repr;
18365 }
18366 
18367 /// This implements the ir_traversable_base::traverse pure virtual
18368 /// function.
18369 ///
18370 /// @param v the visitor used on the current instance.
18371 ///
18372 /// @return true if the entire IR node tree got traversed, false
18373 /// otherwise.
18374 bool
traverse(ir_node_visitor & v)18375 array_type_def::subrange_type::traverse(ir_node_visitor& v)
18376 {
18377   if (v.type_node_has_been_visited(this))
18378     return true;
18379 
18380   if (v.visit_begin(this))
18381     {
18382       visiting(true);
18383       if (type_base_sptr u = get_underlying_type())
18384 	u->traverse(v);
18385       visiting(false);
18386     }
18387 
18388   bool result = v.visit_end(this);
18389   v.mark_type_node_as_visited(this);
18390   return result;
18391 }
18392 
18393 // </array_type_def::subrange_type>
18394 
18395 struct array_type_def::priv
18396 {
18397   type_base_wptr	element_type_;
18398   subranges_type	subranges_;
18399   interned_string	temp_internal_qualified_name_;
18400   interned_string	internal_qualified_name_;
18401 
privabigail::ir::array_type_def::priv18402   priv(type_base_sptr t)
18403     : element_type_(t)
18404   {}
18405 
privabigail::ir::array_type_def::priv18406   priv(type_base_sptr t, subranges_type subs)
18407     : element_type_(t), subranges_(subs)
18408   {}
18409 
privabigail::ir::array_type_def::priv18410   priv()
18411   {}
18412 };
18413 
18414 /// Constructor for the type array_type_def
18415 ///
18416 /// Note how the constructor expects a vector of subrange
18417 /// objects. Parsing of the array information always entails
18418 /// parsing the subrange info as well, thus the class subrange_type
18419 /// is defined inside class array_type_def and also parsed
18420 /// simultaneously.
18421 ///
18422 /// @param e_type the type of the elements contained in the array
18423 ///
18424 /// @param subs a vector of the array's subranges(dimensions)
18425 ///
18426 /// @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)18427 array_type_def::array_type_def(const type_base_sptr			e_type,
18428 			       const std::vector<subrange_sptr>&	subs,
18429 			       const location&				locus)
18430   : type_or_decl_base(e_type->get_environment(),
18431 		      ARRAY_TYPE
18432 		      | ABSTRACT_TYPE_BASE
18433 		      | ABSTRACT_DECL_BASE),
18434     type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
18435     decl_base(e_type->get_environment(), locus),
18436     priv_(new priv(e_type))
18437 {
18438   runtime_type_instance(this);
18439   append_subranges(subs);
18440 }
18441 
18442 /// Constructor for the type array_type_def
18443 ///
18444 /// This constructor builds a temporary array that has no element type
18445 /// associated.  Later when the element type is available, it be set
18446 /// with the array_type_def::set_element_type() member function.
18447 ///
18448 /// Note how the constructor expects a vector of subrange
18449 /// objects. Parsing of the array information always entails
18450 /// parsing the subrange info as well, thus the class subrange_type
18451 /// is defined inside class array_type_def and also parsed
18452 /// simultaneously.
18453 ///
18454 /// @param env the environment of the array type.
18455 ///
18456 /// @param subs a vector of the array's subranges(dimensions)
18457 ///
18458 /// @param locus the source location of the array type definition.
array_type_def(const environment & env,const std::vector<subrange_sptr> & subs,const location & locus)18459 array_type_def::array_type_def(const environment&				env,
18460 			       const std::vector<subrange_sptr>&	subs,
18461 			       const location&				locus)
18462   : type_or_decl_base(env,
18463 		      ARRAY_TYPE
18464 		      | ABSTRACT_TYPE_BASE
18465 		      | ABSTRACT_DECL_BASE),
18466     type_base(env, 0, 0),
18467     decl_base(env, locus),
18468     priv_(new priv)
18469 {
18470   runtime_type_instance(this);
18471   append_subranges(subs);
18472 }
18473 
18474 /// Update the size of the array.
18475 ///
18476 /// This function computes the size of the array and sets it using
18477 /// type_base::set_size_in_bits().
18478 void
update_size()18479 array_type_def::update_size()
18480 {
18481   type_base_sptr e = priv_->element_type_.lock();
18482   if (e)
18483     {
18484       size_t s = e->get_size_in_bits();
18485       if (s)
18486 	{
18487 	  for (const auto &sub : get_subranges())
18488 	    s *= sub->get_length();
18489 	  set_size_in_bits(s);
18490 	}
18491       set_alignment_in_bits(e->get_alignment_in_bits());
18492     }
18493 }
18494 
18495 string
get_subrange_representation() const18496 array_type_def::get_subrange_representation() const
18497 {
18498   string r = subrange_type::vector_as_string(get_subranges());
18499   return r;
18500 }
18501 
18502 /// Get the string representation of an @ref array_type_def.
18503 ///
18504 /// @param a the array type to consider.
18505 ///
18506 /// @param internal set to true if the call is intended for an
18507 /// internal use (for technical use inside the library itself), false
18508 /// otherwise.  If you don't know what this is for, then set it to
18509 /// false.
18510 static string
get_type_representation(const array_type_def & a,bool internal)18511 get_type_representation(const array_type_def& a, bool internal)
18512 {
18513   type_base_sptr e_type = a.get_element_type();
18514   decl_base_sptr d = get_type_declaration(e_type);
18515   string r;
18516 
18517   if (is_ada_language(a.get_language()))
18518     {
18519       std::ostringstream o;
18520       o << "array ("
18521 	<< a.get_subrange_representation()
18522 	<< ") of "
18523 	<<  e_type ? e_type->get_pretty_representation(internal):string("void");
18524     }
18525   else
18526     {
18527       if (internal)
18528 	r = (e_type
18529 	     ? get_type_name(e_type,
18530 			     /*qualified=*/true,
18531 			     /*internal=*/true)
18532 	     : string("void"))
18533 	  + a.get_subrange_representation();
18534       else
18535 	r = (e_type
18536 	     ? get_type_name(e_type, /*qualified=*/true, /*internal=*/false)
18537 	     : string("void"))
18538 	  + a.get_subrange_representation();
18539     }
18540 
18541   return r;
18542 }
18543 
18544 /// Get the pretty representation of the current instance of @ref
18545 /// array_type_def.
18546 ///
18547 /// @param internal set to true if the call is intended to get a
18548 /// representation of the decl (or type) for the purpose of canonical
18549 /// type comparison.  This is mainly used in the function
18550 /// type_base::get_canonical_type_for().
18551 ///
18552 /// In other words if the argument for this parameter is true then the
18553 /// call is meant for internal use (for technical use inside the
18554 /// library itself), false otherwise.  If you don't know what this is
18555 /// for, then set it to false.
18556 /// @param internal set to true if the call is intended for an
18557 /// internal use (for technical use inside the library itself), false
18558 /// otherwise.  If you don't know what this is for, then set it to
18559 /// false.
18560 ///
18561 /// @return the pretty representation of the ABI artifact.
18562 string
get_pretty_representation(bool internal,bool) const18563 array_type_def::get_pretty_representation(bool internal,
18564 					  bool /*qualified_name*/) const
18565 {return get_type_representation(*this, internal);}
18566 
18567 /// Compares two instances of @ref array_type_def.
18568 ///
18569 /// If the two intances are different, set a bitfield to give some
18570 /// insight about the kind of differences there are.
18571 ///
18572 /// @param l the first artifact of the comparison.
18573 ///
18574 /// @param r the second artifact of the comparison.
18575 ///
18576 /// @param k a pointer to a bitfield that gives information about the
18577 /// kind of changes there are between @p l and @p r.  This one is set
18578 /// iff @p k is non-null and the function returns false.
18579 ///
18580 /// Please note that setting k to a non-null value does have a
18581 /// negative performance impact because even if @p l and @p r are not
18582 /// equal, the function keeps up the comparison in order to determine
18583 /// the different kinds of ways in which they are different.
18584 ///
18585 /// @return true if @p l equals @p r, false otherwise.
18586 bool
equals(const array_type_def & l,const array_type_def & r,change_kind * k)18587 equals(const array_type_def& l, const array_type_def& r, change_kind* k)
18588 {
18589   std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
18590   std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
18591 
18592   bool result = true;
18593   if (this_subs.size() != other_subs.size())
18594     {
18595       result = false;
18596       if (k)
18597 	*k |= LOCAL_TYPE_CHANGE_KIND;
18598       else
18599 	ABG_RETURN_FALSE;
18600     }
18601 
18602   std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
18603   for (i = this_subs.begin(), j = other_subs.begin();
18604        i != this_subs.end() && j != other_subs.end();
18605        ++i, ++j)
18606     if (**i != **j)
18607       {
18608 	result = false;
18609 	if (k)
18610 	  {
18611 	    *k |= LOCAL_TYPE_CHANGE_KIND;
18612 	    break;
18613 	  }
18614 	else
18615 	  ABG_RETURN_FALSE;
18616       }
18617 
18618   // Compare the element types modulo the typedefs they might have
18619   if (l.get_element_type() != r.get_element_type())
18620     {
18621       result = false;
18622       if (k)
18623 	*k |= SUBTYPE_CHANGE_KIND;
18624       else
18625 	ABG_RETURN_FALSE;
18626     }
18627 
18628   ABG_RETURN(result);
18629 }
18630 
18631 /// Test if two variables are equals modulo CV qualifiers.
18632 ///
18633 /// @param l the first array of the comparison.
18634 ///
18635 /// @param r the second array of the comparison.
18636 ///
18637 /// @return true iff @p l equals @p r or, if they are different, the
18638 /// difference between the too is just a matter of CV qualifiers.
18639 bool
equals_modulo_cv_qualifier(const array_type_def * l,const array_type_def * r)18640 equals_modulo_cv_qualifier(const array_type_def* l, const array_type_def* r)
18641 {
18642   if (l == r)
18643     return true;
18644 
18645   if (!l || !r)
18646     ABG_RETURN_FALSE;
18647 
18648   l = is_array_type(peel_qualified_or_typedef_type(l));
18649   r = is_array_type(peel_qualified_or_typedef_type(r));
18650 
18651   std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
18652   std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
18653 
18654   if (this_subs.size() != other_subs.size())
18655     ABG_RETURN_FALSE;
18656 
18657   std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
18658   for (i = this_subs.begin(), j = other_subs.begin();
18659        i != this_subs.end() && j != other_subs.end();
18660        ++i, ++j)
18661     if (**i != **j)
18662       ABG_RETURN_FALSE;
18663 
18664   type_base *first_element_type =
18665     peel_qualified_or_typedef_type(l->get_element_type().get());
18666   type_base *second_element_type =
18667     peel_qualified_or_typedef_type(r->get_element_type().get());
18668 
18669   if (*first_element_type != *second_element_type)
18670     ABG_RETURN_FALSE;
18671 
18672   return true;
18673 }
18674 
18675 /// Get the language of the array.
18676 ///
18677 /// @return the language of the array.
18678 translation_unit::language
get_language() const18679 array_type_def::get_language() const
18680 {
18681   const std::vector<subrange_sptr>& subranges =
18682     get_subranges();
18683 
18684   if (subranges.empty())
18685     return translation_unit::LANG_C11;
18686   return subranges.front()->get_language();
18687 }
18688 
18689 bool
operator ==(const decl_base & o) const18690 array_type_def::operator==(const decl_base& o) const
18691 {
18692   const array_type_def* other =
18693     dynamic_cast<const array_type_def*>(&o);
18694   if (!other)
18695     return false;
18696   return try_canonical_compare(this, other);
18697 }
18698 
18699 bool
operator ==(const type_base & o) const18700 array_type_def::operator==(const type_base& o) const
18701 {
18702   const decl_base* other = dynamic_cast<const decl_base*>(&o);
18703   if (!other)
18704     return false;
18705   return *this == *other;
18706 }
18707 
18708 /// Getter of the type of an array element.
18709 ///
18710 /// @return the type of an array element.
18711 const type_base_sptr
get_element_type() const18712 array_type_def::get_element_type() const
18713 {return priv_->element_type_.lock();}
18714 
18715 /// Setter of the type of array element.
18716 ///
18717 /// Beware that after using this function, one might want to
18718 /// re-compute the canonical type of the array, if one has already
18719 /// been computed.
18720 ///
18721 /// The intended use of this method is to permit in-place adjustment
18722 /// of the element type's qualifiers. In particular, the size of the
18723 /// element type should not be changed.
18724 ///
18725 /// @param element_type the new element type to set.
18726 void
set_element_type(const type_base_sptr & element_type)18727 array_type_def::set_element_type(const type_base_sptr& element_type)
18728 {
18729   priv_->element_type_ = element_type;
18730   update_size();
18731   set_name(get_environment().intern(get_pretty_representation()));
18732 }
18733 
18734 /// Append subranges from the vector @param subs to the current
18735 /// vector of subranges.
18736 void
append_subranges(const std::vector<subrange_sptr> & subs)18737 array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
18738 {
18739 
18740   for (const auto &sub : subs)
18741     priv_->subranges_.push_back(sub);
18742 
18743   update_size();
18744   set_name(get_environment().intern(get_pretty_representation()));
18745 }
18746 
18747 /// @return true if one of the sub-ranges of the array is infinite, or
18748 /// if the array has no sub-range at all, also meaning that the size
18749 /// of the array is infinite.
18750 bool
is_infinite() const18751 array_type_def::is_infinite() const
18752 {
18753   if (priv_->subranges_.empty())
18754     return true;
18755 
18756   for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
18757 	 priv_->subranges_.begin();
18758        i != priv_->subranges_.end();
18759        ++i)
18760     if ((*i)->is_infinite())
18761       return true;
18762 
18763   return false;
18764 }
18765 
18766 int
get_dimension_count() const18767 array_type_def::get_dimension_count() const
18768 {return priv_->subranges_.size();}
18769 
18770 /// Build and return the qualified name of the current instance of the
18771 /// @ref array_type_def.
18772 ///
18773 /// @param qn output parameter.  Is set to the newly-built qualified
18774 /// name of the current instance of @ref array_type_def.
18775 ///
18776 /// @param internal set to true if the call is intended for an
18777 /// internal use (for technical use inside the library itself), false
18778 /// otherwise.  If you don't know what this is for, then set it to
18779 /// false.
18780 void
get_qualified_name(interned_string & qn,bool internal) const18781 array_type_def::get_qualified_name(interned_string& qn, bool internal) const
18782 {qn = get_qualified_name(internal);}
18783 
18784 /// Compute the qualified name of the array.
18785 ///
18786 /// @param internal set to true if the call is intended for an
18787 /// internal use (for technical use inside the library itself), false
18788 /// otherwise.  If you don't know what this is for, then set it to
18789 /// false.
18790 ///
18791 /// @return the resulting qualified name.
18792 const interned_string&
get_qualified_name(bool internal) const18793 array_type_def::get_qualified_name(bool internal) const
18794 {
18795   const environment& env = get_environment();
18796 
18797 
18798   if (internal)
18799     {
18800       if (get_canonical_type())
18801 	{
18802 	  if (priv_->internal_qualified_name_.empty())
18803 	    priv_->internal_qualified_name_ =
18804 	      env.intern(get_type_representation(*this, /*internal=*/true));
18805 	  return priv_->internal_qualified_name_;
18806 	}
18807       else
18808 	{
18809 	  priv_->temp_internal_qualified_name_ =
18810 	    env.intern(get_type_representation(*this, /*internal=*/true));
18811 	  return priv_->temp_internal_qualified_name_;
18812 	}
18813     }
18814   else
18815     {
18816       if (get_canonical_type())
18817 	{
18818 	  if (decl_base::peek_qualified_name().empty())
18819 	    set_qualified_name(env.intern(get_type_representation
18820 					   (*this, /*internal=*/false)));
18821 	  return decl_base::peek_qualified_name();
18822 	}
18823       else
18824 	{
18825 	  set_temporary_qualified_name(env.intern(get_type_representation
18826 						   (*this,
18827 						    /*internal=*/false)));
18828 	  return decl_base::peek_temporary_qualified_name();
18829 	}
18830     }
18831 }
18832 
18833 /// This implements the ir_traversable_base::traverse pure virtual
18834 /// function.
18835 ///
18836 /// @param v the visitor used on the current instance.
18837 ///
18838 /// @return true if the entire IR node tree got traversed, false
18839 /// otherwise.
18840 bool
traverse(ir_node_visitor & v)18841 array_type_def::traverse(ir_node_visitor& v)
18842 {
18843   if (v.type_node_has_been_visited(this))
18844     return true;
18845 
18846   if (visiting())
18847     return true;
18848 
18849   if (v.visit_begin(this))
18850     {
18851       visiting(true);
18852       if (type_base_sptr t = get_element_type())
18853 	t->traverse(v);
18854       visiting(false);
18855     }
18856 
18857   bool result = v.visit_end(this);
18858   v.mark_type_node_as_visited(this);
18859   return result;
18860 }
18861 
18862 const location&
get_location() const18863 array_type_def::get_location() const
18864 {return decl_base::get_location();}
18865 
18866 /// Get the array's subranges
18867 const std::vector<array_type_def::subrange_sptr>&
get_subranges() const18868 array_type_def::get_subranges() const
18869 {return priv_->subranges_;}
18870 
~array_type_def()18871 array_type_def::~array_type_def()
18872 {}
18873 
18874 // </array_type_def definitions>
18875 
18876 // <enum_type_decl definitions>
18877 
18878 class enum_type_decl::priv
18879 {
18880   type_base_sptr	underlying_type_;
18881   enumerators		enumerators_;
18882   mutable enumerators	sorted_enumerators_;
18883 
18884   friend class enum_type_decl;
18885 
18886   priv();
18887 
18888 public:
priv(type_base_sptr underlying_type,enumerators & enumerators)18889   priv(type_base_sptr underlying_type,
18890        enumerators& enumerators)
18891     : underlying_type_(underlying_type),
18892       enumerators_(enumerators)
18893   {}
18894 }; // end class enum_type_decl::priv
18895 
18896 /// Constructor.
18897 ///
18898 /// @param name the name of the type declaration.
18899 ///
18900 /// @param locus the source location where the type was defined.
18901 ///
18902 /// @param underlying_type the underlying type of the enum.
18903 ///
18904 /// @param enums the enumerators of this enum type.
18905 ///
18906 /// @param linkage_name the linkage name of the enum.
18907 ///
18908 /// @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)18909 enum_type_decl::enum_type_decl(const string&	name,
18910 			       const location&	locus,
18911 			       type_base_sptr	underlying_type,
18912 			       enumerators&	enums,
18913 			       const string&	linkage_name,
18914 			       visibility	vis)
18915   : type_or_decl_base(underlying_type->get_environment(),
18916 		      ENUM_TYPE
18917 		      | ABSTRACT_TYPE_BASE
18918 		      | ABSTRACT_DECL_BASE),
18919     type_base(underlying_type->get_environment(),
18920 	      underlying_type->get_size_in_bits(),
18921 	      underlying_type->get_alignment_in_bits()),
18922     decl_base(underlying_type->get_environment(),
18923 	      name, locus, linkage_name, vis),
18924     priv_(new priv(underlying_type, enums))
18925 {
18926   runtime_type_instance(this);
18927   for (enumerators::iterator e = get_enumerators().begin();
18928        e != get_enumerators().end();
18929        ++e)
18930     e->set_enum_type(this);
18931 }
18932 
18933 /// Return the underlying type of the enum.
18934 type_base_sptr
get_underlying_type() const18935 enum_type_decl::get_underlying_type() const
18936 {return priv_->underlying_type_;}
18937 
18938 /// @return the list of enumerators of the enum.
18939 const enum_type_decl::enumerators&
get_enumerators() const18940 enum_type_decl::get_enumerators() const
18941 {return priv_->enumerators_;}
18942 
18943 /// @return the list of enumerators of the enum.
18944 enum_type_decl::enumerators&
get_enumerators()18945 enum_type_decl::get_enumerators()
18946 {return priv_->enumerators_;}
18947 
18948 /// Get the lexicographically sorted vector of enumerators.
18949 ///
18950 /// @return the lexicographically sorted vector of enumerators.
18951 const enum_type_decl::enumerators&
get_sorted_enumerators() const18952 enum_type_decl::get_sorted_enumerators() const
18953 {
18954   if (priv_->sorted_enumerators_.empty())
18955     {
18956       for (auto e = get_enumerators().rbegin();
18957 	   e != get_enumerators().rend();
18958 	   ++e)
18959 	priv_->sorted_enumerators_.push_back(*e);
18960 
18961       std::sort(priv_->sorted_enumerators_.begin(),
18962 		priv_->sorted_enumerators_.end(),
18963 		[](const enum_type_decl::enumerator& l,
18964 		   const enum_type_decl::enumerator& r)
18965 		{
18966 		  if (l.get_name() == r.get_name())
18967 		    return l.get_value() < r.get_value();
18968 		  return (l.get_name() < r.get_name());
18969 		});
18970     }
18971 
18972   return priv_->sorted_enumerators_;
18973 }
18974 
18975 /// Get the pretty representation of the current instance of @ref
18976 /// enum_type_decl.
18977 ///
18978 /// @param internal set to true if the call is intended to get a
18979 /// representation of the decl (or type) for the purpose of canonical
18980 /// type comparison.  This is mainly used in the function
18981 /// type_base::get_canonical_type_for().
18982 ///
18983 /// In other words if the argument for this parameter is true then the
18984 /// call is meant for internal use (for technical use inside the
18985 /// library itself), false otherwise.  If you don't know what this is
18986 /// for, then set it to false.
18987 ///
18988 /// @param qualified_name if true, names emitted in the pretty
18989 /// representation are fully qualified.
18990 ///
18991 /// @return the pretty representation of the enum type.
18992 string
get_pretty_representation(bool internal,bool qualified_name) const18993 enum_type_decl::get_pretty_representation(bool internal,
18994 					  bool qualified_name) const
18995 {
18996   string r = "enum ";
18997 
18998   if (internal && get_is_anonymous())
18999     r += get_type_name(this, qualified_name, /*internal=*/true);
19000   else if (get_is_anonymous())
19001     r += get_enum_flat_representation(*this, "",
19002 				      /*one_line=*/true,
19003 				      qualified_name);
19004   else
19005     r += decl_base::get_pretty_representation(internal,
19006 					      qualified_name);
19007   return r;
19008 }
19009 
19010 /// This implements the ir_traversable_base::traverse pure virtual
19011 /// function.
19012 ///
19013 /// @param v the visitor used on the current instance.
19014 ///
19015 /// @return true if the entire IR node tree got traversed, false
19016 /// otherwise.
19017 bool
traverse(ir_node_visitor & v)19018 enum_type_decl::traverse(ir_node_visitor &v)
19019 {
19020   if (v.type_node_has_been_visited(this))
19021     return true;
19022 
19023   if (visiting())
19024     return true;
19025 
19026   if (v.visit_begin(this))
19027     {
19028       visiting(true);
19029       if (type_base_sptr t = get_underlying_type())
19030 	t->traverse(v);
19031       visiting(false);
19032     }
19033 
19034   bool result = v.visit_end(this);
19035   v.mark_type_node_as_visited(this);
19036   return result;
19037 }
19038 
19039 /// Destructor for the enum type declaration.
~enum_type_decl()19040 enum_type_decl::~enum_type_decl()
19041 {}
19042 
19043 /// Test if two enums differ, but not by a name change.
19044 ///
19045 /// @param l the first enum to consider.
19046 ///
19047 /// @param r the second enum to consider.
19048 ///
19049 /// @return true iff @p l differs from @p r by anything but a name
19050 /// change.
19051 bool
enum_has_non_name_change(const enum_type_decl & l,const enum_type_decl & r,change_kind * k)19052 enum_has_non_name_change(const enum_type_decl& l,
19053 			 const enum_type_decl& r,
19054 			 change_kind* k)
19055 {
19056   bool result = false;
19057   if (*l.get_underlying_type() != *r.get_underlying_type())
19058     {
19059       result = true;
19060       if (k)
19061 	*k |= SUBTYPE_CHANGE_KIND;
19062       else
19063 	return true;
19064     }
19065 
19066   enum_type_decl::enumerators::const_iterator i, j;
19067   for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
19068        i != l.get_enumerators().end() && j != r.get_enumerators().end();
19069        ++i, ++j)
19070     if (*i != *j)
19071       {
19072 	result = true;
19073 	if (k)
19074 	  {
19075 	    *k |= LOCAL_TYPE_CHANGE_KIND;
19076 	    break;
19077 	  }
19078 	else
19079 	  return true;
19080       }
19081 
19082   if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
19083     {
19084       result = true;
19085       if (k)
19086 	*k |= LOCAL_TYPE_CHANGE_KIND;
19087       else
19088 	return true;
19089     }
19090 
19091   enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
19092   interned_string qn_r = l.get_environment().intern(r.get_qualified_name());
19093   interned_string qn_l = l.get_environment().intern(l.get_qualified_name());
19094   string n_l = l.get_name();
19095   string n_r = r.get_name();
19096   local_r.set_qualified_name(qn_l);
19097   local_r.set_name(n_l);
19098 
19099   if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
19100     {
19101       result = true;
19102       if (k)
19103 	{
19104 	  if (!l.decl_base::operator==(r))
19105 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19106 	  if (!l.type_base::operator==(r))
19107 	    *k |= LOCAL_TYPE_CHANGE_KIND;
19108 	}
19109       else
19110 	{
19111 	  local_r.set_name(n_r);
19112 	  local_r.set_qualified_name(qn_r);
19113 	  return true;
19114 	}
19115     }
19116   local_r.set_qualified_name(qn_r);
19117   local_r.set_name(n_r);
19118 
19119   return result;
19120 }
19121 
19122 /// Test if a given enumerator is found present in an enum.
19123 ///
19124 /// This is a subroutine of the equals function for enums.
19125 ///
19126 /// @param enr the enumerator to consider.
19127 ///
19128 /// @param enom the enum to consider.
19129 ///
19130 /// @return true iff the enumerator @p enr is present in the enum @p
19131 /// enom.
19132 bool
is_enumerator_present_in_enum(const enum_type_decl::enumerator & enr,const enum_type_decl & enom)19133 is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr,
19134 			      const enum_type_decl &enom)
19135 {
19136   for (const auto &e : enom.get_enumerators())
19137     if (e == enr)
19138       return true;
19139   return false;
19140 }
19141 
19142 /// Check if two enumerators values are equal.
19143 ///
19144 /// This function doesn't check if the names of the enumerators are
19145 /// equal or not.
19146 ///
19147 /// @param enr the first enumerator to consider.
19148 ///
19149 /// @param enl the second enumerator to consider.
19150 ///
19151 /// @return true iff @p enr has the same value as @p enl.
19152 static bool
enumerators_values_are_equal(const enum_type_decl::enumerator & enr,const enum_type_decl::enumerator & enl)19153 enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
19154 			     const enum_type_decl::enumerator &enl)
19155 {return enr.get_value() == enl.get_value();}
19156 
19157 /// Detect if a given enumerator value is present in an enum.
19158 ///
19159 /// This function looks inside the enumerators of a given enum and
19160 /// detect if the enum contains at least one enumerator or a given
19161 /// value.  The function also detects if the enumerator value we are
19162 /// looking at is present in the enum with a different name.  An
19163 /// enumerator with the same value but with a different name is named
19164 /// a "redundant enumerator".  The function returns the set of
19165 /// enumerators that are redundant with the value we are looking at.
19166 ///
19167 /// @param enr the enumerator to consider.
19168 ///
19169 /// @param enom the enum to consider.
19170 ///
19171 /// @param redundant_enrs if the function returns true, then this
19172 /// vector is filled with enumerators that are redundant with the
19173 /// value of @p enr.
19174 ///
19175 /// @return true iff the function detects that @p enom contains
19176 /// enumerators with the same value as @p enr.
19177 static bool
is_enumerator_value_present_in_enum(const enum_type_decl::enumerator & enr,const enum_type_decl & enom,vector<enum_type_decl::enumerator> & redundant_enrs)19178 is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
19179 				    const enum_type_decl &enom,
19180 				    vector<enum_type_decl::enumerator>& redundant_enrs)
19181 {
19182   bool found = false;
19183   for (const auto &e : enom.get_enumerators())
19184     if (enumerators_values_are_equal(e, enr))
19185       {
19186 	found = true;
19187 	if (e != enr)
19188 	  redundant_enrs.push_back(e);
19189       }
19190 
19191   return found;
19192 }
19193 
19194 /// Check if an enumerator value is redundant in a given enum.
19195 ///
19196 /// Given an enumerator value, this function detects if an enum
19197 /// contains at least one enumerator with the the same value but with
19198 /// a different name.
19199 ///
19200 /// @param enr the enumerator to consider.
19201 ///
19202 /// @param enom the enum to consider.
19203 ///
19204 /// @return true iff @p enr is a redundant enumerator in enom.
19205 static bool
is_enumerator_value_redundant(const enum_type_decl::enumerator & enr,const enum_type_decl & enom)19206 is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
19207 			      const enum_type_decl &enom)
19208 {
19209   vector<enum_type_decl::enumerator> redundant_enrs;
19210   if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
19211     {
19212       if (!redundant_enrs.empty())
19213 	return true;
19214     }
19215     return false;
19216 }
19217 
19218 /// Compares two instances of @ref enum_type_decl.
19219 ///
19220 /// If the two intances are different, set a bitfield to give some
19221 /// insight about the kind of differences there are.
19222 ///
19223 /// @param l the first artifact of the comparison.
19224 ///
19225 /// @param r the second artifact of the comparison.
19226 ///
19227 /// @param k a pointer to a bitfield that gives information about the
19228 /// kind of changes there are between @p l and @p r.  This one is set
19229 /// iff @p k is non-null and the function returns false.
19230 ///
19231 /// Please note that setting k to a non-null value does have a
19232 /// negative performance impact because even if @p l and @p r are not
19233 /// equal, the function keeps up the comparison in order to determine
19234 /// the different kinds of ways in which they are different.
19235 ///
19236 /// @return true if @p l equals @p r, false otherwise.
19237 bool
equals(const enum_type_decl & l,const enum_type_decl & r,change_kind * k)19238 equals(const enum_type_decl& l, const enum_type_decl& r, change_kind* k)
19239 {
19240   bool result = true;
19241 
19242   //
19243   // Look through decl-only-enum.
19244   //
19245 
19246   const enum_type_decl *def1 =
19247     l.get_is_declaration_only()
19248     ? is_enum_type(l.get_naked_definition_of_declaration())
19249     : &l;
19250 
19251   const enum_type_decl *def2 =
19252     r.get_is_declaration_only()
19253     ? is_enum_type(r.get_naked_definition_of_declaration())
19254     : &r;
19255 
19256   if (!!def1 != !!def2)
19257     {
19258       // One enum is decl-only while the other is not.
19259       // So the two enums are different.
19260       result = false;
19261       if (k)
19262 	*k |= SUBTYPE_CHANGE_KIND;
19263       else
19264 	ABG_RETURN_FALSE;
19265     }
19266 
19267   //
19268   // At this point, both enums have the same state of decl-only-ness.
19269   // So we can compare oranges to oranges.
19270   //
19271 
19272   if (!def1)
19273     def1 = &l;
19274   if (!def2)
19275     def2 = &r;
19276 
19277   if (def1->get_underlying_type() != def2->get_underlying_type())
19278     {
19279       result = false;
19280       if (k)
19281 	*k |= SUBTYPE_CHANGE_KIND;
19282       else
19283 	ABG_RETURN_FALSE;
19284     }
19285 
19286   if (!(def1->decl_base::operator==(*def2)
19287 	&& def1->type_base::operator==(*def2)))
19288     {
19289       result = false;
19290       if (k)
19291 	{
19292 	  if (!def1->decl_base::operator==(*def2))
19293 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19294 	  if (!def1->type_base::operator==(*def2))
19295 	    *k |= LOCAL_TYPE_CHANGE_KIND;
19296 	}
19297       else
19298 	ABG_RETURN_FALSE;
19299     }
19300 
19301   // Now compare the enumerators.  Note that the order of declaration
19302   // of enumerators should not matter in the comparison.
19303   //
19304   // Also if an enumerator value is redundant, that shouldn't impact
19305   // the comparison.
19306   //
19307   // In that case, note that the two enums below are considered equal:
19308   //
19309   // enum foo
19310   //     {
19311   //       e0 = 0;
19312   //       e1 = 1;
19313   //       e2 = 2;
19314   //     };
19315   //
19316   //     enum foo
19317   //     {
19318   //       e0 = 0;
19319   //       e1 = 1;
19320   //       e2 = 2;
19321   //       e_added = 1; // <-- this value is redundant with the value
19322   //                    //     of the enumerator e1.
19323   //     };
19324   //
19325   //     Note however that in the case below, the enums are different.
19326   //
19327   // enum foo
19328   // {
19329   //   e0 = 0;
19330   //   e1 = 1;
19331   // };
19332   //
19333   // enum foo
19334   // {
19335   //   e0 = 0;
19336   //   e2 = 1;  // <-- this enum value is present in the first version
19337   //            // of foo, but is not redundant with any enumerator
19338   //            // in the second version of of enum foo.
19339   // };
19340   //
19341   // These two enums are considered equal.
19342 
19343   for(const auto &e : def1->get_enumerators())
19344     if (!is_enumerator_present_in_enum(e, *def2)
19345 	&& (!is_enumerator_value_redundant(e, *def2)
19346 	    || !is_enumerator_value_redundant(e, *def1)))
19347       {
19348 	result = false;
19349 	if (k)
19350 	  {
19351 	    *k |= LOCAL_TYPE_CHANGE_KIND;
19352 	    break;
19353 	  }
19354 	else
19355 	  ABG_RETURN_FALSE;
19356       }
19357 
19358   for(const auto &e : def2->get_enumerators())
19359     if (!is_enumerator_present_in_enum(e, *def1)
19360 	&& (!is_enumerator_value_redundant(e, *def1)
19361 	    || !is_enumerator_value_redundant(e, *def2)))
19362       {
19363 	result = false;
19364 	if (k)
19365 	  {
19366 	    *k |= LOCAL_TYPE_CHANGE_KIND;
19367 	    break;
19368 	  }
19369 	else
19370 	  ABG_RETURN_FALSE;
19371       }
19372 
19373   ABG_RETURN(result);
19374 }
19375 
19376 /// Equality operator.
19377 ///
19378 /// @param o the other enum to test against.
19379 ///
19380 /// @return true iff @p o equals the current instance of enum type
19381 /// decl.
19382 bool
operator ==(const decl_base & o) const19383 enum_type_decl::operator==(const decl_base& o) const
19384 {
19385   const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
19386   if (!op)
19387     return false;
19388   return try_canonical_compare(this, op);
19389 }
19390 
19391 /// Equality operator.
19392 ///
19393 /// @param o the other enum to test against.
19394 ///
19395 /// @return true iff @p o is equals the current instance of enum type
19396 /// decl.
19397 bool
operator ==(const type_base & o) const19398 enum_type_decl::operator==(const type_base& o) const
19399 {
19400   const decl_base* other = dynamic_cast<const decl_base*>(&o);
19401   if (!other)
19402     return false;
19403   return *this == *other;
19404 }
19405 
19406 /// Equality operator for @ref enum_type_decl_sptr.
19407 ///
19408 /// @param l the first operand to compare.
19409 ///
19410 /// @param r the second operand to compare.
19411 ///
19412 /// @return true iff @p l equals @p r.
19413 bool
operator ==(const enum_type_decl_sptr & l,const enum_type_decl_sptr & r)19414 operator==(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
19415 {
19416   if (!!l != !!r)
19417     return false;
19418   if (l.get() == r.get())
19419     return true;
19420   decl_base_sptr o = r;
19421   return *l == *o;
19422 }
19423 
19424 /// Inequality operator for @ref enum_type_decl_sptr.
19425 ///
19426 /// @param l the first operand to compare.
19427 ///
19428 /// @param r the second operand to compare.
19429 ///
19430 /// @return true iff @p l equals @p r.
19431 bool
operator !=(const enum_type_decl_sptr & l,const enum_type_decl_sptr & r)19432 operator!=(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
19433 {return !operator==(l, r);}
19434 
19435 /// The type of the private data of an @ref
19436 /// enum_type_decl::enumerator.
19437 class enum_type_decl::enumerator::priv
19438 {
19439   string		name_;
19440   int64_t		value_;
19441   string		qualified_name_;
19442   enum_type_decl*	enum_type_;
19443 
19444   friend class	enum_type_decl::enumerator;
19445 
19446 public:
19447 
priv()19448   priv()
19449     : enum_type_()
19450   {}
19451 
priv(const string & name,int64_t value,enum_type_decl * e=0)19452   priv(const string& name,
19453        int64_t value,
19454        enum_type_decl* e = 0)
19455     : name_(name),
19456       value_(value),
19457       enum_type_(e)
19458   {}
19459 }; // end class enum_type_def::enumerator::priv
19460 
19461 /// Default constructor of the @ref enum_type_decl::enumerator type.
enumerator()19462 enum_type_decl::enumerator::enumerator()
19463   : priv_(new priv)
19464 {}
19465 
19466 enum_type_decl::enumerator::~enumerator() = default;
19467 
19468 /// Constructor of the @ref enum_type_decl::enumerator type.
19469 ///
19470 /// @param env the environment we are operating from.
19471 ///
19472 /// @param name the name of the enumerator.
19473 ///
19474 /// @param value the value of the enumerator.
enumerator(const string & name,int64_t value)19475 enum_type_decl::enumerator::enumerator(const string& name,
19476 				       int64_t value)
19477   : priv_(new priv(name, value))
19478 {}
19479 
19480 /// Copy constructor of the @ref enum_type_decl::enumerator type.
19481 ///
19482 /// @param other enumerator to copy.
enumerator(const enumerator & other)19483 enum_type_decl::enumerator::enumerator(const enumerator& other)
19484   : priv_(new priv(other.get_name(),
19485 		   other.get_value(),
19486 		   other.get_enum_type()))
19487 {}
19488 
19489 /// Assignment operator of the @ref enum_type_decl::enumerator type.
19490 ///
19491 /// @param o
19492 enum_type_decl::enumerator&
operator =(const enumerator & o)19493 enum_type_decl::enumerator::operator=(const enumerator& o)
19494 {
19495   priv_->name_ = o.get_name();
19496   priv_->value_ = o.get_value();
19497   priv_->enum_type_ = o.get_enum_type();
19498   return *this;
19499 }
19500 
19501 /// Equality operator
19502 ///
19503 /// @param other the enumerator to compare to the current
19504 /// instance of enum_type_decl::enumerator.
19505 ///
19506 /// @return true if @p other equals the current instance of
19507 /// enum_type_decl::enumerator.
19508 bool
operator ==(const enumerator & other) const19509 enum_type_decl::enumerator::operator==(const enumerator& other) const
19510 {
19511   bool names_equal = true;
19512   names_equal = (get_name() == other.get_name());
19513   return names_equal && (get_value() == other.get_value());
19514 }
19515 
19516 /// Inequality operator.
19517 ///
19518 /// @param other the other instance to compare against.
19519 ///
19520 /// @return true iff @p other is different from the current instance.
19521 bool
operator !=(const enumerator & other) const19522 enum_type_decl::enumerator::operator!=(const enumerator& other) const
19523 {return !operator==(other);}
19524 
19525 /// Getter for the name of the current instance of
19526 /// enum_type_decl::enumerator.
19527 ///
19528 /// @return a reference to the name of the current instance of
19529 /// enum_type_decl::enumerator.
19530 const string&
get_name() const19531 enum_type_decl::enumerator::get_name() const
19532 {return priv_->name_;}
19533 
19534 /// Getter for the qualified name of the current instance of
19535 /// enum_type_decl::enumerator.  The first invocation of the method
19536 /// builds the qualified name, caches it and return a reference to the
19537 /// cached qualified name.  Subsequent invocations just return the
19538 /// cached value.
19539 ///
19540 /// @param internal set to true if the call is intended for an
19541 /// internal use (for technical use inside the library itself), false
19542 /// otherwise.  If you don't know what this is for, then set it to
19543 /// false.
19544 ///
19545 /// @return the qualified name of the current instance of
19546 /// enum_type_decl::enumerator.
19547 const string&
get_qualified_name(bool internal) const19548 enum_type_decl::enumerator::get_qualified_name(bool internal) const
19549 {
19550   if (priv_->qualified_name_.empty())
19551     {
19552       priv_->qualified_name_ =
19553 	get_enum_type()->get_qualified_name(internal)
19554 	+ "::"
19555 	+ get_name();
19556     }
19557   return priv_->qualified_name_;
19558 }
19559 
19560 /// Setter for the name of @ref enum_type_decl::enumerator.
19561 ///
19562 /// @param n the new name.
19563 void
set_name(const string & n)19564 enum_type_decl::enumerator::set_name(const string& n)
19565 {priv_->name_ = n;}
19566 
19567 /// Getter for the value of @ref enum_type_decl::enumerator.
19568 ///
19569 /// @return the value of the current instance of
19570 /// enum_type_decl::enumerator.
19571 int64_t
get_value() const19572 enum_type_decl::enumerator::get_value() const
19573 {return priv_->value_;}
19574 
19575 /// Setter for the value of @ref enum_type_decl::enumerator.
19576 ///
19577 /// @param v the new value of the enum_type_decl::enumerator.
19578 void
set_value(int64_t v)19579 enum_type_decl::enumerator::set_value(int64_t v)
19580 {priv_->value_= v;}
19581 
19582 /// Getter for the enum type that this enumerator is for.
19583 ///
19584 /// @return the enum type that this enumerator is for.
19585 enum_type_decl*
get_enum_type() const19586 enum_type_decl::enumerator::get_enum_type() const
19587 {return priv_->enum_type_;}
19588 
19589 /// Setter for the enum type that this enumerator is for.
19590 ///
19591 /// @param e the new enum type.
19592 void
set_enum_type(enum_type_decl * e)19593 enum_type_decl::enumerator::set_enum_type(enum_type_decl* e)
19594 {priv_->enum_type_ = e;}
19595 // </enum_type_decl definitions>
19596 
19597 // <typedef_decl definitions>
19598 
19599 /// Private data structure of the @ref typedef_decl.
19600 struct typedef_decl::priv
19601 {
19602   type_base_wptr	underlying_type_;
19603 
privabigail::ir::typedef_decl::priv19604   priv(const type_base_sptr& t)
19605     : underlying_type_(t)
19606   {}
19607 }; // end struct typedef_decl::priv
19608 
19609 /// Constructor of the typedef_decl type.
19610 ///
19611 /// @param name the name of the typedef.
19612 ///
19613 /// @param underlying_type the underlying type of the typedef.
19614 ///
19615 /// @param locus the source location of the typedef declaration.
19616 ///
19617 /// @param linkage_name the mangled name of the typedef.
19618 ///
19619 /// @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)19620 typedef_decl::typedef_decl(const string&		name,
19621 			   const type_base_sptr	underlying_type,
19622 			   const location&		locus,
19623 			   const string&		linkage_name,
19624 			   visibility vis)
19625   : type_or_decl_base(underlying_type->get_environment(),
19626 		      TYPEDEF_TYPE
19627 		      | ABSTRACT_TYPE_BASE
19628 		      | ABSTRACT_DECL_BASE),
19629     type_base(underlying_type->get_environment(),
19630 	      underlying_type->get_size_in_bits(),
19631 	      underlying_type->get_alignment_in_bits()),
19632     decl_base(underlying_type->get_environment(),
19633 	      name, locus, linkage_name, vis),
19634     priv_(new priv(underlying_type))
19635 {
19636   runtime_type_instance(this);
19637 }
19638 
19639 /// Constructor of the typedef_decl type.
19640 ///
19641 /// @param name the name of the typedef.
19642 ///
19643 /// @param env the environment of the current typedef.
19644 ///
19645 /// @param locus the source location of the typedef declaration.
19646 ///
19647 /// @param mangled_name the mangled name of the typedef.
19648 ///
19649 /// @param vis the visibility of the typedef type.
typedef_decl(const string & name,const environment & env,const location & locus,const string & mangled_name,visibility vis)19650 typedef_decl::typedef_decl(const string& name,
19651 			   const environment& env,
19652 			   const location& locus,
19653 			   const string& mangled_name,
19654 			   visibility vis)
19655   : type_or_decl_base(env,
19656 		      TYPEDEF_TYPE
19657 		      | ABSTRACT_TYPE_BASE
19658 		      | ABSTRACT_DECL_BASE),
19659     type_base(env, /*size_in_bits=*/0,
19660 	      /*alignment_in_bits=*/0),
19661     decl_base(env, name, locus, mangled_name, vis),
19662     priv_(new priv(nullptr))
19663 {
19664   runtime_type_instance(this);
19665 }
19666 
19667 /// Return the size of the typedef.
19668 ///
19669 /// This function looks at the size of the underlying type and ensures
19670 /// that it's the same as the size of the typedef.
19671 ///
19672 /// @return the size of the typedef.
19673 size_t
get_size_in_bits() const19674 typedef_decl::get_size_in_bits() const
19675 {
19676   if (!get_underlying_type())
19677     return 0;
19678   size_t s = get_underlying_type()->get_size_in_bits();
19679   if (s != type_base::get_size_in_bits())
19680     const_cast<typedef_decl*>(this)->set_size_in_bits(s);
19681   return type_base::get_size_in_bits();
19682 }
19683 
19684 /// Return the alignment of the typedef.
19685 ///
19686 /// This function looks at the alignment of the underlying type and
19687 /// ensures that it's the same as the alignment of the typedef.
19688 ///
19689 /// @return the size of the typedef.
19690 size_t
get_alignment_in_bits() const19691 typedef_decl::get_alignment_in_bits() const
19692 {
19693   if (!get_underlying_type())
19694     return 0;
19695   size_t s = get_underlying_type()->get_alignment_in_bits();
19696   if (s != type_base::get_alignment_in_bits())
19697     const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
19698   return type_base::get_alignment_in_bits();
19699 }
19700 
19701 /// Compares two instances of @ref typedef_decl.
19702 ///
19703 /// If the two intances are different, set a bitfield to give some
19704 /// insight about the kind of differences there are.
19705 ///
19706 /// @param l the first artifact of the comparison.
19707 ///
19708 /// @param r the second artifact of the comparison.
19709 ///
19710 /// @param k a pointer to a bitfield that gives information about the
19711 /// kind of changes there are between @p l and @p r.  This one is set
19712 /// iff @p k is non-null and the function returns false.
19713 ///
19714 /// Please note that setting k to a non-null value does have a
19715 /// negative performance impact because even if @p l and @p r are not
19716 /// equal, the function keeps up the comparison in order to determine
19717 /// the different kinds of ways in which they are different.
19718 ///
19719 /// @return true if @p l equals @p r, false otherwise.
19720 bool
equals(const typedef_decl & l,const typedef_decl & r,change_kind * k)19721 equals(const typedef_decl& l, const typedef_decl& r, change_kind* k)
19722 {
19723   bool result = true;
19724 
19725   // No need to go further if the types have different names or
19726   // different size / alignment.
19727   if (!(l.decl_base::operator==(r)))
19728     {
19729       result = false;
19730       if (k)
19731 	*k |= LOCAL_TYPE_CHANGE_KIND;
19732       else
19733 	ABG_RETURN_FALSE;
19734     }
19735 
19736   if (*l.get_underlying_type() != *r.get_underlying_type())
19737     {
19738       // Changes to the underlying type of a typedef are considered
19739       // local, a bit like for pointers.
19740       result = false;
19741       if (k)
19742 	*k |= LOCAL_TYPE_CHANGE_KIND;
19743       else
19744 	ABG_RETURN_FALSE;
19745     }
19746 
19747   ABG_RETURN(result);
19748 }
19749 
19750 /// Equality operator
19751 ///
19752 /// @param o the other typedef_decl to test against.
19753 bool
operator ==(const decl_base & o) const19754 typedef_decl::operator==(const decl_base& o) const
19755 {
19756   const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
19757   if (!other)
19758     return false;
19759   return try_canonical_compare(this, other);
19760 }
19761 
19762 /// Equality operator
19763 ///
19764 /// @param o the other typedef_decl to test against.
19765 ///
19766 /// @return true if the current instance of @ref typedef_decl equals
19767 /// @p o.
19768 bool
operator ==(const type_base & o) const19769 typedef_decl::operator==(const type_base& o) const
19770 {
19771   const decl_base* other = dynamic_cast<const decl_base*>(&o);
19772   if (!other)
19773     return false;
19774   return *this == *other;
19775 }
19776 
19777 /// Build a pretty representation for a typedef_decl.
19778 ///
19779 /// @param internal set to true if the call is intended to get a
19780 /// representation of the decl (or type) for the purpose of canonical
19781 /// type comparison.  This is mainly used in the function
19782 /// type_base::get_canonical_type_for().
19783 ///
19784 /// In other words if the argument for this parameter is true then the
19785 /// call is meant for internal use (for technical use inside the
19786 /// library itself), false otherwise.  If you don't know what this is
19787 /// for, then set it to false.
19788 
19789 /// @param qualified_name if true, names emitted in the pretty
19790 /// representation are fully qualified.
19791 ///
19792 /// @return a copy of the pretty representation of the current
19793 /// instance of typedef_decl.
19794 string
get_pretty_representation(bool internal,bool qualified_name) const19795 typedef_decl::get_pretty_representation(bool internal,
19796 					bool qualified_name) const
19797 {
19798 
19799   string result = "typedef ";
19800   if (internal)
19801     result += get_name();
19802   else
19803     {
19804       if (qualified_name)
19805 	result += get_qualified_name(internal);
19806       else
19807 	result += get_name();
19808     }
19809 
19810   return result;
19811 }
19812 
19813 /// Getter of the underlying type of the typedef.
19814 ///
19815 /// @return the underlying_type.
19816 type_base_sptr
get_underlying_type() const19817 typedef_decl::get_underlying_type() const
19818 {return priv_->underlying_type_.lock();}
19819 
19820 /// Setter ofthe underlying type of the typedef.
19821 ///
19822 /// @param t the new underlying type of the typedef.
19823 void
set_underlying_type(const type_base_sptr & t)19824 typedef_decl::set_underlying_type(const type_base_sptr& t)
19825 {
19826   priv_->underlying_type_ = t;
19827   set_size_in_bits(t->get_size_in_bits());
19828   set_alignment_in_bits(t->get_alignment_in_bits());
19829 }
19830 
19831 /// Implementation of the virtual "get_qualified_name" method.
19832 ///
19833 /// @param qualified_name the resuling qualified name of the typedef type.
19834 ///
19835 /// @param internal if true, then it means the qualified name is for
19836 /// "internal" purposes, meaning mainly for type canonicalization
19837 /// purposes.
19838 void
get_qualified_name(interned_string & qualified_name,bool internal) const19839 typedef_decl::get_qualified_name(interned_string& qualified_name,
19840 				 bool internal) const
19841 {qualified_name = get_qualified_name(internal);}
19842 
19843 /// Implementation of the virtual "get_qualified_name" method.
19844 ///
19845 /// @param internal if true, then it means the qualified name is for
19846 /// "internal" purposes, meaning mainly for type canonicalization
19847 /// purposes.
19848 ///
19849 /// @return the qualified name.
19850 const interned_string&
get_qualified_name(bool internal) const19851 typedef_decl::get_qualified_name(bool internal) const
19852 {
19853   // Note that the qualified name has been already set by
19854   // qualified_name_setter::do_update, which is invoked by
19855   // update_qualified_name.  The latter is itself invoked whenever the
19856   // typedef is added to its scope, in scope_decl::add_member_decl.
19857   if (internal)
19858     return decl_base::priv_->internal_qualified_name_;
19859   else
19860     return decl_base::priv_->qualified_name_;
19861 }
19862 
19863 /// This implements the ir_traversable_base::traverse pure virtual
19864 /// function.
19865 ///
19866 /// @param v the visitor used on the current instance.
19867 ///
19868 /// @return true if the entire IR node tree got traversed, false
19869 /// otherwise.
19870 bool
traverse(ir_node_visitor & v)19871 typedef_decl::traverse(ir_node_visitor& v)
19872 {
19873   if (v.type_node_has_been_visited(this))
19874     return true;
19875 
19876   if (visiting())
19877     return true;
19878 
19879   if (v.visit_begin(this))
19880     {
19881       visiting(true);
19882       if (type_base_sptr t = get_underlying_type())
19883 	t->traverse(v);
19884       visiting(false);
19885     }
19886 
19887   bool result = v.visit_end(this);
19888   v.mark_type_node_as_visited(this);
19889   return result;
19890 }
19891 
~typedef_decl()19892 typedef_decl::~typedef_decl()
19893 {}
19894 // </typedef_decl definitions>
19895 
19896 // <var_decl definitions>
19897 
19898 struct var_decl::priv
19899 {
19900   type_base_wptr	type_;
19901   type_base*		naked_type_;
19902   decl_base::binding	binding_;
19903   elf_symbol_sptr	symbol_;
19904   interned_string	id_;
19905 
privabigail::ir::var_decl::priv19906   priv()
19907     : naked_type_(),
19908     binding_(decl_base::BINDING_GLOBAL)
19909   {}
19910 
privabigail::ir::var_decl::priv19911   priv(type_base_sptr t,
19912        decl_base::binding b)
19913     : type_(t),
19914       naked_type_(t.get()),
19915       binding_(b)
19916   {}
19917 
19918   /// Setter of the type of the variable.
19919   ///
19920   /// @param t the new variable type.
19921   void
set_typeabigail::ir::var_decl::priv19922   set_type(type_base_sptr t)
19923   {
19924     type_ = t;
19925     naked_type_ = t.get();
19926   }
19927 }; // end struct var_decl::priv
19928 
19929 /// Constructor of the @ref var_decl type.
19930 ///
19931 /// @param name the name of the variable declaration
19932 ///
19933 /// @param type the type of the variable declaration
19934 ///
19935 /// @param locus the source location where the variable was defined.
19936 ///
19937 /// @param linkage_name the linkage name of the variable.
19938 ///
19939 /// @param vis the visibility of of the variable.
19940 ///
19941 /// @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)19942 var_decl::var_decl(const string&	name,
19943 		   type_base_sptr	type,
19944 		   const location&	locus,
19945 		   const string&	linkage_name,
19946 		   visibility		vis,
19947 		   binding		bind)
19948   : type_or_decl_base(type->get_environment(),
19949 		      VAR_DECL | ABSTRACT_DECL_BASE),
19950     decl_base(type->get_environment(), name, locus, linkage_name, vis),
19951     priv_(new priv(type, bind))
19952 {
19953   runtime_type_instance(this);
19954 }
19955 
19956 /// Getter of the type of the variable.
19957 ///
19958 /// @return the type of the variable.
19959 const type_base_sptr
get_type() const19960 var_decl::get_type() const
19961 {return priv_->type_.lock();}
19962 
19963 /// Setter of the type of the variable.
19964 ///
19965 /// @param the new type of the variable.
19966 void
set_type(type_base_sptr & t)19967 var_decl::set_type(type_base_sptr& t)
19968 {priv_->set_type(t);}
19969 
19970 /// Getter of the type of the variable.
19971 ///
19972 /// This getter returns a bare pointer, as opposed to a smart pointer.
19973 /// It's to be used on performance sensitive code paths identified by
19974 /// careful profiling.
19975 ///
19976 /// @return the type of the variable, as a bare pointer.
19977 const type_base*
get_naked_type() const19978 var_decl::get_naked_type() const
19979 {return priv_->naked_type_;}
19980 
19981 /// Getter of the binding of the variable.
19982 ///
19983 /// @return the biding of the variable.
19984 decl_base::binding
get_binding() const19985 var_decl::get_binding() const
19986 {return priv_->binding_;}
19987 
19988 /// Setter of the binding of the variable.
19989 ///
19990 /// @param b the new binding value.
19991 void
set_binding(decl_base::binding b)19992 var_decl::set_binding(decl_base::binding b)
19993 {priv_->binding_ = b;}
19994 
19995 /// Sets the underlying ELF symbol for the current variable.
19996 ///
19997 /// And underlyin$g ELF symbol for the current variable might exist
19998 /// only if the corpus that this variable originates from was
19999 /// constructed from an ELF binary file.
20000 ///
20001 /// Note that comparing two variables that have underlying ELF symbols
20002 /// involves comparing their underlying elf symbols.  The decl name
20003 /// for the variable thus becomes irrelevant in the comparison.
20004 ///
20005 /// @param sym the new ELF symbol for this variable decl.
20006 void
set_symbol(const elf_symbol_sptr & sym)20007 var_decl::set_symbol(const elf_symbol_sptr& sym)
20008 {
20009   priv_->symbol_ = sym;
20010   // The variable id cache that depends on the symbol must be
20011   // invalidated because the symbol changed.
20012   priv_->id_ = get_environment().intern("");
20013 }
20014 
20015 /// Gets the the underlying ELF symbol for the current variable,
20016 /// that was set using var_decl::set_symbol().  Please read the
20017 /// documentation for that member function for more information about
20018 /// "underlying ELF symbols".
20019 ///
20020 /// @return sym the underlying ELF symbol for this variable decl, if
20021 /// one exists.
20022 const elf_symbol_sptr&
get_symbol() const20023 var_decl::get_symbol() const
20024 {return priv_->symbol_;}
20025 
20026 /// Create a new var_decl that is a clone of the current one.
20027 ///
20028 /// @return the cloned var_decl.
20029 var_decl_sptr
clone() const20030 var_decl::clone() const
20031 {
20032   var_decl_sptr v(new var_decl(get_name(),
20033 			       get_type(),
20034 			       get_location(),
20035 			       get_linkage_name(),
20036 			       get_visibility(),
20037 			       get_binding()));
20038 
20039   v->set_symbol(get_symbol());
20040 
20041   if (is_member_decl(*this))
20042     {
20043       class_or_union* scope = is_class_or_union_type(get_scope());
20044       scope->add_data_member(v, get_member_access_specifier(*this),
20045 			     get_data_member_is_laid_out(*this),
20046 			     get_member_is_static(*this),
20047 			     get_data_member_offset(*this));
20048     }
20049   else
20050     add_decl_to_scope(v, get_scope());
20051 
20052   return v;
20053 }
20054 /// Setter of the scope of the current var_decl.
20055 ///
20056 /// Note that the decl won't hold a reference on the scope.  It's
20057 /// rather the scope that holds a reference on its members.
20058 ///
20059 /// @param scope the new scope.
20060 void
set_scope(scope_decl * scope)20061 var_decl::set_scope(scope_decl* scope)
20062 {
20063   if (!get_context_rel())
20064     set_context_rel(new dm_context_rel(scope));
20065   else
20066     get_context_rel()->set_scope(scope);
20067 }
20068 
20069 /// Compares two instances of @ref var_decl without taking their type
20070 /// into account.
20071 ///
20072 /// If the two intances are different modulo their type, set a
20073 /// bitfield to give some insight about the kind of differences there
20074 /// are.
20075 ///
20076 /// @param l the first artifact of the comparison.
20077 ///
20078 /// @param r the second artifact of the comparison.
20079 ///
20080 /// @param k a pointer to a bitfield that gives information about the
20081 /// kind of changes there are between @p l and @p r.  This one is set
20082 /// iff @p k is non-null and the function returns false.
20083 ///
20084 /// Please note that setting k to a non-null value does have a
20085 /// negative performance impact because even if @p l and @p r are not
20086 /// equal, the function keeps up the comparison in order to determine
20087 /// the different kinds of ways in which they are different.
20088 ///
20089 /// @return true if @p l equals @p r, false otherwise.
20090 bool
var_equals_modulo_types(const var_decl & l,const var_decl & r,change_kind * k)20091 var_equals_modulo_types(const var_decl& l, const var_decl& r, change_kind* k)
20092 {
20093   bool result = true;
20094 
20095   // If there are underlying elf symbols for these variables,
20096   // compare them.  And then compare the other parts.
20097   const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
20098   if (!!s0 != !!s1)
20099     {
20100       result = false;
20101       if (k)
20102 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
20103       else
20104 	ABG_RETURN_FALSE;
20105     }
20106   else if (s0 && s0 != s1)
20107     {
20108       result = false;
20109       if (k)
20110 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
20111       else
20112 	ABG_RETURN_FALSE;
20113     }
20114   bool symbols_are_equal = (s0 && s1 && result);
20115 
20116   if (symbols_are_equal)
20117     {
20118       // The variables have underlying elf symbols that are equal, so
20119       // now, let's compare the decl_base part of the variables w/o
20120       // considering their decl names.
20121       const environment& env = l.get_environment();
20122       const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
20123       const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
20124       const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
20125       bool decl_bases_different = !l.decl_base::operator==(r);
20126       const_cast<var_decl&>(l).set_qualified_name(n1);
20127       const_cast<var_decl&>(r).set_qualified_name(n2);
20128 
20129       if (decl_bases_different)
20130 	{
20131 	  result = false;
20132 	  if (k)
20133 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20134 	  else
20135 	    ABG_RETURN_FALSE;
20136 	}
20137     }
20138   else
20139     if (!l.decl_base::operator==(r))
20140       {
20141 	result = false;
20142 	if (k)
20143 	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20144 	else
20145 	  ABG_RETURN_FALSE;
20146       }
20147 
20148   const dm_context_rel* c0 =
20149     dynamic_cast<const dm_context_rel*>(l.get_context_rel());
20150   const dm_context_rel* c1 =
20151     dynamic_cast<const dm_context_rel*>(r.get_context_rel());
20152   ABG_ASSERT(c0 && c1);
20153 
20154   if (*c0 != *c1)
20155     {
20156       result = false;
20157       if (k)
20158 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
20159       else
20160 	ABG_RETURN_FALSE;
20161     }
20162 
20163   ABG_RETURN(result);
20164 }
20165 
20166 /// Compares two instances of @ref var_decl.
20167 ///
20168 /// If the two intances are different, set a bitfield to give some
20169 /// insight about the kind of differences there are.
20170 ///
20171 /// @param l the first artifact of the comparison.
20172 ///
20173 /// @param r the second artifact of the comparison.
20174 ///
20175 /// @param k a pointer to a bitfield that gives information about the
20176 /// kind of changes there are between @p l and @p r.  This one is set
20177 /// iff @p k is non-null and the function returns false.
20178 ///
20179 /// Please note that setting k to a non-null value does have a
20180 /// negative performance impact because even if @p l and @p r are not
20181 /// equal, the function keeps up the comparison in order to determine
20182 /// the different kinds of ways in which they are different.
20183 ///
20184 /// @return true if @p l equals @p r, false otherwise.
20185 bool
equals(const var_decl & l,const var_decl & r,change_kind * k)20186 equals(const var_decl& l, const var_decl& r, change_kind* k)
20187 {
20188   bool result = true;
20189 
20190   // First test types of variables.  This should be fast because in
20191   // the general case, most types should be canonicalized.
20192   if (*l.get_naked_type() != *r.get_naked_type())
20193     {
20194       result = false;
20195       if (k)
20196 	{
20197 	  if (!types_have_similar_structure(l.get_naked_type(),
20198 					    r.get_naked_type()))
20199 	    *k |= (LOCAL_TYPE_CHANGE_KIND);
20200 	  else
20201 	    *k |= SUBTYPE_CHANGE_KIND;
20202 	}
20203       else
20204 	ABG_RETURN_FALSE;
20205     }
20206 
20207   result &= var_equals_modulo_types(l, r, k);
20208 
20209   ABG_RETURN(result);
20210 }
20211 
20212 /// Comparison operator of @ref var_decl.
20213 ///
20214 /// @param o the instance of @ref var_decl to compare against.
20215 ///
20216 /// @return true iff the current instance of @ref var_decl equals @p o.
20217 bool
operator ==(const decl_base & o) const20218 var_decl::operator==(const decl_base& o) const
20219 {
20220   const var_decl* other = dynamic_cast<const var_decl*>(&o);
20221   if (!other)
20222     return false;
20223 
20224   return equals(*this, *other, 0);
20225 }
20226 
20227 /// Return an ID that tries to uniquely identify the variable inside a
20228 /// program or a library.
20229 ///
20230 /// So if the variable has an underlying elf symbol, the ID is the
20231 /// concatenation of the symbol name and its version.  Otherwise, the
20232 /// ID is the linkage name if its non-null.  Otherwise, it's the
20233 /// pretty representation of the variable.
20234 ///
20235 /// @return the ID.
20236 interned_string
get_id() const20237 var_decl::get_id() const
20238 {
20239   if (priv_->id_.empty())
20240     {
20241       string repr = get_name();
20242       string sym_str;
20243       if (elf_symbol_sptr s = get_symbol())
20244 	sym_str = s->get_id_string();
20245       else if (!get_linkage_name().empty())
20246 	sym_str = get_linkage_name();
20247 
20248       const environment& env = get_type()->get_environment();
20249       priv_->id_ = env.intern(repr);
20250       if (!sym_str.empty())
20251 	priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
20252     }
20253   return priv_->id_;
20254 }
20255 
20256 /// Return the hash value for the current instance.
20257 ///
20258 /// @return the hash value.
20259 size_t
get_hash() const20260 var_decl::get_hash() const
20261 {
20262   var_decl::hash hash_var;
20263   return hash_var(this);
20264 }
20265 
20266 /// Get the qualified name of a given variable or data member.
20267 ///
20268 ///
20269 /// Note that if the current instance of @ref var_decl is an anonymous
20270 /// data member, then the qualified name is actually the flat
20271 /// representation (the definition) of the type of the anonymous data
20272 /// member.  We chose the flat representation because otherwise, the
20273 /// name of an *anonymous* data member is empty, by construction, e.g:
20274 ///
20275 ///   struct foo {
20276 ///     int a;
20277 ///     union {
20278 ///       char b;
20279 ///       char c;
20280 ///     }; // <---- this data member is anonymous.
20281 ///     int d;
20282 ///   }
20283 ///
20284 ///   The string returned for the anonymous member here is going to be:
20285 ///
20286 ///     "union {char b; char c}"
20287 ///
20288 /// @param internal if true then this is for a purpose to the library,
20289 /// otherwise, it's for being displayed to users.
20290 ///
20291 /// @return the resulting qualified name.
20292 const interned_string&
get_qualified_name(bool internal) const20293 var_decl::get_qualified_name(bool internal) const
20294 {
20295   if (is_anonymous_data_member(this)
20296       && decl_base::get_qualified_name().empty())
20297     {
20298       // Display the anonymous data member in a way that makes sense.
20299       string r = get_pretty_representation(internal);
20300       set_qualified_name(get_environment().intern(r));
20301     }
20302 
20303   return decl_base::get_qualified_name(internal);
20304 }
20305 
20306 /// Build and return the pretty representation of this variable.
20307 ///
20308 /// @param internal set to true if the call is intended to get a
20309 /// representation of the decl (or type) for the purpose of canonical
20310 /// type comparison.  This is mainly used in the function
20311 /// type_base::get_canonical_type_for().
20312 ///
20313 /// In other words if the argument for this parameter is true then the
20314 /// call is meant for internal use (for technical use inside the
20315 /// library itself), false otherwise.  If you don't know what this is
20316 /// for, then set it to false.
20317 ///
20318 /// @param qualified_name if true, names emitted in the pretty
20319 /// representation are fully qualified.
20320 ///
20321 /// @return a copy of the pretty representation of this variable.
20322 string
get_pretty_representation(bool internal,bool qualified_name) const20323 var_decl::get_pretty_representation(bool internal, bool qualified_name) const
20324 {
20325   string result;
20326 
20327   if (is_member_decl(this) && get_member_is_static(this))
20328     result = "static ";
20329 
20330   // Detect if the current instance of var_decl is a member of
20331   // an anonymous class or union.
20332   bool member_of_anonymous_class = false;
20333   if (class_or_union* scope = is_at_class_scope(this))
20334     if (scope->get_is_anonymous())
20335       member_of_anonymous_class = true;
20336 
20337   if (array_type_def_sptr t = is_array_type(get_type()))
20338     {
20339       string name;
20340       if (member_of_anonymous_class || !qualified_name)
20341 	name = get_name();
20342       else
20343 	name = get_qualified_name(internal);
20344 
20345       type_base_sptr et = t->get_element_type();
20346       ABG_ASSERT(et);
20347       decl_base_sptr decl = get_type_declaration(et);
20348       ABG_ASSERT(decl);
20349       result += decl->get_qualified_name(internal)
20350 	+ " " + name + t->get_subrange_representation();
20351     }
20352   else
20353     {
20354       if (/*The current var_decl is to be used as an anonymous data
20355 	    member.  */
20356 	  get_name().empty())
20357 	{
20358 	  // Display the anonymous data member in a way that
20359 	  // makes sense.
20360 	  result +=
20361 	    get_class_or_union_flat_representation
20362 	    (is_class_or_union_type(get_type()),
20363 	     "", /*one_line=*/true, internal);
20364 	}
20365       else if (data_member_has_anonymous_type(this))
20366 	{
20367 	  result += get_class_or_union_flat_representation
20368 	    (is_class_or_union_type(get_type()),
20369 	     "", /*one_line=*/true, internal);
20370 	  result += " ";
20371 	  if (!internal
20372 	      && (member_of_anonymous_class || !qualified_name))
20373 	    // It doesn't make sense to name the member of an
20374 	    // anonymous class or union like:
20375 	    // "__anonymous__::data_member_name".  So let's just use
20376 	    // its non-qualified name.
20377 	    result += get_name();
20378 	  else
20379 	    result += get_qualified_name(internal);
20380 	}
20381       else
20382 	{
20383 	  result +=
20384 	    get_type_declaration(get_type())->get_qualified_name(internal)
20385 	    + " ";
20386 
20387 	  if (!internal
20388 	      && (member_of_anonymous_class || !qualified_name))
20389 	    // It doesn't make sense to name the member of an
20390 	    // anonymous class or union like:
20391 	    // "__anonymous__::data_member_name".  So let's just use
20392 	    // its non-qualified name.
20393 	    result += get_name();
20394 	  else
20395 	    result += get_qualified_name(internal);
20396 	}
20397     }
20398   return result;
20399 }
20400 
20401 /// Get a name that is valid even for an anonymous data member.
20402 ///
20403 /// If the current @ref var_decl is an anonymous data member, then
20404 /// return its pretty representation. As of now, that pretty
20405 /// representation is actually its flat representation as returned by
20406 /// get_class_or_union_flat_representation().
20407 ///
20408 /// Otherwise, just return the name of the current @ref var_decl.
20409 ///
20410 /// @param qualified if true, return the qualified name.  This doesn't
20411 /// have an effet if the current @ref var_decl represents an anonymous
20412 /// data member.
20413 string
get_anon_dm_reliable_name(bool qualified) const20414 var_decl::get_anon_dm_reliable_name(bool qualified) const
20415 {
20416   string name;
20417   if (is_anonymous_data_member(this))
20418     // This function is used in the comparison engine to determine
20419     // which anonymous data member was deleted.  So it's not involved
20420     // in type comparison or canonicalization.  We don't want to use
20421     // the 'internal' version of the pretty presentation.
20422     name = get_pretty_representation(/*internal=*/false, qualified);
20423   else
20424     name = get_name();
20425 
20426   return name;
20427 }
20428 
20429 /// This implements the ir_traversable_base::traverse pure virtual
20430 /// function.
20431 ///
20432 /// @param v the visitor used on the current instance.
20433 ///
20434 /// @return true if the entire IR node tree got traversed, false
20435 /// otherwise.
20436 bool
traverse(ir_node_visitor & v)20437 var_decl::traverse(ir_node_visitor& v)
20438 {
20439   if (visiting())
20440     return true;
20441 
20442   if (v.visit_begin(this))
20443     {
20444       visiting(true);
20445       if (type_base_sptr t = get_type())
20446 	t->traverse(v);
20447       visiting(false);
20448     }
20449   return v.visit_end(this);
20450 }
20451 
~var_decl()20452 var_decl::~var_decl()
20453 {}
20454 
20455 // </var_decl definitions>
20456 
20457 /// This function is automatically invoked whenever an instance of
20458 /// this type is canonicalized.
20459 ///
20460 /// It's an overload of the virtual type_base::on_canonical_type_set.
20461 ///
20462 /// We put here what is thus meant to be executed only at the point of
20463 /// type canonicalization.
20464 void
on_canonical_type_set()20465 function_type::on_canonical_type_set()
20466 {
20467   priv_->cached_name_.clear();
20468   priv_->internal_cached_name_.clear();
20469 }
20470 
20471 /// The most straightforward constructor for the function_type class.
20472 ///
20473 /// @param return_type the return type of the function type.
20474 ///
20475 /// @param parms the list of parameters of the function type.
20476 /// Stricto sensu, we just need a list of types; we are using a list
20477 /// of parameters (where each parameter also carries the name of the
20478 /// parameter and its source location) to try and provide better
20479 /// diagnostics whenever it makes sense.  If it appears that this
20480 /// wasts too many resources, we can fall back to taking just a
20481 /// vector of types here.
20482 ///
20483 /// @param size_in_bits the size of this type, in bits.
20484 ///
20485 /// @param alignment_in_bits the alignment of this type, in bits.
20486 ///
20487 /// @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)20488 function_type::function_type(type_base_sptr	return_type,
20489 			     const parameters&	parms,
20490 			     size_t		size_in_bits,
20491 			     size_t		alignment_in_bits)
20492   : type_or_decl_base(return_type->get_environment(),
20493 		      FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
20494     type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
20495     priv_(new priv(parms, return_type))
20496 {
20497   runtime_type_instance(this);
20498 
20499   for (parameters::size_type i = 0, j = 1;
20500        i < priv_->parms_.size();
20501        ++i, ++j)
20502     {
20503       if (i == 0 && priv_->parms_[i]->get_is_artificial())
20504 	// If the first parameter is artificial, then it certainly
20505 	// means that this is a member function, and the first
20506 	// parameter is the implicit this pointer.  In that case, set
20507 	// the index of that implicit parameter to zero.  Otherwise,
20508 	// the index of the first parameter starts at one.
20509 	j = 0;
20510       priv_->parms_[i]->set_index(j);
20511     }
20512 }
20513 
20514 /// A constructor for a function_type that takes no parameters.
20515 ///
20516 /// @param return_type the return type of this function_type.
20517 ///
20518 /// @param size_in_bits the size of this type, in bits.
20519 ///
20520 /// @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)20521 function_type::function_type(type_base_sptr return_type,
20522 			     size_t size_in_bits, size_t alignment_in_bits)
20523   : type_or_decl_base(return_type->get_environment(),
20524 		      FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
20525     type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
20526     priv_(new priv(return_type))
20527 {
20528   runtime_type_instance(this);
20529 }
20530 
20531 /// A constructor for a function_type that takes no parameter and
20532 /// that has no return_type yet.  These missing parts can (and must)
20533 /// be added later.
20534 ///
20535 /// @param env the environment we are operating from.
20536 ///
20537 /// @param size_in_bits the size of this type, in bits.
20538 ///
20539 /// @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)20540 function_type::function_type(const environment& env,
20541 			     size_t		size_in_bits,
20542 			     size_t		alignment_in_bits)
20543   : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
20544     type_base(env, size_in_bits, alignment_in_bits),
20545     priv_(new priv)
20546 {
20547   runtime_type_instance(this);
20548 }
20549 
20550 /// Getter for the return type of the current instance of @ref
20551 /// function_type.
20552 ///
20553 /// @return the return type.
20554 type_base_sptr
get_return_type() const20555 function_type::get_return_type() const
20556 {return priv_->return_type_.lock();}
20557 
20558 /// Setter of the return type of the current instance of @ref
20559 /// function_type.
20560 ///
20561 /// @param t the new return type to set.
20562 void
set_return_type(type_base_sptr t)20563 function_type::set_return_type(type_base_sptr t)
20564 {priv_->return_type_ = t;}
20565 
20566 /// Getter for the set of parameters of the current intance of @ref
20567 /// function_type.
20568 ///
20569 /// @return the parameters of the current instance of @ref
20570 /// function_type.
20571 const function_decl::parameters&
get_parameters() const20572 function_type::get_parameters() const
20573 {return priv_->parms_;}
20574 
20575 /// Get the Ith parameter of the vector of parameters of the current
20576 /// instance of @ref function_type.
20577 ///
20578 /// Note that the first parameter is at index 0.  That parameter is
20579 /// the first parameter that comes after the possible implicit "this"
20580 /// parameter, when the current instance @ref function_type is for a
20581 /// member function.  Otherwise, if the current instance of @ref
20582 /// function_type is for a non-member function, the parameter at index
20583 /// 0 is the first parameter of the function.
20584 ///
20585 ///
20586 /// @param i the index of the parameter to return.  If i is greater
20587 /// than the index of the last parameter, then this function returns
20588 /// an empty parameter (smart) pointer.
20589 ///
20590 /// @return the @p i th parameter that is not implicit.
20591 const function_decl::parameter_sptr
get_parm_at_index_from_first_non_implicit_parm(size_t i) const20592 function_type::get_parm_at_index_from_first_non_implicit_parm(size_t i) const
20593 {
20594   parameter_sptr result;
20595   if (dynamic_cast<const method_type*>(this))
20596     {
20597       if (i + 1 < get_parameters().size())
20598 	result = get_parameters()[i + 1];
20599     }
20600   else
20601     {
20602       if (i < get_parameters().size())
20603 	result = get_parameters()[i];
20604     }
20605   return result;
20606 }
20607 
20608 /// Setter for the parameters of the current instance of @ref
20609 /// function_type.
20610 ///
20611 /// @param p the new vector of parameters to set.
20612 void
set_parameters(const parameters & p)20613 function_type::set_parameters(const parameters &p)
20614 {
20615   priv_->parms_ = p;
20616   for (parameters::size_type i = 0, j = 1;
20617        i < priv_->parms_.size();
20618        ++i, ++j)
20619     {
20620       if (i == 0 && priv_->parms_[i]->get_is_artificial())
20621 	// If the first parameter is artificial, then it certainly
20622 	// means that this is a member function, and the first
20623 	// parameter is the implicit this pointer.  In that case, set
20624 	// the index of that implicit parameter to zero.  Otherwise,
20625 	// the index of the first parameter starts at one.
20626 	j = 0;
20627       priv_->parms_[i]->set_index(j);
20628     }
20629 }
20630 
20631 /// Append a new parameter to the vector of parameters of the current
20632 /// instance of @ref function_type.
20633 ///
20634 /// @param parm the parameter to append.
20635 void
append_parameter(parameter_sptr parm)20636 function_type::append_parameter(parameter_sptr parm)
20637 {
20638   parm->set_index(priv_->parms_.size());
20639   priv_->parms_.push_back(parm);
20640 }
20641 
20642 /// Test if the current instance of @ref function_type is for a
20643 /// variadic function.
20644 ///
20645 /// A variadic function is a function that takes a variable number of
20646 /// arguments.
20647 ///
20648 /// @return true iff the current instance of @ref function_type is for
20649 /// a variadic function.
20650 bool
is_variadic() const20651 function_type::is_variadic() const
20652 {
20653   return (!priv_->parms_.empty()
20654 	 && priv_->parms_.back()->get_variadic_marker());
20655 }
20656 
20657 /// Compare two function types.
20658 ///
20659 /// In case these function types are actually method types, this
20660 /// function avoids comparing two parameters (of the function types)
20661 /// if the types of the parameters are actually the types of the
20662 /// classes of the method types.  This prevents infinite recursion
20663 /// during the comparison of two classes that are structurally
20664 /// identical.
20665 ///
20666 /// This is a subroutine of the equality operator of function_type.
20667 ///
20668 /// @param lhs the first function type to consider
20669 ///
20670 /// @param rhs the second function type to consider
20671 ///
20672 /// @param k a pointer to a bitfield set by the function to give
20673 /// information about the kind of changes carried by @p lhs and @p
20674 /// rhs.  It is set iff @p k is non-null and the function returns
20675 /// false.
20676 ///
20677 /// Please note that setting k to a non-null value does have a
20678 /// negative performance impact because even if @p l and @p r are not
20679 /// equal, the function keeps up the comparison in order to determine
20680 /// the different kinds of ways in which they are different.
20681 ///
20682 ///@return true if lhs == rhs, false otherwise.
20683 bool
equals(const function_type & l,const function_type & r,change_kind * k)20684 equals(const function_type& l, const function_type& r, change_kind* k)
20685 {
20686 #define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
20687 
20688   RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
20689 
20690   {
20691     // First of all, let's see if these two function types haven't
20692     // already been compared.  If so, and if the result of the
20693     // comparison has been cached, let's just re-use it, rather than
20694     // comparing them all over again.
20695     bool cached_result = false;
20696     if (l.get_environment().priv_->is_type_comparison_cached(l, r,
20697 							     cached_result))
20698       ABG_RETURN(cached_result);
20699   }
20700 
20701   mark_types_as_being_compared(l, r);
20702 
20703   bool result = true;
20704 
20705   if (!l.type_base::operator==(r))
20706     {
20707       result = false;
20708       if (k)
20709 	*k |= LOCAL_TYPE_CHANGE_KIND;
20710       else
20711 	RETURN(result);
20712     }
20713 
20714   class_or_union* l_class = 0, *r_class = 0;
20715   if (const method_type* m = dynamic_cast<const method_type*>(&l))
20716     l_class = m->get_class_type().get();
20717 
20718   if (const method_type* m = dynamic_cast<const method_type*>(&r))
20719     r_class = m->get_class_type().get();
20720 
20721   // Compare the names of the class of the method
20722 
20723   if (!!l_class != !!r_class)
20724     {
20725       result = false;
20726       if (k)
20727 	*k |= LOCAL_TYPE_CHANGE_KIND;
20728       else
20729 	RETURN(result);
20730     }
20731   else if (l_class
20732 	   && (l_class->get_qualified_name()
20733 	       != r_class->get_qualified_name()))
20734     {
20735       result = false;
20736       if (k)
20737 	*k |= LOCAL_TYPE_CHANGE_KIND;
20738       else
20739 	RETURN(result);
20740     }
20741 
20742   // Then compare the return type; Beware if it's t's a class type
20743   // that is the same as the method class name; we can recurse for
20744   // ever in that case.
20745 
20746   decl_base* l_return_type_decl =
20747     get_type_declaration(l.get_return_type()).get();
20748   decl_base* r_return_type_decl =
20749     get_type_declaration(r.get_return_type()).get();
20750   bool compare_result_types = true;
20751   string l_rt_name = l_return_type_decl
20752     ? l_return_type_decl->get_qualified_name()
20753     : string();
20754   string r_rt_name = r_return_type_decl
20755     ? r_return_type_decl->get_qualified_name()
20756     : string();
20757 
20758   if ((l_class && (l_class->get_qualified_name() == l_rt_name))
20759       ||
20760       (r_class && (r_class->get_qualified_name() == r_rt_name)))
20761     compare_result_types = false;
20762 
20763   if (compare_result_types)
20764     {
20765       // Let's not consider typedefs when comparing return types to
20766       // avoid spurious changes.
20767       //
20768       // TODO: We should also do this for parameter types, or rather,
20769       // we should teach the equality operators in the IR, at some
20770       // point, to peel typedefs off.
20771       if (peel_typedef_type(l.get_return_type())
20772 	  !=
20773 	  peel_typedef_type(r.get_return_type()))
20774 	{
20775 	  result = false;
20776 	  if (k)
20777 	    {
20778 	      if (!types_have_similar_structure(l.get_return_type(),
20779 						r.get_return_type()))
20780 		*k |= LOCAL_TYPE_CHANGE_KIND;
20781 	      else
20782 		*k |= SUBTYPE_CHANGE_KIND;
20783 	    }
20784 	  else
20785 	    RETURN(result);
20786 	}
20787     }
20788   else
20789     if (l_rt_name != r_rt_name)
20790       {
20791 	result = false;
20792 	if (k)
20793 	  *k |= SUBTYPE_CHANGE_KIND;
20794 	else
20795 	  RETURN(result);
20796       }
20797 
20798   vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
20799   for (i = l.get_first_parm(), j = r.get_first_parm();
20800        i != l.get_parameters().end() && j != r.get_parameters().end();
20801        ++i, ++j)
20802     {
20803       if (**i != **j)
20804 	{
20805 	  result = false;
20806 	  if (k)
20807 	    {
20808 	      if (!types_have_similar_structure((*i)->get_type(),
20809 						(*j)->get_type()))
20810 		*k |= LOCAL_TYPE_CHANGE_KIND;
20811 	      else
20812 		*k |= SUBTYPE_CHANGE_KIND;
20813 	    }
20814 	  else
20815 	    RETURN(result);
20816 	}
20817     }
20818 
20819   if ((i != l.get_parameters().end()
20820        || j != r.get_parameters().end()))
20821     {
20822       result = false;
20823       if (k)
20824 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
20825       else
20826 	RETURN(result);
20827     }
20828 
20829   RETURN(result);
20830 #undef RETURN
20831 }
20832 
20833 /// Get the first parameter of the function.
20834 ///
20835 /// If the function is a non-static member function, the parameter
20836 /// returned is the first one following the implicit 'this' parameter.
20837 ///
20838 /// @return the first non implicit parameter of the function.
20839 function_type::parameters::const_iterator
get_first_non_implicit_parm() const20840 function_type::get_first_non_implicit_parm() const
20841 {
20842   if (get_parameters().empty())
20843     return get_parameters().end();
20844 
20845   bool is_method = dynamic_cast<const method_type*>(this);
20846 
20847   parameters::const_iterator i = get_parameters().begin();
20848 
20849   if (is_method)
20850     ++i;
20851 
20852   return i;
20853 }
20854 
20855 /// Get the first parameter of the function.
20856 ///
20857 /// Note that if the function is a non-static member function, the
20858 /// parameter returned is the implicit 'this' parameter.
20859 ///
20860 /// @return the first parameter of the function.
20861 function_type::parameters::const_iterator
get_first_parm() const20862 function_type::get_first_parm() const
20863 {return get_parameters().begin();}
20864 
20865 /// Get the name of the current @ref function_type.
20866 ///
20867 /// The name is retrieved from a cache.  If the cache is empty, this
20868 /// function computes the name of the type, stores it in the cache and
20869 /// returns it.  Subsequent invocation of the function are going to
20870 /// just hit the cache.
20871 ///
20872 /// Note that if the type is *NOT* canonicalized then function type
20873 /// name is never cached.
20874 ///
20875 /// @param internal if true then it means the function type name is
20876 /// going to be used for purposes that are internal to libabigail
20877 /// itself.  If you don't know what this is then you probably should
20878 /// set this parameter to 'false'.
20879 ///
20880 /// @return the name of the function type.
20881 const interned_string&
get_cached_name(bool internal) const20882 function_type::get_cached_name(bool internal) const
20883 {
20884   if (internal)
20885     {
20886       if (get_naked_canonical_type())
20887 	{
20888 	  if (priv_->internal_cached_name_.empty())
20889 	    priv_->internal_cached_name_ =
20890 	      get_function_type_name(this, /*internal=*/true);
20891 	  return priv_->internal_cached_name_;
20892 	}
20893       else
20894 	{
20895 	  priv_->temp_internal_cached_name_ =
20896 	    get_function_type_name(this,
20897 				   /*internal=*/true);
20898 	  return priv_->temp_internal_cached_name_;
20899 	}
20900     }
20901   else
20902     {
20903       if (get_naked_canonical_type())
20904 	{
20905 	  if (priv_->cached_name_.empty())
20906 	    priv_->cached_name_ =
20907 	      get_function_type_name(this, /*internal=*/false);
20908 	  return priv_->cached_name_;
20909 	}
20910       else
20911 	{
20912 	  priv_->cached_name_ =
20913 	    get_function_type_name(this, /*internal=*/false);
20914 	  return priv_->cached_name_;
20915 	}
20916     }
20917 }
20918 
20919 /// Equality operator for function_type.
20920 ///
20921 /// @param o the other function_type to compare against.
20922 ///
20923 /// @return true iff the two function_type are equal.
20924 bool
operator ==(const type_base & other) const20925 function_type::operator==(const type_base& other) const
20926 {
20927   const function_type* o = dynamic_cast<const function_type*>(&other);
20928   if (!o)
20929     return false;
20930   return try_canonical_compare(this, o);
20931 }
20932 
20933 /// Return a copy of the pretty representation of the current @ref
20934 /// function_type.
20935 ///
20936 /// @param internal set to true if the call is intended to get a
20937 /// representation of the decl (or type) for the purpose of canonical
20938 /// type comparison.  This is mainly used in the function
20939 /// type_base::get_canonical_type_for().
20940 ///
20941 /// In other words if the argument for this parameter is true then the
20942 /// call is meant for internal use (for technical use inside the
20943 /// library itself), false otherwise.  If you don't know what this is
20944 /// for, then set it to false.
20945 ///
20946 /// @return a copy of the pretty representation of the current @ref
20947 /// function_type.
20948 string
get_pretty_representation(bool internal,bool) const20949 function_type::get_pretty_representation(bool internal,
20950 					 bool /*qualified_name*/) const
20951 {return ir::get_pretty_representation(this, internal);}
20952 
20953 /// Traverses an instance of @ref function_type, visiting all the
20954 /// sub-types and decls that it might contain.
20955 ///
20956 /// @param v the visitor that is used to visit every IR sub-node of
20957 /// the current node.
20958 ///
20959 /// @return true if either
20960 ///  - all the children nodes of the current IR node were traversed
20961 ///    and the calling code should keep going with the traversing.
20962 ///  - or the current IR node is already being traversed.
20963 /// Otherwise, returning false means that the calling code should not
20964 /// keep traversing the tree.
20965 bool
traverse(ir_node_visitor & v)20966 function_type::traverse(ir_node_visitor& v)
20967 {
20968   // TODO: should we allow the walker to avoid visiting function type
20969   // twice?  I think that if we do, then ir_node_visitor needs an
20970   // option to specifically disallow this feature for function types.
20971 
20972   if (visiting())
20973     return true;
20974 
20975   if (v.visit_begin(this))
20976     {
20977       visiting(true);
20978       bool keep_going = true;
20979 
20980       if (type_base_sptr t = get_return_type())
20981 	{
20982 	  if (!t->traverse(v))
20983 	    keep_going = false;
20984 	}
20985 
20986       if (keep_going)
20987 	for (parameters::const_iterator i = get_parameters().begin();
20988 	     i != get_parameters().end();
20989 	     ++i)
20990 	  if (type_base_sptr parm_type = (*i)->get_type())
20991 	    if (!parm_type->traverse(v))
20992 	      break;
20993 
20994       visiting(false);
20995     }
20996   return v.visit_end(this);
20997 }
20998 
~function_type()20999 function_type::~function_type()
21000 {}
21001 // </function_type>
21002 
21003 // <method_type>
21004 
21005 struct method_type::priv
21006 {
21007   class_or_union_wptr class_type_;
21008   bool is_const;
21009 
privabigail::ir::method_type::priv21010   priv()
21011     : is_const()
21012   {}
21013 }; // end struct method_type::priv
21014 
21015 /// Constructor for instances of method_type.
21016 ///
21017 /// Instances of method_decl must be of type method_type.
21018 ///
21019 /// @param return_type the type of the return value of the method.
21020 ///
21021 /// @param class_type the base type of the method type.  That is, the
21022 /// type of the class the method belongs to.
21023 ///
21024 /// @param p the vector of the parameters of the method.
21025 ///
21026 /// @param is_const whether this method type is for a const method.
21027 /// Note that const-ness is a property of the method *type* and of the
21028 /// relationship between a method *declaration* and its scope.
21029 ///
21030 /// @param size_in_bits the size of an instance of method_type,
21031 /// expressed in bits.
21032 ///
21033 /// @param alignment_in_bits the alignment of an instance of
21034 /// 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)21035 method_type::method_type (type_base_sptr return_type,
21036 			  class_or_union_sptr class_type,
21037 			  const std::vector<function_decl::parameter_sptr>& p,
21038 			  bool is_const,
21039 			  size_t size_in_bits,
21040 			  size_t alignment_in_bits)
21041   : type_or_decl_base(class_type->get_environment(),
21042 		      METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21043     type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
21044     function_type(return_type, p, size_in_bits, alignment_in_bits),
21045     priv_(new priv)
21046 {
21047   runtime_type_instance(this);
21048   set_class_type(class_type);
21049   set_is_const(is_const);
21050 }
21051 
21052 /// Constructor of instances of method_type.
21053 ///
21054 ///Instances of method_decl must be of type method_type.
21055 ///
21056 /// @param return_type the type of the return value of the method.
21057 ///
21058 /// @param class_type the type of the class the method belongs to.
21059 /// The actual (dynamic) type of class_type must be a pointer
21060 /// class_type.  We are setting it to pointer to type_base here to
21061 /// help client code that is compiled without rtti and thus cannot
21062 /// perform dynamic casts.
21063 ///
21064 /// @param p the vector of the parameters of the method type.
21065 ///
21066 /// @param is_const whether this method type is for a const method.
21067 /// Note that const-ness is a property of the method *type* and of the
21068 /// relationship between a method *declaration* and its scope.
21069 ///
21070 /// @param size_in_bits the size of an instance of method_type,
21071 /// expressed in bits.
21072 ///
21073 /// @param alignment_in_bits the alignment of an instance of
21074 /// 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)21075 method_type::method_type(type_base_sptr return_type,
21076 			 type_base_sptr class_type,
21077 			 const std::vector<function_decl::parameter_sptr>& p,
21078 			 bool is_const,
21079 			 size_t size_in_bits,
21080 			 size_t alignment_in_bits)
21081   : type_or_decl_base(class_type->get_environment(),
21082 		      METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21083     type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
21084     function_type(return_type, p, size_in_bits, alignment_in_bits),
21085     priv_(new priv)
21086 {
21087   runtime_type_instance(this);
21088   set_class_type(is_class_type(class_type));
21089   set_is_const(is_const);
21090 }
21091 
21092 /// Constructor of the qualified_type_def
21093 ///
21094 /// @param env the environment we are operating from.
21095 ///
21096 /// @param size_in_bits the size of the type, expressed in bits.
21097 ///
21098 /// @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)21099 method_type::method_type(const environment&	env,
21100 			 size_t		size_in_bits,
21101 			 size_t		alignment_in_bits)
21102   : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21103     type_base(env, size_in_bits, alignment_in_bits),
21104     function_type(env, size_in_bits, alignment_in_bits),
21105     priv_(new priv)
21106 {
21107   runtime_type_instance(this);
21108 }
21109 
21110 /// Constructor of instances of method_type.
21111 ///
21112 /// When constructed with this constructor, and instane of method_type
21113 /// must set a return type using method_type::set_return_type
21114 ///
21115 /// @param class_typ the base type of the method type.  That is, the
21116 /// type of the class (or union) the method belongs to.
21117 ///
21118 /// @param size_in_bits the size of an instance of method_type,
21119 /// expressed in bits.
21120 ///
21121 /// @param alignment_in_bits the alignment of an instance of
21122 /// 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)21123 method_type::method_type(class_or_union_sptr class_type,
21124 			 bool is_const,
21125 			 size_t size_in_bits,
21126 			 size_t alignment_in_bits)
21127   : type_or_decl_base(class_type->get_environment(),
21128 		      METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21129     type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
21130     function_type(class_type->get_environment(),
21131 		  size_in_bits,
21132 		  alignment_in_bits),
21133     priv_(new priv)
21134 {
21135   runtime_type_instance(this);
21136   set_class_type(class_type);
21137   set_is_const(is_const);
21138 }
21139 
21140 /// Get the class type this method belongs to.
21141 ///
21142 /// @return the class type.
21143 class_or_union_sptr
get_class_type() const21144 method_type::get_class_type() const
21145 {return class_or_union_sptr(priv_->class_type_);}
21146 
21147 /// Sets the class type of the current instance of method_type.
21148 ///
21149 /// The class type is the type of the class the method belongs to.
21150 ///
21151 /// @param t the new class type to set.
21152 void
set_class_type(const class_or_union_sptr & t)21153 method_type::set_class_type(const class_or_union_sptr& t)
21154 {
21155   if (!t)
21156     return;
21157 
21158   priv_->class_type_ = t;
21159 }
21160 
21161 /// Return a copy of the pretty representation of the current @ref
21162 /// method_type.
21163 ///
21164 /// @param internal set to true if the call is intended to get a
21165 /// representation of the decl (or type) for the purpose of canonical
21166 /// type comparison.  This is mainly used in the function
21167 /// type_base::get_canonical_type_for().
21168 ///
21169 /// In other words if the argument for this parameter is true then the
21170 /// call is meant for internal use (for technical use inside the
21171 /// library itself), false otherwise.  If you don't know what this is
21172 /// for, then set it to false.
21173 ///
21174 /// @return a copy of the pretty representation of the current @ref
21175 /// method_type.
21176 string
get_pretty_representation(bool internal,bool) const21177 method_type::get_pretty_representation(bool internal,
21178 				       bool /*qualified_name*/) const
21179 {return ir::get_pretty_representation(*this, internal);}
21180 
21181 /// Setter of the "is-const" property of @ref method_type.
21182 ///
21183 /// @param the new value of the "is-const" property.
21184 void
set_is_const(bool f)21185 method_type::set_is_const(bool f)
21186 {priv_->is_const = f;}
21187 
21188 /// Getter of the "is-const" property of @ref method_type.
21189 ///
21190 /// @return true iff the "is-const" property was set.
21191 bool
get_is_const() const21192 method_type::get_is_const() const
21193 {return priv_->is_const;}
21194 
21195 /// The destructor of method_type
~method_type()21196 method_type::~method_type()
21197 {}
21198 
21199 // </method_type>
21200 
21201 // <function_decl definitions>
21202 
21203 struct function_decl::priv
21204 {
21205   bool			declared_inline_;
21206   decl_base::binding	binding_;
21207   function_type_wptr	type_;
21208   function_type*	naked_type_;
21209   elf_symbol_sptr	symbol_;
21210   interned_string id_;
21211 
privabigail::ir::function_decl::priv21212   priv()
21213     : declared_inline_(false),
21214       binding_(decl_base::BINDING_GLOBAL),
21215       naked_type_()
21216   {}
21217 
privabigail::ir::function_decl::priv21218   priv(function_type_sptr t,
21219        bool declared_inline,
21220        decl_base::binding binding)
21221     : declared_inline_(declared_inline),
21222       binding_(binding),
21223       type_(t),
21224       naked_type_(t.get())
21225   {}
21226 
privabigail::ir::function_decl::priv21227   priv(function_type_sptr t,
21228        bool declared_inline,
21229        decl_base::binding binding,
21230        elf_symbol_sptr s)
21231     : declared_inline_(declared_inline),
21232       binding_(binding),
21233       type_(t),
21234       naked_type_(t.get()),
21235       symbol_(s)
21236   {}
21237 }; // end sruct function_decl::priv
21238 
21239 /// Constructor of the @ref function_decl.
21240 ///
21241 /// @param name the name of the function.
21242 ///
21243 /// @param function_type the type of the function.
21244 ///
21245 /// @param declared_inline wether the function is declared inline.
21246 ///
21247 /// @param locus the source location of the function.
21248 ///
21249 /// @param mangled_name the linkage name of the function.
21250 ///
21251 /// @param vis the visibility of the function.
21252 ///
21253 /// @param bind the binding of the function.
function_decl(const string & name,function_type_sptr function_type,bool declared_inline,const location & locus,const string & mangled_name,visibility vis,binding bind)21254 function_decl::function_decl(const string& name,
21255 			     function_type_sptr function_type,
21256 			     bool declared_inline,
21257 			     const location& locus,
21258 			     const string& mangled_name,
21259 			     visibility vis,
21260 			     binding bind)
21261   : type_or_decl_base(function_type->get_environment(),
21262 		      FUNCTION_DECL | ABSTRACT_DECL_BASE),
21263     decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
21264     priv_(new priv(function_type, declared_inline, bind))
21265 {
21266   runtime_type_instance(this);
21267 }
21268 
21269 /// Constructor of the function_decl type.
21270 ///
21271 /// This flavour of constructor is for when the pointer to the
21272 /// instance of function_type that the client code has is presented as
21273 /// a pointer to type_base.  In that case, this constructor saves the
21274 /// client code from doing a dynamic_cast to get the function_type
21275 /// pointer.
21276 ///
21277 /// @param name the name of the function declaration.
21278 ///
21279 /// @param fn_type the type of the function declaration.  The dynamic
21280 /// type of this parameter should be 'pointer to function_type'
21281 ///
21282 /// @param declared_inline whether this function was declared inline
21283 ///
21284 /// @param locus the source location of the function declaration.
21285 ///
21286 /// @param linkage_name the mangled name of the function declaration.
21287 ///
21288 /// @param vis the visibility of the function declaration.
21289 ///
21290 /// @param bind  the kind of the binding of the function
21291 /// 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)21292 function_decl::function_decl(const string&	name,
21293 			     type_base_sptr	fn_type,
21294 			     bool		declared_inline,
21295 			     const location&	locus,
21296 			     const string&	linkage_name,
21297 			     visibility	vis,
21298 			     binding		bind)
21299   : type_or_decl_base(fn_type->get_environment(),
21300 		      FUNCTION_DECL | ABSTRACT_DECL_BASE),
21301     decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
21302     priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
21303 		   declared_inline,
21304 		   bind))
21305 {
21306   runtime_type_instance(this);
21307 }
21308 
21309 /// Get the pretty representation of the current instance of @ref function_decl.
21310 ///
21311 /// @param internal set to true if the call is intended to get a
21312 /// representation of the decl (or type) for the purpose of canonical
21313 /// type comparison.  This is mainly used in the function
21314 /// type_base::get_canonical_type_for().
21315 ///
21316 /// In other words if the argument for this parameter is true then the
21317 /// call is meant for internal use (for technical use inside the
21318 /// library itself), false otherwise.  If you don't know what this is
21319 /// for, then set it to false.
21320 ///
21321 /// @return the pretty representation for a function.
21322 string
get_pretty_representation(bool internal,bool qualified_name) const21323 function_decl::get_pretty_representation(bool internal,
21324 					 bool qualified_name) const
21325 {
21326   const method_decl* mem_fn =
21327     dynamic_cast<const method_decl*>(this);
21328 
21329   string result = mem_fn ? "method ": "function ";
21330 
21331   if (mem_fn
21332       && is_member_function(mem_fn)
21333       && get_member_function_is_virtual(mem_fn))
21334     result += "virtual ";
21335 
21336   decl_base_sptr type;
21337   if ((mem_fn
21338        && is_member_function(mem_fn)
21339        && (get_member_function_is_dtor(*mem_fn)
21340 	   || get_member_function_is_ctor(*mem_fn))))
21341     /*cdtors do not have return types.  */;
21342   else
21343     type = mem_fn
21344       ? get_type_declaration(mem_fn->get_type()->get_return_type())
21345       : get_type_declaration(get_type()->get_return_type());
21346 
21347   if (type)
21348     result += get_type_name(is_type(type).get(),
21349 			    qualified_name,
21350 			    internal) + " ";
21351 
21352   result += get_pretty_representation_of_declarator(internal);
21353 
21354   return result;
21355 }
21356 
21357 /// Compute and return the pretty representation for the part of the
21358 /// function declaration that starts at the declarator.  That is, the
21359 /// return type and the other specifiers of the beginning of the
21360 /// function's declaration ar omitted.
21361 ///
21362 /// @param internal set to true if the call is intended to get a
21363 /// representation of the decl (or type) for the purpose of canonical
21364 /// type comparison.  This is mainly used in the function
21365 /// type_base::get_canonical_type_for().
21366 ///
21367 /// In other words if the argument for this parameter is true then the
21368 /// call is meant for internal use (for technical use inside the
21369 /// library itself), false otherwise.  If you don't know what this is
21370 /// for, then set it to false.
21371 ///
21372 /// @return the pretty representation for the part of the function
21373 /// declaration that starts at the declarator.
21374 string
get_pretty_representation_of_declarator(bool internal) const21375 function_decl::get_pretty_representation_of_declarator (bool internal) const
21376 {
21377   const method_decl* mem_fn =
21378     dynamic_cast<const method_decl*>(this);
21379 
21380   string result;
21381 
21382   if (mem_fn)
21383     {
21384       result += mem_fn->get_type()->get_class_type()->get_qualified_name()
21385 	+ "::" + mem_fn->get_name();
21386     }
21387   else
21388     result += get_qualified_name();
21389 
21390   result += "(";
21391 
21392   parameters::const_iterator i = get_parameters().begin(),
21393     end = get_parameters().end();
21394 
21395   // Skip the first parameter if this is a method.
21396   if (mem_fn && i != end)
21397     ++i;
21398   parameter_sptr parm;
21399   parameter_sptr first_parm;
21400   if (i != end)
21401     first_parm = *i;
21402   for (; i != end; ++i)
21403     {
21404       parm = *i;
21405       if (parm.get() != first_parm.get())
21406 	result += ", ";
21407       if (parm->get_variadic_marker()
21408 	  || get_environment().is_variadic_parameter_type(parm->get_type()))
21409 	result += "...";
21410       else
21411 	{
21412 	  type_base_sptr type = parm->get_type();
21413 	  if (internal)
21414 	    type = peel_typedef_type(type);
21415 	  result += get_type_name(type, /*qualified=*/true, internal);
21416 	}
21417     }
21418   result += ")";
21419 
21420   if (mem_fn
21421       &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
21422 	 || is_method_type(mem_fn->get_type())->get_is_const()))
21423     result += " const";
21424 
21425   return result;
21426 }
21427 
21428 /// Getter for the first non-implicit parameter of a function decl.
21429 ///
21430 /// If the function is a non-static member function, the parameter
21431 /// returned is the first one following the implicit 'this' parameter.
21432 ///
21433 /// @return the first non implicit parm.
21434 function_decl::parameters::const_iterator
get_first_non_implicit_parm() const21435 function_decl::get_first_non_implicit_parm() const
21436 {
21437   if (get_parameters().empty())
21438     return get_parameters().end();
21439 
21440   bool is_method = dynamic_cast<const method_decl*>(this);
21441 
21442   parameters::const_iterator i = get_parameters().begin();
21443   if (is_method)
21444     ++i;
21445 
21446   return i;
21447 }
21448 
21449 /// Return the type of the current instance of @ref function_decl.
21450 ///
21451 /// It's either a function_type or method_type.
21452 /// @return the type of the current instance of @ref function_decl.
21453 const shared_ptr<function_type>
get_type() const21454 function_decl::get_type() const
21455 {return priv_->type_.lock();}
21456 
21457 /// Fast getter of the type of the current instance of @ref function_decl.
21458 ///
21459 /// Note that this function returns the underlying pointer managed by
21460 /// the smart pointer returned by function_decl::get_type().  It's
21461 /// faster than function_decl::get_type().  This getter is to be used
21462 /// in code paths that are proven to be performance hot spots;
21463 /// especially (for instance) when comparing function types.  Those
21464 /// are compared extremely frequently when libabigail is used to
21465 /// handle huge binaries with a lot of functions.
21466 ///
21467 /// @return the type of the current instance of @ref function_decl.
21468 const function_type*
get_naked_type() const21469 function_decl::get_naked_type() const
21470 {return priv_->naked_type_;}
21471 
21472 void
set_type(const function_type_sptr & fn_type)21473 function_decl::set_type(const function_type_sptr& fn_type)
21474 {
21475   priv_->type_ = fn_type;
21476   priv_->naked_type_ = fn_type.get();
21477 }
21478 
21479 /// This sets the underlying ELF symbol for the current function decl.
21480 ///
21481 /// And underlyin$g ELF symbol for the current function decl might
21482 /// exist only if the corpus that this function decl originates from
21483 /// was constructed from an ELF binary file.
21484 ///
21485 /// Note that comparing two function decls that have underlying ELF
21486 /// symbols involves comparing their underlying elf symbols.  The decl
21487 /// name for the function thus becomes irrelevant in the comparison.
21488 ///
21489 /// @param sym the new ELF symbol for this function decl.
21490 void
set_symbol(const elf_symbol_sptr & sym)21491 function_decl::set_symbol(const elf_symbol_sptr& sym)
21492 {
21493   priv_->symbol_ = sym;
21494   // The function id cache that depends on the symbol must be
21495   // invalidated because the symbol changed.
21496   priv_->id_ = get_environment().intern("");
21497 }
21498 
21499 /// Gets the the underlying ELF symbol for the current variable,
21500 /// that was set using function_decl::set_symbol().  Please read the
21501 /// documentation for that member function for more information about
21502 /// "underlying ELF symbols".
21503 ///
21504 /// @return sym the underlying ELF symbol for this function decl, if
21505 /// one exists.
21506 const elf_symbol_sptr&
get_symbol() const21507 function_decl::get_symbol() const
21508 {return priv_->symbol_;}
21509 
21510 bool
is_declared_inline() const21511 function_decl::is_declared_inline() const
21512 {return priv_->declared_inline_;}
21513 
21514 decl_base::binding
get_binding() const21515 function_decl::get_binding() const
21516 {return priv_->binding_;}
21517 
21518 /// @return the return type of the current instance of function_decl.
21519 const shared_ptr<type_base>
get_return_type() const21520 function_decl::get_return_type() const
21521 {return get_type()->get_return_type();}
21522 
21523 /// @return the parameters of the function.
21524 const std::vector<shared_ptr<function_decl::parameter> >&
get_parameters() const21525 function_decl::get_parameters() const
21526 {return get_type()->get_parameters();}
21527 
21528 /// Append a parameter to the type of this function.
21529 ///
21530 /// @param parm the parameter to append.
21531 void
append_parameter(shared_ptr<parameter> parm)21532 function_decl::append_parameter(shared_ptr<parameter> parm)
21533 {get_type()->append_parameter(parm);}
21534 
21535 /// Append a vector of parameters to the type of this function.
21536 ///
21537 /// @param parms the vector of parameters to append.
21538 void
append_parameters(std::vector<shared_ptr<parameter>> & parms)21539 function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
21540 {
21541   for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
21542        i != parms.end();
21543        ++i)
21544     get_type()->append_parameter(*i);
21545 }
21546 
21547 /// Create a new instance of function_decl that is a clone of the
21548 /// current one.
21549 ///
21550 /// @return the new clone.
21551 function_decl_sptr
clone() const21552 function_decl::clone() const
21553 {
21554   function_decl_sptr f;
21555   if (is_member_function(*this))
21556     {
21557       method_decl_sptr
21558 	m(new method_decl(get_name(),
21559 				      get_type(),
21560 				      is_declared_inline(),
21561 				      get_location(),
21562 				      get_linkage_name(),
21563 				      get_visibility(),
21564 				      get_binding()));
21565       class_or_union* scope = is_class_or_union_type(get_scope());
21566       ABG_ASSERT(scope);
21567       scope->add_member_function(m, get_member_access_specifier(*this),
21568 				 get_member_function_is_virtual(*this),
21569 				 get_member_function_vtable_offset(*this),
21570 				 get_member_is_static(*this),
21571 				 get_member_function_is_ctor(*this),
21572 				 get_member_function_is_dtor(*this),
21573 				 get_member_function_is_const(*this));
21574       f = m;
21575     }
21576   else
21577     {
21578       f.reset(new function_decl(get_name(),
21579 				get_type(),
21580 				is_declared_inline(),
21581 				get_location(),
21582 				get_linkage_name(),
21583 				get_visibility(),
21584 				get_binding()));
21585       add_decl_to_scope(f, get_scope());
21586     }
21587   f->set_symbol(get_symbol());
21588 
21589   return f;
21590 }
21591 
21592 /// Compares two instances of @ref function_decl.
21593 ///
21594 /// If the two intances are different, set a bitfield to give some
21595 /// insight about the kind of differences there are.
21596 ///
21597 /// @param l the first artifact of the comparison.
21598 ///
21599 /// @param r the second artifact of the comparison.
21600 ///
21601 /// @param k a pointer to a bitfield that gives information about the
21602 /// kind of changes there are between @p l and @p r.  This one is set
21603 /// iff @p k is non-null and the function returns false.
21604 ///
21605 /// Please note that setting k to a non-null value does have a
21606 /// negative performance impact because even if @p l and @p r are not
21607 /// equal, the function keeps up the comparison in order to determine
21608 /// the different kinds of ways in which they are different.
21609 ///
21610 /// @return true if @p l equals @p r, false otherwise.
21611 bool
equals(const function_decl & l,const function_decl & r,change_kind * k)21612 equals(const function_decl& l, const function_decl& r, change_kind* k)
21613 {
21614   bool result = true;
21615 
21616   // Compare function types
21617   const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
21618   if (t0 == t1 || *t0 == *t1)
21619     ; // the types are equal, let's move on to compare the other
21620       // properties of the functions.
21621   else
21622     {
21623       result = false;
21624       if (k)
21625 	{
21626 	  if (!types_have_similar_structure(t0, t1))
21627 	    *k |= LOCAL_TYPE_CHANGE_KIND;
21628 	  else
21629 	    *k |= SUBTYPE_CHANGE_KIND;
21630 	}
21631       else
21632 	ABG_RETURN_FALSE;
21633     }
21634 
21635   const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
21636   if (!!s0 != !!s1)
21637     {
21638       result = false;
21639       if (k)
21640 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
21641       else
21642 	ABG_RETURN_FALSE;
21643     }
21644   else if (s0 && s0 != s1)
21645     {
21646       if (!elf_symbols_alias(s0, s1))
21647 	{
21648 	  result = false;
21649 	  if (k)
21650 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21651 	  else
21652 	    ABG_RETURN_FALSE;
21653 	}
21654     }
21655   bool symbols_are_equal = (s0 && s1 && result);
21656 
21657   if (symbols_are_equal)
21658     {
21659       // The functions have underlying elf symbols that are equal,
21660       // so now, let's compare the decl_base part of the functions
21661       // w/o considering their decl names.
21662       interned_string n1 = l.get_name(), n2 = r.get_name();
21663       interned_string ln1 = l.get_linkage_name(), ln2 = r.get_linkage_name();
21664       const_cast<function_decl&>(l).set_name("");
21665       const_cast<function_decl&>(l).set_linkage_name("");
21666       const_cast<function_decl&>(r).set_name("");
21667       const_cast<function_decl&>(r).set_linkage_name("");
21668 
21669       bool decl_bases_different = !l.decl_base::operator==(r);
21670 
21671       const_cast<function_decl&>(l).set_name(n1);
21672       const_cast<function_decl&>(l).set_linkage_name(ln1);
21673       const_cast<function_decl&>(r).set_name(n2);
21674       const_cast<function_decl&>(r).set_linkage_name(ln2);
21675 
21676       if (decl_bases_different)
21677 	{
21678 	  result = false;
21679 	  if (k)
21680 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21681 	  else
21682 	    ABG_RETURN_FALSE;
21683 	}
21684     }
21685   else
21686     if (!l.decl_base::operator==(r))
21687       {
21688 	result = false;
21689 	if (k)
21690 	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21691 	else
21692 	  ABG_RETURN_FALSE;
21693       }
21694 
21695   // Compare the remaining properties
21696   if (l.is_declared_inline() != r.is_declared_inline()
21697       || l.get_binding() != r.get_binding())
21698     {
21699       result = false;
21700       if (k)
21701 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
21702       else
21703 	ABG_RETURN_FALSE;
21704     }
21705 
21706   if (is_member_function(l) != is_member_function(r))
21707     {
21708       result = false;
21709       if (k)
21710 	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21711       else
21712 	ABG_RETURN_FALSE;
21713     }
21714 
21715   if (is_member_function(l) && is_member_function(r))
21716     {
21717       if (!((get_member_function_is_ctor(l)
21718 	     == get_member_function_is_ctor(r))
21719 	    && (get_member_function_is_dtor(l)
21720 		== get_member_function_is_dtor(r))
21721 	    && (get_member_is_static(l)
21722 		== get_member_is_static(r))
21723 	    && (get_member_function_is_const(l)
21724 		== get_member_function_is_const(r))
21725 	    && (get_member_function_is_virtual(l)
21726 		== get_member_function_is_virtual(r))
21727 	    && (get_member_function_vtable_offset(l)
21728 		== get_member_function_vtable_offset(r))))
21729 	{
21730 	  result = false;
21731 	  if (k)
21732 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21733 	  else
21734 	    ABG_RETURN_FALSE;
21735 	}
21736     }
21737 
21738   ABG_RETURN(result);
21739 }
21740 
21741 /// Comparison operator for @ref function_decl.
21742 ///
21743 /// @param other the other instance of @ref function_decl to compare
21744 /// against.
21745 ///
21746 /// @return true iff the current instance of @ref function_decl equals
21747 /// @p other.
21748 bool
operator ==(const decl_base & other) const21749 function_decl::operator==(const decl_base& other) const
21750 {
21751   const function_decl* o = dynamic_cast<const function_decl*>(&other);
21752   if (!o)
21753     return false;
21754   return equals(*this, *o, 0);
21755 }
21756 
21757 /// Return true iff the function takes a variable number of
21758 /// parameters.
21759 ///
21760 /// @return true if the function taks a variable number
21761 /// of parameters.
21762 bool
is_variadic() const21763 function_decl::is_variadic() const
21764 {
21765   return (!get_parameters().empty()
21766 	  && get_parameters().back()->get_variadic_marker());
21767 }
21768 
21769 /// The virtual implementation of 'get_hash' for a function_decl.
21770 ///
21771 /// This allows decl_base::get_hash to work for function_decls.
21772 ///
21773 /// @return the hash value for function decl.
21774 size_t
get_hash() const21775 function_decl::get_hash() const
21776 {
21777   function_decl::hash hash_fn;
21778   return hash_fn(*this);
21779 }
21780 
21781 /// Return an ID that tries to uniquely identify the function inside a
21782 /// program or a library.
21783 ///
21784 /// So if the function has an underlying elf symbol, the ID is the
21785 /// concatenation of the symbol name and its version.  Otherwise, the
21786 /// ID is the linkage name if its non-null.  Otherwise, it's the
21787 /// pretty representation of the function.
21788 ///
21789 /// @return the ID.
21790 interned_string
get_id() const21791 function_decl::get_id() const
21792 {
21793   if (priv_->id_.empty())
21794     {
21795       const environment& env = get_type()->get_environment();
21796       if (elf_symbol_sptr s = get_symbol())
21797 	{
21798 	  string virtual_member_suffix;
21799 	  if (is_member_function(this))
21800 	      {
21801 		method_decl* m = is_method_decl(this);
21802 		ABG_ASSERT(m);
21803 		if (get_member_function_is_virtual(m))
21804 		  {
21805 		    if (is_declaration_only_class_or_union_type
21806 			(m->get_type()->get_class_type(),
21807 			 /*look_through_decl_only=*/true))
21808 		      virtual_member_suffix += "/o";
21809 		  }
21810 	      }
21811 	  if (s->has_aliases())
21812 	    // The symbol has several aliases, so let's use a scheme
21813 	    // that allows all aliased functions to have different
21814 	    // IDs.
21815 	    priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
21816 	  else
21817 	    // Let's use the full symbol name with its version as ID.
21818 	    priv_->id_ = env.intern(s->get_id_string());
21819 
21820 	  if (!virtual_member_suffix.empty())
21821 	    priv_->id_ = env.intern(priv_->id_ + virtual_member_suffix);
21822 	}
21823       else if (!get_linkage_name().empty())
21824 	priv_->id_= env.intern(get_linkage_name());
21825       else
21826 	priv_->id_ = env.intern(get_pretty_representation());
21827     }
21828   return priv_->id_;
21829 }
21830 
21831 /// Test if two function declarations are aliases.
21832 ///
21833 /// Two functions declarations are aliases if their symbols are
21834 /// aliases, in the ELF sense.
21835 ///
21836 /// @param f1 the first function to consider.
21837 ///
21838 /// @param f2 the second function to consider.
21839 ///
21840 /// @return true iff @p f1 is an alias of @p f2
21841 bool
function_decls_alias(const function_decl & f1,const function_decl & f2)21842 function_decls_alias(const function_decl& f1, const function_decl& f2)
21843 {
21844   elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
21845 
21846   if (!s1 || !s2)
21847     return false;
21848 
21849   return elf_symbols_alias(s1, s2);
21850 }
21851 
21852 /// This implements the ir_traversable_base::traverse pure virtual
21853 /// function.
21854 ///
21855 /// @param v the visitor used on the current instance.
21856 ///
21857 /// @return true if the entire IR node tree got traversed, false
21858 /// otherwise.
21859 bool
traverse(ir_node_visitor & v)21860 function_decl::traverse(ir_node_visitor& v)
21861 {
21862   if (visiting())
21863     return true;
21864 
21865   if (v.visit_begin(this))
21866     {
21867       visiting(true);
21868       if (type_base_sptr t = get_type())
21869 	t->traverse(v);
21870       visiting(false);
21871     }
21872   return v.visit_end(this);
21873 }
21874 
21875 /// Destructor of the @ref function_decl type.
~function_decl()21876 function_decl::~function_decl()
21877 {delete priv_;}
21878 
21879 /// A deep comparison operator for a shared pointer to @ref function_decl
21880 ///
21881 /// This function compares to shared pointers to @ref function_decl by
21882 /// looking at the pointed-to instances of @ref function_dec
21883 /// comparing them too.  If the two pointed-to objects are equal then
21884 /// this function returns true.
21885 ///
21886 /// @param l the left-hand side argument of the equality operator.
21887 ///
21888 /// @param r the right-hand side argument of the equality operator.
21889 ///
21890 /// @return true iff @p l equals @p r.
21891 bool
operator ==(const function_decl_sptr & l,const function_decl_sptr & r)21892 operator==(const function_decl_sptr& l, const function_decl_sptr& r)
21893 {
21894   if (l.get() == r.get())
21895     return true;
21896   if (!!l != !!r)
21897     return false;
21898 
21899   return *l == *r;
21900 }
21901 
21902 /// A deep inequality operator for smart pointers to functions.
21903 ///
21904 /// @param l the left-hand side argument of the inequality operator.
21905 ///
21906 /// @pram r the right-hand side argument of the inequality operator.
21907 ///
21908 /// @return true iff @p is not equal to @p r.
21909 bool
operator !=(const function_decl_sptr & l,const function_decl_sptr & r)21910 operator!=(const function_decl_sptr& l, const function_decl_sptr& r)
21911 {return !operator==(l, r);}
21912 
21913 // <function_decl definitions>
21914 
21915 // <function_decl::parameter definitions>
21916 
21917 struct function_decl::parameter::priv
21918 {
21919   type_base_wptr	type_;
21920   unsigned		index_;
21921   bool			variadic_marker_;
21922 
privabigail::ir::function_decl::parameter::priv21923   priv()
21924     : index_(),
21925       variadic_marker_()
21926   {}
21927 
privabigail::ir::function_decl::parameter::priv21928   priv(type_base_sptr type,
21929        unsigned index,
21930        bool variadic_marker)
21931     : type_(type),
21932       index_(index),
21933       variadic_marker_(variadic_marker)
21934   {}
21935 };// end struct function_decl::parameter::priv
21936 
parameter(const type_base_sptr type,unsigned index,const string & name,const location & loc,bool is_variadic)21937 function_decl::parameter::parameter(const type_base_sptr	type,
21938 				    unsigned			index,
21939 				    const string&		name,
21940 				    const location&		loc,
21941 				    bool			is_variadic)
21942   : type_or_decl_base(type->get_environment(),
21943 		      FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
21944     decl_base(type->get_environment(), name, loc),
21945     priv_(new priv(type, index, is_variadic))
21946 {
21947   runtime_type_instance(this);
21948 }
21949 
parameter(const type_base_sptr type,unsigned index,const string & name,const location & loc,bool is_variadic,bool is_artificial)21950 function_decl::parameter::parameter(const type_base_sptr	type,
21951 				    unsigned			index,
21952 				    const string&		name,
21953 				    const location&		loc,
21954 				    bool			is_variadic,
21955 				    bool			is_artificial)
21956   : type_or_decl_base(type->get_environment(),
21957 		      FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
21958     decl_base(type->get_environment(), name, loc),
21959     priv_(new priv(type, index, is_variadic))
21960 {
21961   runtime_type_instance(this);
21962   set_is_artificial(is_artificial);
21963 }
21964 
parameter(const type_base_sptr type,const string & name,const location & loc,bool is_variadic,bool is_artificial)21965 function_decl::parameter::parameter(const type_base_sptr	type,
21966 				    const string&		name,
21967 				    const location&		loc,
21968 				    bool			is_variadic,
21969 				    bool			is_artificial)
21970   : type_or_decl_base(type->get_environment(),
21971 		      FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
21972     decl_base(type->get_environment(), name, loc),
21973     priv_(new priv(type, 0, is_variadic))
21974 {
21975   runtime_type_instance(this);
21976   set_is_artificial(is_artificial);
21977 }
21978 
parameter(const type_base_sptr type,unsigned index,bool variad)21979 function_decl::parameter::parameter(const type_base_sptr	type,
21980 				    unsigned			index,
21981 				    bool			variad)
21982   : type_or_decl_base(type->get_environment(),
21983 		      FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
21984     decl_base(type->get_environment(), "", location()),
21985     priv_(new priv(type, index, variad))
21986 {
21987   runtime_type_instance(this);
21988 }
21989 
21990 function_decl::parameter::~parameter() = default;
21991 
21992 const type_base_sptr
get_type() const21993 function_decl::parameter::get_type()const
21994 {return priv_->type_.lock();}
21995 
21996 /// @return a copy of the type name of the parameter.
21997 interned_string
get_type_name() const21998 function_decl::parameter::get_type_name() const
21999 {
22000   const environment& env = get_environment();
22001 
22002   type_base_sptr t = get_type();
22003   string str;
22004   if (get_variadic_marker() || env.is_variadic_parameter_type(t))
22005     str = "...";
22006   else
22007     {
22008 	ABG_ASSERT(t);
22009 	str = abigail::ir::get_type_name(t);
22010     }
22011   return env.intern(str);
22012 }
22013 
22014 /// @return a copy of the pretty representation of the type of the
22015 /// parameter.
22016 const string
get_type_pretty_representation() const22017 function_decl::parameter::get_type_pretty_representation() const
22018 {
22019   type_base_sptr t = get_type();
22020   string str;
22021   if (get_variadic_marker()
22022       || get_environment().is_variadic_parameter_type(t))
22023     str = "...";
22024   else
22025     {
22026 	ABG_ASSERT(t);
22027 	str += get_type_declaration(t)->get_pretty_representation();
22028     }
22029   return str;
22030 }
22031 
22032 /// Get a name uniquely identifying the parameter in the function.
22033 ///
22034 ///@return the unique parm name id.
22035 interned_string
get_name_id() const22036 function_decl::parameter::get_name_id() const
22037 {
22038   const environment& env = get_environment();
22039 
22040 
22041   std::ostringstream o;
22042   o << "parameter-" << get_index();
22043 
22044   return env.intern(o.str());
22045 }
22046 
22047 unsigned
get_index() const22048 function_decl::parameter::get_index() const
22049 {return priv_->index_;}
22050 
22051 void
set_index(unsigned i)22052 function_decl::parameter::set_index(unsigned i)
22053 {priv_->index_ = i;}
22054 
22055 
22056 bool
get_variadic_marker() const22057 function_decl::parameter::get_variadic_marker() const
22058 {return priv_->variadic_marker_;}
22059 
22060 /// Compares two instances of @ref function_decl::parameter.
22061 ///
22062 /// If the two intances are different, set a bitfield to give some
22063 /// insight about the kind of differences there are.
22064 ///
22065 /// @param l the first artifact of the comparison.
22066 ///
22067 /// @param r the second artifact of the comparison.
22068 ///
22069 /// @param k a pointer to a bitfield that gives information about the
22070 /// kind of changes there are between @p l and @p r.  This one is set
22071 /// iff @p k is non-null and the function returns false.
22072 ///
22073 /// Please note that setting k to a non-null value does have a
22074 /// negative performance impact because even if @p l and @p r are not
22075 /// equal, the function keeps up the comparison in order to determine
22076 /// the different kinds of ways in which they are different.
22077 ///
22078 /// @return true if @p l equals @p r, false otherwise.
22079 bool
equals(const function_decl::parameter & l,const function_decl::parameter & r,change_kind * k)22080 equals(const function_decl::parameter& l,
22081        const function_decl::parameter& r,
22082        change_kind* k)
22083 {
22084   bool result = true;
22085 
22086   if ((l.get_variadic_marker() != r.get_variadic_marker())
22087       || (l.get_index() != r.get_index())
22088       || (!!l.get_type() != !!r.get_type()))
22089     {
22090       result = false;
22091       if (k)
22092 	{
22093 	  if (l.get_index() != r.get_index())
22094 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
22095 	  if (l.get_variadic_marker() != r.get_variadic_marker()
22096 	      || !!l.get_type() != !!r.get_type())
22097 	    *k |= LOCAL_TYPE_CHANGE_KIND;
22098 	}
22099       else
22100 	ABG_RETURN_FALSE;
22101     }
22102 
22103   type_base_sptr l_type = peel_typedef_type(l.get_type());
22104   type_base_sptr r_type = peel_typedef_type(r.get_type());
22105   if (l_type != r_type)
22106     {
22107       result = false;
22108       if (k)
22109 	{
22110 	  if (!types_have_similar_structure(l_type, r_type))
22111 	    *k |= LOCAL_TYPE_CHANGE_KIND;
22112 	  else
22113 	    *k |= SUBTYPE_CHANGE_KIND;
22114 	}
22115       else
22116 	ABG_RETURN_FALSE;
22117     }
22118 
22119   ABG_RETURN(result);
22120 }
22121 
22122 bool
operator ==(const parameter & o) const22123 function_decl::parameter::operator==(const parameter& o) const
22124 {return equals(*this, o, 0);}
22125 
22126 bool
operator ==(const decl_base & o) const22127 function_decl::parameter::operator==(const decl_base& o) const
22128 {
22129   const function_decl::parameter* p =
22130     dynamic_cast<const function_decl::parameter*>(&o);
22131   if (!p)
22132     return false;
22133   return function_decl::parameter::operator==(*p);
22134 }
22135 
22136 /// Non-member equality operator for @ref function_decl::parameter.
22137 ///
22138 /// @param l the left-hand side of the equality operator
22139 ///
22140 /// @param r the right-hand side of the equality operator
22141 ///
22142 /// @return true iff @p l and @p r equals.
22143 bool
operator ==(const function_decl::parameter_sptr & l,const function_decl::parameter_sptr & r)22144 operator==(const function_decl::parameter_sptr& l,
22145 	   const function_decl::parameter_sptr& r)
22146 {
22147   if (!!l != !!r)
22148     return false;
22149   if (!l)
22150     return true;
22151   return *l == *r;
22152 }
22153 
22154 /// Non-member inequality operator for @ref function_decl::parameter.
22155 ///
22156 /// @param l the left-hand side of the equality operator
22157 ///
22158 /// @param r the right-hand side of the equality operator
22159 ///
22160 /// @return true iff @p l and @p r different.
22161 bool
operator !=(const function_decl::parameter_sptr & l,const function_decl::parameter_sptr & r)22162 operator!=(const function_decl::parameter_sptr& l,
22163 	   const function_decl::parameter_sptr& r)
22164 {return !operator==(l, r);}
22165 
22166 /// Traverse the diff sub-tree under the current instance
22167 /// function_decl.
22168 ///
22169 /// @param v the visitor to invoke on each diff node of the sub-tree.
22170 ///
22171 /// @return true if the traversing has to keep going on, false
22172 /// otherwise.
22173 bool
traverse(ir_node_visitor & v)22174 function_decl::parameter::traverse(ir_node_visitor& v)
22175 {
22176   if (visiting())
22177     return true;
22178 
22179   if (v.visit_begin(this))
22180     {
22181       visiting(true);
22182       if (type_base_sptr t = get_type())
22183 	t->traverse(v);
22184       visiting(false);
22185     }
22186   return v.visit_end(this);
22187 }
22188 
22189 /// Get the hash of a decl.  If the hash hasn't been computed yet,
22190 /// compute it ans store its value; otherwise, just return the hash.
22191 ///
22192 /// @return the hash of the decl.
22193 size_t
get_hash() const22194 function_decl::parameter::get_hash() const
22195 {
22196   function_decl::parameter::hash hash_fn_parm;
22197   return hash_fn_parm(this);
22198 }
22199 
22200 /// Compute the qualified name of the parameter.
22201 ///
22202 /// @param internal set to true if the call is intended for an
22203 /// internal use (for technical use inside the library itself), false
22204 /// otherwise.  If you don't know what this is for, then set it to
22205 /// false.
22206 ///
22207 /// @param qn the resulting qualified name.
22208 void
get_qualified_name(interned_string & qualified_name,bool) const22209 function_decl::parameter::get_qualified_name(interned_string& qualified_name,
22210 					     bool /*internal*/) const
22211 {qualified_name = get_name();}
22212 
22213 /// Compute and return a copy of the pretty representation of the
22214 /// current function parameter.
22215 ///
22216 /// @param internal set to true if the call is intended to get a
22217 /// representation of the decl (or type) for the purpose of canonical
22218 /// type comparison.  This is mainly used in the function
22219 /// type_base::get_canonical_type_for().
22220 ///
22221 /// In other words if the argument for this parameter is true then the
22222 /// call is meant for internal use (for technical use inside the
22223 /// library itself), false otherwise.  If you don't know what this is
22224 /// for, then set it to false.
22225 ///
22226 /// @return a copy of the textual representation of the current
22227 /// function parameter.
22228 string
get_pretty_representation(bool internal,bool) const22229 function_decl::parameter::get_pretty_representation(bool internal,
22230 						    bool /*qualified_name*/) const
22231 {
22232   const environment& env = get_environment();
22233 
22234   string type_repr;
22235   type_base_sptr t = get_type();
22236   if (!t)
22237     type_repr = "void";
22238   else if (env.is_variadic_parameter_type(t))
22239     type_repr = "...";
22240   else
22241     type_repr = ir::get_pretty_representation(t, internal);
22242 
22243   string result = type_repr;
22244   string parm_name = get_name_id();
22245 
22246   if (!parm_name.empty())
22247     result += " " + parm_name;
22248 
22249   return result;
22250 }
22251 
22252 // </function_decl::parameter definitions>
22253 
22254 // <class_or_union definitions>
22255 
22256 /// A Constructor for instances of @ref class_or_union
22257 ///
22258 /// @param env the environment we are operating from.
22259 ///
22260 /// @param name the identifier of the class.
22261 ///
22262 /// @param size_in_bits the size of an instance of @ref
22263 /// class_or_union, expressed in bits
22264 ///
22265 /// @param align_in_bits the alignment of an instance of @ref class_or_union,
22266 /// expressed in bits.
22267 ///
22268 /// @param locus the source location of declaration point this class.
22269 ///
22270 /// @param vis the visibility of instances of @ref class_or_union.
22271 ///
22272 /// @param mem_types the vector of member types of this instance of
22273 /// @ref class_or_union.
22274 ///
22275 /// @param data_members the vector of data members of this instance of
22276 /// @ref class_or_union.
22277 ///
22278 /// @param member_fns the vector of member functions of this instance
22279 /// 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)22280 class_or_union::class_or_union(const environment& env, const string& name,
22281 			       size_t size_in_bits, size_t align_in_bits,
22282 			       const location& locus, visibility vis,
22283 			       member_types& mem_types,
22284 			       data_members& data_members,
22285 			       member_functions& member_fns)
22286   : type_or_decl_base(env,
22287 		      ABSTRACT_TYPE_BASE
22288 		      | ABSTRACT_DECL_BASE
22289 		      | ABSTRACT_SCOPE_TYPE_DECL
22290 		      | ABSTRACT_SCOPE_DECL),
22291     decl_base(env, name, locus, name, vis),
22292     type_base(env, size_in_bits, align_in_bits),
22293     scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
22294     priv_(new priv(data_members, member_fns))
22295 {
22296   for (member_types::iterator i = mem_types.begin();
22297        i != mem_types.end();
22298        ++i)
22299     if (!has_scope(get_type_declaration(*i)))
22300       add_decl_to_scope(get_type_declaration(*i), this);
22301 
22302   for (data_members::iterator i = data_members.begin();
22303        i != data_members.end();
22304        ++i)
22305     if (!has_scope(*i))
22306       add_decl_to_scope(*i, this);
22307 
22308   for (member_functions::iterator i = member_fns.begin();
22309        i != member_fns.end();
22310        ++i)
22311     if (!has_scope(static_pointer_cast<decl_base>(*i)))
22312       add_decl_to_scope(*i, this);
22313 }
22314 
22315 /// A constructor for instances of @ref class_or_union.
22316 ///
22317 /// @param env the environment we are operating from.
22318 ///
22319 /// @param name the name of the class.
22320 ///
22321 /// @param size_in_bits the size of an instance of @ref
22322 /// class_or_union, expressed in bits
22323 ///
22324 /// @param align_in_bits the alignment of an instance of @ref class_or_union,
22325 /// expressed in bits.
22326 ///
22327 /// @param locus the source location of declaration point this class.
22328 ///
22329 /// @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)22330 class_or_union::class_or_union(const environment& env, const string& name,
22331 			       size_t size_in_bits, size_t align_in_bits,
22332 			       const location& locus, visibility vis)
22333   : type_or_decl_base(env,
22334 		      ABSTRACT_TYPE_BASE
22335 		      | ABSTRACT_DECL_BASE
22336 		      | ABSTRACT_SCOPE_TYPE_DECL
22337 		      | ABSTRACT_SCOPE_DECL),
22338     decl_base(env, name, locus, name, vis),
22339     type_base(env, size_in_bits, align_in_bits),
22340     scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
22341     priv_(new priv)
22342 {}
22343 
22344 /// Constructor of the @ref class_or_union type.
22345 ///
22346 /// @param env the @ref environment we are operating from.
22347 ///
22348 /// @param name the name of the @ref class_or_union.
22349 ///
22350 /// @param is_declaration_only a boolean saying whether the instance
22351 /// represents a declaration only, or not.
class_or_union(const environment & env,const string & name,bool is_declaration_only)22352 class_or_union::class_or_union(const environment& env, const string& name,
22353 			       bool is_declaration_only)
22354   : type_or_decl_base(env,
22355 		      ABSTRACT_TYPE_BASE
22356 		      | ABSTRACT_DECL_BASE
22357 		      | ABSTRACT_SCOPE_TYPE_DECL
22358 		      | ABSTRACT_SCOPE_DECL),
22359     decl_base(env, name, location(), name),
22360     type_base(env, 0, 0),
22361     scope_type_decl(env, name, 0, 0, location()),
22362     priv_(new priv)
22363 {
22364   set_is_declaration_only(is_declaration_only);
22365 }
22366 
22367 /// This implements the ir_traversable_base::traverse pure virtual
22368 /// function.
22369 ///
22370 /// @param v the visitor used on the member nodes of the translation
22371 /// unit during the traversal.
22372 ///
22373 /// @return true if the entire IR node tree got traversed, false
22374 /// otherwise.
22375 bool
traverse(ir_node_visitor & v)22376 class_or_union::traverse(ir_node_visitor& v)
22377 {
22378   if (v.type_node_has_been_visited(this))
22379     return true;
22380 
22381   if (visiting())
22382     return true;
22383 
22384   if (v.visit_begin(this))
22385     {
22386       visiting(true);
22387       bool stop = false;
22388 
22389       if (!stop)
22390 	for (data_members::const_iterator i = get_data_members().begin();
22391 	     i != get_data_members().end();
22392 	     ++i)
22393 	  if (!(*i)->traverse(v))
22394 	    {
22395 	      stop = true;
22396 	      break;
22397 	    }
22398 
22399       if (!stop)
22400 	for (member_functions::const_iterator i= get_member_functions().begin();
22401 	     i != get_member_functions().end();
22402 	     ++i)
22403 	  if (!(*i)->traverse(v))
22404 	    {
22405 	      stop = true;
22406 	      break;
22407 	    }
22408 
22409       if (!stop)
22410 	for (member_types::const_iterator i = get_member_types().begin();
22411 	     i != get_member_types().end();
22412 	     ++i)
22413 	  if (!(*i)->traverse(v))
22414 	    {
22415 	      stop = true;
22416 	      break;
22417 	    }
22418 
22419       if (!stop)
22420 	for (member_function_templates::const_iterator i =
22421 	       get_member_function_templates().begin();
22422 	     i != get_member_function_templates().end();
22423 	     ++i)
22424 	  if (!(*i)->traverse(v))
22425 	    {
22426 	      stop = true;
22427 	      break;
22428 	    }
22429 
22430       if (!stop)
22431 	for (member_class_templates::const_iterator i =
22432 	       get_member_class_templates().begin();
22433 	     i != get_member_class_templates().end();
22434 	     ++i)
22435 	  if (!(*i)->traverse(v))
22436 	    {
22437 	      stop = true;
22438 	      break;
22439 	    }
22440       visiting(false);
22441     }
22442 
22443   bool result = v.visit_end(this);
22444   v.mark_type_node_as_visited(this);
22445   return result;
22446 }
22447 
22448 /// Destrcutor of the @ref class_or_union type.
~class_or_union()22449 class_or_union::~class_or_union()
22450 {delete priv_;}
22451 
22452 /// Add a member declaration to the current instance of class_or_union.
22453 /// The member declaration can be either a member type, data member,
22454 /// member function, or member template.
22455 ///
22456 /// @param d the member declaration to add.
22457 decl_base_sptr
add_member_decl(const decl_base_sptr & d)22458 class_or_union::add_member_decl(const decl_base_sptr& d)
22459 {return insert_member_decl(d);}
22460 
22461 /// Remove a given decl from the current @ref class_or_union scope.
22462 ///
22463 /// Note that only type declarations are supported by this method for
22464 /// now.  Support for the other kinds of declaration is left as an
22465 /// exercise for the interested reader of the code.
22466 ///
22467 /// @param decl the declaration to remove from this @ref
22468 /// class_or_union scope.
22469 void
remove_member_decl(decl_base_sptr decl)22470 class_or_union::remove_member_decl(decl_base_sptr decl)
22471 {
22472   type_base_sptr t = is_type(decl);
22473 
22474   // For now we want to support just removing types from classes.  For
22475   // other kinds of IR node, we need more work.
22476   ABG_ASSERT(t);
22477 
22478   remove_member_type(t);
22479 }
22480 
22481 /// Fixup the members of the type of an anonymous data member.
22482 ///
22483 /// Walk all data members of (the type of) a given anonymous data
22484 /// member and set a particular property of the relationship between
22485 /// each data member and its containing type.
22486 ///
22487 /// That property records the fact that the data member belongs to the
22488 /// anonymous data member we consider.
22489 ///
22490 /// In the future, if there are other properties of this relationship
22491 /// to set in this manner, they ought to be added here.
22492 ///
22493 /// @param anon_dm the anonymous data member to consider.
22494 void
maybe_fixup_members_of_anon_data_member(var_decl_sptr & anon_dm)22495 class_or_union::maybe_fixup_members_of_anon_data_member(var_decl_sptr& anon_dm)
22496 {
22497   class_or_union * anon_dm_type =
22498     anonymous_data_member_to_class_or_union(anon_dm.get());
22499   if (!anon_dm_type)
22500     return;
22501 
22502   for (class_or_union::data_members::const_iterator it =
22503 	 anon_dm_type->get_non_static_data_members().begin();
22504        it != anon_dm_type->get_non_static_data_members().end();
22505        ++it)
22506     {
22507       dm_context_rel *rel =
22508 	dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
22509       ABG_ASSERT(rel);
22510       rel->set_anonymous_data_member(anon_dm.get());
22511     }
22512 }
22513 
22514 /// Getter of the alignment of the @ref class_or_union type.
22515 ///
22516 /// If this @ref class_or_union is a declaration of a definition that
22517 /// is elsewhere, then the size of the definition is returned.
22518 ///
22519 /// @return the alignment of the @ref class_or_union type.
22520 size_t
get_alignment_in_bits() const22521 class_or_union::get_alignment_in_bits() const
22522 {
22523   if (get_is_declaration_only() && get_definition_of_declaration())
22524     return is_class_or_union_type
22525       (get_definition_of_declaration())->get_alignment_in_bits();
22526 
22527    return type_base::get_alignment_in_bits();
22528 }
22529 
22530 /// Setter of the alignment of the class type.
22531 ///
22532 /// If this class is a declaration of a definition that is elsewhere,
22533 /// then the new alignment is set to the definition.
22534 ///
22535 /// @param s the new alignment.
22536 void
set_alignment_in_bits(size_t a)22537 class_or_union::set_alignment_in_bits(size_t a)
22538 {
22539   if (get_is_declaration_only() && get_definition_of_declaration())
22540     is_class_or_union_type
22541       (get_definition_of_declaration()) ->set_alignment_in_bits(a);
22542   else
22543     type_base::set_alignment_in_bits(a);
22544 }
22545 
22546 /// Setter of the size of the @ref class_or_union type.
22547 ///
22548 /// If this @ref class_or_union is a declaration of a definition that
22549 /// is elsewhere, then the new size is set to the definition.
22550 ///
22551 /// @param s the new size.
22552 void
set_size_in_bits(size_t s)22553 class_or_union::set_size_in_bits(size_t s)
22554 {
22555   if (get_is_declaration_only() && get_definition_of_declaration())
22556     is_class_or_union_type
22557       (get_definition_of_declaration())->set_size_in_bits(s);
22558   else
22559     type_base::set_size_in_bits(s);
22560 }
22561 
22562 /// Getter of the size of the @ref class_or_union type.
22563 ///
22564 /// If this @ref class_or_union is a declaration of a definition that
22565 /// is elsewhere, then the size of the definition is returned.
22566 ///
22567 /// @return the size of the @ref class_or_union type.
22568 size_t
get_size_in_bits() const22569 class_or_union::get_size_in_bits() const
22570 {
22571   if (get_is_declaration_only() && get_definition_of_declaration())
22572     return is_class_or_union_type
22573       (get_definition_of_declaration())->get_size_in_bits();
22574 
22575   return type_base::get_size_in_bits();
22576 }
22577 
22578 /// Get the number of anonymous member classes contained in this
22579 /// class.
22580 ///
22581 /// @return the number of anonymous member classes contained in this
22582 /// class.
22583 size_t
get_num_anonymous_member_classes() const22584 class_or_union::get_num_anonymous_member_classes() const
22585 {
22586   int result = 0;
22587   for (member_types::const_iterator it = get_member_types().begin();
22588        it != get_member_types().end();
22589        ++it)
22590     if (class_decl_sptr t = is_class_type(*it))
22591       if (t->get_is_anonymous())
22592 	++result;
22593 
22594   return result;
22595 }
22596 
22597 /// Get the number of anonymous member unions contained in this class.
22598 ///
22599 /// @return the number of anonymous member unions contained in this
22600 /// class.
22601 size_t
get_num_anonymous_member_unions() const22602 class_or_union::get_num_anonymous_member_unions() const
22603 {
22604   int result = 0;
22605   for (member_types::const_iterator it = get_member_types().begin();
22606        it != get_member_types().end();
22607        ++it)
22608     if (union_decl_sptr t = is_union_type(*it))
22609       if (t->get_is_anonymous())
22610 	++result;
22611 
22612   return result;
22613 }
22614 
22615 /// Get the number of anonymous member enums contained in this class.
22616 ///
22617 /// @return the number of anonymous member enums contained in this
22618 /// class.
22619 size_t
get_num_anonymous_member_enums() const22620 class_or_union::get_num_anonymous_member_enums() const
22621 {
22622   int result = 0;
22623   for (member_types::const_iterator it = get_member_types().begin();
22624        it != get_member_types().end();
22625        ++it)
22626     if (enum_type_decl_sptr t = is_enum_type(*it))
22627       if (t->get_is_anonymous())
22628 	++result;
22629 
22630   return result;
22631 }
22632 
22633 /// Add a data member to the current instance of class_or_union.
22634 ///
22635 /// @param v a var_decl to add as a data member.  A proper
22636 /// class_or_union::data_member is created from @p v and added to the
22637 /// class_or_union.  This var_decl should not have been already added
22638 /// to a scope.
22639 ///
22640 /// @param access the access specifier for the data member.
22641 ///
22642 /// @param is_laid_out whether the data member was laid out.  That is,
22643 /// if its offset has been computed.  In the pattern of a class
22644 /// template for instance, this would be set to false.
22645 ///
22646 /// @param is_static whether the data memer is static.
22647 ///
22648 /// @param offset_in_bits if @p is_laid_out is true, this is the
22649 /// offset of the data member, expressed (oh, surprise) in bits.
22650 void
add_data_member(var_decl_sptr v,access_specifier access,bool is_laid_out,bool is_static,size_t offset_in_bits)22651 class_or_union::add_data_member(var_decl_sptr v, access_specifier access,
22652 				bool is_laid_out, bool is_static,
22653 				size_t offset_in_bits)
22654 {
22655   ABG_ASSERT(!has_scope(v));
22656 
22657   priv_->data_members_.push_back(v);
22658   scope_decl::add_member_decl(v);
22659   set_data_member_is_laid_out(v, is_laid_out);
22660   set_data_member_offset(v, offset_in_bits);
22661   set_member_access_specifier(v, access);
22662   set_member_is_static(v, is_static);
22663 
22664   if (!is_static)
22665     {
22666       // If this is a non-static variable, add it to the set of
22667       // non-static variables, if it's not only in there.
22668       bool is_already_in = false;
22669       for (data_members::const_iterator i =
22670 	     priv_->non_static_data_members_.begin();
22671 	   i != priv_->non_static_data_members_.end();
22672 	   ++i)
22673 	if (*i == v)
22674 	  {
22675 	    is_already_in = true;
22676 	    break;
22677 	  }
22678       if (!is_already_in)
22679 	priv_->non_static_data_members_.push_back(v);
22680     }
22681 
22682   // If v is an anonymous data member, then fixup its data members.
22683   // For now, the only thing the fixup does is to make the data
22684   // members of the anonymous data member be aware of their containing
22685   // anonymous data member.  That is helpful to compute the absolute
22686   // bit offset of each of the members of the anonymous data member.
22687   maybe_fixup_members_of_anon_data_member(v);
22688 }
22689 
22690 /// Get the data members of this @ref class_or_union.
22691 ///
22692 /// @return a vector of the data members of this @ref class_or_union.
22693 const class_or_union::data_members&
get_data_members() const22694 class_or_union::get_data_members() const
22695 {return priv_->data_members_;}
22696 
22697 /// Find a data member of a given name in the current @ref class_or_union.
22698 ///
22699 /// @param name the name of the data member to find in the current
22700 /// @ref class_or_union.
22701 ///
22702 /// @return a pointer to the @ref var_decl that represents the data
22703 /// member to find inside the current @ref class_or_union.
22704 const var_decl_sptr
find_data_member(const string & name) const22705 class_or_union::find_data_member(const string& name) const
22706 {
22707   for (data_members::const_iterator i = get_data_members().begin();
22708        i != get_data_members().end();
22709        ++i)
22710     if ((*i)->get_name() == name)
22711       return *i;
22712 
22713   // We haven't found a data member with the name 'name'.  Let's look
22714   // closer again, this time in our anonymous data members.
22715   for (data_members::const_iterator i = get_data_members().begin();
22716        i != get_data_members().end();
22717        ++i)
22718     if (is_anonymous_data_member(*i))
22719       {
22720 	class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
22721 	ABG_ASSERT(type);
22722 	if (var_decl_sptr data_member = type->find_data_member(name))
22723 	  return data_member;
22724       }
22725 
22726   return var_decl_sptr();
22727 }
22728 
22729 /// Find an anonymous data member in the class.
22730 ///
22731 /// @param v the anonymous data member to find.
22732 ///
22733 /// @return the anonymous data member found, or nil if none was found.
22734 const var_decl_sptr
find_anonymous_data_member(const var_decl_sptr & v) const22735 class_or_union::find_anonymous_data_member(const var_decl_sptr& v) const
22736 {
22737   if (!v->get_name().empty())
22738     return var_decl_sptr();
22739 
22740   for (data_members::const_iterator it = get_non_static_data_members().begin();
22741        it != get_non_static_data_members().end();
22742        ++it)
22743     {
22744       if (is_anonymous_data_member(*it))
22745 	if ((*it)->get_pretty_representation(/*internal=*/false, true)
22746 	    == v->get_pretty_representation(/*internal=*/false, true))
22747 	  return *it;
22748     }
22749 
22750   return var_decl_sptr();
22751 }
22752 
22753 /// Find a given data member.
22754 ///
22755 /// This function takes a @ref var_decl as an argument.  If it has a
22756 /// non-empty name, then it tries to find a data member which has the
22757 /// same name as the argument.
22758 ///
22759 /// If it has an empty name, then the @ref var_decl is considered as
22760 /// an anonymous data member.  In that case, this function tries to
22761 /// find an anonymous data member which type equals that of the @ref
22762 /// var_decl argument.
22763 ///
22764 /// @param v this carries either the name of the data member we need
22765 /// to look for, or the type of the anonymous data member we are
22766 /// looking for.
22767 const var_decl_sptr
find_data_member(const var_decl_sptr & v) const22768 class_or_union::find_data_member(const var_decl_sptr& v) const
22769 {
22770   if (!v)
22771     return var_decl_sptr();
22772 
22773   if (v->get_name().empty())
22774     return find_anonymous_data_member(v);
22775 
22776   return find_data_member(v->get_name());
22777 }
22778 
22779 
22780 /// Get the non-static data memebers of this @ref class_or_union.
22781 ///
22782 /// @return a vector of the non-static data members of this @ref
22783 /// class_or_union.
22784 const class_or_union::data_members&
get_non_static_data_members() const22785 class_or_union::get_non_static_data_members() const
22786 {return priv_->non_static_data_members_;}
22787 
22788 /// Add a member function.
22789 ///
22790 /// @param f the new member function to add.
22791 ///
22792 /// @param a the access specifier to use for the new member function.
22793 ///
22794 /// @param is_static whether the new member function is static.
22795 ///
22796 /// @param is_ctor whether the new member function is a constructor.
22797 ///
22798 /// @param is_dtor whether the new member function is a destructor.
22799 ///
22800 /// @param is_const whether the new member function is const.
22801 void
add_member_function(method_decl_sptr f,access_specifier a,bool is_static,bool is_ctor,bool is_dtor,bool is_const)22802 class_or_union::add_member_function(method_decl_sptr f,
22803 				    access_specifier a,
22804 				    bool is_static, bool is_ctor,
22805 				    bool is_dtor, bool is_const)
22806 {
22807   ABG_ASSERT(!has_scope(f));
22808 
22809   scope_decl::add_member_decl(f);
22810 
22811   set_member_function_is_ctor(f, is_ctor);
22812   set_member_function_is_dtor(f, is_dtor);
22813   set_member_access_specifier(f, a);
22814   set_member_is_static(f, is_static);
22815   set_member_function_is_const(f, is_const);
22816 
22817   priv_->member_functions_.push_back(f);
22818 
22819   // Update the map of linkage name -> member functions.  It's useful,
22820   // so that class_or_union::find_member_function() can function.
22821   if (!f->get_linkage_name().empty())
22822     priv_->mem_fns_map_[f->get_linkage_name()] = f;
22823 }
22824 
22825 /// Get the member functions of this @ref class_or_union.
22826 ///
22827 /// @return a vector of the member functions of this @ref
22828 /// class_or_union.
22829 const class_or_union::member_functions&
get_member_functions() const22830 class_or_union::get_member_functions() const
22831 {return priv_->member_functions_;}
22832 
22833 /// Find a method, using its linkage name as a key.
22834 ///
22835 /// @param linkage_name the linkage name of the method to find.
22836 ///
22837 /// @return the method found, or nil if none was found.
22838 const method_decl*
find_member_function(const string & linkage_name) const22839 class_or_union::find_member_function(const string& linkage_name) const
22840 {
22841   return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
22842 }
22843 
22844 /// Find a method, using its linkage name as a key.
22845 ///
22846 /// @param linkage_name the linkage name of the method to find.
22847 ///
22848 /// @return the method found, or nil if none was found.
22849 method_decl*
find_member_function(const string & linkage_name)22850 class_or_union::find_member_function(const string& linkage_name)
22851 {
22852   string_mem_fn_sptr_map_type::const_iterator i =
22853     priv_->mem_fns_map_.find(linkage_name);
22854   if (i == priv_->mem_fns_map_.end())
22855     return 0;
22856   return i->second.get();
22857 }
22858 
22859 /// Find a method, using its linkage name as a key.
22860 ///
22861 /// @param linkage_name the linkage name of the method to find.
22862 ///
22863 /// @return the method found, or nil if none was found.
22864 method_decl_sptr
find_member_function_sptr(const string & linkage_name)22865 class_or_union::find_member_function_sptr(const string& linkage_name)
22866 {
22867   string_mem_fn_sptr_map_type::const_iterator i =
22868     priv_->mem_fns_map_.find(linkage_name);
22869   if (i == priv_->mem_fns_map_.end())
22870     return 0;
22871   return i->second;
22872 }
22873 
22874 /// Find a method (member function) using its signature (pretty
22875 /// representation) as a key.
22876 ///
22877 /// @param s the signature of the method.
22878 ///
22879 /// @return the method found, or nil if none was found.
22880 const method_decl*
find_member_function_from_signature(const string & s) const22881 class_or_union::find_member_function_from_signature(const string& s) const
22882 {
22883   return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
22884 }
22885 
22886 /// Find a method (member function) using its signature (pretty
22887 /// representation) as a key.
22888 ///
22889 /// @param s the signature of the method.
22890 ///
22891 /// @return the method found, or nil if none was found.
22892 method_decl*
find_member_function_from_signature(const string & s)22893 class_or_union::find_member_function_from_signature(const string& s)
22894 {
22895   string_mem_fn_ptr_map_type::const_iterator i =
22896     priv_->signature_2_mem_fn_map_.find(s);
22897   if (i == priv_->signature_2_mem_fn_map_.end())
22898     return 0;
22899   return i->second;
22900 }
22901 
22902 /// Get the member function templates of this class.
22903 ///
22904 /// @return a vector of the member function templates of this class.
22905 const member_function_templates&
get_member_function_templates() const22906 class_or_union::get_member_function_templates() const
22907 {return priv_->member_function_templates_;}
22908 
22909 /// Get the member class templates of this class.
22910 ///
22911 /// @return a vector of the member class templates of this class.
22912 const member_class_templates&
get_member_class_templates() const22913 class_or_union::get_member_class_templates() const
22914 {return priv_->member_class_templates_;}
22915 
22916 /// Append a member function template to the @ref class_or_union.
22917 ///
22918 /// @param m the member function template to append.
22919 void
add_member_function_template(member_function_template_sptr m)22920 class_or_union::add_member_function_template(member_function_template_sptr m)
22921 {
22922   decl_base* c = m->as_function_tdecl()->get_scope();
22923   /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
22924   /// error message or something like a structured error.
22925   priv_->member_function_templates_.push_back(m);
22926   if (!c)
22927     scope_decl::add_member_decl(m->as_function_tdecl());
22928 }
22929 
22930 /// Append a member class template to the @ref class_or_union.
22931 ///
22932 /// @param m the member function template to append.
22933 void
add_member_class_template(member_class_template_sptr m)22934 class_or_union::add_member_class_template(member_class_template_sptr m)
22935 {
22936   decl_base* c = m->as_class_tdecl()->get_scope();
22937   /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
22938   /// error message or something like a structured error.
22939   m->set_scope(this);
22940   priv_->member_class_templates_.push_back(m);
22941   if (!c)
22942     scope_decl::add_member_decl(m->as_class_tdecl());
22943 }
22944 
22945 ///@return true iff the current instance has no member.
22946 bool
has_no_member() const22947 class_or_union::has_no_member() const
22948 {
22949   return (get_member_types().empty()
22950 	  && priv_->data_members_.empty()
22951 	  && priv_->member_functions_.empty()
22952 	  && priv_->member_function_templates_.empty()
22953 	  && priv_->member_class_templates_.empty());
22954 }
22955 
22956 /// Insert a data member to this @ref class_or_union type.
22957 ///
22958 /// @param d the data member to insert.
22959 ///
22960 /// @return the decl @p that got inserted.
22961 decl_base_sptr
insert_member_decl(decl_base_sptr d)22962 class_or_union::insert_member_decl(decl_base_sptr d)
22963 {
22964   if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
22965     {
22966       add_data_member(v, public_access,
22967 		      /*is_laid_out=*/false,
22968 		      /*is_static=*/true,
22969 		      /*offset_in_bits=*/0);
22970       d = v;
22971     }
22972   else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
22973     add_member_function(f, public_access,
22974 			/*is_static=*/false,
22975 			/*is_ctor=*/false,
22976 			/*is_dtor=*/false,
22977 			/*is_const=*/false);
22978   else if (member_function_template_sptr f =
22979 	   dynamic_pointer_cast<member_function_template>(d))
22980     add_member_function_template(f);
22981   else if (member_class_template_sptr c =
22982 	   dynamic_pointer_cast<member_class_template>(d))
22983     add_member_class_template(c);
22984   else
22985     scope_decl::add_member_decl(d);
22986 
22987   return d;
22988 }
22989 
22990 /// Equality operator.
22991 ///
22992 /// @param other the other @ref class_or_union to compare against.
22993 ///
22994 /// @return true iff @p other equals the current @ref class_or_union.
22995 bool
operator ==(const decl_base & other) const22996 class_or_union::operator==(const decl_base& other) const
22997 {
22998   const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
22999   if (!op)
23000     return false;
23001 
23002   // If this is a decl-only type (and thus with no canonical type),
23003   // use the canonical type of the definition, if any.
23004   const class_or_union *l = 0;
23005   if (get_is_declaration_only())
23006     l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
23007   if (l == 0)
23008     l = this;
23009 
23010   // Likewise for the other class.
23011   const class_or_union *r = 0;
23012   if (op->get_is_declaration_only())
23013     r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
23014   if (r == 0)
23015     r = op;
23016 
23017   return try_canonical_compare(l, r);
23018 }
23019 
23020 /// Equality operator.
23021 ///
23022 /// @param other the other @ref class_or_union to compare against.
23023 ///
23024 /// @return true iff @p other equals the current @ref class_or_union.
23025 bool
operator ==(const type_base & other) const23026 class_or_union::operator==(const type_base& other) const
23027 {
23028   const decl_base* o = dynamic_cast<const decl_base*>(&other);
23029   if (!o)
23030     return false;
23031   return *this == *o;
23032 }
23033 
23034 /// Equality operator.
23035 ///
23036 /// @param other the other @ref class_or_union to compare against.
23037 ///
23038 /// @return true iff @p other equals the current @ref class_or_union.
23039 bool
operator ==(const class_or_union & other) const23040 class_or_union::operator==(const class_or_union& other) const
23041 {
23042   const decl_base& o = other;
23043   return class_or_union::operator==(o);
23044 }
23045 
23046 /// Compares two instances of @ref class_or_union.
23047 ///
23048 /// If the two intances are different, set a bitfield to give some
23049 /// insight about the kind of differences there are.
23050 ///
23051 /// @param l the first artifact of the comparison.
23052 ///
23053 /// @param r the second artifact of the comparison.
23054 ///
23055 /// @param k a pointer to a bitfield that gives information about the
23056 /// kind of changes there are between @p l and @p r.  This one is set
23057 /// iff it's non-null and if the function returns false.
23058 ///
23059 /// Please note that setting k to a non-null value does have a
23060 /// negative performance impact because even if @p l and @p r are not
23061 /// equal, the function keeps up the comparison in order to determine
23062 /// the different kinds of ways in which they are different.
23063 ///
23064 /// @return true if @p l equals @p r, false otherwise.
23065 bool
equals(const class_or_union & l,const class_or_union & r,change_kind * k)23066 equals(const class_or_union& l, const class_or_union& r, change_kind* k)
23067 {
23068   // if one of the classes is declaration-only, look through it to
23069   // get its definition.
23070   bool l_is_decl_only = l.get_is_declaration_only();
23071   bool r_is_decl_only = r.get_is_declaration_only();
23072   if (l_is_decl_only || r_is_decl_only)
23073     {
23074       const class_or_union* def1 = l_is_decl_only
23075 	? is_class_or_union_type(l.get_naked_definition_of_declaration())
23076 	: &l;
23077 
23078       const class_or_union* def2 = r_is_decl_only
23079 	? is_class_or_union_type(r.get_naked_definition_of_declaration())
23080 	: &r;
23081 
23082       if (!def1 || !def2)
23083 	{
23084 	  if (!l.get_is_anonymous()
23085 	      && !r.get_is_anonymous()
23086 	      && l_is_decl_only && r_is_decl_only
23087 	      && comparison::filtering::is_decl_only_class_with_size_change(l, r))
23088 	    // The two decl-only classes differ from their size.  A
23089 	    // true decl-only class should not have a size property to
23090 	    // begin with.  This comes from a DWARF oddity and can
23091 	    // results in a false positive, so let's not consider that
23092 	    // change.
23093 	    return true;
23094 
23095 	  if ((l.get_environment().decl_only_class_equals_definition()
23096 	       || ((odr_is_relevant(l) && !def1)
23097 		   || (odr_is_relevant(r) && !def2)))
23098 	      && !is_anonymous_or_typedef_named(l)
23099 	      && !is_anonymous_or_typedef_named(r))
23100 	    {
23101 	      const interned_string& q1 = l.get_scoped_name();
23102 	      const interned_string& q2 = r.get_scoped_name();
23103 	      if (q1 == q2)
23104 		// Not using RETURN(true) here, because that causes
23105 		// performance issues.  We don't need to do
23106 		// l.priv_->unmark_as_being_compared({l,r}) here because
23107 		// we haven't marked l or r as being compared yet, and
23108 		// doing so has a peformance cost that shows up on
23109 		// performance profiles for *big* libraries.
23110 		return true;
23111 	      else
23112 		{
23113 		  if (k)
23114 		    *k |= LOCAL_TYPE_CHANGE_KIND;
23115 		  // Not using RETURN(true) here, because that causes
23116 		  // performance issues.  We don't need to do
23117 		  // l.priv_->unmark_as_being_compared({l,r}) here because
23118 		  // we haven't marked l or r as being compared yet, and
23119 		  // doing so has a peformance cost that shows up on
23120 		  // performance profiles for *big* libraries.
23121 		  ABG_RETURN_FALSE;
23122 		}
23123 	    }
23124 	  else // A decl-only class is considered different from a
23125 	       // class definition of the same name.
23126 	    {
23127 	      if (!!def1 != !!def2)
23128 		{
23129 		  if (k)
23130 		    *k |= LOCAL_TYPE_CHANGE_KIND;
23131 		  ABG_RETURN_FALSE;
23132 		}
23133 
23134 	      // both definitions are empty
23135 	      if (!(l.decl_base::operator==(r)
23136 		       && l.type_base::operator==(r)))
23137 		{
23138 		  if (k)
23139 		    *k |= LOCAL_TYPE_CHANGE_KIND;
23140 		  ABG_RETURN_FALSE;
23141 		}
23142 
23143 	      return true;
23144 	    }
23145 	}
23146 
23147       bool val = *def1 == *def2;
23148       if (!val)
23149 	if (k)
23150 	  *k |= LOCAL_TYPE_CHANGE_KIND;
23151       ABG_RETURN(val);
23152     }
23153 
23154   // No need to go further if the classes have different names or
23155   // different size / alignment.
23156   if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
23157     {
23158       if (k)
23159 	*k |= LOCAL_TYPE_CHANGE_KIND;
23160       ABG_RETURN_FALSE;
23161     }
23162 
23163   if (types_defined_same_linux_kernel_corpus_public(l, r))
23164     return true;
23165 
23166   //TODO: Maybe remove this (cycle detection and canonical type
23167   //propagation handling) from here and have it only in the equal
23168   //overload for class_decl and union_decl because this one ( the
23169   //equal overload for class_or_union) is just a sub-routine of these
23170   //two above.
23171 #define RETURN(value)							\
23172   return return_comparison_result(l, r, value,				\
23173 				  /*propagate_canonical_type=*/false);
23174 
23175   RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
23176 
23177   mark_types_as_being_compared(l, r);
23178 
23179   bool result = true;
23180 
23181   //compare data_members
23182   {
23183     if (l.get_non_static_data_members().size()
23184 	!= r.get_non_static_data_members().size())
23185       {
23186 	result = false;
23187 	if (k)
23188 	  *k |= LOCAL_TYPE_CHANGE_KIND;
23189 	else
23190 	  RETURN(result);
23191       }
23192 
23193     for (class_or_union::data_members::const_iterator
23194 	   d0 = l.get_non_static_data_members().begin(),
23195 	   d1 = r.get_non_static_data_members().begin();
23196 	 (d0 != l.get_non_static_data_members().end()
23197 	  && d1 != r.get_non_static_data_members().end());
23198 	 ++d0, ++d1)
23199       if (**d0 != **d1)
23200 	{
23201 	  result = false;
23202 	  if (k)
23203 	    {
23204 	      // Report any representation change as being local.
23205 	      if (!types_have_similar_structure((*d0)->get_type(),
23206 						(*d1)->get_type())
23207 		  || (*d0)->get_type() == (*d1)->get_type())
23208 		*k |= LOCAL_TYPE_CHANGE_KIND;
23209 	      else
23210 		*k |= SUBTYPE_CHANGE_KIND;
23211 	    }
23212 	  else
23213 	    RETURN(result);
23214 	}
23215   }
23216 
23217   // Do not compare member functions.  DWARF does not necessarily
23218   // all the member functions, be they virtual or not, in all
23219   // translation units.  So we cannot have a clear view of them, per
23220   // class
23221 
23222   // compare member function templates
23223   {
23224     if (l.get_member_function_templates().size()
23225 	!= r.get_member_function_templates().size())
23226       {
23227 	result = false;
23228 	if (k)
23229 	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
23230 	else
23231 	  RETURN(result);
23232       }
23233 
23234     for (member_function_templates::const_iterator
23235 	   fn_tmpl_it0 = l.get_member_function_templates().begin(),
23236 	   fn_tmpl_it1 = r.get_member_function_templates().begin();
23237 	 fn_tmpl_it0 != l.get_member_function_templates().end()
23238 	   &&  fn_tmpl_it1 != r.get_member_function_templates().end();
23239 	 ++fn_tmpl_it0, ++fn_tmpl_it1)
23240       if (**fn_tmpl_it0 != **fn_tmpl_it1)
23241 	{
23242 	  result = false;
23243 	  if (k)
23244 	    {
23245 	      *k |= LOCAL_NON_TYPE_CHANGE_KIND;
23246 	      break;
23247 	    }
23248 	  else
23249 	    RETURN(result);
23250 	}
23251   }
23252 
23253   // compare member class templates
23254   {
23255     if (l.get_member_class_templates().size()
23256 	!= r.get_member_class_templates().size())
23257       {
23258 	result = false;
23259 	if (k)
23260 	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
23261 	else
23262 	  RETURN(result);
23263       }
23264 
23265     for (member_class_templates::const_iterator
23266 	   cl_tmpl_it0 = l.get_member_class_templates().begin(),
23267 	   cl_tmpl_it1 = r.get_member_class_templates().begin();
23268 	 cl_tmpl_it0 != l.get_member_class_templates().end()
23269 	   &&  cl_tmpl_it1 != r.get_member_class_templates().end();
23270 	 ++cl_tmpl_it0, ++cl_tmpl_it1)
23271       if (**cl_tmpl_it0 != **cl_tmpl_it1)
23272 	{
23273 	  result = false;
23274 	  if (k)
23275 	    {
23276 	      *k |= LOCAL_NON_TYPE_CHANGE_KIND;
23277 	      break;
23278 	    }
23279 	  else
23280 	    RETURN(result);
23281 	}
23282   }
23283 
23284   RETURN(result);
23285 #undef RETURN
23286 }
23287 
23288 
23289 /// Copy a method of a @ref class_or_union into a new @ref
23290 /// class_or_union.
23291 ///
23292 /// @param t the @ref class_or_union into which the method is to be copied.
23293 ///
23294 /// @param method the method to copy into @p t.
23295 ///
23296 /// @return the resulting newly copied method.
23297 method_decl_sptr
copy_member_function(const class_or_union_sptr & t,const method_decl_sptr & method)23298 copy_member_function(const class_or_union_sptr& t,
23299 		     const method_decl_sptr& method)
23300 {return copy_member_function(t, method.get());}
23301 
23302 
23303 /// Copy a method of a @ref class_or_union into a new @ref
23304 /// class_or_union.
23305 ///
23306 /// @param t the @ref class_or_union into which the method is to be copied.
23307 ///
23308 /// @param method the method to copy into @p t.
23309 ///
23310 /// @return the resulting newly copied method.
23311 method_decl_sptr
copy_member_function(const class_or_union_sptr & t,const method_decl * method)23312 copy_member_function(const class_or_union_sptr& t, const method_decl* method)
23313 {
23314   ABG_ASSERT(t);
23315   ABG_ASSERT(method);
23316 
23317   method_type_sptr old_type = method->get_type();
23318   ABG_ASSERT(old_type);
23319   method_type_sptr new_type(new method_type(old_type->get_return_type(),
23320 					    t,
23321 					    old_type->get_parameters(),
23322 					    old_type->get_is_const(),
23323 					    old_type->get_size_in_bits(),
23324 					    old_type->get_alignment_in_bits()));
23325   t->get_translation_unit()->bind_function_type_life_time(new_type);
23326 
23327   method_decl_sptr
23328     new_method(new method_decl(method->get_name(),
23329 			       new_type,
23330 			       method->is_declared_inline(),
23331 			       method->get_location(),
23332 			       method->get_linkage_name(),
23333 			       method->get_visibility(),
23334 			       method->get_binding()));
23335   new_method->set_symbol(method->get_symbol());
23336 
23337   if (class_decl_sptr class_type = is_class_type(t))
23338     class_type->add_member_function(new_method,
23339 				    get_member_access_specifier(*method),
23340 				    get_member_function_is_virtual(*method),
23341 				    get_member_function_vtable_offset(*method),
23342 				    get_member_is_static(*method),
23343 				    get_member_function_is_ctor(*method),
23344 				    get_member_function_is_dtor(*method),
23345 				    get_member_function_is_const(*method));
23346   else
23347     t->add_member_function(new_method,
23348 			   get_member_access_specifier(*method),
23349 			   get_member_is_static(*method),
23350 			   get_member_function_is_ctor(*method),
23351 			   get_member_function_is_dtor(*method),
23352 			   get_member_function_is_const(*method));
23353   return new_method;
23354 }
23355 
23356 // </class_or_union definitions>
23357 
23358 /// @defgroup OnTheFlyCanonicalization On-the-fly Canonicalization
23359 /// @{
23360 ///
23361 /// This optimization is also known as "canonical type propagation".
23362 ///
23363 /// During the canonicalization of a type T (which doesn't yet have a
23364 /// canonical type), T is compared structurally (member-wise) against
23365 /// a type C which already has a canonical type.  The comparison
23366 /// expression is C == T.
23367 ///
23368 /// During that structural comparison, if a subtype of C (which also
23369 /// already has a canonical type) is structurally compared to a
23370 /// subtype of T (which doesn't yet have a canonical type) and if they
23371 /// are equal, then we can deduce that the canonical type of the
23372 /// subtype of C is the canonical type of the subtype of C.
23373 ///
23374 /// Thus, we can canonicalize the sub-type of the T, during the
23375 /// canonicalization of T itself.  That canonicalization of the
23376 /// sub-type of T is what we call the "on-the-fly canonicalization".
23377 /// It's on the fly because it happens during a comparison -- which
23378 /// itself happens during the canonicalization of T.
23379 ///
23380 /// For now this on-the-fly canonicalization only happens when
23381 /// comparing @ref class_decl and @ref function_type.
23382 ///
23383 /// Note however that there is a case when a type is *NOT* eligible to
23384 /// this canonical type propagation optimization.
23385 ///
23386 /// The reason why a type is deemed NON-eligible to the canonical type
23387 /// propagation optimization is that it "depends" on recursively
23388 /// present type.  Let me explain.
23389 ///
23390 /// Suppose we have a type T that has sub-types named ST0 and ST1.
23391 /// Suppose ST1 itself has a sub-type that is T itself.  In this case,
23392 /// we say that T is a recursive type, because it has T (itself) as
23393 /// one of its sub-types:
23394 ///
23395 /// <PRE>
23396 ///    T
23397 ///    +-- ST0
23398 ///    |
23399 ///    +-- ST1
23400 ///    |    +
23401 ///    |    |
23402 ///    |    +-- T
23403 ///    |
23404 ///    +-- ST2
23405 /// </PRE>
23406 ///
23407 /// ST1 is said to "depend" on T because it has T as a sub-type.  But
23408 /// because T is recursive, then ST1 is said to depend on a recursive
23409 /// type.  Notice however that ST0 does not depend on any recursive
23410 /// type.
23411 ///
23412 /// Now suppose we are comparing T to a type T' that has the same
23413 /// structure with sub-types ST0', ST1' and ST2'.  During the
23414 /// comparison of ST1 against ST1', their sub-type T is compared
23415 /// against T'.  Because T (resp. T') is a recursive type that is
23416 /// already being compared, the comparison of T against T' (as a
23417 /// subtypes of ST1 and ST1') returns true, meaning they are
23418 /// considered equal.  This is done so that we don't enter an infinite
23419 /// recursion.
23420 ///
23421 /// That means ST1 is also deemed equal to ST1'.  If we are in the
23422 /// course of the canonicalization of T' and thus if T (as well as as
23423 /// all of its sub-types) is already canonicalized, then the canonical
23424 /// type propagation optimization will make us propagate the canonical
23425 /// type of ST1 onto ST1'.  So the canonical type of ST1' will be
23426 /// equal to the canonical type of ST1 as a result of that
23427 /// optmization.
23428 ///
23429 /// But then, later down the road, when ST2 is compared against ST2',
23430 /// let's suppose that we find out that they are different. Meaning
23431 /// that ST2 != ST2'.  This means that T != T', i.e, the
23432 /// canonicalization of T' failed for now.  But most importantly, it
23433 /// means that the propagation of the canonical type of ST1 to ST1'
23434 /// must now be invalidated.  Meaning, ST1' must now be considered as
23435 /// not having any canonical type.
23436 ///
23437 /// In other words, during type canonicalization, if ST1' depends on a
23438 /// recursive type T', its propagated canonical type must be
23439 /// invalidated (set to nullptr) if T' appears to be different from T,
23440 /// a.k.a, the canonicalization of T' temporarily failed.
23441 ///
23442 /// This means that any sub-type that depends on recursive types and
23443 /// that has been the target of the canonical type propagation
23444 /// optimization must be tracked.  If the dependant recursive type
23445 /// fails its canonicalization, then the sub-type being compared must
23446 /// have its propagated canonical type cleared.  In other words, its
23447 /// propagated canonical type must be cancelled.
23448 ///
23449 /// @}
23450 
23451 
23452 /// If on-the-fly canonicalization is turned on, then this function
23453 /// sets the canonical type of its second parameter to the canonical
23454 /// type of the first parameter.
23455 ///
23456 /// @param lhs_type the type which canonical type to propagate.
23457 ///
23458 /// @param rhs_type the type which canonical type to set.
23459 static bool
maybe_propagate_canonical_type(const type_base & lhs_type,const type_base & rhs_type)23460 maybe_propagate_canonical_type(const type_base& lhs_type,
23461 			       const type_base& rhs_type)
23462 {
23463   const environment& env = lhs_type.get_environment();
23464 #if WITH_DEBUG_TYPE_CANONICALIZATION
23465   if (!env.priv_->use_canonical_type_comparison_)
23466     return false;
23467 #endif
23468 
23469   if (env.do_on_the_fly_canonicalization())
23470     if (type_base_sptr canonical_type = lhs_type.get_canonical_type())
23471       if (!rhs_type.get_canonical_type())
23472 	if (env.priv_->propagate_ct(lhs_type, rhs_type))
23473 	  return true;
23474   return false;
23475 }
23476 
23477 // <class_decl definitions>
23478 
23479 static void
23480 sort_virtual_member_functions(class_decl::member_functions& mem_fns);
23481 
23482 /// The private data for the class_decl type.
23483 struct class_decl::priv
23484 {
23485   base_specs					bases_;
23486   unordered_map<string, base_spec_sptr>	bases_map_;
23487   member_functions				virtual_mem_fns_;
23488   virtual_mem_fn_map_type			virtual_mem_fns_map_;
23489   bool						is_struct_;
23490 
privabigail::ir::class_decl::priv23491   priv()
23492     : is_struct_(false)
23493   {}
23494 
privabigail::ir::class_decl::priv23495   priv(bool is_struct, class_decl::base_specs& bases)
23496     : bases_(bases),
23497       is_struct_(is_struct)
23498   {
23499   }
23500 
privabigail::ir::class_decl::priv23501   priv(bool is_struct)
23502     : is_struct_(is_struct)
23503   {}
23504 };// end struct class_decl::priv
23505 
23506 /// A Constructor for instances of \ref class_decl
23507 ///
23508 /// @param env the environment we are operating from.
23509 ///
23510 /// @param name the identifier of the class.
23511 ///
23512 /// @param size_in_bits the size of an instance of class_decl, expressed
23513 /// in bits
23514 ///
23515 /// @param align_in_bits the alignment of an instance of class_decl,
23516 /// expressed in bits.
23517 ///
23518 /// @param locus the source location of declaration point this class.
23519 ///
23520 /// @param vis the visibility of instances of class_decl.
23521 ///
23522 /// @param bases the vector of base classes for this instance of class_decl.
23523 ///
23524 /// @param mbrs the vector of member types of this instance of
23525 /// class_decl.
23526 ///
23527 /// @param data_mbrs the vector of data members of this instance of
23528 /// class_decl.
23529 ///
23530 /// @param mbr_fns the vector of member functions of this instance of
23531 /// 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)23532 class_decl::class_decl(const environment& env, const string& name,
23533 		       size_t size_in_bits, size_t align_in_bits,
23534 		       bool is_struct, const location& locus,
23535 		       visibility vis, base_specs& bases,
23536 		       member_types& mbr_types,
23537 		       data_members& data_mbrs,
23538 		       member_functions& mbr_fns)
23539   : type_or_decl_base(env,
23540 		      CLASS_TYPE
23541 		      | ABSTRACT_TYPE_BASE
23542 		      | ABSTRACT_DECL_BASE
23543 		      | ABSTRACT_SCOPE_TYPE_DECL
23544 		      | ABSTRACT_SCOPE_DECL),
23545     decl_base(env, name, locus, name, vis),
23546     type_base(env, size_in_bits, align_in_bits),
23547     class_or_union(env, name, size_in_bits, align_in_bits,
23548 		   locus, vis, mbr_types, data_mbrs, mbr_fns),
23549     priv_(new priv(is_struct, bases))
23550 {
23551   runtime_type_instance(this);
23552 }
23553 
23554 /// A Constructor for instances of @ref class_decl
23555 ///
23556 /// @param env the environment we are operating from.
23557 ///
23558 /// @param name the identifier of the class.
23559 ///
23560 /// @param size_in_bits the size of an instance of class_decl, expressed
23561 /// in bits
23562 ///
23563 /// @param align_in_bits the alignment of an instance of class_decl,
23564 /// expressed in bits.
23565 ///
23566 /// @param locus the source location of declaration point this class.
23567 ///
23568 /// @param vis the visibility of instances of class_decl.
23569 ///
23570 /// @param bases the vector of base classes for this instance of class_decl.
23571 ///
23572 /// @param mbrs the vector of member types of this instance of
23573 /// class_decl.
23574 ///
23575 /// @param data_mbrs the vector of data members of this instance of
23576 /// class_decl.
23577 ///
23578 /// @param mbr_fns the vector of member functions of this instance of
23579 /// class_decl.
23580 ///
23581 /// @param is_anonymous whether the newly created instance is
23582 /// 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)23583 class_decl::class_decl(const environment& env, const string& name,
23584 		       size_t size_in_bits, size_t align_in_bits,
23585 		       bool is_struct, const location& locus,
23586 		       visibility vis, base_specs& bases,
23587 		       member_types& mbr_types, data_members& data_mbrs,
23588 		       member_functions& mbr_fns, bool is_anonymous)
23589   : type_or_decl_base(env,
23590 		      CLASS_TYPE
23591 		      | ABSTRACT_TYPE_BASE
23592 		      | ABSTRACT_DECL_BASE
23593 		      | ABSTRACT_SCOPE_TYPE_DECL
23594 		      | ABSTRACT_SCOPE_DECL),
23595     decl_base(env, name, locus,
23596 	      // If the class is anonymous then by default it won't
23597 	      // have a linkage name.  Also, the anonymous class does
23598 	      // have an internal-only unique name that is generally
23599 	      // not taken into account when comparing classes; such a
23600 	      // unique internal-only name, when used as a linkage
23601 	      // name might introduce spurious comparison false
23602 	      // negatives.
23603 	      /*linkage_name=*/is_anonymous ? string() : name,
23604 	      vis),
23605     type_base(env, size_in_bits, align_in_bits),
23606     class_or_union(env, name, size_in_bits, align_in_bits,
23607 		   locus, vis, mbr_types, data_mbrs, mbr_fns),
23608     priv_(new priv(is_struct, bases))
23609 {
23610   runtime_type_instance(this);
23611   set_is_anonymous(is_anonymous);
23612 }
23613 
23614 /// A constructor for instances of class_decl.
23615 ///
23616 /// @param env the environment we are operating from.
23617 ///
23618 /// @param name the name of the class.
23619 ///
23620 /// @param size_in_bits the size of an instance of class_decl, expressed
23621 /// in bits
23622 ///
23623 /// @param align_in_bits the alignment of an instance of class_decl,
23624 /// expressed in bits.
23625 ///
23626 /// @param locus the source location of declaration point this class.
23627 ///
23628 /// @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)23629 class_decl::class_decl(const environment& env, const string& name,
23630 		       size_t size_in_bits, size_t align_in_bits,
23631 		       bool is_struct, const location& locus,
23632 		       visibility vis)
23633   : type_or_decl_base(env,
23634 		      CLASS_TYPE
23635 		      | ABSTRACT_TYPE_BASE
23636 		      | ABSTRACT_DECL_BASE
23637 		      | ABSTRACT_SCOPE_TYPE_DECL
23638 		      | ABSTRACT_SCOPE_DECL),
23639     decl_base(env, name, locus, name, vis),
23640     type_base(env, size_in_bits, align_in_bits),
23641     class_or_union(env, name, size_in_bits, align_in_bits,
23642 		   locus, vis),
23643     priv_(new priv(is_struct))
23644 {
23645   runtime_type_instance(this);
23646 }
23647 
23648 /// A constructor for instances of @ref class_decl.
23649 ///
23650 /// @param env the environment we are operating from.
23651 ///
23652 /// @param name the name of the class.
23653 ///
23654 /// @param size_in_bits the size of an instance of class_decl, expressed
23655 /// in bits
23656 ///
23657 /// @param align_in_bits the alignment of an instance of class_decl,
23658 /// expressed in bits.
23659 ///
23660 /// @param locus the source location of declaration point this class.
23661 ///
23662 /// @param vis the visibility of instances of class_decl.
23663 ///
23664 /// @param is_anonymous whether the newly created instance is
23665 /// 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)23666 class_decl:: class_decl(const environment& env, const string& name,
23667 			size_t size_in_bits, size_t align_in_bits,
23668 			bool is_struct, const location& locus,
23669 			visibility vis, bool is_anonymous)
23670   : type_or_decl_base(env,
23671 		      CLASS_TYPE
23672 		      | ABSTRACT_TYPE_BASE
23673 		      | ABSTRACT_DECL_BASE
23674 		      | ABSTRACT_SCOPE_TYPE_DECL
23675 		      | ABSTRACT_SCOPE_DECL),
23676     decl_base(env, name, locus,
23677 	      // If the class is anonymous then by default it won't
23678 	      // have a linkage name.  Also, the anonymous class does
23679 	      // have an internal-only unique name that is generally
23680 	      // not taken into account when comparing classes; such a
23681 	      // unique internal-only name, when used as a linkage
23682 	      // name might introduce spurious comparison false
23683 	      // negatives.
23684 	      /*linkage_name=*/ is_anonymous ? string() : name,
23685 	      vis),
23686     type_base(env, size_in_bits, align_in_bits),
23687     class_or_union(env, name, size_in_bits, align_in_bits,
23688 		   locus, vis),
23689   priv_(new priv(is_struct))
23690 {
23691   runtime_type_instance(this);
23692   set_is_anonymous(is_anonymous);
23693 }
23694 
23695 /// A constuctor for instances of class_decl that represent a
23696 /// declaration without definition.
23697 ///
23698 /// @param env the environment we are operating from.
23699 ///
23700 /// @param name the name of the class.
23701 ///
23702 /// @param is_declaration_only a boolean saying whether the instance
23703 /// represents a declaration only, or not.
class_decl(const environment & env,const string & name,bool is_struct,bool is_declaration_only)23704 class_decl::class_decl(const environment& env, const string& name,
23705 		       bool is_struct, bool is_declaration_only)
23706   : type_or_decl_base(env,
23707 		      CLASS_TYPE
23708 		      | ABSTRACT_TYPE_BASE
23709 		      | ABSTRACT_DECL_BASE
23710 		      | ABSTRACT_SCOPE_TYPE_DECL
23711 		      | ABSTRACT_SCOPE_DECL),
23712     decl_base(env, name, location(), name),
23713     type_base(env, 0, 0),
23714     class_or_union(env, name, is_declaration_only),
23715     priv_(new priv(is_struct))
23716 {
23717   runtime_type_instance(this);
23718 }
23719 
23720 /// This method is invoked automatically right after the current
23721 /// instance of @ref class_decl has been canonicalized.
23722 ///
23723 /// Currently, the only thing it does is to sort the virtual member
23724 /// functions vector.
23725 void
on_canonical_type_set()23726 class_decl::on_canonical_type_set()
23727 {
23728   sort_virtual_mem_fns();
23729 
23730   for (class_decl::virtual_mem_fn_map_type::iterator i =
23731 	 priv_->virtual_mem_fns_map_.begin();
23732        i != priv_->virtual_mem_fns_map_.end();
23733        ++i)
23734     sort_virtual_member_functions(i->second);
23735 }
23736 
23737 /// Set the "is-struct" flag of the class.
23738 ///
23739 /// @param f the new value of the flag.
23740 void
is_struct(bool f)23741 class_decl::is_struct(bool f)
23742 {priv_->is_struct_ = f;}
23743 
23744 /// Test if the class is a struct.
23745 ///
23746 /// @return true iff the class is a struct.
23747 bool
is_struct() const23748 class_decl::is_struct() const
23749 {return priv_->is_struct_;}
23750 
23751 /// Add a base specifier to this class.
23752 ///
23753 /// @param b the new base specifier.
23754 void
add_base_specifier(base_spec_sptr b)23755 class_decl::add_base_specifier(base_spec_sptr b)
23756 {
23757   priv_->bases_.push_back(b);
23758   priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
23759 }
23760 
23761 /// Get the base specifiers for this class.
23762 ///
23763 /// @return a vector of the base specifiers.
23764 const class_decl::base_specs&
get_base_specifiers() const23765 class_decl::get_base_specifiers() const
23766 {return priv_->bases_;}
23767 
23768 /// Find a base class of a given qualified name for the current class.
23769 ///
23770 /// @param qualified_name the qualified name of the base class to look for.
23771 ///
23772 /// @return a pointer to the @ref class_decl that represents the base
23773 /// class of name @p qualified_name, if found.
23774 class_decl_sptr
find_base_class(const string & qualified_name) const23775 class_decl::find_base_class(const string& qualified_name) const
23776 {
23777   unordered_map<string, base_spec_sptr>::iterator i =
23778     priv_->bases_map_.find(qualified_name);
23779 
23780   if (i != priv_->bases_map_.end())
23781     return i->second->get_base_class();
23782 
23783   return class_decl_sptr();
23784 }
23785 
23786 /// Get the virtual member functions of this class.
23787 ///
23788 /// @param return a vector of the virtual member functions of this
23789 /// class.
23790 const class_decl::member_functions&
get_virtual_mem_fns() const23791 class_decl::get_virtual_mem_fns() const
23792 {return priv_->virtual_mem_fns_;}
23793 
23794 /// Get the map that associates a virtual table offset to the virtual
23795 /// member functions with that virtual table offset.
23796 ///
23797 /// Usually, there should be a 1:1 mapping between a given vtable
23798 /// offset and virtual member functions of that vtable offset.  But
23799 /// because of some implementation details, there can be several C++
23800 /// destructor functions that are *generated* by compilers, for a
23801 /// given destructor that is defined in the source code.  If the
23802 /// destructor is virtual then those generated functions have some
23803 /// DWARF attributes in common with the constructor that the user
23804 /// actually defined in its source code.  Among those attributes are
23805 /// the vtable offset of the destructor.
23806 ///
23807 /// @return the map that associates a virtual table offset to the
23808 /// virtual member functions with that virtual table offset.
23809 const class_decl::virtual_mem_fn_map_type&
get_virtual_mem_fns_map() const23810 class_decl::get_virtual_mem_fns_map() const
23811 {return priv_->virtual_mem_fns_map_;}
23812 
23813 /// Sort the virtual member functions by their virtual index.
23814 void
sort_virtual_mem_fns()23815 class_decl::sort_virtual_mem_fns()
23816 {sort_virtual_member_functions(priv_->virtual_mem_fns_);}
23817 
23818 /// Getter of the pretty representation of the current instance of
23819 /// @ref class_decl.
23820 ///
23821 /// @param internal set to true if the call is intended to get a
23822 /// representation of the decl (or type) for the purpose of canonical
23823 /// type comparison.  This is mainly used in the function
23824 /// type_base::get_canonical_type_for().
23825 ///
23826 /// In other words if the argument for this parameter is true then the
23827 /// call is meant for internal use (for technical use inside the
23828 /// library itself), false otherwise.  If you don't know what this is
23829 /// for, then set it to false.
23830 ///
23831 /// @param qualified_name if true, names emitted in the pretty
23832 /// representation are fully qualified.
23833 ///
23834 /// @return the pretty representaion for a class_decl.
23835 string
get_pretty_representation(bool internal,bool qualified_name) const23836 class_decl::get_pretty_representation(bool internal,
23837 				      bool qualified_name) const
23838 {
23839   string cl = "class ";
23840   if (!internal && is_struct())
23841     cl = "struct ";
23842 
23843   // When computing the pretty representation for internal purposes,
23844   // if an anonymous class is named by a typedef, then consider that
23845   // it has a name, which is the typedef name.
23846   if (get_is_anonymous())
23847     {
23848       if (internal && !get_name().empty())
23849 	return cl + get_type_name(this, qualified_name, /*internal=*/true);
23850       return get_class_or_union_flat_representation(this, "",
23851 						    /*one_line=*/true,
23852 						    internal);
23853 
23854     }
23855 
23856   string result = cl;
23857   if (qualified_name)
23858     result += get_qualified_name(internal);
23859   else
23860     result += get_name();
23861 
23862   return result;
23863 }
23864 
23865 decl_base_sptr
insert_member_decl(decl_base_sptr d)23866 class_decl::insert_member_decl(decl_base_sptr d)
23867 {
23868   if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
23869     add_member_function(f, public_access,
23870 			/*is_virtual=*/false,
23871 			/*vtable_offset=*/0,
23872 			/*is_static=*/false,
23873 			/*is_ctor=*/false,
23874 			/*is_dtor=*/false,
23875 			/*is_const=*/false);
23876   else
23877     d = class_or_union::insert_member_decl(d);
23878 
23879   return d;
23880 }
23881 
23882 /// The private data structure of class_decl::base_spec.
23883 struct class_decl::base_spec::priv
23884 {
23885   class_decl_wptr	base_class_;
23886   long			offset_in_bits_;
23887   bool			is_virtual_;
23888 
privabigail::ir::class_decl::base_spec::priv23889   priv(const class_decl_sptr& cl,
23890        long offset_in_bits,
23891        bool is_virtual)
23892     : base_class_(cl),
23893       offset_in_bits_(offset_in_bits),
23894       is_virtual_(is_virtual)
23895   {}
23896 };
23897 
23898 /// Constructor for base_spec instances.
23899 ///
23900 /// @param base the base class to consider
23901 ///
23902 /// @param a the access specifier of the base class.
23903 ///
23904 /// @param offset_in_bits if positive or null, represents the offset
23905 /// of the base in the layout of its containing type..  If negative,
23906 /// means that the current base is not laid out in its containing type.
23907 ///
23908 /// @param is_virtual if true, means that the current base class is
23909 /// virtual in it's containing type.
base_spec(const class_decl_sptr & base,access_specifier a,long offset_in_bits,bool is_virtual)23910 class_decl::base_spec::base_spec(const class_decl_sptr& base,
23911 				 access_specifier a,
23912 				 long offset_in_bits,
23913 				 bool is_virtual)
23914   : type_or_decl_base(base->get_environment(),
23915 		      ABSTRACT_DECL_BASE),
23916     decl_base(base->get_environment(), base->get_name(), base->get_location(),
23917 	      base->get_linkage_name(), base->get_visibility()),
23918     member_base(a),
23919     priv_(new priv(base, offset_in_bits, is_virtual))
23920 {
23921   runtime_type_instance(this);
23922   set_qualified_name(base->get_qualified_name());
23923 }
23924 
23925 /// Get the base class referred to by the current base class
23926 /// specifier.
23927 ///
23928 /// @return the base class.
23929 class_decl_sptr
get_base_class() const23930 class_decl::base_spec::get_base_class() const
23931 {return priv_->base_class_.lock();}
23932 
23933 /// Getter of the "is-virtual" proprerty of the base class specifier.
23934 ///
23935 /// @return true iff this specifies a virtual base class.
23936 bool
get_is_virtual() const23937 class_decl::base_spec::get_is_virtual() const
23938 {return priv_->is_virtual_;}
23939 
23940 /// Getter of the offset of the base.
23941 ///
23942 /// @return the offset of the base.
23943 long
get_offset_in_bits() const23944 class_decl::base_spec::get_offset_in_bits() const
23945 {return priv_->offset_in_bits_;}
23946 
23947 /// Calculate the hash value for a class_decl::base_spec.
23948 ///
23949 /// @return the hash value.
23950 size_t
get_hash() const23951 class_decl::base_spec::get_hash() const
23952 {
23953   base_spec::hash h;
23954   return h(*this);
23955 }
23956 
23957 /// Traverses an instance of @ref class_decl::base_spec, visiting all
23958 /// the sub-types and decls that it might contain.
23959 ///
23960 /// @param v the visitor that is used to visit every IR sub-node of
23961 /// the current node.
23962 ///
23963 /// @return true if either
23964 ///  - all the children nodes of the current IR node were traversed
23965 ///    and the calling code should keep going with the traversing.
23966 ///  - or the current IR node is already being traversed.
23967 /// Otherwise, returning false means that the calling code should not
23968 /// keep traversing the tree.
23969 bool
traverse(ir_node_visitor & v)23970 class_decl::base_spec::traverse(ir_node_visitor& v)
23971 {
23972   if (visiting())
23973     return true;
23974 
23975   if (v.visit_begin(this))
23976     {
23977       visiting(true);
23978       get_base_class()->traverse(v);
23979       visiting(false);
23980     }
23981 
23982   return v.visit_end(this);
23983 }
23984 
23985 /// Constructor for base_spec instances.
23986 ///
23987 /// Note that this constructor is for clients that don't support RTTI
23988 /// and that have a base class of type_base, but of dynamic type
23989 /// class_decl.
23990 ///
23991 /// @param base the base class to consider.  Must be a pointer to an
23992 /// instance of class_decl
23993 ///
23994 /// @param a the access specifier of the base class.
23995 ///
23996 /// @param offset_in_bits if positive or null, represents the offset
23997 /// of the base in the layout of its containing type..  If negative,
23998 /// means that the current base is not laid out in its containing type.
23999 ///
24000 /// @param is_virtual if true, means that the current base class is
24001 /// virtual in it's containing type.
base_spec(const type_base_sptr & base,access_specifier a,long offset_in_bits,bool is_virtual)24002 class_decl::base_spec::base_spec(const type_base_sptr& base,
24003 				 access_specifier a,
24004 				 long offset_in_bits,
24005 				 bool is_virtual)
24006   : type_or_decl_base(base->get_environment(),
24007 		      ABSTRACT_DECL_BASE),
24008     decl_base(base->get_environment(), get_type_declaration(base)->get_name(),
24009 	      get_type_declaration(base)->get_location(),
24010 	      get_type_declaration(base)->get_linkage_name(),
24011 	      get_type_declaration(base)->get_visibility()),
24012     member_base(a),
24013     priv_(new priv(dynamic_pointer_cast<class_decl>(base),
24014 		   offset_in_bits,
24015 		   is_virtual))
24016 {
24017   runtime_type_instance(this);
24018 }
24019 
24020 class_decl::base_spec::~base_spec() = default;
24021 
24022 /// Compares two instances of @ref class_decl::base_spec.
24023 ///
24024 /// If the two intances are different, set a bitfield to give some
24025 /// insight about the kind of differences there are.
24026 ///
24027 /// @param l the first artifact of the comparison.
24028 ///
24029 /// @param r the second artifact of the comparison.
24030 ///
24031 /// @param k a pointer to a bitfield that gives information about the
24032 /// kind of changes there are between @p l and @p r.  This one is set
24033 /// iff @p k is non-null and the function returns false.
24034 ///
24035 /// Please note that setting k to a non-null value does have a
24036 /// negative performance impact because even if @p l and @p r are not
24037 /// equal, the function keeps up the comparison in order to determine
24038 /// the different kinds of ways in which they are different.
24039 ///
24040 /// @return true if @p l equals @p r, false otherwise.
24041 bool
equals(const class_decl::base_spec & l,const class_decl::base_spec & r,change_kind * k)24042 equals(const class_decl::base_spec& l,
24043        const class_decl::base_spec& r,
24044        change_kind* k)
24045 {
24046   if (!l.member_base::operator==(r))
24047     {
24048       if (k)
24049 	*k |= LOCAL_TYPE_CHANGE_KIND;
24050       ABG_RETURN_FALSE;
24051     }
24052 
24053   ABG_RETURN((*l.get_base_class() == *r.get_base_class()));
24054 }
24055 
24056 /// Comparison operator for @ref class_decl::base_spec.
24057 ///
24058 /// @param other the instance of @ref class_decl::base_spec to compare
24059 /// against.
24060 ///
24061 /// @return true if the current instance of @ref class_decl::base_spec
24062 /// equals @p other.
24063 bool
operator ==(const decl_base & other) const24064 class_decl::base_spec::operator==(const decl_base& other) const
24065 {
24066   const class_decl::base_spec* o =
24067     dynamic_cast<const class_decl::base_spec*>(&other);
24068 
24069   if (!o)
24070     return false;
24071 
24072   return equals(*this, *o, 0);
24073 }
24074 
24075 /// Comparison operator for @ref class_decl::base_spec.
24076 ///
24077 /// @param other the instance of @ref class_decl::base_spec to compare
24078 /// against.
24079 ///
24080 /// @return true if the current instance of @ref class_decl::base_spec
24081 /// equals @p other.
24082 bool
operator ==(const member_base & other) const24083 class_decl::base_spec::operator==(const member_base& other) const
24084 {
24085   const class_decl::base_spec* o =
24086     dynamic_cast<const class_decl::base_spec*>(&other);
24087   if (!o)
24088     return false;
24089 
24090   return operator==(static_cast<const decl_base&>(*o));
24091 }
24092 
~mem_fn_context_rel()24093 mem_fn_context_rel::~mem_fn_context_rel()
24094 {
24095 }
24096 
24097 /// A constructor for instances of method_decl.
24098 ///
24099 /// @param name the name of the method.
24100 ///
24101 /// @param type the type of the method.
24102 ///
24103 /// @param declared_inline whether the method was
24104 /// declared inline or not.
24105 ///
24106 /// @param locus the source location of the method.
24107 ///
24108 /// @param linkage_name the mangled name of the method.
24109 ///
24110 /// @param vis the visibility of the method.
24111 ///
24112 /// @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)24113 method_decl::method_decl(const string&		name,
24114 			 method_type_sptr	type,
24115 			 bool			declared_inline,
24116 			 const location&	locus,
24117 			 const string&		linkage_name,
24118 			 visibility		vis,
24119 			 binding		bind)
24120   : type_or_decl_base(type->get_environment(),
24121 		      METHOD_DECL
24122 		      | ABSTRACT_DECL_BASE
24123 		      |FUNCTION_DECL),
24124     decl_base(type->get_environment(), name, locus, linkage_name, vis),
24125     function_decl(name, static_pointer_cast<function_type>(type),
24126 		  declared_inline, locus, linkage_name, vis, bind)
24127 {
24128   runtime_type_instance(this);
24129   set_context_rel(new mem_fn_context_rel(0));
24130   set_member_function_is_const(*this, type->get_is_const());
24131 }
24132 
24133 /// A constructor for instances of method_decl.
24134 ///
24135 /// @param name the name of the method.
24136 ///
24137 /// @param type the type of the method.  Must be an instance of
24138 /// method_type.
24139 ///
24140 /// @param declared_inline whether the method was
24141 /// declared inline or not.
24142 ///
24143 /// @param locus the source location of the method.
24144 ///
24145 /// @param linkage_name the mangled name of the method.
24146 ///
24147 /// @param vis the visibility of the method.
24148 ///
24149 /// @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)24150 method_decl::method_decl(const string&		name,
24151 			 function_type_sptr	type,
24152 			 bool			declared_inline,
24153 			 const location&	locus,
24154 			 const string&		linkage_name,
24155 			 visibility		vis,
24156 			 binding		bind)
24157   : type_or_decl_base(type->get_environment(),
24158 		      METHOD_DECL
24159 		      | ABSTRACT_DECL_BASE
24160 		      | FUNCTION_DECL),
24161     decl_base(type->get_environment(), name, locus, linkage_name, vis),
24162     function_decl(name, static_pointer_cast<function_type>
24163 		  (dynamic_pointer_cast<method_type>(type)),
24164 		  declared_inline, locus, linkage_name, vis, bind)
24165 {
24166   runtime_type_instance(this);
24167   set_context_rel(new mem_fn_context_rel(0));
24168 }
24169 
24170 /// A constructor for instances of method_decl.
24171 ///
24172 /// @param name the name of the method.
24173 ///
24174 /// @param type the type of the method.  Must be an instance of
24175 /// method_type.
24176 ///
24177 /// @param declared_inline whether the method was
24178 /// declared inline or not.
24179 ///
24180 /// @param locus the source location of the method.
24181 ///
24182 /// @param linkage_name the mangled name of the method.
24183 ///
24184 /// @param vis the visibility of the method.
24185 ///
24186 /// @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)24187 method_decl::method_decl(const string&		name,
24188 			 type_base_sptr	type,
24189 			 bool			declared_inline,
24190 			 const location&	locus,
24191 			 const string&		linkage_name,
24192 			 visibility		vis,
24193 			 binding		bind)
24194   : type_or_decl_base(type->get_environment(),
24195 		      METHOD_DECL
24196 		      | ABSTRACT_DECL_BASE
24197 		      | FUNCTION_DECL),
24198     decl_base(type->get_environment(), name, locus, linkage_name, vis),
24199     function_decl(name, static_pointer_cast<function_type>
24200 		  (dynamic_pointer_cast<method_type>(type)),
24201 		  declared_inline, locus, linkage_name, vis, bind)
24202 {
24203   runtime_type_instance(this);
24204   set_context_rel(new mem_fn_context_rel(0));
24205 }
24206 
24207 /// Set the linkage name of the method.
24208 ///
24209 /// @param l the new linkage name of the method.
24210 void
set_linkage_name(const string & l)24211 method_decl::set_linkage_name(const string& l)
24212 {
24213   string old_lname = get_linkage_name();
24214   decl_base::set_linkage_name(l);
24215   // Update the linkage_name -> member function map of the containing
24216   // class declaration.
24217   if (!l.empty())
24218     {
24219       method_type_sptr t = get_type();
24220       class_or_union_sptr cl = t->get_class_type();
24221       method_decl_sptr m(this, sptr_utils::noop_deleter());
24222       cl->priv_->mem_fns_map_[l] = m;
24223       if (!old_lname.empty() && l != old_lname)
24224 	{
24225 	  if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
24226 	    {
24227 	      ABG_ASSERT(m.get() == this);
24228 	      cl->priv_->mem_fns_map_.erase(old_lname);
24229 	    }
24230 	}
24231     }
24232 }
24233 
~method_decl()24234 method_decl::~method_decl()
24235 {}
24236 
24237 const method_type_sptr
get_type() const24238 method_decl::get_type() const
24239 {
24240   method_type_sptr result;
24241   if (function_decl::get_type())
24242     result = dynamic_pointer_cast<method_type>(function_decl::get_type());
24243   return result;
24244 }
24245 
24246 /// Set the containing class of a method_decl.
24247 ///
24248 /// @param scope the new containing class_decl.
24249 void
set_scope(scope_decl * scope)24250 method_decl::set_scope(scope_decl* scope)
24251 {
24252   if (!get_context_rel())
24253     set_context_rel(new mem_fn_context_rel(scope));
24254   else
24255     get_context_rel()->set_scope(scope);
24256 }
24257 
24258 /// Equality operator for @ref method_decl_sptr.
24259 ///
24260 /// This is a deep equality operator, as it compares the @ref
24261 /// method_decl that is pointed-to by the smart pointer.
24262 ///
24263 /// @param l the left-hand side argument of the equality operator.
24264 ///
24265 /// @param r the righ-hand side argument of the equality operator.
24266 ///
24267 /// @return true iff @p l equals @p r.
24268 bool
operator ==(const method_decl_sptr & l,const method_decl_sptr & r)24269 operator==(const method_decl_sptr& l, const method_decl_sptr& r)
24270 {
24271   if (l.get() == r.get())
24272     return true;
24273   if (!!l != !!r)
24274     return false;
24275 
24276   return *l == *r;
24277 }
24278 
24279 /// Inequality operator for @ref method_decl_sptr.
24280 ///
24281 /// This is a deep equality operator, as it compares the @ref
24282 /// method_decl that is pointed-to by the smart pointer.
24283 ///
24284 /// @param l the left-hand side argument of the equality operator.
24285 ///
24286 /// @param r the righ-hand side argument of the equality operator.
24287 ///
24288 /// @return true iff @p l differs from @p r.
24289 bool
operator !=(const method_decl_sptr & l,const method_decl_sptr & r)24290 operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
24291 {return !operator==(l, r);}
24292 
24293 /// Test if a function_decl is actually a method_decl.
24294 ///
24295 ///@param d the @ref function_decl to consider.
24296 ///
24297 /// @return the method_decl sub-object of @p d if inherits
24298 /// a method_decl type.
24299 method_decl*
is_method_decl(const type_or_decl_base * d)24300 is_method_decl(const type_or_decl_base *d)
24301 {
24302   return dynamic_cast<method_decl*>
24303     (const_cast<type_or_decl_base*>(d));
24304 }
24305 
24306 /// Test if a function_decl is actually a method_decl.
24307 ///
24308 ///@param d the @ref function_decl to consider.
24309 ///
24310 /// @return the method_decl sub-object of @p d if inherits
24311 /// a method_decl type.
24312 method_decl*
is_method_decl(const type_or_decl_base & d)24313 is_method_decl(const type_or_decl_base&d)
24314 {return is_method_decl(&d);}
24315 
24316 /// Test if a function_decl is actually a method_decl.
24317 ///
24318 ///@param d the @ref function_decl to consider.
24319 ///
24320 /// @return the method_decl sub-object of @p d if inherits
24321 /// a method_decl type.
24322 method_decl_sptr
is_method_decl(const type_or_decl_base_sptr & d)24323 is_method_decl(const type_or_decl_base_sptr& d)
24324 {return dynamic_pointer_cast<method_decl>(d);}
24325 
24326 /// A "less than" functor to sort a vector of instances of
24327 /// method_decl that are virtual.
24328 struct virtual_member_function_less_than
24329 {
24330   /// The less than operator.  First, it sorts the methods by their
24331   /// vtable index.  If they have the same vtable index, it sorts them
24332   /// by the name of their ELF symbol.  If they don't have elf
24333   /// symbols, it sorts them by considering their pretty
24334   /// representation.
24335   ///
24336   ///  Note that this method expects virtual methods.
24337   ///
24338   /// @param f the first method to consider.
24339   ///
24340   /// @param s the second method to consider.
24341   ///
24342   /// @return true if method @p is less than method @s.
24343   bool
operator ()abigail::ir::virtual_member_function_less_than24344   operator()(const method_decl& f,
24345 	     const method_decl& s)
24346   {
24347     ABG_ASSERT(get_member_function_is_virtual(f));
24348     ABG_ASSERT(get_member_function_is_virtual(s));
24349 
24350     ssize_t f_offset = get_member_function_vtable_offset(f);
24351     ssize_t s_offset = get_member_function_vtable_offset(s);
24352     if (f_offset != s_offset) return f_offset < s_offset;
24353 
24354     string fn, sn;
24355 
24356     // If the functions have symbols, then compare their symbol-id
24357     // string.
24358     elf_symbol_sptr f_sym = f.get_symbol();
24359     elf_symbol_sptr s_sym = s.get_symbol();
24360     if ((!f_sym) != (!s_sym)) return !f_sym;
24361     if (f_sym && s_sym)
24362       {
24363 	fn = f_sym->get_id_string();
24364 	sn = s_sym->get_id_string();
24365 	if (fn != sn) return fn < sn;
24366       }
24367 
24368     // Try the linkage names (important for destructors).
24369     fn = f.get_linkage_name();
24370     sn = s.get_linkage_name();
24371     if (fn != sn) return fn < sn;
24372 
24373     // None of the functions have symbols or linkage names that
24374     // distinguish them, so compare their pretty representation.
24375     fn = f.get_pretty_representation();
24376     sn = s.get_pretty_representation();
24377     if (fn != sn) return fn < sn;
24378 
24379     /// If it's just the file paths that are different then sort them
24380     /// too.
24381     string fn_filepath, sn_filepath;
24382     unsigned line = 0, column = 0;
24383     location fn_loc = f.get_location(), sn_loc = s.get_location();
24384     if (fn_loc)
24385       fn_loc.expand(fn_filepath, line, column);
24386     if (sn_loc)
24387       sn_loc.expand(sn_filepath, line, column);
24388     return fn_filepath < sn_filepath;
24389   }
24390 
24391   /// The less than operator.  First, it sorts the methods by their
24392   /// vtable index.  If they have the same vtable index, it sorts them
24393   /// by the name of their ELF symbol.  If they don't have elf
24394   /// symbols, it sorts them by considering their pretty
24395   /// representation.
24396   ///
24397   ///  Note that this method expects to take virtual methods.
24398   ///
24399   /// @param f the first method to consider.
24400   ///
24401   /// @param s the second method to consider.
24402   bool
operator ()abigail::ir::virtual_member_function_less_than24403   operator()(const method_decl_sptr f,
24404 	     const method_decl_sptr s)
24405   {return operator()(*f, *s);}
24406 }; // end struct virtual_member_function_less_than
24407 
24408 /// Sort a vector of instances of virtual member functions.
24409 ///
24410 /// @param mem_fns the vector of member functions to sort.
24411 static void
sort_virtual_member_functions(class_decl::member_functions & mem_fns)24412 sort_virtual_member_functions(class_decl::member_functions& mem_fns)
24413 {
24414   virtual_member_function_less_than lt;
24415   std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
24416 }
24417 
24418 /// Add a member function to the current instance of @ref class_or_union.
24419 ///
24420 /// @param f a method_decl to add to the current class.  This function
24421 /// should not have been already added to a scope.
24422 ///
24423 /// @param access the access specifier for the member function to add.
24424 ///
24425 /// @param is_virtual if this is true then it means the function @p f
24426 /// is a virtual function.  That also means that the current instance
24427 /// of @ref class_or_union is actually an instance of @ref class_decl.
24428 ///
24429 /// @param vtable_offset the offset of the member function in the
24430 /// virtual table.  This parameter is taken into account only if @p
24431 /// is_virtual is true.
24432 ///
24433 /// @param is_static whether the member function is static.
24434 ///
24435 /// @param is_ctor whether the member function is a constructor.
24436 ///
24437 /// @param is_dtor whether the member function is a destructor.
24438 ///
24439 /// @param is_const whether the member function is const.
24440 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)24441 class_or_union::add_member_function(method_decl_sptr f,
24442 				    access_specifier a,
24443 				    bool is_virtual,
24444 				    size_t vtable_offset,
24445 				    bool is_static, bool is_ctor,
24446 				    bool is_dtor, bool is_const)
24447 {
24448   add_member_function(f, a, is_static, is_ctor,
24449 		      is_dtor, is_const);
24450 
24451   if (class_decl* klass = is_class_type(this))
24452     {
24453       set_member_function_is_virtual(f, is_virtual);
24454       if (is_virtual)
24455 	{
24456 	  set_member_function_vtable_offset(f, vtable_offset);
24457 	  sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
24458 	}
24459     }
24460 }
24461 
24462 /// When a virtual member function has seen its virtualness set by
24463 /// set_member_function_is_virtual(), this function ensures that the
24464 /// member function is added to the specific vectors and maps of
24465 /// virtual member function of its class.
24466 ///
24467 /// @param method the method to fixup.
24468 void
fixup_virtual_member_function(method_decl_sptr method)24469 fixup_virtual_member_function(method_decl_sptr method)
24470 {
24471   if (!method || !get_member_function_is_virtual(method))
24472     return;
24473 
24474   class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
24475 
24476   class_decl::member_functions::const_iterator m;
24477   for (m = klass->priv_->virtual_mem_fns_.begin();
24478        m != klass->priv_->virtual_mem_fns_.end();
24479        ++m)
24480     if (m->get() == method.get())
24481       break;
24482   if (m == klass->priv_->virtual_mem_fns_.end())
24483     klass->priv_->virtual_mem_fns_.push_back(method);
24484 
24485   // Build or udpate the map that associates a vtable offset to the
24486   // number of virtual member functions that "point" to it.
24487   ssize_t voffset = get_member_function_vtable_offset(method);
24488   if (voffset == -1)
24489     return;
24490 
24491   class_decl::virtual_mem_fn_map_type::iterator i =
24492     klass->priv_->virtual_mem_fns_map_.find(voffset);
24493   if (i == klass->priv_->virtual_mem_fns_map_.end())
24494     {
24495       class_decl::member_functions virtual_mem_fns_at_voffset;
24496       virtual_mem_fns_at_voffset.push_back(method);
24497       klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
24498     }
24499   else
24500     {
24501       for (m = i->second.begin() ; m != i->second.end(); ++m)
24502 	if (m->get() == method.get())
24503 	  break;
24504       if (m == i->second.end())
24505 	i->second.push_back(method);
24506     }
24507 }
24508 
24509 /// Return true iff the class has no entity in its scope.
24510 bool
has_no_base_nor_member() const24511 class_decl::has_no_base_nor_member() const
24512 {return priv_->bases_.empty() && has_no_member();}
24513 
24514 /// Test if the current instance of @ref class_decl has virtual member
24515 /// functions.
24516 ///
24517 /// @return true iff the current instance of @ref class_decl has
24518 /// virtual member functions.
24519 bool
has_virtual_member_functions() const24520 class_decl::has_virtual_member_functions() const
24521 {return !get_virtual_mem_fns().empty();}
24522 
24523 /// Test if the current instance of @ref class_decl has at least one
24524 /// virtual base.
24525 ///
24526 /// @return true iff the current instance of @ref class_decl has a
24527 /// virtual member function.
24528 bool
has_virtual_bases() const24529 class_decl::has_virtual_bases() const
24530 {
24531   for (base_specs::const_iterator b = get_base_specifiers().begin();
24532        b != get_base_specifiers().end();
24533        ++b)
24534     if ((*b)->get_is_virtual()
24535 	|| (*b)->get_base_class()->has_virtual_bases())
24536       return true;
24537 
24538   return false;
24539 }
24540 
24541 /// Test if the current instance has a vtable.
24542 ///
24543 /// This is only valid for a C++ program.
24544 ///
24545 /// Basically this function checks if the class has either virtual
24546 /// functions, or virtual bases.
24547 bool
has_vtable() const24548 class_decl::has_vtable() const
24549 {
24550   if (has_virtual_member_functions()
24551       || has_virtual_bases())
24552     return true;
24553   return false;
24554 }
24555 
24556 /// Get the highest vtable offset of all the virtual methods of the
24557 /// class.
24558 ///
24559 /// @return the highest vtable offset of all the virtual methods of
24560 /// the class.
24561 ssize_t
get_biggest_vtable_offset() const24562 class_decl::get_biggest_vtable_offset() const
24563 {
24564   ssize_t offset = -1;
24565   for (class_decl::virtual_mem_fn_map_type::const_iterator e =
24566 	 get_virtual_mem_fns_map().begin();
24567        e != get_virtual_mem_fns_map().end();
24568        ++e)
24569     if (e->first > offset)
24570       offset = e->first;
24571 
24572   return offset;
24573 }
24574 
24575 /// Return the hash value for the current instance.
24576 ///
24577 /// @return the hash value.
24578 size_t
get_hash() const24579 class_decl::get_hash() const
24580 {
24581   class_decl::hash hash_class;
24582   return hash_class(this);
24583 }
24584 
24585 /// Test if two methods are equal without taking their symbol or
24586 /// linkage name into account.
24587 ///
24588 /// @param f the first method.
24589 ///
24590 /// @param s the second method.
24591 ///
24592 /// @return true iff @p f equals @p s without taking their linkage
24593 /// name or symbol into account.
24594 static bool
methods_equal_modulo_elf_symbol(const method_decl_sptr & f,const method_decl_sptr & s)24595 methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
24596 				const method_decl_sptr& s)
24597 {
24598   method_decl_sptr first = f, second = s;
24599   elf_symbol_sptr saved_first_elf_symbol =
24600     first->get_symbol();
24601   elf_symbol_sptr saved_second_elf_symbol =
24602     second->get_symbol();
24603   interned_string saved_first_linkage_name =
24604     first->get_linkage_name();
24605   interned_string saved_second_linkage_name =
24606     second->get_linkage_name();
24607 
24608   first->set_symbol(elf_symbol_sptr());
24609   first->set_linkage_name("");
24610   second->set_symbol(elf_symbol_sptr());
24611   second->set_linkage_name("");
24612 
24613   bool equal = *first == *second;
24614 
24615   first->set_symbol(saved_first_elf_symbol);
24616   first->set_linkage_name(saved_first_linkage_name);
24617   second->set_symbol(saved_second_elf_symbol);
24618   second->set_linkage_name(saved_second_linkage_name);
24619 
24620   return equal;
24621 }
24622 
24623 /// Test if a given method is equivalent to at least of other method
24624 /// that is in a vector of methods.
24625 ///
24626 /// Note that "equivalent" here means being equal without taking the
24627 /// linkage name or the symbol of the methods into account.
24628 ///
24629 /// This is a sub-routine of the 'equals' function that compares @ref
24630 /// class_decl.
24631 ///
24632 /// @param method the method to compare.
24633 ///
24634 /// @param fns the vector of functions to compare @p method against.
24635 ///
24636 /// @return true iff @p is equivalent to at least one method in @p
24637 /// fns.
24638 static bool
method_matches_at_least_one_in_vector(const method_decl_sptr & method,const class_decl::member_functions & fns)24639 method_matches_at_least_one_in_vector(const method_decl_sptr& method,
24640 				      const class_decl::member_functions& fns)
24641 {
24642   for (class_decl::member_functions::const_iterator i = fns.begin();
24643        i != fns.end();
24644        ++i)
24645     // Note that the comparison must be done in this order: method ==
24646     //  *i This is to keep the consistency of the comparison.  It's
24647     //  important especially when doing type canonicalization.  The
24648     //  already canonicalize type is the left operand, and the type
24649     //  being canonicalized is the right operand.  This comes from the
24650     // code in type_base::get_canonical_type_for().
24651     if (methods_equal_modulo_elf_symbol(method, *i))
24652       return true;
24653 
24654   return false;
24655 }
24656 
24657 /// Cancel the canonical type that was propagated.
24658 ///
24659 /// If we are in the process of comparing a type for the purpose of
24660 /// canonicalization, and if that type has been the target of the
24661 /// canonical type propagation optimization, then clear the propagated
24662 /// canonical type.  See @ref OnTheFlyCanonicalization for more about
24663 /// the canonical type  optimization
24664 ///
24665 /// @param t the type to consider.
24666 static bool
maybe_cancel_propagated_canonical_type(const class_or_union & t)24667 maybe_cancel_propagated_canonical_type(const class_or_union& t)
24668 {
24669   const environment& env = t.get_environment();
24670   if (env.do_on_the_fly_canonicalization())
24671     if (is_type(&t)->priv_->canonical_type_propagated())
24672       {
24673 	is_type(&t)->priv_->clear_propagated_canonical_type();
24674 	env.priv_->remove_from_types_with_non_confirmed_propagated_ct(&t);
24675 	return true;
24676       }
24677   return false;
24678 }
24679 
24680 /// Compares two instances of @ref class_decl.
24681 ///
24682 /// If the two intances are different, set a bitfield to give some
24683 /// insight about the kind of differences there are.
24684 ///
24685 /// @param l the first artifact of the comparison.
24686 ///
24687 /// @param r the second artifact of the comparison.
24688 ///
24689 /// @param k a pointer to a bitfield that gives information about the
24690 /// kind of changes there are between @p l and @p r.  This one is set
24691 /// iff @p k is non-null and the function returns false.
24692 ///
24693 /// Please note that setting k to a non-null value does have a
24694 /// negative performance impact because even if @p l and @p r are not
24695 /// equal, the function keeps up the comparison in order to determine
24696 /// the different kinds of ways in which they are different.
24697 ///
24698 /// @return true if @p l equals @p r, false otherwise.
24699 bool
equals(const class_decl & l,const class_decl & r,change_kind * k)24700 equals(const class_decl& l, const class_decl& r, change_kind* k)
24701 {
24702   {
24703     // First of all, let's see if these two types haven't already been
24704     // compared.  If so, and if the result of the comparison has been
24705     // cached, let's just re-use it, rather than comparing them all
24706     // over again.
24707     bool result = false;
24708     if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
24709       ABG_RETURN(result);
24710   }
24711 
24712   // if one of the classes is declaration-only then we take a fast
24713   // path here.
24714   if (l.get_is_declaration_only() || r.get_is_declaration_only())
24715     ABG_RETURN(equals(static_cast<const class_or_union&>(l),
24716 		      static_cast<const class_or_union&>(r),
24717 		      k));
24718 
24719   bool had_canonical_type = !!r.get_naked_canonical_type();
24720   bool result = true;
24721   if (!equals(static_cast<const class_or_union&>(l),
24722 	      static_cast<const class_or_union&>(r),
24723 	      k))
24724     {
24725       result = false;
24726       if (!k)
24727 	ABG_RETURN(result);
24728     }
24729 
24730   // If comparing the class_or_union 'part' of the type led to
24731   // canonical type propagation, then cancel that because it's too
24732   // early to do that at this point.  We still need to compare bases
24733   // virtual members.
24734   if (!had_canonical_type)
24735     maybe_cancel_propagated_canonical_type(r);
24736 
24737   RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
24738 
24739   mark_types_as_being_compared(l, r);
24740 
24741 #define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
24742 
24743   // Compare bases.
24744   if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
24745     {
24746       result = false;
24747       if (k)
24748 	*k |= LOCAL_TYPE_CHANGE_KIND;
24749       else
24750 	RETURN(result);
24751     }
24752 
24753   for (class_decl::base_specs::const_iterator
24754 	 b0 = l.get_base_specifiers().begin(),
24755 	 b1 = r.get_base_specifiers().begin();
24756        (b0 != l.get_base_specifiers().end()
24757 	&& b1 != r.get_base_specifiers().end());
24758        ++b0, ++b1)
24759     if (*b0 != *b1)
24760       {
24761 	result = false;
24762 	if (k)
24763 	  {
24764 	    if (!types_have_similar_structure((*b0)->get_base_class().get(),
24765 					      (*b1)->get_base_class().get()))
24766 	      *k |= LOCAL_TYPE_CHANGE_KIND;
24767 	    else
24768 	      *k |= SUBTYPE_CHANGE_KIND;
24769 	    break;
24770 	  }
24771 	RETURN(result);
24772       }
24773 
24774   // Compare virtual member functions
24775 
24776   // We look at the map that associates a given vtable offset to a
24777   // vector of virtual member functions that point to that offset.
24778   //
24779   // This is because there are cases where several functions can
24780   // point to the same virtual table offset.
24781   //
24782   // This is usually the case for virtual destructors.  Even though
24783   // there can be only one virtual destructor declared in source
24784   // code, there are actually potentially up to three generated
24785   // functions for that destructor.  Some of these generated
24786   // functions can be clones of other functions that are among those
24787   // generated ones.  In any cases, they all have the same
24788   // properties, including the vtable offset property.
24789 
24790   // So, there should be the same number of different vtable
24791   // offsets, the size of two maps must be equals.
24792   if (l.get_virtual_mem_fns_map().size()
24793       != r.get_virtual_mem_fns_map().size())
24794     {
24795       result = false;
24796       if (k)
24797 	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
24798       else
24799 	RETURN(result);
24800     }
24801 
24802   // Then, each virtual member function of a given vtable offset in
24803   // the first class type, must match an equivalent virtual member
24804   // function of a the same vtable offset in the second class type.
24805   //
24806   // By "match", I mean that the two virtual member function should
24807   // be equal if we don't take into account their symbol name or
24808   // their linkage name.  This is because two destructor functions
24809   // clones (for instance) might have different linkage name, but
24810   // are still equivalent if their other properties are the same.
24811   for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
24812 	 l.get_virtual_mem_fns_map().begin();
24813        first_v_fn_entry != l.get_virtual_mem_fns_map().end();
24814        ++first_v_fn_entry)
24815     {
24816       unsigned voffset = first_v_fn_entry->first;
24817       const class_decl::member_functions& first_vfns =
24818 	first_v_fn_entry->second;
24819 
24820       const class_decl::virtual_mem_fn_map_type::const_iterator
24821 	second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
24822 
24823       if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
24824 	{
24825 	  result = false;
24826 	  if (k)
24827 	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
24828 	  RETURN(result);
24829 	}
24830 
24831       const class_decl::member_functions& second_vfns =
24832 	second_v_fn_entry->second;
24833 
24834       bool matches = false;
24835       for (class_decl::member_functions::const_iterator i =
24836 	     first_vfns.begin();
24837 	   i != first_vfns.end();
24838 	   ++i)
24839 	if (method_matches_at_least_one_in_vector(*i, second_vfns))
24840 	  {
24841 	    matches = true;
24842 	    break;
24843 	  }
24844 
24845       if (!matches)
24846 	{
24847 	  result = false;
24848 	  if (k)
24849 	    *k |= SUBTYPE_CHANGE_KIND;
24850 	  else
24851 	    RETURN(result);
24852 	}
24853     }
24854 
24855   RETURN(result);
24856 #undef RETURN
24857 }
24858 
24859 /// Copy a method of a class into a new class.
24860 ///
24861 /// @param klass the class into which the method is to be copied.
24862 ///
24863 /// @param method the method to copy into @p klass.
24864 ///
24865 /// @return the resulting newly copied method.
24866 method_decl_sptr
copy_member_function(const class_decl_sptr & clazz,const method_decl_sptr & f)24867 copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
24868 {return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
24869 
24870 /// Copy a method of a class into a new class.
24871 ///
24872 /// @param klass the class into which the method is to be copied.
24873 ///
24874 /// @param method the method to copy into @p klass.
24875 ///
24876 /// @return the resulting newly copied method.
24877 method_decl_sptr
copy_member_function(const class_decl_sptr & clazz,const method_decl * f)24878 copy_member_function(const class_decl_sptr& clazz, const method_decl* f)
24879 {return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
24880 
24881 /// Comparison operator for @ref class_decl.
24882 ///
24883 /// @param other the instance of @ref class_decl to compare against.
24884 ///
24885 /// @return true iff the current instance of @ref class_decl equals @p
24886 /// other.
24887 bool
operator ==(const decl_base & other) const24888 class_decl::operator==(const decl_base& other) const
24889 {
24890   const class_decl* op = is_class_type(&other);
24891   if (!op)
24892     return false;
24893 
24894   // If this is a decl-only type (and thus with no canonical type),
24895   // use the canonical type of the definition, if any.
24896   const class_decl *l = 0;
24897   if (get_is_declaration_only())
24898     l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
24899   if (l == 0)
24900     l = this;
24901 
24902   ABG_ASSERT(l);
24903 
24904   // Likewise for the other type.
24905   const class_decl *r = 0;
24906   if (op->get_is_declaration_only())
24907     r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
24908   if (r == 0)
24909     r = op;
24910 
24911   ABG_ASSERT(r);
24912 
24913   return try_canonical_compare(l, r);
24914 }
24915 
24916 /// Equality operator for class_decl.
24917 ///
24918 /// Re-uses the equality operator that takes a decl_base.
24919 ///
24920 /// @param other the other class_decl to compare against.
24921 ///
24922 /// @return true iff the current instance equals the other one.
24923 bool
operator ==(const type_base & other) const24924 class_decl::operator==(const type_base& other) const
24925 {
24926   const decl_base* o = is_decl(&other);
24927   if (!o)
24928     return false;
24929   return *this == *o;
24930 }
24931 
24932 /// Equality operator for class_decl.
24933 ///
24934 /// Re-uses the equality operator that takes a decl_base.
24935 ///
24936 /// @param other the other class_decl to compare against.
24937 ///
24938 /// @return true iff the current instance equals the other one.
24939 bool
operator ==(const class_or_union & other) const24940 class_decl::operator==(const class_or_union& other) const
24941 {
24942   const decl_base& o = other;
24943   return *this == o;
24944 }
24945 
24946 /// Comparison operator for @ref class_decl.
24947 ///
24948 /// @param other the instance of @ref class_decl to compare against.
24949 ///
24950 /// @return true iff the current instance of @ref class_decl equals @p
24951 /// other.
24952 bool
operator ==(const class_decl & other) const24953 class_decl::operator==(const class_decl& other) const
24954 {
24955   const decl_base& o = other;
24956   return *this == o;
24957 }
24958 
24959 /// Turn equality of shared_ptr of class_decl into a deep equality;
24960 /// that is, make it compare the pointed to objects too.
24961 ///
24962 /// @param l the shared_ptr of class_decl on left-hand-side of the
24963 /// equality.
24964 ///
24965 /// @param r the shared_ptr of class_decl on right-hand-side of the
24966 /// equality.
24967 ///
24968 /// @return true if the class_decl pointed to by the shared_ptrs are
24969 /// equal, false otherwise.
24970 bool
operator ==(const class_decl_sptr & l,const class_decl_sptr & r)24971 operator==(const class_decl_sptr& l, const class_decl_sptr& r)
24972 {
24973   if (l.get() == r.get())
24974     return true;
24975   if (!!l != !!r)
24976     return false;
24977 
24978   return *l == *r;
24979 }
24980 
24981 /// Turn inequality of shared_ptr of class_decl into a deep equality;
24982 /// that is, make it compare the pointed to objects too.
24983 ///
24984 /// @param l the shared_ptr of class_decl on left-hand-side of the
24985 /// equality.
24986 ///
24987 /// @param r the shared_ptr of class_decl on right-hand-side of the
24988 /// equality.
24989 ///
24990 /// @return true if the class_decl pointed to by the shared_ptrs are
24991 /// different, false otherwise.
24992 bool
operator !=(const class_decl_sptr & l,const class_decl_sptr & r)24993 operator!=(const class_decl_sptr& l, const class_decl_sptr& r)
24994 {return !operator==(l, r);}
24995 
24996 /// Turn equality of shared_ptr of class_or_union into a deep
24997 /// equality; that is, make it compare the pointed to objects too.
24998 ///
24999 /// @param l the left-hand-side operand of the operator
25000 ///
25001 /// @param r the right-hand-side operand of the operator.
25002 ///
25003 /// @return true iff @p l equals @p r.
25004 bool
operator ==(const class_or_union_sptr & l,const class_or_union_sptr & r)25005 operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
25006 {
25007   if (l.get() == r.get())
25008     return true;
25009   if (!!l != !!r)
25010     return false;
25011 
25012   return *l == *r;
25013 }
25014 
25015 /// Turn inequality of shared_ptr of class_or_union into a deep
25016 /// equality; that is, make it compare the pointed to objects too.
25017 ///
25018 /// @param l the left-hand-side operand of the operator
25019 ///
25020 /// @param r the right-hand-side operand of the operator.
25021 ///
25022 /// @return true iff @p l is different from @p r.
25023 bool
operator !=(const class_or_union_sptr & l,const class_or_union_sptr & r)25024 operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
25025 {return !operator==(l, r);}
25026 
25027 /// This implements the ir_traversable_base::traverse pure virtual
25028 /// function.
25029 ///
25030 /// @param v the visitor used on the current instance and on its
25031 /// members.
25032 ///
25033 /// @return true if the entire IR node tree got traversed, false
25034 /// otherwise.
25035 bool
traverse(ir_node_visitor & v)25036 class_decl::traverse(ir_node_visitor& v)
25037 {
25038   if (v.type_node_has_been_visited(this))
25039     return true;
25040 
25041   if (visiting())
25042     return true;
25043 
25044   if (v.visit_begin(this))
25045     {
25046       visiting(true);
25047       bool stop = false;
25048 
25049       for (base_specs::const_iterator i = get_base_specifiers().begin();
25050 	   i != get_base_specifiers().end();
25051 	   ++i)
25052 	{
25053 	  if (!(*i)->traverse(v))
25054 	    {
25055 	      stop = true;
25056 	      break;
25057 	    }
25058 	}
25059 
25060       if (!stop)
25061 	for (data_members::const_iterator i = get_data_members().begin();
25062 	     i != get_data_members().end();
25063 	     ++i)
25064 	  if (!(*i)->traverse(v))
25065 	    {
25066 	      stop = true;
25067 	      break;
25068 	    }
25069 
25070       if (!stop)
25071 	for (member_functions::const_iterator i= get_member_functions().begin();
25072 	     i != get_member_functions().end();
25073 	     ++i)
25074 	  if (!(*i)->traverse(v))
25075 	    {
25076 	      stop = true;
25077 	      break;
25078 	    }
25079 
25080       if (!stop)
25081 	for (member_types::const_iterator i = get_member_types().begin();
25082 	     i != get_member_types().end();
25083 	     ++i)
25084 	  if (!(*i)->traverse(v))
25085 	    {
25086 	      stop = true;
25087 	      break;
25088 	    }
25089 
25090       if (!stop)
25091 	for (member_function_templates::const_iterator i =
25092 	       get_member_function_templates().begin();
25093 	     i != get_member_function_templates().end();
25094 	     ++i)
25095 	  if (!(*i)->traverse(v))
25096 	    {
25097 	      stop = true;
25098 	      break;
25099 	    }
25100 
25101       if (!stop)
25102 	for (member_class_templates::const_iterator i =
25103 	       get_member_class_templates().begin();
25104 	     i != get_member_class_templates().end();
25105 	     ++i)
25106 	  if (!(*i)->traverse(v))
25107 	    {
25108 	      stop = true;
25109 	      break;
25110 	    }
25111       visiting(false);
25112     }
25113 
25114   bool result = v.visit_end(this);
25115   v.mark_type_node_as_visited(this);
25116   return result;
25117 }
25118 
25119 /// Destructor of the @ref class_decl type.
~class_decl()25120 class_decl::~class_decl()
25121 {delete priv_;}
25122 
~context_rel()25123 context_rel::~context_rel()
25124 {}
25125 
25126 bool
operator ==(const member_base & o) const25127 member_base::operator==(const member_base& o) const
25128 {
25129   return (get_access_specifier() == o.get_access_specifier()
25130 	  && get_is_static() == o.get_is_static());
25131 }
25132 
25133 /// Equality operator for smart pointers to @ref
25134 /// class_decl::base_specs.
25135 ///
25136 /// This compares the pointed-to objects.
25137 ///
25138 /// @param l the first instance to consider.
25139 ///
25140 /// @param r the second instance to consider.
25141 ///
25142 /// @return true iff @p l equals @p r.
25143 bool
operator ==(const class_decl::base_spec_sptr & l,const class_decl::base_spec_sptr & r)25144 operator==(const class_decl::base_spec_sptr& l,
25145 	   const class_decl::base_spec_sptr& r)
25146 {
25147   if (l.get() == r.get())
25148     return true;
25149   if (!!l != !!r)
25150     return false;
25151 
25152   return *l == static_cast<const decl_base&>(*r);
25153 }
25154 
25155 /// Inequality operator for smart pointers to @ref
25156 /// class_decl::base_specs.
25157 ///
25158 /// This compares the pointed-to objects.
25159 ///
25160 /// @param l the first instance to consider.
25161 ///
25162 /// @param r the second instance to consider.
25163 ///
25164 /// @return true iff @p l is different from @p r.
25165 bool
operator !=(const class_decl::base_spec_sptr & l,const class_decl::base_spec_sptr & r)25166 operator!=(const class_decl::base_spec_sptr& l,
25167 	   const class_decl::base_spec_sptr& r)
25168 {return !operator==(l, r);}
25169 
25170 /// Test if an ABI artifact is a class base specifier.
25171 ///
25172 /// @param tod the ABI artifact to consider.
25173 ///
25174 /// @return a pointer to the @ref class_decl::base_spec sub-object of
25175 /// @p tod iff it's a class base specifier.
25176 class_decl::base_spec*
is_class_base_spec(const type_or_decl_base * tod)25177 is_class_base_spec(const type_or_decl_base* tod)
25178 {
25179   return dynamic_cast<class_decl::base_spec*>
25180     (const_cast<type_or_decl_base*>(tod));
25181 }
25182 
25183 /// Test if an ABI artifact is a class base specifier.
25184 ///
25185 /// @param tod the ABI artifact to consider.
25186 ///
25187 /// @return a pointer to the @ref class_decl::base_spec sub-object of
25188 /// @p tod iff it's a class base specifier.
25189 class_decl::base_spec_sptr
is_class_base_spec(type_or_decl_base_sptr tod)25190 is_class_base_spec(type_or_decl_base_sptr tod)
25191 {return dynamic_pointer_cast<class_decl::base_spec>(tod);}
25192 
25193 bool
operator ==(const member_base & other) const25194 member_function_template::operator==(const member_base& other) const
25195 {
25196   try
25197     {
25198       const member_function_template& o =
25199 	dynamic_cast<const member_function_template&>(other);
25200 
25201       if (!(is_constructor() == o.is_constructor()
25202 	    && is_const() == o.is_const()
25203 	    && member_base::operator==(o)))
25204 	return false;
25205 
25206       if (function_tdecl_sptr ftdecl = as_function_tdecl())
25207 	{
25208 	  function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
25209 	  if (other_ftdecl)
25210 	    return ftdecl->function_tdecl::operator==(*other_ftdecl);
25211 	}
25212     }
25213   catch(...)
25214     {}
25215   return false;
25216 }
25217 
25218 /// Equality operator for smart pointers to @ref
25219 /// member_function_template.  This is compares the
25220 /// pointed-to instances.
25221 ///
25222 /// @param l the first instance to consider.
25223 ///
25224 /// @param r the second instance to consider.
25225 ///
25226 /// @return true iff @p l equals @p r.
25227 bool
operator ==(const member_function_template_sptr & l,const member_function_template_sptr & r)25228 operator==(const member_function_template_sptr& l,
25229 	   const member_function_template_sptr& r)
25230 {
25231   if (l.get() == r.get())
25232     return true;
25233   if (!!l != !!r)
25234     return false;
25235 
25236   return *l == *r;
25237 }
25238 
25239 /// Inequality operator for smart pointers to @ref
25240 /// member_function_template.  This is compares the pointed-to
25241 /// instances.
25242 ///
25243 /// @param l the first instance to consider.
25244 ///
25245 /// @param r the second instance to consider.
25246 ///
25247 /// @return true iff @p l equals @p r.
25248 bool
operator !=(const member_function_template_sptr & l,const member_function_template_sptr & r)25249 operator!=(const member_function_template_sptr& l,
25250 	   const member_function_template_sptr& r)
25251 {return !operator==(l, r);}
25252 
25253 /// This implements the ir_traversable_base::traverse pure virtual
25254 /// function.
25255 ///
25256 /// @param v the visitor used on the current instance and on its
25257 /// underlying function template.
25258 ///
25259 /// @return true if the entire IR node tree got traversed, false
25260 /// otherwise.
25261 bool
traverse(ir_node_visitor & v)25262 member_function_template::traverse(ir_node_visitor& v)
25263 {
25264   if (visiting())
25265     return true;
25266 
25267   if (v.visit_begin(this))
25268     {
25269       visiting(true);
25270       if (function_tdecl_sptr f = as_function_tdecl())
25271 	f->traverse(v);
25272       visiting(false);
25273     }
25274   return v.visit_end(this);
25275 }
25276 
25277 /// Equality operator of the the @ref member_class_template class.
25278 ///
25279 /// @param other the other @ref member_class_template to compare against.
25280 ///
25281 /// @return true iff the current instance equals @p other.
25282 bool
operator ==(const member_base & other) const25283 member_class_template::operator==(const member_base& other) const
25284 {
25285   try
25286     {
25287       const member_class_template& o =
25288 	dynamic_cast<const member_class_template&>(other);
25289 
25290       if (!member_base::operator==(o))
25291 	return false;
25292 
25293       return as_class_tdecl()->class_tdecl::operator==(o);
25294     }
25295   catch(...)
25296     {return false;}
25297 }
25298 
25299 /// Equality operator of the the @ref member_class_template class.
25300 ///
25301 /// @param other the other @ref member_class_template to compare against.
25302 ///
25303 /// @return true iff the current instance equals @p other.
25304 bool
operator ==(const decl_base & other) const25305 member_class_template::operator==(const decl_base& other) const
25306 {
25307   if (!decl_base::operator==(other))
25308     return false;
25309   return as_class_tdecl()->class_tdecl::operator==(other);
25310 }
25311 
25312 /// Comparison operator for the @ref member_class_template
25313 /// type.
25314 ///
25315 /// @param other the other instance of @ref
25316 /// member_class_template to compare against.
25317 ///
25318 /// @return true iff the two instances are equal.
25319 bool
operator ==(const member_class_template & other) const25320 member_class_template::operator==(const member_class_template& other) const
25321 {
25322   const decl_base* o = dynamic_cast<const decl_base*>(&other);
25323   return *this == *o;
25324 }
25325 
25326 /// Comparison operator for the @ref member_class_template
25327 /// type.
25328 ///
25329 /// @param l the first argument of the operator.
25330 ///
25331 /// @param r the second argument of the operator.
25332 ///
25333 /// @return true iff the two instances are equal.
25334 bool
operator ==(const member_class_template_sptr & l,const member_class_template_sptr & r)25335 operator==(const member_class_template_sptr& l,
25336 	   const member_class_template_sptr& r)
25337 {
25338   if (l.get() == r.get())
25339     return true;
25340   if (!!l != !!r)
25341     return false;
25342 
25343   return *l == *r;
25344 }
25345 
25346 /// Inequality operator for the @ref member_class_template
25347 /// type.
25348 ///
25349 /// @param l the first argument of the operator.
25350 ///
25351 /// @param r the second argument of the operator.
25352 ///
25353 /// @return true iff the two instances are equal.
25354 bool
operator !=(const member_class_template_sptr & l,const member_class_template_sptr & r)25355 operator!=(const member_class_template_sptr& l,
25356 	   const member_class_template_sptr& r)
25357 {return !operator==(l, r);}
25358 
25359 /// This implements the ir_traversable_base::traverse pure virtual
25360 /// function.
25361 ///
25362 /// @param v the visitor used on the current instance and on the class
25363 /// pattern of the template.
25364 ///
25365 /// @return true if the entire IR node tree got traversed, false
25366 /// otherwise.
25367 bool
traverse(ir_node_visitor & v)25368 member_class_template::traverse(ir_node_visitor& v)
25369 {
25370   if (visiting())
25371     return true;
25372 
25373   if (v.visit_begin(this))
25374     {
25375       visiting(true);
25376       if (class_tdecl_sptr t = as_class_tdecl())
25377 	t->traverse(v);
25378       visiting(false);
25379     }
25380   return v.visit_end(this);
25381 }
25382 
25383 /// Streaming operator for class_decl::access_specifier.
25384 ///
25385 /// @param o the output stream to serialize the access specifier to.
25386 ///
25387 /// @param a the access specifier to serialize.
25388 ///
25389 /// @return the output stream.
25390 std::ostream&
operator <<(std::ostream & o,access_specifier a)25391 operator<<(std::ostream& o, access_specifier a)
25392 {
25393   string r;
25394 
25395   switch (a)
25396   {
25397   case no_access:
25398     r = "none";
25399     break;
25400   case private_access:
25401     r = "private";
25402     break;
25403   case protected_access:
25404     r = "protected";
25405     break;
25406   case public_access:
25407     r= "public";
25408     break;
25409   };
25410   o << r;
25411   return o;
25412 }
25413 
25414 /// Sets the static-ness property of a class member.
25415 ///
25416 /// @param d the class member to set the static-ness property for.
25417 /// Note that this must be a class member otherwise the function
25418 /// aborts the current process.
25419 ///
25420 /// @param s this must be true if the member is to be static, false
25421 /// otherwise.
25422 void
set_member_is_static(decl_base & d,bool s)25423 set_member_is_static(decl_base& d, bool s)
25424 {
25425   ABG_ASSERT(is_member_decl(d));
25426 
25427   context_rel* c = d.get_context_rel();
25428   ABG_ASSERT(c);
25429 
25430   c->set_is_static(s);
25431 
25432   scope_decl* scope = d.get_scope();
25433 
25434   if (class_or_union* cl = is_class_or_union_type(scope))
25435     {
25436       if (var_decl* v = is_var_decl(&d))
25437 	{
25438 	  if (s)
25439 	    // remove from the non-static data members
25440 	    for (class_decl::data_members::iterator i =
25441 		   cl->priv_->non_static_data_members_.begin();
25442 		 i != cl->priv_->non_static_data_members_.end();
25443 		 ++i)
25444 	      {
25445 		if ((*i)->get_name() == v->get_name())
25446 		  {
25447 		    cl->priv_->non_static_data_members_.erase(i);
25448 		    break;
25449 		  }
25450 	      }
25451 	  else
25452 	    {
25453 	      bool is_already_in_non_static_data_members = false;
25454 	      for (class_or_union::data_members::iterator i =
25455 		     cl->priv_->non_static_data_members_.begin();
25456 		   i != cl->priv_->non_static_data_members_.end();
25457 		   ++i)
25458 	      {
25459 		if ((*i)->get_name() == v->get_name())
25460 		  {
25461 		    is_already_in_non_static_data_members = true;
25462 		    break;
25463 		  }
25464 	      }
25465 	      if (!is_already_in_non_static_data_members)
25466 		{
25467 		  var_decl_sptr var;
25468 		  // add to non-static data members.
25469 		  for (class_or_union::data_members::const_iterator i =
25470 			 cl->priv_->data_members_.begin();
25471 		       i != cl->priv_->data_members_.end();
25472 		       ++i)
25473 		    {
25474 		      if ((*i)->get_name() == v->get_name())
25475 			{
25476 			  var = *i;
25477 			  break;
25478 			}
25479 		    }
25480 		  ABG_ASSERT(var);
25481 		  cl->priv_->non_static_data_members_.push_back(var);
25482 		}
25483 	    }
25484 	}
25485     }
25486 }
25487 
25488 /// Sets the static-ness property of a class member.
25489 ///
25490 /// @param d the class member to set the static-ness property for.
25491 /// Note that this must be a class member otherwise the function
25492 /// aborts the current process.
25493 ///
25494 /// @param s this must be true if the member is to be static, false
25495 /// otherwise.
25496 void
set_member_is_static(const decl_base_sptr & d,bool s)25497 set_member_is_static(const decl_base_sptr& d, bool s)
25498 {set_member_is_static(*d, s);}
25499 
25500 // </class_decl>
25501 
25502 // <union_decl>
25503 
25504 /// Constructor for the @ref union_decl type.
25505 ///
25506 /// @param env the @ref environment we are operating from.
25507 ///
25508 /// @param name the name of the union type.
25509 ///
25510 /// @param size_in_bits the size of the union, in bits.
25511 ///
25512 /// @param locus the location of the type.
25513 ///
25514 /// @param vis the visibility of instances of @ref union_decl.
25515 ///
25516 /// @param mbr_types the member types of the union.
25517 ///
25518 /// @param data_mbrs the data members of the union.
25519 ///
25520 /// @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)25521 union_decl::union_decl(const environment& env, const string& name,
25522 		       size_t size_in_bits, const location& locus,
25523 		       visibility vis, member_types& mbr_types,
25524 		       data_members& data_mbrs, member_functions& member_fns)
25525   : type_or_decl_base(env,
25526 		      UNION_TYPE
25527 		      | ABSTRACT_TYPE_BASE
25528 		      | ABSTRACT_DECL_BASE),
25529     decl_base(env, name, locus, name, vis),
25530     type_base(env, size_in_bits, 0),
25531     class_or_union(env, name, size_in_bits, 0,
25532 		   locus, vis, mbr_types, data_mbrs, member_fns)
25533 {
25534   runtime_type_instance(this);
25535 }
25536 
25537 /// Constructor for the @ref union_decl type.
25538 ///
25539 /// @param env the @ref environment we are operating from.
25540 ///
25541 /// @param name the name of the union type.
25542 ///
25543 /// @param size_in_bits the size of the union, in bits.
25544 ///
25545 /// @param locus the location of the type.
25546 ///
25547 /// @param vis the visibility of instances of @ref union_decl.
25548 ///
25549 /// @param mbr_types the member types of the union.
25550 ///
25551 /// @param data_mbrs the data members of the union.
25552 ///
25553 /// @param member_fns the member functions of the union.
25554 ///
25555 /// @param is_anonymous whether the newly created instance is
25556 /// 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)25557 union_decl::union_decl(const environment& env, const string& name,
25558 		       size_t size_in_bits, const location& locus,
25559 		       visibility vis, member_types& mbr_types,
25560 		       data_members& data_mbrs, member_functions& member_fns,
25561 		       bool is_anonymous)
25562   : type_or_decl_base(env,
25563 		      UNION_TYPE
25564 		      | ABSTRACT_TYPE_BASE
25565 		      | ABSTRACT_DECL_BASE),
25566     decl_base(env, name, locus,
25567 	      // If the class is anonymous then by default it won't
25568 	      // have a linkage name.  Also, the anonymous class does
25569 	      // have an internal-only unique name that is generally
25570 	      // not taken into account when comparing classes; such a
25571 	      // unique internal-only name, when used as a linkage
25572 	      // name might introduce spurious comparison false
25573 	      // negatives.
25574 	      /*linkage_name=*/is_anonymous ? string() : name,
25575 	      vis),
25576     type_base(env, size_in_bits, 0),
25577     class_or_union(env, name, size_in_bits, 0,
25578 		   locus, vis, mbr_types, data_mbrs, member_fns)
25579 {
25580   runtime_type_instance(this);
25581   set_is_anonymous(is_anonymous);
25582 }
25583 
25584 /// Constructor for the @ref union_decl type.
25585 ///
25586 /// @param env the @ref environment we are operating from.
25587 ///
25588 /// @param name the name of the union type.
25589 ///
25590 /// @param size_in_bits the size of the union, in bits.
25591 ///
25592 /// @param locus the location of the type.
25593 ///
25594 /// @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)25595 union_decl::union_decl(const environment& env, const string& name,
25596 		       size_t size_in_bits, const location& locus,
25597 		       visibility vis)
25598   : type_or_decl_base(env,
25599 		      UNION_TYPE
25600 		      | ABSTRACT_TYPE_BASE
25601 		      | ABSTRACT_DECL_BASE
25602 		      | ABSTRACT_SCOPE_TYPE_DECL
25603 		      | ABSTRACT_SCOPE_DECL),
25604     decl_base(env, name, locus, name, vis),
25605     type_base(env, size_in_bits, 0),
25606     class_or_union(env, name, size_in_bits,
25607 		   0, locus, vis)
25608 {
25609   runtime_type_instance(this);
25610 }
25611 
25612 /// Constructor for the @ref union_decl type.
25613 ///
25614 /// @param env the @ref environment we are operating from.
25615 ///
25616 /// @param name the name of the union type.
25617 ///
25618 /// @param size_in_bits the size of the union, in bits.
25619 ///
25620 /// @param locus the location of the type.
25621 ///
25622 /// @param vis the visibility of instances of @ref union_decl.
25623 ///
25624 /// @param is_anonymous whether the newly created instance is
25625 /// anonymous.
union_decl(const environment & env,const string & name,size_t size_in_bits,const location & locus,visibility vis,bool is_anonymous)25626 union_decl::union_decl(const environment& env, const string& name,
25627 		       size_t size_in_bits, const location& locus,
25628 		       visibility vis, bool is_anonymous)
25629   : type_or_decl_base(env,
25630 		      UNION_TYPE
25631 		      | ABSTRACT_TYPE_BASE
25632 		      | ABSTRACT_DECL_BASE
25633 		      | ABSTRACT_SCOPE_TYPE_DECL
25634 		      | ABSTRACT_SCOPE_DECL),
25635     decl_base(env, name, locus,
25636 	      // If the class is anonymous then by default it won't
25637 	      // have a linkage name.  Also, the anonymous class does
25638 	      // have an internal-only unique name that is generally
25639 	      // not taken into account when comparing classes; such a
25640 	      // unique internal-only name, when used as a linkage
25641 	      // name might introduce spurious comparison false
25642 	      // negatives.
25643 	      /*linkage_name=*/is_anonymous ? string() : name,
25644 	      vis),
25645     type_base(env, size_in_bits, 0),
25646     class_or_union(env, name, size_in_bits,
25647 		   0, locus, vis)
25648 {
25649   runtime_type_instance(this);
25650   set_is_anonymous(is_anonymous);
25651 }
25652 
25653 /// Constructor for the @ref union_decl type.
25654 ///
25655 /// @param env the @ref environment we are operating from.
25656 ///
25657 /// @param name the name of the union type.
25658 ///
25659 /// @param is_declaration_only a boolean saying whether the instance
25660 /// represents a declaration only, or not.
union_decl(const environment & env,const string & name,bool is_declaration_only)25661 union_decl::union_decl(const environment& env,
25662 		       const string& name,
25663 		       bool is_declaration_only)
25664   : type_or_decl_base(env,
25665 		      UNION_TYPE
25666 		      | ABSTRACT_TYPE_BASE
25667 		      | ABSTRACT_DECL_BASE
25668 		      | ABSTRACT_SCOPE_TYPE_DECL
25669 		      | ABSTRACT_SCOPE_DECL),
25670     decl_base(env, name, location(), name),
25671     type_base(env, 0, 0),
25672     class_or_union(env, name, is_declaration_only)
25673 {
25674   runtime_type_instance(this);
25675 }
25676 
25677 /// Getter of the pretty representation of the current instance of
25678 /// @ref union_decl.
25679 ///
25680 /// @param internal set to true if the call is intended to get a
25681 /// representation of the decl (or type) for the purpose of canonical
25682 /// type comparison.  This is mainly used in the function
25683 /// type_base::get_canonical_type_for().
25684 ///
25685 /// In other words if the argument for this parameter is true then the
25686 /// call is meant for internal use (for technical use inside the
25687 /// library itself), false otherwise.  If you don't know what this is
25688 /// for, then set it to false.
25689 ///
25690 /// @param qualified_name if true, names emitted in the pretty
25691 /// representation are fully qualified.
25692 ///
25693 /// @return the pretty representaion for a union_decl.
25694 string
get_pretty_representation(bool internal,bool qualified_name) const25695 union_decl::get_pretty_representation(bool internal,
25696 				      bool qualified_name) const
25697 {
25698   string repr;
25699   if (get_is_anonymous())
25700     {
25701       if (internal && !get_name().empty())
25702 	repr = string("union ") +
25703 	  get_type_name(this, qualified_name, /*internal=*/true);
25704       else
25705 	repr = get_class_or_union_flat_representation(this, "",
25706 						      /*one_line=*/true,
25707 						      internal);
25708     }
25709   else
25710     {
25711       repr = "union ";
25712       if (qualified_name)
25713 	repr += get_qualified_name(internal);
25714       else
25715 	repr += get_name();
25716     }
25717 
25718   return repr;
25719 }
25720 
25721 /// Comparison operator for @ref union_decl.
25722 ///
25723 /// @param other the instance of @ref union_decl to compare against.
25724 ///
25725 /// @return true iff the current instance of @ref union_decl equals @p
25726 /// other.
25727 bool
operator ==(const decl_base & other) const25728 union_decl::operator==(const decl_base& other) const
25729 {
25730   const union_decl* op = dynamic_cast<const union_decl*>(&other);
25731   if (!op)
25732     return false;
25733   return try_canonical_compare(this, op);
25734 }
25735 
25736 /// Equality operator for union_decl.
25737 ///
25738 /// Re-uses the equality operator that takes a decl_base.
25739 ///
25740 /// @param other the other union_decl to compare against.
25741 ///
25742 /// @return true iff the current instance equals the other one.
25743 bool
operator ==(const type_base & other) const25744 union_decl::operator==(const type_base& other) const
25745 {
25746   const decl_base *o = dynamic_cast<const decl_base*>(&other);
25747   if (!o)
25748     return false;
25749   return *this == *o;
25750 }
25751 
25752 /// Equality operator for union_decl.
25753 ///
25754 /// Re-uses the equality operator that takes a decl_base.
25755 ///
25756 /// @param other the other union_decl to compare against.
25757 ///
25758 /// @return true iff the current instance equals the other one.
25759 bool
operator ==(const class_or_union & other) const25760 union_decl::operator==(const class_or_union&other) const
25761 {
25762   const decl_base *o = dynamic_cast<const decl_base*>(&other);
25763   return *this == *o;
25764 }
25765 
25766 /// Comparison operator for @ref union_decl.
25767 ///
25768 /// @param other the instance of @ref union_decl to compare against.
25769 ///
25770 /// @return true iff the current instance of @ref union_decl equals @p
25771 /// other.
25772 bool
operator ==(const union_decl & other) const25773 union_decl::operator==(const union_decl& other) const
25774 {
25775   const decl_base& o = other;
25776   return *this == o;
25777 }
25778 
25779 /// This implements the ir_traversable_base::traverse pure virtual
25780 /// function.
25781 ///
25782 /// @param v the visitor used on the current instance and on its
25783 /// members.
25784 ///
25785 /// @return true if the entire IR node tree got traversed, false
25786 /// otherwise.
25787 bool
traverse(ir_node_visitor & v)25788 union_decl::traverse(ir_node_visitor& v)
25789 {
25790   if (v.type_node_has_been_visited(this))
25791     return true;
25792 
25793   if (visiting())
25794     return true;
25795 
25796   if (v.visit_begin(this))
25797     {
25798       visiting(true);
25799       bool stop = false;
25800 
25801       if (!stop)
25802 	for (data_members::const_iterator i = get_data_members().begin();
25803 	     i != get_data_members().end();
25804 	     ++i)
25805 	  if (!(*i)->traverse(v))
25806 	    {
25807 	      stop = true;
25808 	      break;
25809 	    }
25810 
25811       if (!stop)
25812 	for (member_functions::const_iterator i= get_member_functions().begin();
25813 	     i != get_member_functions().end();
25814 	     ++i)
25815 	  if (!(*i)->traverse(v))
25816 	    {
25817 	      stop = true;
25818 	      break;
25819 	    }
25820 
25821       if (!stop)
25822 	for (member_types::const_iterator i = get_member_types().begin();
25823 	     i != get_member_types().end();
25824 	     ++i)
25825 	  if (!(*i)->traverse(v))
25826 	    {
25827 	      stop = true;
25828 	      break;
25829 	    }
25830 
25831       if (!stop)
25832 	for (member_function_templates::const_iterator i =
25833 	       get_member_function_templates().begin();
25834 	     i != get_member_function_templates().end();
25835 	     ++i)
25836 	  if (!(*i)->traverse(v))
25837 	    {
25838 	      stop = true;
25839 	      break;
25840 	    }
25841 
25842       if (!stop)
25843 	for (member_class_templates::const_iterator i =
25844 	       get_member_class_templates().begin();
25845 	     i != get_member_class_templates().end();
25846 	     ++i)
25847 	  if (!(*i)->traverse(v))
25848 	    {
25849 	      stop = true;
25850 	      break;
25851 	    }
25852       visiting(false);
25853     }
25854 
25855   bool result = v.visit_end(this);
25856   v.mark_type_node_as_visited(this);
25857   return result;
25858 }
25859 
25860 /// Destructor of the @ref union_decl type.
~union_decl()25861 union_decl::~union_decl()
25862 {}
25863 
25864 /// Compares two instances of @ref union_decl.
25865 ///
25866 /// If the two intances are different, set a bitfield to give some
25867 /// insight about the kind of differences there are.
25868 ///
25869 /// @param l the first artifact of the comparison.
25870 ///
25871 /// @param r the second artifact of the comparison.
25872 ///
25873 /// @param k a pointer to a bitfield that gives information about the
25874 /// kind of changes there are between @p l and @p r.  This one is set
25875 /// iff @p k is non-null and the function returns false.
25876 ///
25877 /// Please note that setting k to a non-null value does have a
25878 /// negative performance impact because even if @p l and @p r are not
25879 /// equal, the function keeps up the comparison in order to determine
25880 /// the different kinds of ways in which they are different.
25881 ///
25882 /// @return true if @p l equals @p r, false otherwise.
25883 bool
equals(const union_decl & l,const union_decl & r,change_kind * k)25884 equals(const union_decl& l, const union_decl& r, change_kind* k)
25885 {
25886 
25887   RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
25888 
25889   {
25890     // First of all, let's see if these two types haven't already been
25891     // compared.  If so, and if the result of the comparison has been
25892     // cached, let's just re-use it, rather than comparing them all
25893     // over again.
25894     bool result = false;
25895     if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
25896       ABG_RETURN(result);
25897   }
25898 
25899   bool result = equals(static_cast<const class_or_union&>(l),
25900 		       static_cast<const class_or_union&>(r),
25901 		       k);
25902 
25903   CACHE_COMPARISON_RESULT_AND_RETURN(result);
25904 }
25905 
25906 /// Copy a method of a @ref union_decl into a new @ref
25907 /// union_decl.
25908 ///
25909 /// @param t the @ref union_decl into which the method is to be copied.
25910 ///
25911 /// @param method the method to copy into @p t.
25912 ///
25913 /// @return the resulting newly copied method.
25914 method_decl_sptr
copy_member_function(const union_decl_sptr & union_type,const method_decl_sptr & f)25915 copy_member_function(const union_decl_sptr& union_type,
25916 		     const method_decl_sptr& f)
25917 {return copy_member_function(union_type, f.get());}
25918 
25919 /// Copy a method of a @ref union_decl into a new @ref
25920 /// union_decl.
25921 ///
25922 /// @param t the @ref union_decl into which the method is to be copied.
25923 ///
25924 /// @param method the method to copy into @p t.
25925 ///
25926 /// @return the resulting newly copied method.
25927 method_decl_sptr
copy_member_function(const union_decl_sptr & union_type,const method_decl * f)25928 copy_member_function(const union_decl_sptr& union_type,
25929 		     const method_decl* f)
25930 {
25931   const class_or_union_sptr t = union_type;
25932   return copy_member_function(t, f);
25933 }
25934 
25935 /// Turn equality of shared_ptr of union_decl into a deep equality;
25936 /// that is, make it compare the pointed to objects too.
25937 ///
25938 /// @param l the left-hand-side operand of the operator
25939 ///
25940 /// @param r the right-hand-side operand of the operator.
25941 ///
25942 /// @return true iff @p l equals @p r.
25943 bool
operator ==(const union_decl_sptr & l,const union_decl_sptr & r)25944 operator==(const union_decl_sptr& l, const union_decl_sptr& r)
25945 {
25946   if (l.get() == r.get())
25947     return true;
25948   if (!!l != !!r)
25949     return false;
25950 
25951   return *l == *r;
25952 }
25953 
25954 /// Turn inequality of shared_ptr of union_decl into a deep equality;
25955 /// that is, make it compare the pointed to objects too.
25956 ///
25957 /// @param l the left-hand-side operand of the operator
25958 ///
25959 /// @param r the right-hand-side operand of the operator.
25960 ///
25961 /// @return true iff @p l is different from @p r.
25962 bool
operator !=(const union_decl_sptr & l,const union_decl_sptr & r)25963 operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
25964 {return !operator==(l, r);}
25965 // </union_decl>
25966 
25967 // <template_decl stuff>
25968 
25969 /// Data type of the private data of the @template_decl type.
25970 class template_decl::priv
25971 {
25972   friend class template_decl;
25973 
25974   std::list<template_parameter_sptr> parms_;
25975 public:
25976 
priv()25977   priv()
25978   {}
25979 }; // end class template_decl::priv
25980 
25981 /// Add a new template parameter to the current instance of @ref
25982 /// template_decl.
25983 ///
25984 /// @param p the new template parameter to add.
25985 void
add_template_parameter(const template_parameter_sptr p)25986 template_decl::add_template_parameter(const template_parameter_sptr p)
25987 {priv_->parms_.push_back(p);}
25988 
25989 /// Get the list of template parameters of the current instance of
25990 /// @ref template_decl.
25991 ///
25992 /// @return the list of template parameters.
25993 const std::list<template_parameter_sptr>&
get_template_parameters() const25994 template_decl::get_template_parameters() const
25995 {return priv_->parms_;}
25996 
25997 /// Constructor.
25998 ///
25999 /// @param env the environment we are operating from.
26000 ///
26001 /// @param name the name of the template decl.
26002 ///
26003 /// @param locus the source location where the template declaration is
26004 /// defined.
26005 ///
26006 /// @param vis the visibility of the template declaration.
template_decl(const environment & env,const string & name,const location & locus,visibility vis)26007 template_decl::template_decl(const environment& env,
26008 			     const string& name,
26009 			     const location& locus,
26010 			     visibility vis)
26011   : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
26012     decl_base(env, name, locus, /*mangled_name=*/"", vis),
26013     priv_(new priv)
26014 {
26015   runtime_type_instance(this);
26016 }
26017 
26018 /// Destructor.
~template_decl()26019 template_decl::~template_decl()
26020 {}
26021 
26022 /// Equality operator.
26023 ///
26024 /// @param o the other instance to compare against.
26025 ///
26026 /// @return true iff @p equals the current instance.
26027 bool
operator ==(const decl_base & o) const26028 template_decl::operator==(const decl_base& o) const
26029 {
26030   const template_decl* other = dynamic_cast<const template_decl*>(&o);
26031   if (!other)
26032     return false;
26033   return *this == *other;
26034 }
26035 
26036 /// Equality operator.
26037 ///
26038 /// @param o the other instance to compare against.
26039 ///
26040 /// @return true iff @p equals the current instance.
26041 bool
operator ==(const template_decl & o) const26042 template_decl::operator==(const template_decl& o) const
26043 {
26044   try
26045     {
26046       list<shared_ptr<template_parameter> >::const_iterator t0, t1;
26047       for (t0 = get_template_parameters().begin(),
26048 	     t1 = o.get_template_parameters().begin();
26049 	   (t0 != get_template_parameters().end()
26050 	    && t1 != o.get_template_parameters().end());
26051 	   ++t0, ++t1)
26052 	{
26053 	  if (**t0 != **t1)
26054 	    return false;
26055 	}
26056 
26057       if (t0 != get_template_parameters().end()
26058 	  || t1 != o.get_template_parameters().end())
26059 	return false;
26060 
26061       return true;
26062     }
26063   catch(...)
26064     {return false;}
26065 }
26066 
26067 // </template_decl stuff>
26068 
26069 //<template_parameter>
26070 
26071 /// The type of the private data of the @ref template_parameter type.
26072 class template_parameter::priv
26073 {
26074   friend class template_parameter;
26075 
26076   unsigned index_;
26077   template_decl_wptr template_decl_;
26078   mutable bool hashing_started_;
26079   mutable bool comparison_started_;
26080 
26081   priv();
26082 
26083 public:
26084 
priv(unsigned index,template_decl_sptr enclosing_template_decl)26085   priv(unsigned index, template_decl_sptr enclosing_template_decl)
26086     : index_(index),
26087       template_decl_(enclosing_template_decl),
26088       hashing_started_(),
26089       comparison_started_()
26090   {}
26091 }; // end class template_parameter::priv
26092 
template_parameter(unsigned index,template_decl_sptr enclosing_template)26093 template_parameter::template_parameter(unsigned	 index,
26094 				       template_decl_sptr enclosing_template)
26095   : priv_(new priv(index, enclosing_template))
26096   {}
26097 
26098 unsigned
get_index() const26099 template_parameter::get_index() const
26100 {return priv_->index_;}
26101 
26102 const template_decl_sptr
get_enclosing_template_decl() const26103 template_parameter::get_enclosing_template_decl() const
26104 {return priv_->template_decl_.lock();}
26105 
26106 bool
get_hashing_has_started() const26107 template_parameter::get_hashing_has_started() const
26108 {return priv_->hashing_started_;}
26109 
26110 void
set_hashing_has_started(bool f) const26111 template_parameter::set_hashing_has_started(bool f) const
26112 {priv_->hashing_started_ = f;}
26113 
26114 bool
operator ==(const template_parameter & o) const26115 template_parameter::operator==(const template_parameter& o) const
26116 {
26117   if (get_index() != o.get_index())
26118     return false;
26119 
26120   if (priv_->comparison_started_)
26121     return true;
26122 
26123   bool result = false;
26124 
26125   // Avoid inifite loops due to the fact that comparison the enclosing
26126   // template decl might lead to comparing this very same template
26127   // parameter with another one ...
26128   priv_->comparison_started_ = true;
26129 
26130   if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
26131     ;
26132   else if (get_enclosing_template_decl()
26133 	   && (*get_enclosing_template_decl()
26134 	       != *o.get_enclosing_template_decl()))
26135     ;
26136   else
26137     result = true;
26138 
26139   priv_->comparison_started_ = false;
26140 
26141   return result;
26142 }
26143 
26144 /// Inequality operator.
26145 ///
26146 /// @param other the other instance to compare against.
26147 ///
26148 /// @return true iff the other instance is different from the current
26149 /// one.
26150 bool
operator !=(const template_parameter & other) const26151 template_parameter::operator!=(const template_parameter& other) const
26152 {return !operator==(other);}
26153 
26154 /// Destructor.
~template_parameter()26155 template_parameter::~template_parameter()
26156 {}
26157 
26158 /// The type of the private data of the @ref type_tparameter type.
26159 class type_tparameter::priv
26160 {
26161   friend class type_tparameter;
26162 }; // end class type_tparameter::priv
26163 
26164 /// Constructor of the @ref type_tparameter type.
26165 ///
26166 /// @param index the index the type template parameter.
26167 ///
26168 /// @param enclosing_tdecl the enclosing template declaration.
26169 ///
26170 /// @param name the name of the template parameter.
26171 ///
26172 /// @param locus the location of the declaration of this type template
26173 /// parameter.
type_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,const location & locus)26174 type_tparameter::type_tparameter(unsigned		index,
26175 				 template_decl_sptr	enclosing_tdecl,
26176 				 const string&		name,
26177 				 const location&	locus)
26178   : type_or_decl_base(enclosing_tdecl->get_environment(),
26179 		      ABSTRACT_DECL_BASE
26180 		      | ABSTRACT_TYPE_BASE
26181 		      | BASIC_TYPE),
26182     decl_base(enclosing_tdecl->get_environment(), name, locus),
26183     type_base(enclosing_tdecl->get_environment(), 0, 0),
26184     type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
26185     template_parameter(index, enclosing_tdecl),
26186     priv_(new priv)
26187 {
26188   runtime_type_instance(this);
26189 }
26190 
26191 /// Equality operator.
26192 ///
26193 /// @param other the other template type parameter to compare against.
26194 ///
26195 /// @return true iff @p other equals the current instance.
26196 bool
operator ==(const type_base & other) const26197 type_tparameter::operator==(const type_base& other) const
26198 {
26199   if (!type_decl::operator==(other))
26200     return false;
26201 
26202   try
26203     {
26204       const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
26205       return template_parameter::operator==(o);
26206     }
26207   catch (...)
26208     {return false;}
26209 }
26210 
26211 /// Equality operator.
26212 ///
26213 /// @param other the other template type parameter to compare against.
26214 ///
26215 /// @return true iff @p other equals the current instance.
26216 bool
operator ==(const type_decl & other) const26217 type_tparameter::operator==(const type_decl& other) const
26218 {
26219   if (!type_decl::operator==(other))
26220     return false;
26221 
26222   try
26223     {
26224       const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
26225       return template_parameter::operator==(o);
26226     }
26227   catch (...)
26228     {return false;}
26229 }
26230 
26231 /// Equality operator.
26232 ///
26233 /// @param other the other template type parameter to compare against.
26234 ///
26235 /// @return true iff @p other equals the current instance.
26236 bool
operator ==(const decl_base & other) const26237 type_tparameter::operator==(const decl_base& other) const
26238 {
26239   if (!decl_base::operator==(other))
26240     return false;
26241 
26242   try
26243     {
26244       const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
26245       return template_parameter::operator==(o);
26246     }
26247   catch (...)
26248     {return false;}
26249 }
26250 
26251 /// Equality operator.
26252 ///
26253 /// @param other the other template type parameter to compare against.
26254 ///
26255 /// @return true iff @p other equals the current instance.
26256 bool
operator ==(const template_parameter & other) const26257 type_tparameter::operator==(const template_parameter& other) const
26258 {
26259   try
26260     {
26261       const type_base& o = dynamic_cast<const type_base&>(other);
26262       return *this == o;
26263     }
26264   catch(...)
26265     {return false;}
26266 }
26267 
26268 /// Equality operator.
26269 ///
26270 /// @param other the other template type parameter to compare against.
26271 ///
26272 /// @return true iff @p other equals the current instance.
26273 bool
operator ==(const type_tparameter & other) const26274 type_tparameter::operator==(const type_tparameter& other) const
26275 {return *this == static_cast<const type_base&>(other);}
26276 
~type_tparameter()26277 type_tparameter::~type_tparameter()
26278 {}
26279 
26280 /// The type of the private data of the @ref non_type_tparameter type.
26281 class non_type_tparameter::priv
26282 {
26283   friend class non_type_tparameter;
26284 
26285   type_base_wptr type_;
26286 
26287   priv();
26288 
26289 public:
26290 
priv(type_base_sptr type)26291   priv(type_base_sptr type)
26292     : type_(type)
26293   {}
26294 }; // end class non_type_tparameter::priv
26295 
26296 /// The constructor for the @ref non_type_tparameter type.
26297 ///
26298 /// @param index the index of the template parameter.
26299 ///
26300 /// @param enclosing_tdecl the enclosing template declaration that
26301 /// holds this parameter parameter.
26302 ///
26303 /// @param name the name of the template parameter.
26304 ///
26305 /// @param type the type of the template parameter.
26306 ///
26307 /// @param locus the location of the declaration of this template
26308 /// parameter.
non_type_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,type_base_sptr type,const location & locus)26309 non_type_tparameter::non_type_tparameter(unsigned		index,
26310 					 template_decl_sptr	enclosing_tdecl,
26311 					 const string&		name,
26312 					 type_base_sptr	type,
26313 					 const location&	locus)
26314   : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
26315     decl_base(type->get_environment(), name, locus, ""),
26316     template_parameter(index, enclosing_tdecl),
26317     priv_(new priv(type))
26318 {
26319   runtime_type_instance(this);
26320 }
26321 
26322 /// Getter for the type of the template parameter.
26323 ///
26324 /// @return the type of the template parameter.
26325 const type_base_sptr
get_type() const26326 non_type_tparameter::get_type() const
26327 {return priv_->type_.lock();}
26328 
26329 /// Get the hash value of the current instance.
26330 ///
26331 /// @return the hash value.
26332 size_t
get_hash() const26333 non_type_tparameter::get_hash() const
26334 {
26335   non_type_tparameter::hash hash_tparm;
26336   return hash_tparm(this);
26337 }
26338 
26339 bool
operator ==(const decl_base & other) const26340 non_type_tparameter::operator==(const decl_base& other) const
26341 {
26342   if (!decl_base::operator==(other))
26343     return false;
26344 
26345   try
26346     {
26347       const non_type_tparameter& o =
26348 	dynamic_cast<const non_type_tparameter&>(other);
26349       return (template_parameter::operator==(o)
26350 	      && get_type() == o.get_type());
26351     }
26352   catch(...)
26353     {return false;}
26354 }
26355 
26356 bool
operator ==(const template_parameter & other) const26357 non_type_tparameter::operator==(const template_parameter& other) const
26358 {
26359   try
26360     {
26361       const decl_base& o = dynamic_cast<const decl_base&>(other);
26362       return *this == o;
26363     }
26364   catch(...)
26365     {return false;}
26366 }
26367 
~non_type_tparameter()26368 non_type_tparameter::~non_type_tparameter()
26369 {}
26370 
26371 // <template_tparameter stuff>
26372 
26373 /// Type of the private data of the @ref template_tparameter type.
26374 class template_tparameter::priv
26375 {
26376 }; //end class template_tparameter::priv
26377 
26378 /// Constructor for the @ref template_tparameter.
26379 ///
26380 /// @param index the index of the template parameter.
26381 ///
26382 /// @param enclosing_tdecl the enclosing template declaration.
26383 ///
26384 /// @param name the name of the template parameter.
26385 ///
26386 /// @param locus the location of the declaration of the template
26387 /// parameter.
template_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,const location & locus)26388 template_tparameter::template_tparameter(unsigned		index,
26389 					 template_decl_sptr	enclosing_tdecl,
26390 					 const string&		name,
26391 					 const location&	locus)
26392   : type_or_decl_base(enclosing_tdecl->get_environment(),
26393 		      ABSTRACT_DECL_BASE
26394 		      | ABSTRACT_TYPE_BASE
26395 		      | BASIC_TYPE),
26396     decl_base(enclosing_tdecl->get_environment(), name, locus),
26397     type_base(enclosing_tdecl->get_environment(), 0, 0),
26398     type_decl(enclosing_tdecl->get_environment(), name,
26399 	      0, 0, locus, name, VISIBILITY_DEFAULT),
26400     type_tparameter(index, enclosing_tdecl, name, locus),
26401     template_decl(enclosing_tdecl->get_environment(), name, locus),
26402     priv_(new priv)
26403 {
26404   runtime_type_instance(this);
26405 }
26406 
26407 /// Equality operator.
26408 ///
26409 /// @param other the other template parameter to compare against.
26410 ///
26411 /// @return true iff @p other equals the current instance.
26412 bool
operator ==(const type_base & other) const26413 template_tparameter::operator==(const type_base& other) const
26414 {
26415   try
26416     {
26417       const template_tparameter& o =
26418 	dynamic_cast<const template_tparameter&>(other);
26419       return (type_tparameter::operator==(o)
26420 	      && template_decl::operator==(o));
26421     }
26422   catch(...)
26423     {return false;}
26424 }
26425 
26426 /// Equality operator.
26427 ///
26428 /// @param other the other template parameter to compare against.
26429 ///
26430 /// @return true iff @p other equals the current instance.
26431 bool
operator ==(const decl_base & other) const26432 template_tparameter::operator==(const decl_base& other) const
26433 {
26434   try
26435     {
26436       const template_tparameter& o =
26437 	dynamic_cast<const template_tparameter&>(other);
26438       return (type_tparameter::operator==(o)
26439 	      && template_decl::operator==(o));
26440     }
26441   catch(...)
26442     {return false;}
26443 }
26444 
26445 bool
operator ==(const template_parameter & o) const26446 template_tparameter::operator==(const template_parameter& o) const
26447 {
26448   try
26449     {
26450       const template_tparameter& other =
26451 	dynamic_cast<const template_tparameter&>(o);
26452       return *this == static_cast<const type_base&>(other);
26453     }
26454   catch(...)
26455     {return false;}
26456 }
26457 
26458 bool
operator ==(const template_decl & o) const26459 template_tparameter::operator==(const template_decl& o) const
26460 {
26461   try
26462     {
26463       const template_tparameter& other =
26464 	dynamic_cast<const template_tparameter&>(o);
26465       return type_base::operator==(other);
26466     }
26467   catch(...)
26468     {return false;}
26469 }
26470 
~template_tparameter()26471 template_tparameter::~template_tparameter()
26472 {}
26473 
26474 // </template_tparameter stuff>
26475 
26476 // <type_composition stuff>
26477 
26478 /// The type of the private data of the @ref type_composition type.
26479 class type_composition::priv
26480 {
26481   friend class type_composition;
26482 
26483   type_base_wptr type_;
26484 
26485   // Forbid this.
26486   priv();
26487 
26488 public:
26489 
priv(type_base_wptr type)26490   priv(type_base_wptr type)
26491     : type_(type)
26492   {}
26493 }; //end class type_composition::priv
26494 
26495 /// Constructor for the @ref type_composition type.
26496 ///
26497 /// @param index the index of the template type composition.
26498 ///
26499 /// @param tdecl the enclosing template parameter that owns the
26500 /// composition.
26501 ///
26502 /// @param t the resulting type.
type_composition(unsigned index,template_decl_sptr tdecl,type_base_sptr t)26503 type_composition::type_composition(unsigned		index,
26504 				   template_decl_sptr	tdecl,
26505 				   type_base_sptr	t)
26506   : type_or_decl_base(tdecl->get_environment(),
26507 		      ABSTRACT_DECL_BASE),
26508     decl_base(tdecl->get_environment(), "", location()),
26509     template_parameter(index, tdecl),
26510     priv_(new priv(t))
26511 {
26512   runtime_type_instance(this);
26513 }
26514 
26515 /// Getter for the resulting composed type.
26516 ///
26517 /// @return the composed type.
26518 const type_base_sptr
get_composed_type() const26519 type_composition::get_composed_type() const
26520 {return priv_->type_.lock();}
26521 
26522 /// Setter for the resulting composed type.
26523 ///
26524 /// @param t the composed type.
26525 void
set_composed_type(type_base_sptr t)26526 type_composition::set_composed_type(type_base_sptr t)
26527 {priv_->type_ = t;}
26528 
26529 /// Get the hash value for the current instance.
26530 ///
26531 /// @return the hash value.
26532 size_t
get_hash() const26533 type_composition::get_hash() const
26534 {
26535   type_composition::hash hash_type_composition;
26536   return hash_type_composition(this);
26537 }
26538 
~type_composition()26539 type_composition::~type_composition()
26540 {}
26541 
26542 // </type_composition stuff>
26543 
26544 //</template_parameter stuff>
26545 
26546 // <function_template>
26547 
26548 class function_tdecl::priv
26549 {
26550   friend class function_tdecl;
26551 
26552   function_decl_sptr pattern_;
26553   binding binding_;
26554 
26555   priv();
26556 
26557 public:
26558 
priv(function_decl_sptr pattern,binding bind)26559   priv(function_decl_sptr pattern, binding bind)
26560     : pattern_(pattern), binding_(bind)
26561   {}
26562 
priv(binding bind)26563   priv(binding bind)
26564     : binding_(bind)
26565   {}
26566 }; // end class function_tdecl::priv
26567 
26568 /// Constructor for a function template declaration.
26569 ///
26570 /// @param env the environment we are operating from.
26571 ///
26572 /// @param locus the location of the declaration.
26573 ///
26574 /// @param vis the visibility of the declaration.  This is the
26575 /// visibility the functions instantiated from this template are going
26576 /// to have.
26577 ///
26578 /// @param bind the binding of the declaration.  This is the binding
26579 /// the functions instantiated from this template are going to have.
function_tdecl(const environment & env,const location & locus,visibility vis,binding bind)26580 function_tdecl::function_tdecl(const environment&	env,
26581 			       const location&		locus,
26582 			       visibility		vis,
26583 			       binding			bind)
26584   : type_or_decl_base(env,
26585 		      ABSTRACT_DECL_BASE
26586 		      | TEMPLATE_DECL
26587 		      | ABSTRACT_SCOPE_DECL),
26588     decl_base(env, "", locus, "", vis),
26589     template_decl(env, "", locus, vis),
26590     scope_decl(env, "", locus),
26591     priv_(new priv(bind))
26592 {
26593   runtime_type_instance(this);
26594 }
26595 
26596 /// Constructor for a function template declaration.
26597 ///
26598 /// @param pattern the pattern of the template.
26599 ///
26600 /// @param locus the location of the declaration.
26601 ///
26602 /// @param vis the visibility of the declaration.  This is the
26603 /// visibility the functions instantiated from this template are going
26604 /// to have.
26605 ///
26606 /// @param bind the binding of the declaration.  This is the binding
26607 /// the functions instantiated from this template are going to have.
function_tdecl(function_decl_sptr pattern,const location & locus,visibility vis,binding bind)26608 function_tdecl::function_tdecl(function_decl_sptr	pattern,
26609 			       const location&		locus,
26610 			       visibility		vis,
26611 			       binding			bind)
26612   : type_or_decl_base(pattern->get_environment(),
26613 		      ABSTRACT_DECL_BASE
26614 		      | TEMPLATE_DECL
26615 		      | ABSTRACT_SCOPE_DECL),
26616     decl_base(pattern->get_environment(), pattern->get_name(), locus,
26617 	      pattern->get_name(), vis),
26618     template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
26619     scope_decl(pattern->get_environment(), pattern->get_name(), locus),
26620     priv_(new priv(pattern, bind))
26621 {
26622   runtime_type_instance(this);
26623 }
26624 
26625 /// Set a new pattern to the function template.
26626 ///
26627 /// @param p the new pattern.
26628 void
set_pattern(function_decl_sptr p)26629 function_tdecl::set_pattern(function_decl_sptr p)
26630 {
26631   priv_->pattern_ = p;
26632   add_decl_to_scope(p, this);
26633   set_name(p->get_name());
26634 }
26635 
26636 /// Get the pattern of the function template.
26637 ///
26638 /// @return the pattern.
26639 function_decl_sptr
get_pattern() const26640 function_tdecl::get_pattern() const
26641 {return priv_->pattern_;}
26642 
26643 /// Get the binding of the function template.
26644 ///
26645 /// @return the binding
26646 decl_base::binding
get_binding() const26647 function_tdecl::get_binding() const
26648 {return priv_->binding_;}
26649 
26650 /// Comparison operator for the @ref function_tdecl type.
26651 ///
26652 /// @param other the other instance of @ref function_tdecl to compare against.
26653 ///
26654 /// @return true iff the two instance are equal.
26655 bool
operator ==(const decl_base & other) const26656 function_tdecl::operator==(const decl_base& other) const
26657 {
26658   const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
26659   if (o)
26660     return *this == *o;
26661   return false;
26662 }
26663 
26664 /// Comparison operator for the @ref function_tdecl type.
26665 ///
26666 /// @param other the other instance of @ref function_tdecl to compare against.
26667 ///
26668 /// @return true iff the two instance are equal.
26669 bool
operator ==(const template_decl & other) const26670 function_tdecl::operator==(const template_decl& other) const
26671 {
26672   const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
26673   if (o)
26674     return *this == *o;
26675   return false;
26676 }
26677 
26678 /// Comparison operator for the @ref function_tdecl type.
26679 ///
26680 /// @param o the other instance of @ref function_tdecl to compare against.
26681 ///
26682 /// @return true iff the two instance are equal.
26683 bool
operator ==(const function_tdecl & o) const26684 function_tdecl::operator==(const function_tdecl& o) const
26685 {
26686   if (!(get_binding() == o.get_binding()
26687 	&& template_decl::operator==(o)
26688 	&& scope_decl::operator==(o)
26689 	&& !!get_pattern() == !!o.get_pattern()))
26690     return false;
26691 
26692   if (get_pattern())
26693     return (*get_pattern() == *o.get_pattern());
26694 
26695   return true;
26696 }
26697 
26698 /// This implements the ir_traversable_base::traverse pure virtual
26699 /// function.
26700 ///
26701 /// @param v the visitor used on the current instance and on the
26702 /// function pattern of the template.
26703 ///
26704 /// @return true if the entire IR node tree got traversed, false
26705 /// otherwise.
26706 bool
traverse(ir_node_visitor & v)26707 function_tdecl::traverse(ir_node_visitor&v)
26708 {
26709   if (visiting())
26710     return true;
26711 
26712   if (!v.visit_begin(this))
26713     {
26714       visiting(true);
26715       if (get_pattern())
26716 	get_pattern()->traverse(v);
26717       visiting(false);
26718     }
26719   return v.visit_end(this);
26720 }
26721 
~function_tdecl()26722 function_tdecl::~function_tdecl()
26723 {}
26724 
26725 // </function_template>
26726 
26727 // <class template>
26728 
26729 /// Type of the private data of the the @ref class_tdecl type.
26730 class class_tdecl::priv
26731 {
26732   friend class class_tdecl;
26733   class_decl_sptr pattern_;
26734 
26735 public:
26736 
priv()26737   priv()
26738   {}
26739 
priv(class_decl_sptr pattern)26740   priv(class_decl_sptr pattern)
26741     : pattern_(pattern)
26742   {}
26743 }; // end class class_tdecl::priv
26744 
26745 /// Constructor for the @ref class_tdecl type.
26746 ///
26747 /// @param env the environment we are operating from.
26748 ///
26749 /// @param locus the location of the declaration of the class_tdecl
26750 /// type.
26751 ///
26752 /// @param vis the visibility of the instance of class instantiated
26753 /// from this template.
class_tdecl(const environment & env,const location & locus,visibility vis)26754 class_tdecl::class_tdecl(const environment&	env,
26755 			 const location&	locus,
26756 			 visibility		vis)
26757   : type_or_decl_base(env,
26758 		      ABSTRACT_DECL_BASE
26759 		      | TEMPLATE_DECL
26760 		      | ABSTRACT_SCOPE_DECL),
26761     decl_base(env, "", locus, "", vis),
26762     template_decl(env, "", locus, vis),
26763     scope_decl(env, "", locus),
26764     priv_(new priv)
26765 {
26766   runtime_type_instance(this);
26767 }
26768 
26769 /// Constructor for the @ref class_tdecl type.
26770 ///
26771 /// @param pattern The details of the class template. This must NOT be a
26772 /// null pointer.  If you really this to be null, please use the
26773 /// constructor above instead.
26774 ///
26775 /// @param locus the source location of the declaration of the type.
26776 ///
26777 /// @param vis the visibility of the instances of class instantiated
26778 /// from this template.
class_tdecl(class_decl_sptr pattern,const location & locus,visibility vis)26779 class_tdecl::class_tdecl(class_decl_sptr	pattern,
26780 			 const location&	locus,
26781 			 visibility		vis)
26782   : type_or_decl_base(pattern->get_environment(),
26783 		      ABSTRACT_DECL_BASE
26784 		      | TEMPLATE_DECL
26785 		      | ABSTRACT_SCOPE_DECL),
26786     decl_base(pattern->get_environment(), pattern->get_name(),
26787 	      locus, pattern->get_name(), vis),
26788     template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
26789     scope_decl(pattern->get_environment(), pattern->get_name(), locus),
26790     priv_(new priv(pattern))
26791 {
26792   runtime_type_instance(this);
26793 }
26794 
26795 /// Setter of the pattern of the template.
26796 ///
26797 /// @param p the new template.
26798 void
set_pattern(class_decl_sptr p)26799 class_tdecl::set_pattern(class_decl_sptr p)
26800 {
26801   priv_->pattern_ = p;
26802   add_decl_to_scope(p, this);
26803   set_name(p->get_name());
26804 }
26805 
26806 /// Getter of the pattern of the template.
26807 ///
26808 /// @return p the new template.
26809 class_decl_sptr
get_pattern() const26810 class_tdecl::get_pattern() const
26811 {return priv_->pattern_;}
26812 
26813 bool
operator ==(const decl_base & other) const26814 class_tdecl::operator==(const decl_base& other) const
26815 {
26816   try
26817     {
26818       const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
26819 
26820       if (!(template_decl::operator==(o)
26821 	    && scope_decl::operator==(o)
26822 	    && !!get_pattern() == !!o.get_pattern()))
26823 	return false;
26824 
26825       if (!get_pattern() || !o.get_pattern())
26826 	return true;
26827 
26828       return get_pattern()->decl_base::operator==(*o.get_pattern());
26829     }
26830   catch(...) {}
26831   return false;
26832 }
26833 
26834 bool
operator ==(const template_decl & other) const26835 class_tdecl::operator==(const template_decl& other) const
26836 {
26837   try
26838     {
26839       const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
26840       return *this == static_cast<const decl_base&>(o);
26841     }
26842   catch(...)
26843     {return false;}
26844 }
26845 
26846 bool
operator ==(const class_tdecl & o) const26847 class_tdecl::operator==(const class_tdecl& o) const
26848 {return *this == static_cast<const decl_base&>(o);}
26849 
26850 /// This implements the ir_traversable_base::traverse pure virtual
26851 /// function.
26852 ///
26853 /// @param v the visitor used on the current instance and on the class
26854 /// pattern of the template.
26855 ///
26856 /// @return true if the entire IR node tree got traversed, false
26857 /// otherwise.
26858 bool
traverse(ir_node_visitor & v)26859 class_tdecl::traverse(ir_node_visitor&v)
26860 {
26861   if (visiting())
26862     return true;
26863 
26864   if (v.visit_begin(this))
26865     {
26866       visiting(true);
26867       if (class_decl_sptr pattern = get_pattern())
26868 	pattern->traverse(v);
26869       visiting(false);
26870     }
26871   return v.visit_end(this);
26872 }
26873 
~class_tdecl()26874 class_tdecl::~class_tdecl()
26875 {}
26876 
26877 /// This visitor checks if a given type as non-canonicalized sub
26878 /// types.
26879 class non_canonicalized_subtype_detector : public ir::ir_node_visitor
26880 {
26881   type_base* type_;
26882   type_base* has_non_canonical_type_;
26883 
26884 private:
26885   non_canonicalized_subtype_detector();
26886 
26887 public:
non_canonicalized_subtype_detector(type_base * type)26888   non_canonicalized_subtype_detector(type_base* type)
26889     : type_(type),
26890       has_non_canonical_type_()
26891   {}
26892 
26893   /// Return true if the visitor detected that there is a
26894   /// non-canonicalized sub-type.
26895   ///
26896   /// @return true if the visitor detected that there is a
26897   /// non-canonicalized sub-type.
26898   type_base*
has_non_canonical_type() const26899   has_non_canonical_type() const
26900   {return has_non_canonical_type_;}
26901 
26902   /// The intent of this visitor handler is to avoid looking into
26903   /// sub-types of member functions of the type we are traversing.
26904   bool
visit_begin(function_decl * f)26905   visit_begin(function_decl* f)
26906   {
26907     // Do not look at sub-types of non-virtual member functions.
26908     if (is_member_function(f)
26909 	&& get_member_function_is_virtual(*f))
26910       return false;
26911     return true;
26912   }
26913 
26914   /// When visiting a sub-type, if it's *NOT* been canonicalized, set
26915   /// the 'has_non_canonical_type' flag.  And in any case, when
26916   /// visiting a sub-type, do not visit its children nodes.  So this
26917   /// function only goes to the level below the level of the top-most
26918   /// type.
26919   ///
26920   /// @return true if we are at the same level as the top-most type,
26921   /// otherwise return false.
26922   bool
visit_begin(type_base * t)26923   visit_begin(type_base* t)
26924   {
26925     if (t != type_)
26926       {
26927 	if (!t->get_canonical_type())
26928 	  // We are looking a sub-type of 'type_' which has no
26929 	  // canonical type.  So tada! we found one!  Get out right
26930 	  // now with the trophy.
26931 	  has_non_canonical_type_ = t;
26932 
26933 	return false;
26934       }
26935     return true;
26936   }
26937 
26938   /// When we are done visiting a sub-type, if it's been flagged as
26939   /// been non-canonicalized, then stop the traversing.
26940   ///
26941   /// Otherwise, keep going.
26942   ///
26943   /// @return false iff the sub-type that has been visited is
26944   /// non-canonicalized.
26945   bool
visit_end(type_base *)26946   visit_end(type_base* )
26947   {
26948     if (has_non_canonical_type_)
26949       return false;
26950     return true;
26951   }
26952 }; //end class non_canonicalized_subtype_detector
26953 
26954 /// Test if a type has sub-types that are non-canonicalized.
26955 ///
26956 /// @param t the type which sub-types to consider.
26957 ///
26958 /// @return true if a type has sub-types that are non-canonicalized.
26959 type_base*
type_has_non_canonicalized_subtype(type_base_sptr t)26960 type_has_non_canonicalized_subtype(type_base_sptr t)
26961 {
26962   if (!t)
26963     return 0;
26964 
26965   non_canonicalized_subtype_detector v(t.get());
26966   t->traverse(v);
26967   return v.has_non_canonical_type();
26968 }
26969 
26970 /// Tests if the change of a given type effectively comes from just
26971 /// its sub-types.  That is, if the type has changed but its type name
26972 /// hasn't changed, then the change of the type mostly likely is a
26973 /// sub-type change.
26974 ///
26975 /// @param t_v1 the first version of the type.
26976 ///
26977 /// @param t_v2 the second version of the type.
26978 ///
26979 /// @return true iff the type changed and the change is about its
26980 /// sub-types.
26981 bool
type_has_sub_type_changes(const type_base_sptr t_v1,const type_base_sptr t_v2)26982 type_has_sub_type_changes(const type_base_sptr t_v1,
26983 			  const type_base_sptr t_v2)
26984 {
26985   type_base_sptr t1 = strip_typedef(t_v1);
26986   type_base_sptr t2 = strip_typedef(t_v2);
26987 
26988   string repr1 = get_pretty_representation(t1, /*internal=*/false),
26989     repr2 = get_pretty_representation(t2, /*internal=*/false);
26990   return (t1 != t2 && repr1 == repr2);
26991 }
26992 
26993 /// Make sure that the life time of a given (smart pointer to a) type
26994 /// is the same as the life time of the libabigail library.
26995 ///
26996 /// @param t the type to consider.
26997 void
keep_type_alive(type_base_sptr t)26998 keep_type_alive(type_base_sptr t)
26999 {
27000   const environment& env = t->get_environment();
27001   env.priv_->extra_live_types_.push_back(t);
27002 }
27003 
27004 /// Hash an ABI artifact that is either a type or a decl.
27005 ///
27006 /// This function intends to provides the fastest possible hashing for
27007 /// types and decls, while being completely correct.
27008 ///
27009 /// Note that if the artifact is a type and if it has a canonical
27010 /// type, the hash value is going to be the pointer value of the
27011 /// canonical type.  Otherwise, this function computes a hash value
27012 /// for the type by recursively walking the type members.  This last
27013 /// code path is possibly *very* slow and should only be used when
27014 /// only handful of types are going to be hashed.
27015 ///
27016 /// If the artifact is a decl, then a combination of the hash of its
27017 /// type and the hash of the other properties of the decl is computed.
27018 ///
27019 /// @param tod the type or decl to hash.
27020 ///
27021 /// @return the resulting hash value.
27022 size_t
hash_type_or_decl(const type_or_decl_base * tod)27023 hash_type_or_decl(const type_or_decl_base *tod)
27024 {
27025   size_t result = 0;
27026 
27027   if (tod == 0)
27028     ;
27029   else if (const type_base* t = is_type(tod))
27030     result = hash_type(t);
27031   else if (const decl_base* d = is_decl(tod))
27032     {
27033       if (var_decl* v = is_var_decl(d))
27034 	{
27035 	  ABG_ASSERT(v->get_type());
27036 	  size_t h = hash_type_or_decl(v->get_type());
27037 	  string repr = v->get_pretty_representation(/*internal=*/true);
27038 	  std::hash<string> hash_string;
27039 	  h = hashing::combine_hashes(h, hash_string(repr));
27040 	  result = h;
27041 	}
27042       else if (function_decl* f = is_function_decl(d))
27043 	{
27044 	  ABG_ASSERT(f->get_type());
27045 	  size_t h = hash_type_or_decl(f->get_type());
27046 	  string repr = f->get_pretty_representation(/*internal=*/true);
27047 	  std::hash<string> hash_string;
27048 	  h = hashing::combine_hashes(h, hash_string(repr));
27049 	  result = h;
27050 	}
27051       else if (function_decl::parameter* p = is_function_parameter(d))
27052 	{
27053 	  type_base_sptr parm_type = p->get_type();
27054 	  ABG_ASSERT(parm_type);
27055 	  std::hash<bool> hash_bool;
27056 	  std::hash<unsigned> hash_unsigned;
27057 	  size_t h = hash_type_or_decl(parm_type);
27058 	  h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
27059 	  h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
27060 	  result = h;
27061 	}
27062       else if (class_decl::base_spec *bs = is_class_base_spec(d))
27063 	{
27064 	  member_base::hash hash_member;
27065 	  std::hash<size_t> hash_size;
27066 	  std::hash<bool> hash_bool;
27067 	  type_base_sptr type = bs->get_base_class();
27068 	  size_t h = hash_type_or_decl(type);
27069 	  h = hashing::combine_hashes(h, hash_member(*bs));
27070 	  h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
27071 	  h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
27072 	  result = h;
27073 	}
27074       else
27075 	// This is a *really* *SLOW* path.  If it shows up in a
27076 	// performance profile, I bet it'd be a good idea to try to
27077 	// avoid it altogether.
27078 	result = d->get_hash();
27079     }
27080   else
27081     // We should never get here.
27082     abort();
27083   return result;
27084 }
27085 
27086 /// Hash an ABI artifact that is either a type.
27087 ///
27088 /// This function intends to provides the fastest possible hashing for
27089 /// types while being completely correct.
27090 ///
27091 /// Note that if the type artifact has a canonical type, the hash
27092 /// value is going to be the pointer value of the canonical type.
27093 /// Otherwise, this function computes a hash value for the type by
27094 /// recursively walking the type members.  This last code path is
27095 /// possibly *very* slow and should only be used when only handful of
27096 /// types are going to be hashed.
27097 ///
27098 /// @param t the type or decl to hash.
27099 ///
27100 /// @return the resulting hash value.
27101 size_t
hash_type(const type_base * t)27102 hash_type(const type_base *t)
27103 {return hash_as_canonical_type_or_constant(t);}
27104 
27105 /// Hash an ABI artifact that is either a type of a decl.
27106 ///
27107 /// @param tod the ABI artifact to hash.
27108 ///
27109 /// @return the hash value of the ABI artifact.
27110 size_t
hash_type_or_decl(const type_or_decl_base_sptr & tod)27111 hash_type_or_decl(const type_or_decl_base_sptr& tod)
27112 {return hash_type_or_decl(tod.get());}
27113 
27114 /// Test if a given type is allowed to be non canonicalized
27115 ///
27116 /// This is a subroutine of hash_as_canonical_type_or_constant.
27117 ///
27118 /// For now, the only types allowed to be non canonicalized in the
27119 /// system are (typedefs & pointers to) decl-only class/union, the
27120 /// void type and variadic parameter types.
27121 ///
27122 /// @return true iff @p t is a one of the only types allowed to be
27123 /// non-canonicalized in the system.
27124 bool
is_non_canonicalized_type(const type_base * t)27125 is_non_canonicalized_type(const type_base *t)
27126 {
27127   if (!t)
27128     return true;
27129 
27130   return (// The IR nodes for the types below are unique across the
27131 	  // entire ABI corpus.  Thus, no need to canonicalize them.
27132 	  // Maybe we could say otherwise and canonicalize them once
27133 	  // for all so that they can be removed from here.
27134 	  is_unique_type(t)
27135 
27136 	  // An IR node for the types below can be equal to several
27137 	  // other types (i.e, a decl-only type t equals a fully
27138 	  // defined type of the same name in ODR-supported
27139 	  // languages). Hence, they can't be given a canonical type.
27140 	  //
27141 	  // TODO: Maybe add a mode that would detect ODR violations
27142 	  // that would make a decl-only type co-exists with several
27143 	  // different definitions of the type in the ABI corpus.
27144 	  || is_void_pointer_type_equivalent(t)
27145 	  || is_declaration_only_class_or_union_type(t,
27146 						     /*look_through_decl_only=*/true)
27147 	  || is_typedef_ptr_or_ref_to_decl_only_class_or_union_type(t));
27148 
27149 }
27150 
27151 /// Test if a type is unique in the entire environment.
27152 ///
27153 /// Examples of unique types are void, void* and variadic parameter
27154 /// types.
27155 ///
27156 /// @param t the type to test for.
27157 ///
27158 /// @return true iff the type @p t is unique in the entire
27159 /// environment.
27160 bool
is_unique_type(const type_base_sptr & t)27161 is_unique_type(const type_base_sptr& t)
27162 {return is_unique_type(t.get());}
27163 
27164 /// Test if a type is unique in the entire environment.
27165 ///
27166 /// Examples of unique types are void, void* and variadic parameter
27167 /// types.
27168 ///
27169 /// @param t the type to test for.
27170 ///
27171 /// @return true iff the type @p t is unique in the entire
27172 /// environment.
27173 bool
is_unique_type(const type_base * t)27174 is_unique_type(const type_base* t)
27175 {
27176   if (!t)
27177     return false;
27178 
27179   const environment& env = t->get_environment();
27180   return (env.is_void_type(t)
27181 	  || env.is_void_pointer_type(t)
27182 	  || env.is_variadic_parameter_type(t));
27183 }
27184 
27185 /// For a given type, return its exemplar type.
27186 ///
27187 /// For a given type, its exemplar type is either its canonical type
27188 /// or the canonical type of the definition type of a given
27189 /// declaration-only type.  If the neither of those two types exist,
27190 /// then the exemplar type is the given type itself.
27191 ///
27192 /// @param type the input to consider.
27193 ///
27194 /// @return the exemplar type.
27195 type_base*
get_exemplar_type(const type_base * type)27196 get_exemplar_type(const type_base* type)
27197 {
27198   if (decl_base * decl = is_decl(type))
27199     {
27200       // Make sure we get the real definition of a decl-only type.
27201       decl = look_through_decl_only(decl);
27202       type = is_type(decl);
27203       ABG_ASSERT(type);
27204     }
27205   type_base *exemplar = type->get_naked_canonical_type();
27206   if (!exemplar)
27207     {
27208       // The type has no canonical type.  Let's be sure that it's one
27209       // of those rare types that are allowed to be non canonicalized
27210       // in the system.
27211       exemplar = const_cast<type_base*>(type);
27212       ABG_ASSERT(is_non_canonicalized_type(exemplar));
27213     }
27214   return exemplar;
27215 }
27216 
27217 /// Test if a given type is allowed to be non canonicalized
27218 ///
27219 /// This is a subroutine of hash_as_canonical_type_or_constant.
27220 ///
27221 /// For now, the only types allowed to be non canonicalized in the
27222 /// system are decl-only class/union and the void type.
27223 ///
27224 /// @return true iff @p t is a one of the only types allowed to be
27225 /// non-canonicalized in the system.
27226 bool
is_non_canonicalized_type(const type_base_sptr & t)27227 is_non_canonicalized_type(const type_base_sptr& t)
27228 {return is_non_canonicalized_type(t.get());}
27229 
27230 /// Hash a type by either returning the pointer value of its canonical
27231 /// type or by returning a constant if the type doesn't have a
27232 /// canonical type.
27233 ///
27234 /// This is a subroutine of hash_type.
27235 ///
27236 /// @param t the type to consider.
27237 ///
27238 /// @return the hash value.
27239 static size_t
hash_as_canonical_type_or_constant(const type_base * t)27240 hash_as_canonical_type_or_constant(const type_base *t)
27241 {
27242   type_base *canonical_type = 0;
27243 
27244   if (t)
27245     canonical_type = t->get_naked_canonical_type();
27246 
27247   if (!canonical_type)
27248     {
27249       // If the type doesn't have a canonical type, maybe it's because
27250       // it's a declaration-only type?  If that's the case, let's try
27251       // to get the canonical type of the definition of this
27252       // declaration.
27253       decl_base *decl = is_decl(t);
27254       if (decl
27255 	  && decl->get_is_declaration_only()
27256 	  && decl->get_naked_definition_of_declaration())
27257 	{
27258 	  type_base *definition =
27259 	    is_type(decl->get_naked_definition_of_declaration());
27260 	  ABG_ASSERT(definition);
27261 	  canonical_type = definition->get_naked_canonical_type();
27262 	}
27263     }
27264 
27265   if (canonical_type)
27266     return reinterpret_cast<size_t>(canonical_type);
27267 
27268   // If we reached this point, it means we are seeing a
27269   // non-canonicalized type.  It must be a decl-only class or a void
27270   // type, otherwise it means that for some weird reason, the type
27271   // hasn't been canonicalized.  It should be!
27272   ABG_ASSERT(is_non_canonicalized_type(t));
27273 
27274   return 0xDEADBABE;
27275 }
27276 
27277 /// Test if the pretty representation of a given @ref function_decl is
27278 /// lexicographically less then the pretty representation of another
27279 /// @ref function_decl.
27280 ///
27281 /// @param f the first @ref function_decl to consider for comparison.
27282 ///
27283 /// @param s the second @ref function_decl to consider for comparison.
27284 ///
27285 /// @return true iff the pretty representation of @p f is
27286 /// lexicographically less than the pretty representation of @p s.
27287 bool
function_decl_is_less_than(const function_decl & f,const function_decl & s)27288 function_decl_is_less_than(const function_decl &f, const function_decl &s)
27289 {
27290   string fr = f.get_pretty_representation_of_declarator(),
27291     sr = s.get_pretty_representation_of_declarator();
27292 
27293   if (fr != sr)
27294     return fr < sr;
27295 
27296   fr = f.get_pretty_representation(/*internal=*/true),
27297     sr = s.get_pretty_representation(/*internal=*/true);
27298 
27299   if (fr != sr)
27300     return fr < sr;
27301 
27302   if (f.get_symbol())
27303     fr = f.get_symbol()->get_id_string();
27304   else if (!f.get_linkage_name().empty())
27305     fr = f.get_linkage_name();
27306 
27307   if (s.get_symbol())
27308     sr = s.get_symbol()->get_id_string();
27309   else if (!s.get_linkage_name().empty())
27310     sr = s.get_linkage_name();
27311 
27312   return fr < sr;
27313 }
27314 
27315 /// Test if two types have similar structures, even though they are
27316 /// (or can be) different.
27317 ///
27318 /// const and volatile qualifiers are completely ignored.
27319 ///
27320 /// typedef are resolved to their definitions; their names are ignored.
27321 ///
27322 /// Two indirect types (pointers or references) have similar structure
27323 /// if their underlying types are of the same kind and have the same
27324 /// name.  In the indirect types case, the size of the underlying type
27325 /// does not matter.
27326 ///
27327 /// Two direct types (i.e, non indirect) have a similar structure if
27328 /// they have the same kind, name and size.  Two class types have
27329 /// similar structure if they have the same name, size, and if the
27330 /// types of their data members have similar types.
27331 ///
27332 /// @param first the first type to consider.
27333 ///
27334 /// @param second the second type to consider.
27335 ///
27336 /// @param indirect_type whether to do an indirect comparison
27337 ///
27338 /// @return true iff @p first and @p second have similar structures.
27339 bool
types_have_similar_structure(const type_base_sptr & first,const type_base_sptr & second,bool indirect_type)27340 types_have_similar_structure(const type_base_sptr& first,
27341 			     const type_base_sptr& second,
27342 			     bool indirect_type)
27343 {return types_have_similar_structure(first.get(), second.get(), indirect_type);}
27344 
27345 /// Test if two types have similar structures, even though they are
27346 /// (or can be) different.
27347 ///
27348 /// const and volatile qualifiers are completely ignored.
27349 ///
27350 /// typedef are resolved to their definitions; their names are ignored.
27351 ///
27352 /// Two indirect types (pointers, references or arrays) have similar
27353 /// structure if their underlying types are of the same kind and have
27354 /// the same name.  In the indirect types case, the size of the
27355 /// underlying type does not matter.
27356 ///
27357 /// Two direct types (i.e, non indirect) have a similar structure if
27358 /// they have the same kind, name and size.  Two class types have
27359 /// similar structure if they have the same name, size, and if the
27360 /// types of their data members have similar types.
27361 ///
27362 /// @param first the first type to consider.
27363 ///
27364 /// @param second the second type to consider.
27365 ///
27366 /// @param indirect_type if true, then consider @p first and @p
27367 /// second as being underlying types of indirect types.  Meaning that
27368 /// their size does not matter.
27369 ///
27370 /// @return true iff @p first and @p second have similar structures.
27371 bool
types_have_similar_structure(const type_base * first,const type_base * second,bool indirect_type)27372 types_have_similar_structure(const type_base* first,
27373 			     const type_base* second,
27374 			     bool indirect_type)
27375 {
27376   if (!!first != !!second)
27377     return false;
27378 
27379   if (!first)
27380     return false;
27381 
27382   // Treat typedefs purely as type aliases and ignore CV-qualifiers.
27383   first = peel_qualified_or_typedef_type(first);
27384   second = peel_qualified_or_typedef_type(second);
27385 
27386   // Eliminate all but N of the N^2 comparison cases. This also guarantees the
27387   // various ty2 below cannot be null.
27388   if (typeid(*first) != typeid(*second))
27389     return false;
27390 
27391   // Peel off matching pointers.
27392   if (const pointer_type_def* ty1 = is_pointer_type(first))
27393     {
27394       const pointer_type_def* ty2 = is_pointer_type(second);
27395       return types_have_similar_structure(ty1->get_pointed_to_type(),
27396 					  ty2->get_pointed_to_type(),
27397 					  /*indirect_type=*/true);
27398     }
27399 
27400   // Peel off matching references.
27401   if (const reference_type_def* ty1 = is_reference_type(first))
27402     {
27403       const reference_type_def* ty2 = is_reference_type(second);
27404       if (ty1->is_lvalue() != ty2->is_lvalue())
27405 	return false;
27406       return types_have_similar_structure(ty1->get_pointed_to_type(),
27407 					  ty2->get_pointed_to_type(),
27408 					  /*indirect_type=*/true);
27409     }
27410 
27411   if (const type_decl* ty1 = is_type_decl(first))
27412     {
27413       const type_decl* ty2 = is_type_decl(second);
27414       if (!indirect_type)
27415 	if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
27416 	  return false;
27417 
27418       return ty1->get_name() == ty2->get_name();
27419     }
27420 
27421   if (const enum_type_decl* ty1 = is_enum_type(first))
27422     {
27423       const enum_type_decl* ty2 = is_enum_type(second);
27424       if (!indirect_type)
27425 	if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
27426 	  return false;
27427 
27428       return (get_name(ty1->get_underlying_type())
27429 	      == get_name(ty2->get_underlying_type()));
27430     }
27431 
27432   if (const class_decl* ty1 = is_class_type(first))
27433     {
27434       const class_decl* ty2 = is_class_type(second);
27435       if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
27436 	  && ty1->get_name() != ty2->get_name())
27437 	return false;
27438 
27439       if (!indirect_type)
27440 	{
27441 	  if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
27442 	      || (ty1->get_non_static_data_members().size()
27443 		  != ty2->get_non_static_data_members().size()))
27444 	    return false;
27445 
27446 	  for (class_or_union::data_members::const_iterator
27447 		 i = ty1->get_non_static_data_members().begin(),
27448 		 j = ty2->get_non_static_data_members().begin();
27449 	       (i != ty1->get_non_static_data_members().end()
27450 		&& j != ty2->get_non_static_data_members().end());
27451 	       ++i, ++j)
27452 	    {
27453 	      var_decl_sptr dm1 = *i;
27454 	      var_decl_sptr dm2 = *j;
27455 	      if (!types_have_similar_structure(dm1->get_type().get(),
27456 						dm2->get_type().get(),
27457 						indirect_type))
27458 		return false;
27459 	    }
27460 	}
27461 
27462       return true;
27463     }
27464 
27465   if (const union_decl* ty1 = is_union_type(first))
27466     {
27467       const union_decl* ty2 = is_union_type(second);
27468       if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
27469 	  && ty1->get_name() != ty2->get_name())
27470 	return false;
27471 
27472       if (!indirect_type)
27473 	return ty1->get_size_in_bits() == ty2->get_size_in_bits();
27474 
27475       return true;
27476     }
27477 
27478   if (const array_type_def* ty1 = is_array_type(first))
27479     {
27480       const array_type_def* ty2 = is_array_type(second);
27481       // TODO: Handle int[5][2] vs int[2][5] better.
27482       if (!indirect_type)
27483 	{
27484 	  if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
27485 	      || ty1->get_dimension_count() != ty2->get_dimension_count())
27486 	    return false;
27487 	}
27488 
27489       if (!types_have_similar_structure(ty1->get_element_type(),
27490 					ty2->get_element_type(),
27491 					/*indirect_type=*/true))
27492 	return false;
27493 
27494       return true;
27495     }
27496 
27497   if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
27498     {
27499       const array_type_def::subrange_type *ty2 = is_subrange_type(second);
27500       if (ty1->get_upper_bound() != ty2->get_upper_bound()
27501 	  || ty1->get_lower_bound() != ty2->get_lower_bound()
27502 	  || ty1->get_language() != ty2->get_language()
27503 	  || !types_have_similar_structure(ty1->get_underlying_type(),
27504 					   ty2->get_underlying_type(),
27505 					   indirect_type))
27506 	return false;
27507 
27508       return true;
27509     }
27510 
27511   if (const function_type* ty1 = is_function_type(first))
27512     {
27513       const function_type* ty2 = is_function_type(second);
27514       if (!types_have_similar_structure(ty1->get_return_type(),
27515 					ty2->get_return_type(),
27516 					indirect_type))
27517 	return false;
27518 
27519       if (ty1->get_parameters().size() != ty2->get_parameters().size())
27520 	return false;
27521 
27522       for (function_type::parameters::const_iterator
27523 	     i = ty1->get_parameters().begin(),
27524 	     j = ty2->get_parameters().begin();
27525 	   (i != ty1->get_parameters().end()
27526 	    && j != ty2->get_parameters().end());
27527 	   ++i, ++j)
27528 	if (!types_have_similar_structure((*i)->get_type(),
27529 					  (*j)->get_type(),
27530 					  indirect_type))
27531 	  return false;
27532 
27533       return true;
27534     }
27535 
27536   // All kinds of type should have been handled at this point.
27537   ABG_ASSERT_NOT_REACHED;
27538 
27539   return false;
27540 }
27541 
27542 /// Look for a data member of a given class, struct or union type and
27543 /// return it.
27544 ///
27545 /// The data member is designated by its name.
27546 ///
27547 /// @param type the class, struct or union type to consider.
27548 ///
27549 /// @param dm_name the name of the data member to lookup.
27550 ///
27551 /// @return the data member iff it was found in @type or NULL if no
27552 /// data member with that name was found.
27553 const var_decl*
lookup_data_member(const type_base * type,const char * dm_name)27554 lookup_data_member(const type_base* type,
27555 		   const char* dm_name)
27556 
27557 {
27558   class_or_union *cou = is_class_or_union_type(type);
27559   if (!cou)
27560     return 0;
27561 
27562   return cou->find_data_member(dm_name).get();
27563 }
27564 
27565 /// Look for a data member of a given class, struct or union type and
27566 /// return it.
27567 ///
27568 /// The data member is designated by its name.
27569 ///
27570 /// @param type the class, struct or union type to consider.
27571 ///
27572 /// @param dm the data member to lookup.
27573 ///
27574 /// @return the data member iff it was found in @type or NULL if no
27575 /// data member with that name was found.
27576 const var_decl_sptr
lookup_data_member(const type_base_sptr & type,const var_decl_sptr & dm)27577 lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
27578 {
27579   class_or_union_sptr cou = is_class_or_union_type(type);
27580   if (!cou)
27581     return var_decl_sptr();
27582 
27583   return cou->find_data_member(dm);
27584 }
27585 
27586 /// Get the function parameter designated by its index.
27587 ///
27588 /// Note that the first function parameter has index 0.
27589 ///
27590 /// @param fun the function to consider.
27591 ///
27592 /// @param parm_index the index of the function parameter to get.
27593 ///
27594 /// @return the function parameter designated by its index, of NULL if
27595 /// no function parameter with that index was found.
27596 const function_decl::parameter*
get_function_parameter(const decl_base * fun,unsigned parm_index)27597 get_function_parameter(const decl_base* fun,
27598 		       unsigned parm_index)
27599 {
27600   function_decl* fn = is_function_decl(fun);
27601   if (!fn)
27602     return 0;
27603 
27604   const function_decl::parameters &parms = fn->get_type()->get_parameters();
27605   if (parms.size() <= parm_index)
27606     return 0;
27607 
27608   return parms[parm_index].get();
27609 }
27610 
27611 /// Build the internal name of the underlying type of an enum.
27612 ///
27613 /// @param base_name the (unqualified) name of the enum the underlying
27614 /// type is destined to.
27615 ///
27616 /// @param is_anonymous true if the underlying type of the enum is to
27617 /// be anonymous.
27618 string
build_internal_underlying_enum_type_name(const string & base_name,bool is_anonymous,uint64_t size)27619 build_internal_underlying_enum_type_name(const string &base_name,
27620 					 bool is_anonymous,
27621 					 uint64_t size)
27622 {
27623   std::ostringstream o;
27624 
27625   if (is_anonymous)
27626     o << "unnamed-enum";
27627   else
27628     o << "enum-" << base_name;
27629 
27630   o << "-underlying-type-" << size;
27631 
27632   return o.str();
27633 }
27634 
27635 /// Find the first data member of a class or union which name matches
27636 /// a regular expression.
27637 ///
27638 /// @param t the class or union to consider.
27639 ///
27640 /// @param r the regular expression to consider.
27641 ///
27642 /// @return the data member matched by @p r or nil if none was found.
27643 var_decl_sptr
find_first_data_member_matching_regexp(const class_or_union & t,const regex::regex_t_sptr & r)27644 find_first_data_member_matching_regexp(const class_or_union& t,
27645 				       const regex::regex_t_sptr& r)
27646 {
27647   for (auto data_member : t.get_data_members())
27648     {
27649       if (regex::match(r, data_member->get_name()))
27650 	return data_member;
27651     }
27652 
27653   return var_decl_sptr();
27654 }
27655 
27656 /// Find the last data member of a class or union which name matches
27657 /// a regular expression.
27658 ///
27659 /// @param t the class or union to consider.
27660 ///
27661 /// @param r the regular expression to consider.
27662 ///
27663 /// @return the data member matched by @p r or nil if none was found.
27664 var_decl_sptr
find_last_data_member_matching_regexp(const class_or_union & t,const regex::regex_t_sptr & regex)27665 find_last_data_member_matching_regexp(const class_or_union& t,
27666 				      const regex::regex_t_sptr& regex)
27667 {
27668   auto d = t.get_data_members().rbegin();
27669   auto e = t.get_data_members().rend();
27670   for (; d != e; ++d)
27671     {
27672       if (regex::match(regex, (*d)->get_name()))
27673 	return *d;
27674     }
27675 
27676   return var_decl_sptr();
27677 }
27678 
27679 bool
traverse(ir_node_visitor &)27680 ir_traversable_base::traverse(ir_node_visitor&)
27681 {return true;}
27682 
27683 // <ir_node_visitor stuff>
27684 
27685 /// The private data structure of the ir_node_visitor type.
27686 struct ir_node_visitor::priv
27687 {
27688   pointer_set visited_ir_nodes;
27689   bool allow_visiting_already_visited_type_node;
27690 
privabigail::ir::ir_node_visitor::priv27691   priv()
27692     : allow_visiting_already_visited_type_node(true)
27693   {}
27694 }; // end struct ir_node_visitory::priv
27695 
27696 /// Default Constructor of the ir_node_visitor type.
ir_node_visitor()27697 ir_node_visitor::ir_node_visitor()
27698   : priv_(new priv)
27699 {}
27700 
27701 ir_node_visitor::~ir_node_visitor() = default;
27702 
27703 /// Set if the walker using this visitor is allowed to re-visit a type
27704 /// node that was previously visited or not.
27705 ///
27706 /// @param f if true, then the walker using this visitor is allowed to
27707 /// re-visit a type node that was previously visited.
27708 void
allow_visiting_already_visited_type_node(bool f)27709 ir_node_visitor::allow_visiting_already_visited_type_node(bool f)
27710 {priv_->allow_visiting_already_visited_type_node = f;}
27711 
27712 /// Get if the walker using this visitor is allowed to re-visit a type
27713 /// node that was previously visited or not.
27714 ///
27715 /// @return true iff the walker using this visitor is allowed to
27716 /// re-visit a type node that was previously visited.
27717 bool
allow_visiting_already_visited_type_node() const27718 ir_node_visitor::allow_visiting_already_visited_type_node() const
27719 {return priv_->allow_visiting_already_visited_type_node;}
27720 
27721 /// Mark a given type node as having been visited.
27722 ///
27723 /// Note that for this function to work, the type node must have been
27724 /// canonicalized.  Otherwise the process is aborted.
27725 ///
27726 /// @param p the type to mark as having been visited.
27727 void
mark_type_node_as_visited(type_base * p)27728 ir_node_visitor::mark_type_node_as_visited(type_base *p)
27729 {
27730   if (allow_visiting_already_visited_type_node())
27731     return;
27732 
27733   if (p == 0 || type_node_has_been_visited(p))
27734     return;
27735 
27736   type_base* canonical_type = p->get_naked_canonical_type();
27737   ABG_ASSERT(canonical_type);
27738 
27739   size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
27740   priv_->visited_ir_nodes.insert(canonical_ptr_value);
27741 }
27742 
27743 /// Un-mark all visited type nodes.
27744 ///
27745 /// That is, no type node is going to be considered as having been
27746 /// visited anymore.
27747 ///
27748 /// In other words, after invoking this funciton,
27749 /// ir_node_visitor::type_node_has_been_visited() is going to return
27750 /// false on all type nodes.
27751 void
forget_visited_type_nodes()27752 ir_node_visitor::forget_visited_type_nodes()
27753 {priv_->visited_ir_nodes.clear();}
27754 
27755 /// Test if a given type node has been marked as visited.
27756 ///
27757 /// @param p the type node to consider.
27758 ///
27759 /// @return true iff the type node @p p has been marked as visited by
27760 /// the function ir_node_visitor::mark_type_node_as_visited.
27761 bool
type_node_has_been_visited(type_base * p) const27762 ir_node_visitor::type_node_has_been_visited(type_base* p) const
27763 {
27764   if (allow_visiting_already_visited_type_node())
27765     return false;
27766 
27767   if (p == 0)
27768     return false;
27769 
27770   type_base *canonical_type = p->get_naked_canonical_type();
27771   ABG_ASSERT(canonical_type);
27772 
27773   size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
27774   pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
27775   if (it == priv_->visited_ir_nodes.end())
27776     return false;
27777 
27778   return true;
27779 }
27780 
27781 bool
visit_begin(decl_base *)27782 ir_node_visitor::visit_begin(decl_base*)
27783 {return true;}
27784 
27785 bool
visit_end(decl_base *)27786 ir_node_visitor::visit_end(decl_base*)
27787 {return true;}
27788 
27789 bool
visit_begin(scope_decl *)27790 ir_node_visitor::visit_begin(scope_decl*)
27791 {return true;}
27792 
27793 bool
visit_end(scope_decl *)27794 ir_node_visitor::visit_end(scope_decl*)
27795 {return true;}
27796 
27797 bool
visit_begin(type_base *)27798 ir_node_visitor::visit_begin(type_base*)
27799 {return true;}
27800 
27801 bool
visit_end(type_base *)27802 ir_node_visitor::visit_end(type_base*)
27803 {return true;}
27804 
27805 bool
visit_begin(scope_type_decl * t)27806 ir_node_visitor::visit_begin(scope_type_decl* t)
27807 {return visit_begin(static_cast<type_base*>(t));}
27808 
27809 bool
visit_end(scope_type_decl * t)27810 ir_node_visitor::visit_end(scope_type_decl* t)
27811 {return visit_end(static_cast<type_base*>(t));}
27812 
27813 bool
visit_begin(type_decl * t)27814 ir_node_visitor::visit_begin(type_decl* t)
27815 {return visit_begin(static_cast<type_base*>(t));}
27816 
27817 bool
visit_end(type_decl * t)27818 ir_node_visitor::visit_end(type_decl* t)
27819 {return visit_end(static_cast<type_base*>(t));}
27820 
27821 bool
visit_begin(namespace_decl * d)27822 ir_node_visitor::visit_begin(namespace_decl* d)
27823 {return visit_begin(static_cast<decl_base*>(d));}
27824 
27825 bool
visit_end(namespace_decl * d)27826 ir_node_visitor::visit_end(namespace_decl* d)
27827 {return visit_end(static_cast<decl_base*>(d));}
27828 
27829 bool
visit_begin(qualified_type_def * t)27830 ir_node_visitor::visit_begin(qualified_type_def* t)
27831 {return visit_begin(static_cast<type_base*>(t));}
27832 
27833 bool
visit_end(qualified_type_def * t)27834 ir_node_visitor::visit_end(qualified_type_def* t)
27835 {return visit_end(static_cast<type_base*>(t));}
27836 
27837 bool
visit_begin(pointer_type_def * t)27838 ir_node_visitor::visit_begin(pointer_type_def* t)
27839 {return visit_begin(static_cast<type_base*>(t));}
27840 
27841 bool
visit_end(pointer_type_def * t)27842 ir_node_visitor::visit_end(pointer_type_def* t)
27843 {return visit_end(static_cast<type_base*>(t));}
27844 
27845 bool
visit_begin(reference_type_def * t)27846 ir_node_visitor::visit_begin(reference_type_def* t)
27847 {return visit_begin(static_cast<type_base*>(t));}
27848 
27849 bool
visit_end(reference_type_def * t)27850 ir_node_visitor::visit_end(reference_type_def* t)
27851 {return visit_end(static_cast<type_base*>(t));}
27852 
27853 bool
visit_begin(array_type_def * t)27854 ir_node_visitor::visit_begin(array_type_def* t)
27855 {return visit_begin(static_cast<type_base*>(t));}
27856 
27857 bool
visit_end(array_type_def * t)27858 ir_node_visitor::visit_end(array_type_def* t)
27859 {return visit_end(static_cast<type_base*>(t));}
27860 
27861 bool
visit_begin(array_type_def::subrange_type * t)27862 ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
27863 {return visit_begin(static_cast<type_base*>(t));}
27864 
27865 bool
visit_end(array_type_def::subrange_type * t)27866 ir_node_visitor::visit_end(array_type_def::subrange_type* t)
27867 {return visit_end(static_cast<type_base*>(t));}
27868 
27869 bool
visit_begin(enum_type_decl * t)27870 ir_node_visitor::visit_begin(enum_type_decl* t)
27871 {return visit_begin(static_cast<type_base*>(t));}
27872 
27873 bool
visit_end(enum_type_decl * t)27874 ir_node_visitor::visit_end(enum_type_decl* t)
27875 {return visit_end(static_cast<type_base*>(t));}
27876 
27877 bool
visit_begin(typedef_decl * t)27878 ir_node_visitor::visit_begin(typedef_decl* t)
27879 {return visit_begin(static_cast<type_base*>(t));}
27880 
27881 bool
visit_end(typedef_decl * t)27882 ir_node_visitor::visit_end(typedef_decl* t)
27883 {return visit_end(static_cast<type_base*>(t));}
27884 
27885 bool
visit_begin(function_type * t)27886 ir_node_visitor::visit_begin(function_type* t)
27887 {return visit_begin(static_cast<type_base*>(t));}
27888 
27889 bool
visit_end(function_type * t)27890 ir_node_visitor::visit_end(function_type* t)
27891 {return visit_end(static_cast<type_base*>(t));}
27892 
27893 bool
visit_begin(var_decl * d)27894 ir_node_visitor::visit_begin(var_decl* d)
27895 {return visit_begin(static_cast<decl_base*>(d));}
27896 
27897 bool
visit_end(var_decl * d)27898 ir_node_visitor::visit_end(var_decl* d)
27899 {return visit_end(static_cast<decl_base*>(d));}
27900 
27901 bool
visit_begin(function_decl * d)27902 ir_node_visitor::visit_begin(function_decl* d)
27903 {return visit_begin(static_cast<decl_base*>(d));}
27904 
27905 bool
visit_end(function_decl * d)27906 ir_node_visitor::visit_end(function_decl* d)
27907 {return visit_end(static_cast<decl_base*>(d));}
27908 
27909 bool
visit_begin(function_decl::parameter * d)27910 ir_node_visitor::visit_begin(function_decl::parameter* d)
27911 {return visit_begin(static_cast<decl_base*>(d));}
27912 
27913 bool
visit_end(function_decl::parameter * d)27914 ir_node_visitor::visit_end(function_decl::parameter* d)
27915 {return visit_end(static_cast<decl_base*>(d));}
27916 
27917 bool
visit_begin(function_tdecl * d)27918 ir_node_visitor::visit_begin(function_tdecl* d)
27919 {return visit_begin(static_cast<decl_base*>(d));}
27920 
27921 bool
visit_end(function_tdecl * d)27922 ir_node_visitor::visit_end(function_tdecl* d)
27923 {return visit_end(static_cast<decl_base*>(d));}
27924 
27925 bool
visit_begin(class_tdecl * d)27926 ir_node_visitor::visit_begin(class_tdecl* d)
27927 {return visit_begin(static_cast<decl_base*>(d));}
27928 
27929 bool
visit_end(class_tdecl * d)27930 ir_node_visitor::visit_end(class_tdecl* d)
27931 {return visit_end(static_cast<decl_base*>(d));}
27932 
27933 bool
visit_begin(class_or_union * t)27934 ir_node_visitor::visit_begin(class_or_union* t)
27935 {return visit_begin(static_cast<type_base*>(t));}
27936 
27937 bool
visit_end(class_or_union * t)27938 ir_node_visitor::visit_end(class_or_union* t)
27939 {return visit_end(static_cast<type_base*>(t));}
27940 
27941 bool
visit_begin(class_decl * t)27942 ir_node_visitor::visit_begin(class_decl* t)
27943 {return visit_begin(static_cast<type_base*>(t));}
27944 
27945 bool
visit_end(class_decl * t)27946 ir_node_visitor::visit_end(class_decl* t)
27947 {return visit_end(static_cast<type_base*>(t));}
27948 
27949 bool
visit_begin(union_decl * t)27950 ir_node_visitor::visit_begin(union_decl* t)
27951 {return visit_begin(static_cast<type_base*>(t));}
27952 
27953 bool
visit_end(union_decl * t)27954 ir_node_visitor::visit_end(union_decl* t)
27955 {return visit_end(static_cast<type_base*>(t));}
27956 
27957 bool
visit_begin(class_decl::base_spec * d)27958 ir_node_visitor::visit_begin(class_decl::base_spec* d)
27959 {return visit_begin(static_cast<decl_base*>(d));}
27960 
27961 bool
visit_end(class_decl::base_spec * d)27962 ir_node_visitor::visit_end(class_decl::base_spec* d)
27963 {return visit_end(static_cast<decl_base*>(d));}
27964 
27965 bool
visit_begin(member_function_template * d)27966 ir_node_visitor::visit_begin(member_function_template* d)
27967 {return visit_begin(static_cast<decl_base*>(d));}
27968 
27969 bool
visit_end(member_function_template * d)27970 ir_node_visitor::visit_end(member_function_template* d)
27971 {return visit_end(static_cast<decl_base*>(d));}
27972 
27973 bool
visit_begin(member_class_template * d)27974 ir_node_visitor::visit_begin(member_class_template* d)
27975 {return visit_begin(static_cast<decl_base*>(d));}
27976 
27977 bool
visit_end(member_class_template * d)27978 ir_node_visitor::visit_end(member_class_template* d)
27979 {return visit_end(static_cast<decl_base*>(d));}
27980 
27981 // </ir_node_visitor stuff>
27982 
27983 // <debugging facilities>
27984 
27985 /// Generate a different string at each invocation.
27986 ///
27987 /// @return the resulting string.
27988 static string
get_next_string()27989 get_next_string()
27990 {
27991   static __thread size_t counter;
27992   ++counter;
27993   std::ostringstream o;
27994   o << counter;
27995   return o.str();
27996 }
27997 
27998 /// Convenience typedef for a hash map of pointer to function_decl and
27999 /// string.
28000 typedef unordered_map<const function_decl*, string,
28001 		      function_decl::hash,
28002 		      function_decl::ptr_equal> fns_to_str_map_type;
28003 
28004 /// Return a string associated to a given function.  Two functions
28005 /// that compare equal would yield the same string, as far as this
28006 /// routine is concerned.  And two functions that are different would
28007 /// yield different strings.
28008 ///
28009 /// This is used to debug core diffing issues on functions.  The
28010 /// sequence of strings can be given to the 'testdiff2' program that
28011 /// is in the tests/ directory of the source tree, to reproduce core
28012 /// diffing issues on string and thus ease the debugging.
28013 ///
28014 /// @param fn the function to generate a string for.
28015 ///
28016 /// @param m the function_decl* <-> string map to be used by this
28017 /// function to generate strings associated to a function.
28018 ///
28019 /// @return the resulting string.
28020 static const string&
fn_to_str(const function_decl * fn,fns_to_str_map_type & m)28021 fn_to_str(const function_decl* fn,
28022 	  fns_to_str_map_type& m)
28023 {
28024   fns_to_str_map_type::const_iterator i = m.find(fn);
28025   if (i != m.end())
28026     return i->second;
28027   string s = get_next_string();
28028   return m[fn]= s;
28029 }
28030 
28031 /// Generate a sequence of string that matches a given sequence of
28032 /// function.  In the resulting sequence, each function is "uniquely
28033 /// representated" by a string.  For instance, if the same function "foo"
28034 /// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
28035 /// we don't care about the actual string) would appear at index 1 and 3.
28036 ///
28037 /// @param begin the beginning of the sequence of functions to consider.
28038 ///
28039 /// @param end the end of the sequence of functions.  This points to
28040 /// one-passed-the-end of the actual sequence.
28041 ///
28042 /// @param m the function_decl* <-> string map to be used by this
28043 /// function to generate strings associated to a function.
28044 ///
28045 /// @param o the output stream where to emit the generated list of
28046 /// strings to.
28047 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)28048 fns_to_str(vector<function_decl*>::const_iterator begin,
28049 	   vector<function_decl*>::const_iterator end,
28050 	   fns_to_str_map_type& m,
28051 	   std::ostream& o)
28052 {
28053   vector<function_decl*>::const_iterator i;
28054   for (i = begin; i != end; ++i)
28055     o << "'" << fn_to_str(*i, m) << "' ";
28056 }
28057 
28058 /// For each sequence of functions given in argument, generate a
28059 /// sequence of string that matches a given sequence of function.  In
28060 /// the resulting sequence, each function is "uniquely representated"
28061 /// by a string.  For instance, if the same function "foo" appears at
28062 /// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
28063 /// care about the actual string) would appear at index 1 and 3.
28064 ///
28065 /// @param a_begin the beginning of the sequence of functions to consider.
28066 ///
28067 /// @param a_end the end of the sequence of functions.  This points to
28068 /// one-passed-the-end of the actual sequence.
28069 ///
28070 /// @param b_begin the beginning of the second sequence of functions
28071 /// to consider.
28072 ///
28073 /// @param b_end the end of the second sequence of functions.
28074 ///
28075 /// @param m the function_decl* <-> string map to be used by this
28076 /// function to generate strings associated to a function.
28077 ///
28078 /// @param o the output stream where to emit the generated list of
28079 /// strings to.
28080 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)28081 fns_to_str(vector<function_decl*>::const_iterator a_begin,
28082 	   vector<function_decl*>::const_iterator a_end,
28083 	   vector<function_decl*>::const_iterator b_begin,
28084 	   vector<function_decl*>::const_iterator b_end,
28085 	   fns_to_str_map_type& m,
28086 	   std::ostream& o)
28087 {
28088   fns_to_str(a_begin, a_end, m, o);
28089   o << "->|<- ";
28090   fns_to_str(b_begin, b_end, m, o);
28091   o << "\n";
28092 }
28093 
28094 /// For each sequence of functions given in argument, generate a
28095 /// sequence of string that matches a given sequence of function.  In
28096 /// the resulting sequence, each function is "uniquely representated"
28097 /// by a string.  For instance, if the same function "foo" appears at
28098 /// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
28099 /// care about the actual string) would appear at index 1 and 3.
28100 ///
28101 /// @param a_begin the beginning of the sequence of functions to consider.
28102 ///
28103 /// @param a_end the end of the sequence of functions.  This points to
28104 /// one-passed-the-end of the actual sequence.
28105 ///
28106 /// @param b_begin the beginning of the second sequence of functions
28107 /// to consider.
28108 ///
28109 /// @param b_end the end of the second sequence of functions.
28110 ///
28111 /// @param o the output stream where to emit the generated list of
28112 /// strings to.
28113 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)28114 fns_to_str(vector<function_decl*>::const_iterator a_begin,
28115 	   vector<function_decl*>::const_iterator a_end,
28116 	   vector<function_decl*>::const_iterator b_begin,
28117 	   vector<function_decl*>::const_iterator b_end,
28118 	   std::ostream& o)
28119 {
28120   fns_to_str_map_type m;
28121   fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
28122 }
28123 
28124 // </debugging facilities>
28125 
28126 // </class template>
28127 
28128 }// end namespace ir
28129 }//end namespace abigail
28130 
28131 namespace
28132 {
28133 
28134 /// Update the qualified parent name, qualified name and scoped name
28135 /// of a tree decl node.
28136 ///
28137 /// @return true if the tree walking should continue, false otherwise.
28138 ///
28139 /// @param d the tree node to take in account.
28140 bool
do_update(abigail::ir::decl_base * d)28141 qualified_name_setter::do_update(abigail::ir::decl_base* d)
28142 {
28143   std::string parent_qualified_name;
28144   abigail::ir::scope_decl* parent = d->get_scope();
28145   if (parent)
28146     d->priv_->qualified_parent_name_ = parent->get_qualified_name();
28147   else
28148     d->priv_->qualified_parent_name_ = abigail::interned_string();
28149 
28150   const abigail::ir::environment& env = d->get_environment();
28151 
28152   if (!d->priv_->qualified_parent_name_.empty())
28153     {
28154       if (d->get_name().empty())
28155 	d->priv_->qualified_name_ = abigail::interned_string();
28156       else
28157 	{
28158 	  d->priv_->qualified_name_ =
28159 	    env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
28160 	  d->priv_->internal_qualified_name_ = env.intern(d->get_name());
28161 	}
28162     }
28163 
28164   if (d->priv_->scoped_name_.empty())
28165     {
28166       if (parent
28167 	  && !parent->get_is_anonymous()
28168 	  && !parent->get_name().empty())
28169 	d->priv_->scoped_name_ =
28170 	  env.intern(parent->get_name() + "::" + d->get_name());
28171       else
28172 	d->priv_->scoped_name_ =
28173 	  env.intern(d->get_name());
28174     }
28175 
28176   if (!is_scope_decl(d))
28177     return false;
28178 
28179   return true;
28180 }
28181 
28182 /// This is called when we start visiting a decl node, during the
28183 /// udpate of the qualified name of a given sub-tree.
28184 ///
28185 /// @param d the decl node we are visiting.
28186 ///
28187 /// @return true iff the traversal should keep going.
28188 bool
visit_begin(abigail::ir::decl_base * d)28189 qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
28190 {return do_update(d);}
28191 
28192 /// This is called when we start visiting a type node, during the
28193 /// udpate of the qualified name of a given sub-tree.
28194 ///
28195 /// @param d the decl node we are visiting.
28196 ///
28197 /// @return true iff the traversal should keep going.
28198 bool
visit_begin(abigail::ir::type_base * t)28199 qualified_name_setter::visit_begin(abigail::ir::type_base* t)
28200 {
28201   if (abigail::ir::decl_base* d = get_type_declaration(t))
28202     return do_update(d);
28203   return false;
28204 }
28205 }// end anonymous namespace.
28206