• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2013-2020 Red Hat, Inc.
5 //
6 // Author: Dodji Seketeli
7 
8 /// @file
9 ///
10 /// Types of the main internal representation of libabigail.
11 ///
12 /// This internal representation abstracts the artifacts that make up
13 /// an application binary interface.
14 
15 #ifndef __ABG_IR_H__
16 #define __ABG_IR_H__
17 
18 #include <assert.h>
19 #include <stdint.h>
20 #include <cstdlib>
21 #include <functional>
22 #include <set>
23 #include <unordered_map>
24 #include "abg-fwd.h"
25 #include "abg-hash.h"
26 #include "abg-traverse.h"
27 #include "abg-config.h"
28 
29 /// @file
30 ///
31 /// This file contains the declarations of the Internal Representation
32 /// of libabigail.
33 
34 /// @defgroup Memory Memory management
35 /// @{
36 ///
37 /// How objects' lifetime is handled in libabigail.
38 ///
39 /// For memory management and garbage collection of libabigail's IR
40 /// artifacts, we use std::shared_ptr and std::weak_ptr.
41 ///
42 /// When manipulating these IR artifacts, there are a few rules to keep in
43 /// mind.
44 ///
45 /// <b>The declaration for a type is owned by only one scope </b>
46 ///
47 /// This means that for each instance of abigail::type_base (a type) there
48 /// is an instance of abigail::scope_decl that owns a @ref
49 /// abigail::decl_base_sptr (a shared pointer to an abigail::decl_base)
50 /// that points to the declaration of that type.  The
51 /// abigail::type_base_sptr is added to the scope using the function
52 /// abigail::add_decl_to_scope().
53 ///
54 /// There is a kind of type that is usually not syntactically owned by
55 /// a scope: it's function type.  In libabigail, function types are
56 /// represented by abigail::function_type and abigail::method_type.
57 /// These types must be owned by the translation unit they originate
58 /// from.  Adding them to the translation unit must be done by a call
59 /// to the method function
60 /// abigail::translation::bind_function_type_life_time().
61 ///
62 /// <b> A declaration that has a type does NOT own the type </b>
63 ///
64 /// This means that, for instance, in an abigail::var_decl (a variable
65 /// declaration), the type of the declaration is not owned by the
66 /// declaration.  In other (concrete) words, the variable declaration
67 /// doesn't have a shared pointer to the type.  Rather, it has a *weak*
68 /// pointer to its type.  That means that it has a data member of type
69 /// abigail::type_base_wptr that contains the type of the declaration.
70 ///
71 /// But then abigail::var_decl::get_type() returns a shared pointer that
72 /// is constructed from the internal weak pointer to the type.  That way,
73 /// users of the type of the var can own a temporary reference on it and
74 /// be assured that the type's life time is long enough for their need.
75 ///
76 /// Likewise, data members, function and template parameters similarly
77 /// have weak pointers on their type.
78 ///
79 /// If, for a reason, you really need to keep a type alive for the
80 /// entire lifetime of the type system, then you can bind the life
81 /// time of that type to the life time of the @ref environment that is
82 /// supposed to outlive the type system.  You do that by passing the
83 /// type to the function environment::keep_type_alive().
84 ///
85 /// @}
86 
87 namespace abigail
88 {
89 
90 /// The namespace of the internal representation of ABI artifacts like
91 /// types and decls.
92 namespace ir
93 {
94 
95 // Inject some std types in here.
96 using std::unordered_map;
97 
98 /// A convenience typedef for an unordered set of pointer values
99 typedef unordered_set<uintptr_t> pointer_set;
100 
101 /// Functor to hash a canonical type by using its pointer value.
102 struct canonical_type_hash
103 {
104   size_t operator()(const type_base_sptr& l) const;
105   size_t operator()(const type_base *l) const;
106 }; //end struct canonical_type_hash
107 
108 /// Helper typedef for an unordered set of type_base_sptr which uses
109 /// pointer value to tell its members appart, because the members are
110 /// canonical types.
111 typedef unordered_set<type_base_sptr,
112 		      canonical_type_hash> canonical_type_sptr_set_type;
113 
114 /// Helper typedef for a vector of pointer to type_base.
115 typedef vector<type_base*> type_base_ptrs_type;
116 
117 /// Helper typedef for a vector of shared pointer to a type_base.
118 typedef vector<type_base_sptr> type_base_sptrs_type;
119 
120 /// This is an abstraction of the set of resources necessary to manage
121 /// several aspects of the internal representations of the Abigail
122 /// library.
123 ///
124 /// An environment can be seen as the boundaries in which all related
125 /// Abigail artifacts live.  So before doing anything using this
126 /// library, the first thing to create is, well, you know it now, an
127 /// environment.
128 ///
129 /// Note that the lifetime of environment objects must be longer than
130 /// the lifetime of any other type in the Abigail system.  So a given
131 /// instance of @ref environment must stay around as long as you are
132 /// using libabigail.  It's only when you are done using the library
133 /// that you can de-allocate the environment instance.
134 class environment
135 {
136 public:
137   struct priv;
138   std::unique_ptr<priv> priv_;
139 
140   /// A convenience typedef for a map of canonical types.  The key is
141   /// the pretty representation string of a particular type and the
142   /// value is the vector of canonical types that have the same pretty
143   /// representation string.
144   typedef std::unordered_map<string, std::vector<type_base_sptr> >
145       canonical_types_map_type;
146 
147   environment();
148 
149   virtual ~environment();
150 
151   canonical_types_map_type&
152   get_canonical_types_map();
153 
154   const canonical_types_map_type&
155   get_canonical_types_map() const;
156 
157   const type_base_sptr&
158   get_void_type() const;
159 
160   const type_base_sptr&
161   get_variadic_parameter_type() const;
162 
163   bool
164   canonicalization_is_done() const;
165 
166   void
167   canonicalization_is_done(bool);
168 
169   bool
170   do_on_the_fly_canonicalization() const;
171 
172   void
173   do_on_the_fly_canonicalization(bool f);
174 
175   bool
176   decl_only_class_equals_definition() const;
177 
178   void
179   decl_only_class_equals_definition(bool f) const;
180 
181   bool
182   use_enum_binary_only_equality() const;
183 
184   void
185   use_enum_binary_only_equality(bool f) const;
186 
187   bool
188   is_void_type(const type_base_sptr&) const;
189 
190   bool
191   is_void_type(const type_base*) const;
192 
193   bool
194   is_variadic_parameter_type(const type_base*) const;
195 
196   bool
197   is_variadic_parameter_type(const type_base_sptr&) const;
198 
199   interned_string
200   intern(const string&) const;
201 
202   const config&
203   get_config() const;
204 
205 #ifdef WITH_DEBUG_SELF_COMPARISON
206   void
207   set_self_comparison_debug_input(const corpus_sptr& corpus);
208 
209   void
210   get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
211 				   corpus_sptr& second_corpus);
212 
213   void
214   self_comparison_debug_is_on(bool);
215 
216   bool
217   self_comparison_debug_is_on() const;
218 #endif
219 
220 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
221   void
222   debug_type_canonicalization_is_on(bool flag);
223 
224   bool
225   debug_type_canonicalization_is_on() const;
226 #endif
227 
228   vector<type_base_sptr>* get_canonical_types(const char* name);
229 
230   type_base* get_canonical_type(const char* name, unsigned index);
231 
232 #ifdef WITH_DEBUG_SELF_COMPARISON
233   unordered_map<string, uintptr_t>&
234   get_type_id_canonical_type_map() const;
235 
236   unordered_map<uintptr_t, string>&
237   get_pointer_type_id_map();
238 
239   string
240   get_type_id_from_pointer(uintptr_t ptr);
241 
242   uintptr_t
243   get_canonical_type_from_type_id(const char*);
244 #endif
245 
246   friend class class_or_union;
247   friend class class_decl;
248   friend class function_type;
249 
250   friend void keep_type_alive(type_base_sptr);
251 }; // end class environment
252 
253 class location_manager;
254 /// @brief The source location of a token.
255 ///
256 /// This represents the location of a token coming from a given
257 /// translation unit.  This location is actually an abstraction of
258 /// cursor in the table of all the locations of all the tokens of the
259 /// translation unit.  That table is managed by the @ref location_manager
260 /// type.  To get the file path, line and column numbers associated to
261 /// a given instance of @ref location, you need to use the
262 /// location_manager::expand_location method.
263 class location
264 {
265   unsigned		value_;
266   // The location manager to use to decode the value above.  There is
267   // one location manager per translation unit, and the location
268   // manager's life time is managed by its translation unit.
269   location_manager*	loc_manager_;
270   // Whether the location is artificial.  Being artificial means that
271   // the location wasn't generated by the original emitter of the
272   // metadata (i.e, the compiler if the metadata is debug info).  For
273   // instance, implicit location derived from the position of XML
274   // elements in the abixml file is represented as artificial
275   // locations.
276   bool			is_artificial_;
277 
location(unsigned v,location_manager * m)278   location(unsigned v, location_manager* m)
279     : value_(v), loc_manager_(m), is_artificial_(false)
280   {}
281 
282   /// Get the location manager to use to decode the value of this
283   /// location.
284   ///
285   /// @return the location manager for the current location value.
286   location_manager*
get_location_manager()287   get_location_manager() const
288   {return loc_manager_;}
289 
290 public:
291 
292   /// Test if the location is artificial.
293   ///
294   /// Being artificial means that the location wasn't generated by the
295   /// original emitter of the metadata (i.e, the compiler if the
296   /// metadata is debug info).  For instance, the implicit location
297   /// derived from the position of a given XML element in the abixml
298   /// file is represented as artificial locations.  The same XML
299   /// element might carry a non-artificial (natural?) location that was
300   /// originally emitted by the compiler that generated the original
301   /// debug info the abixml file is derived from.
302   ///
303   /// @return true iff the location is artificial.
304   bool
get_is_artificial()305   get_is_artificial() const
306   {return is_artificial_;}
307 
308   /// Set the artificial-ness of the location.
309   ///
310   /// Being artificial means that the location wasn't generated by the
311   /// original emitter of the metadata (i.e, the compiler if the
312   /// metadata is debug info).  For instance, the implicit location
313   /// derived from the position of a given XML element in the abixml
314   /// file is represented as artificial locations.  The same XML
315   /// element might carry a non-artificial (natural?) location that
316   /// was originally emitted by the compiler that generated the
317   /// original debug info the abixml file is derived from.
318   ///
319   /// @param f the new artificial-ness state.
320   void
set_is_artificial(bool f)321   set_is_artificial(bool f)
322   {is_artificial_ = f;}
323 
324   /// Copy constructor of the location.
325   ///
326   /// @param l the location to copy from.
location(const location & l)327   location(const location& l)
328     : value_(l.value_),
329       loc_manager_(l.loc_manager_),
330       is_artificial_(l.is_artificial_)
331   {}
332 
333   /// Assignment operator of the location.
334   ///
335   /// @param l the location to assign to the current one.
336   location&
337   operator=(const location& l)
338   {
339     value_ = l.value_;
340     loc_manager_ = l.loc_manager_;
341     is_artificial_ = l.is_artificial_;
342     return *this;
343   }
344 
345   /// Default constructor for the @ref location type.
location()346   location()
347     : value_(), loc_manager_(), is_artificial_()
348   {}
349 
350   /// Get the value of the location.
351   unsigned
get_value()352   get_value() const
353   {return value_;}
354 
355   /// Convert the location into a boolean.
356   ///
357   /// @return true iff the value of the location is different from
358   /// zero.
359   operator bool() const
360   {return !!value_;}
361 
362   /// Equality operator of the @ref location type.
363   ///
364   /// @param other the other location to compare against.
365   ///
366   /// @return true iff both locations are equal.
367   bool
368   operator==(const location &other) const
369   {return value_ == other.value_;}
370 
371   /// "Less than" operator of the @ref location type.
372   ///
373   /// @parm other the other location type to compare against.
374   ///
375   /// @return true iff the current instance is less than the @p other
376   /// one.
377   bool
378   operator<(const location &other) const
379   {return value_ < other.value_;}
380 
381   /// Expand the current location into a tripplet file path, line and
382   /// column number.
383   ///
384   /// @param path the output parameter this function sets the expanded
385   /// path to.
386   ///
387   /// @param line the output parameter this function sets the expanded
388   /// line number to.
389   ///
390   /// @param column the output parameter this function sets the
391   /// expanded column number to.
392   void
393   expand(std::string& path, unsigned& line, unsigned& column) const;
394 
395   string
396   expand(void) const;
397 
398   friend class location_manager;
399 }; // end class location
400 
401 /// @brief The entry point to manage locations.
402 ///
403 /// This type keeps a table of all the locations for tokens of a
404 /// given translation unit.
405 class location_manager
406 {
407   struct priv;
408   std::unique_ptr<priv> priv_;
409 
410 public:
411 
412   location_manager();
413 
414   ~location_manager();
415 
416   location
417   create_new_location(const std::string& fle, size_t lne, size_t col);
418 
419   void
420   expand_location(const location& location, std::string& path,
421 		  unsigned& line, unsigned& column) const;
422 };
423 
424 /// The base of an entity of the intermediate representation that is
425 /// to be traversed.
426 struct ir_traversable_base : public traversable_base
427 {
428   /// Traverse a given IR node and its children, calling an visitor on
429   /// each node.
430   ///
431   /// @param v the visitor to call on each traversed node.
432   ///
433   /// @return true if the all the IR node tree was traversed.
434   virtual bool
435   traverse(ir_node_visitor& v);
436 }; // end class ir_traversable_base
437 
438 /// The hashing functor for using instances of @ref type_or_decl_base
439 /// as values in a hash map or set.
440 struct type_or_decl_hash
441 {
442 
443   /// Function-call Operator to hash the string representation of an
444   /// ABI artifact.
445   ///
446   /// @param artifact the ABI artifact to hash.
447   ///
448   /// @return the hash value of the string representation of @p
449   /// artifact.
450   size_t
operatortype_or_decl_hash451   operator()(const type_or_decl_base *artifact) const
452   {
453     string repr =  get_pretty_representation(artifact);
454     std::hash<string> do_hash;
455     return do_hash(repr);
456   }
457 
458   /// Function-call Operator to hash the string representation of an
459   /// ABI artifact.
460   ///
461   /// @param artifact the ABI artifact to hash.
462   ///
463   /// @return the hash value of the string representation of @p
464   /// artifact.
465   size_t
operatortype_or_decl_hash466   operator()(const type_or_decl_base_sptr& artifact) const
467   {return operator()(artifact.get());}
468 }; // end struct type_or_decl_hash
469 
470 /// The comparison functor for using instances of @ref
471 /// type_or_decl_base as values in a hash map or set.
472 struct type_or_decl_equal
473 {
474 
475   /// The function-call operator to compare the string representations
476   /// of two ABI artifacts.
477   ///
478   /// @param l the left hand side ABI artifact operand of the
479   /// comparison.
480   ///
481   /// @param r the right hand side ABI artifact operand of the
482   /// comparison.
483   ///
484   /// @return true iff the string representation of @p l equals the one
485   /// of @p r.
486   bool
operatortype_or_decl_equal487   operator()(const type_or_decl_base *l, const type_or_decl_base *r) const
488   {
489     string repr1 = get_pretty_representation(l);
490     string repr2 = get_pretty_representation(r);
491 
492     return repr1 == repr2;
493   }
494 
495   /// The function-call operator to compare the string representations
496   /// of two ABI artifacts.
497   ///
498   /// @param l the left hand side ABI artifact operand of the
499   /// comparison.
500   ///
501   /// @param r the right hand side ABI artifact operand of the
502   /// comparison.
503   ///
504   /// @return true iff the string representation of @p l equals the one
505   /// of @p r.
506   bool
operatortype_or_decl_equal507   operator()(const type_or_decl_base_sptr &l,
508 	     const type_or_decl_base_sptr &r) const
509   {return operator()(l.get(), r.get());}
510 }; // end type_or_decl_equal
511 
512 /// A convenience typedef for a hash set of type_or_decl_base_sptr
513 typedef unordered_set<type_or_decl_base_sptr,
514 		      type_or_decl_hash,
515 		      type_or_decl_equal> artifact_sptr_set_type;
516 
517 /// A convenience typedef for a hash set of const type_or_decl_base*
518 typedef unordered_set<const type_or_decl_base*,
519 		      type_or_decl_hash,
520 		      type_or_decl_equal> artifact_ptr_set_type;
521 
522 /// A convenience typedef for a map which key is a string and which
523 /// value is a @ref type_base_wptr.
524 typedef unordered_map<string, type_base_wptr> string_type_base_wptr_map_type;
525 
526 /// A convenience typedef for a map which key is an @ref
527 /// interned_string and which value is a @ref type_base_wptr.
528 typedef unordered_map<interned_string, type_base_wptr, hash_interned_string>
529 istring_type_base_wptr_map_type;
530 
531 /// A convenience typedef for a map which key is an @ref
532 /// interned_string and which value is a @ref type_base_wptr.
533 typedef unordered_map<interned_string,
534 		      type_or_decl_base_sptr,
535 		      hash_interned_string>
536 istring_type_or_decl_base_sptr_map_type;
537 
538 /// This is a type that aggregates maps of all the kinds of types that
539 /// are supported by libabigail.
540 ///
541 /// For instance, the type_maps contains a map of string to basic
542 /// type, a map of string to class type, a map of string to union
543 /// types, etc.  The key of a map entry is the pretty representation
544 /// of the type, and the value of the map entry is the type.
545 class type_maps
546 {
547   struct priv;
548   std::unique_ptr<priv> priv_;
549 
550 public:
551 
552   type_maps();
553 
554   ~type_maps();
555 
556   bool
557   empty() const;
558 
559   const istring_type_base_wptrs_map_type&
560   basic_types() const;
561 
562   istring_type_base_wptrs_map_type&
563   basic_types();
564 
565   const istring_type_base_wptrs_map_type&
566   class_types() const;
567 
568   istring_type_base_wptrs_map_type&
569   class_types();
570 
571   istring_type_base_wptrs_map_type&
572   union_types();
573 
574   const istring_type_base_wptrs_map_type&
575   union_types() const;
576 
577   istring_type_base_wptrs_map_type&
578   enum_types();
579 
580   const istring_type_base_wptrs_map_type&
581   enum_types() const;
582 
583   istring_type_base_wptrs_map_type&
584   typedef_types();
585 
586   const istring_type_base_wptrs_map_type&
587   typedef_types() const;
588 
589   istring_type_base_wptrs_map_type&
590   qualified_types();
591 
592   const istring_type_base_wptrs_map_type&
593   qualified_types() const;
594 
595   istring_type_base_wptrs_map_type&
596   pointer_types();
597 
598   const istring_type_base_wptrs_map_type&
599   pointer_types() const;
600 
601   istring_type_base_wptrs_map_type&
602   reference_types();
603 
604   const istring_type_base_wptrs_map_type&
605   reference_types() const;
606 
607   istring_type_base_wptrs_map_type&
608   array_types();
609 
610   const istring_type_base_wptrs_map_type&
611   array_types() const;
612 
613   const istring_type_base_wptrs_map_type&
614   subrange_types() const;
615 
616   istring_type_base_wptrs_map_type&
617   subrange_types();
618 
619   istring_type_base_wptrs_map_type&
620   function_types();
621 
622   const istring_type_base_wptrs_map_type&
623   function_types() const;
624 
625   const vector<type_base_wptr>&
626   get_types_sorted_by_name() const;
627 }; // end class type_maps;
628 
629 /// This is the abstraction of the set of relevant artefacts (types,
630 /// variable declarations, functions, templates, etc) bundled together
631 /// into a translation unit.
632 class translation_unit : public traversable_base
633 {
634   struct priv;
635   std::unique_ptr<priv> priv_;
636 
637   // Forbidden
638   translation_unit() = delete;
639 
640 public:
641   /// Convenience typedef for a shared pointer on a @ref global_scope.
642   typedef shared_ptr<scope_decl> global_scope_sptr;
643 
644   /// The language of the translation unit.
645   enum language
646   {
647     LANG_UNKNOWN = 0,
648     LANG_Cobol74,
649     LANG_Cobol85,
650     LANG_C89,
651     LANG_C99,
652     LANG_C11,
653     LANG_C,
654     LANG_C_plus_plus_03,
655     LANG_C_plus_plus_11,
656     LANG_C_plus_plus_14,
657     LANG_C_plus_plus,
658     LANG_ObjC,
659     LANG_ObjC_plus_plus,
660     LANG_Fortran77,
661     LANG_Fortran90,
662     LANG_Fortran95,
663     LANG_Ada83,
664     LANG_Ada95,
665     LANG_Pascal83,
666     LANG_Modula2,
667     LANG_Java,
668     LANG_PLI,
669     LANG_UPC,
670     LANG_D,
671     LANG_Python,
672     LANG_Go,
673     LANG_Rust,
674     LANG_Mips_Assembler
675   };
676 
677 public:
678   translation_unit(const ir::environment*	env,
679 		   const std::string&		path,
680 		   char			address_size = 0);
681 
682   virtual ~translation_unit();
683 
684   const environment*
685   get_environment() const;
686 
687   environment*
688   get_environment();
689 
690   void
691   set_environment(const environment*);
692 
693   language
694   get_language() const;
695 
696   void
697   set_language(language l);
698 
699   const std::string&
700   get_path() const;
701 
702   void
703   set_path(const string&);
704 
705   const std::string&
706   get_compilation_dir_path() const;
707 
708   void
709   set_compilation_dir_path(const std::string&);
710 
711   const std::string&
712   get_absolute_path() const;
713 
714   void
715   set_corpus(corpus*);
716 
717   const corpus*
718   get_corpus() const;
719 
720   corpus*
721   get_corpus();
722 
723   const scope_decl_sptr&
724   get_global_scope() const;
725 
726   scope_decl_sptr&
727   get_global_scope();
728 
729   const type_maps&
730   get_types() const;
731 
732   type_maps&
733   get_types();
734 
735   const vector<function_type_sptr>&
736   get_live_fn_types() const;
737 
738   location_manager&
739   get_loc_mgr();
740 
741   const location_manager&
742   get_loc_mgr() const;
743 
744   bool
745   is_empty() const;
746 
747   char
748   get_address_size() const;
749 
750   void
751   set_address_size(char);
752 
753   bool
754   is_constructed() const;
755 
756   void
757   set_is_constructed(bool);
758 
759   bool
760   operator==(const translation_unit&) const;
761 
762   bool
763   operator!=(const translation_unit&) const;
764 
765   void
766   bind_function_type_life_time(function_type_sptr) const;
767 
768   virtual bool
769   traverse(ir_node_visitor& v);
770 
771   friend function_type_sptr
772   lookup_function_type_in_translation_unit(const function_type& t,
773 					   const translation_unit& tu);
774 
775   friend function_type_sptr
776   synthesize_function_type_from_translation_unit(const function_type& fn_type,
777 						 translation_unit& tu);
778 
779   friend type_base_sptr
780   synthesize_type_from_translation_unit(const type_base_sptr& type,
781 					translation_unit& tu);
782 };//end class translation_unit
783 
784 /// A comparison functor to compare translation units based on their
785 /// absolute paths.
786 struct shared_translation_unit_comp
787 {
788   /// Compare two translations units based on their absolute paths.
789   ///
790   /// @param lhs the first translation unit to consider for the
791   /// comparison.
792   ///
793   /// @param rhs the second translatin unit to consider for the
794   /// comparison.
795   bool
operatorshared_translation_unit_comp796   operator()(const translation_unit_sptr& lhs,
797 	     const translation_unit_sptr& rhs) const
798   {return lhs->get_absolute_path() < rhs->get_absolute_path();}
799 }; // end struct shared_translation_unit_comp
800 
801 /// Convenience typedef for an ordered set of @ref
802 /// translation_unit_sptr.
803 typedef std::set<translation_unit_sptr,
804 		 shared_translation_unit_comp> translation_units;
805 
806 string
807 translation_unit_language_to_string(translation_unit::language);
808 
809 translation_unit::language
810 string_to_translation_unit_language(const string&);
811 
812 bool
813 is_c_language(translation_unit::language l);
814 
815 bool
816 is_cplus_plus_language(translation_unit::language l);
817 
818 bool
819 is_java_language(translation_unit::language l);
820 
821 bool
822 is_ada_language(translation_unit::language l);
823 
824 bool
825 operator==(const translation_unit_sptr&, const translation_unit_sptr&);
826 
827 bool
828 operator!=(const translation_unit_sptr&, const translation_unit_sptr&);
829 
830 /// Access specifier for class members.
831 enum access_specifier
832 {
833   no_access,
834   public_access,
835   protected_access,
836   private_access,
837 };
838 
839 class elf_symbol;
840 /// A convenience typedef for a shared pointer to elf_symbol.
841 typedef shared_ptr<elf_symbol> elf_symbol_sptr;
842 
843 /// A convenience typedef for a weak pointer to elf_symbol.
844 typedef weak_ptr<elf_symbol> elf_symbol_wptr;
845 
846 /// Convenience typedef for a map which key is a string and which
847 /// value if the elf symbol of the same name.
848 typedef std::unordered_map<string, elf_symbol_sptr>
849 string_elf_symbol_sptr_map_type;
850 
851 /// Convenience typedef for a shared pointer to an
852 /// string_elf_symbol_sptr_map_type.
853 typedef shared_ptr<string_elf_symbol_sptr_map_type>
854 string_elf_symbol_sptr_map_sptr;
855 
856 /// Convenience typedef for a vector of elf_symbol
857 typedef std::vector<elf_symbol_sptr> elf_symbols;
858 
859 /// Convenience typedef for a map which key is a string and which
860 /// value is a vector of elf_symbol.
861 typedef std::unordered_map<string, elf_symbols>
862 string_elf_symbols_map_type;
863 
864 /// Convenience typedef for a shared pointer to
865 /// string_elf_symbols_map_type.
866 typedef shared_ptr<string_elf_symbols_map_type> string_elf_symbols_map_sptr;
867 
868 /// Abstraction of an elf symbol.
869 ///
870 /// This is useful when a given corpus has been read from an ELF file.
871 /// In that case, a given decl might be associated to its underlying
872 /// ELF symbol, if that decl is publicly exported in the ELF file.  In
873 /// that case, comparing decls might involve comparing their
874 /// underlying symbols as well.
875 class elf_symbol
876 {
877 public:
878   /// The type of a symbol.
879   enum type
880   {
881     NOTYPE_TYPE = 0,
882     OBJECT_TYPE,
883     FUNC_TYPE,
884     SECTION_TYPE,
885     FILE_TYPE,
886     COMMON_TYPE,
887     TLS_TYPE,
888     GNU_IFUNC_TYPE
889   };
890 
891   /// The binding of a symbol.
892   enum binding
893   {
894     LOCAL_BINDING = 0,
895     GLOBAL_BINDING,
896     WEAK_BINDING,
897     GNU_UNIQUE_BINDING
898   };
899 
900   /// The visibility of the symbol.
901   enum visibility
902   {
903     DEFAULT_VISIBILITY,
904     PROTECTED_VISIBILITY,
905     HIDDEN_VISIBILITY,
906     INTERNAL_VISIBILITY,
907   };
908 
909   /// Inject the elf_symbol::version here.
910   class version;
911 
912 private:
913   struct priv;
914   std::unique_ptr<priv> priv_;
915 
916   elf_symbol();
917 
918   elf_symbol(const environment* e,
919 	     size_t		i,
920 	     size_t		s,
921 	     const string&	n,
922 	     type		t,
923 	     binding		b,
924 	     bool		d,
925 	     bool		c,
926 	     const version&	ve,
927 	     visibility		vi,
928 	     bool		is_in_ksymtab = false,
929 	     uint64_t		crc = 0,
930 	     bool		is_suppressed = false);
931 
932   elf_symbol(const elf_symbol&);
933 
934   elf_symbol&
935   operator=(const elf_symbol& s);
936 
937 public:
938 
939   static elf_symbol_sptr
940   create();
941 
942   static elf_symbol_sptr
943   create(const environment* e,
944 	 size_t		    i,
945 	 size_t		    s,
946 	 const string&	    n,
947 	 type		    t,
948 	 binding	    b,
949 	 bool		    d,
950 	 bool		    c,
951 	 const version&	    ve,
952 	 visibility	    vi,
953 	 bool		    is_in_ksymtab = false,
954 	 uint64_t	    crc = 0,
955 	 bool		    is_suppressed = false);
956 
957   const environment*
958   get_environment() const;
959 
960   void
961   set_environment(const environment*) const;
962 
963   size_t
964   get_index() const;
965 
966   void
967   set_index(size_t);
968 
969   const string&
970   get_name() const;
971 
972   void
973   set_name(const string& n);
974 
975   type
976   get_type() const;
977 
978   void
979   set_type(type t);
980 
981   size_t
982   get_size() const;
983 
984   void
985   set_size(size_t);
986 
987   binding
988   get_binding() const;
989 
990   void
991   set_binding(binding b);
992 
993   version&
994   get_version() const;
995 
996   void
997   set_version(const version& v);
998 
999   void
1000   set_visibility(visibility v);
1001 
1002   visibility
1003   get_visibility() const;
1004 
1005   bool
1006   is_defined() const;
1007 
1008   void
1009   is_defined(bool d);
1010 
1011   bool
1012   is_public() const;
1013 
1014   bool
1015   is_function() const;
1016 
1017   bool
1018   is_variable() const;
1019 
1020   bool
1021   is_in_ksymtab() const;
1022 
1023   void
1024   set_is_in_ksymtab(bool is_in_ksymtab);
1025 
1026   uint64_t
1027   get_crc() const;
1028 
1029   void
1030   set_crc(uint64_t crc);
1031 
1032   bool
1033   is_suppressed() const;
1034 
1035   void
1036   set_is_suppressed(bool is_suppressed);
1037 
1038   const elf_symbol_sptr
1039   get_main_symbol() const;
1040 
1041   elf_symbol_sptr
1042   get_main_symbol();
1043 
1044   bool
1045   is_main_symbol() const;
1046 
1047   elf_symbol_sptr
1048   update_main_symbol(const std::string&);
1049 
1050   elf_symbol_sptr
1051   get_next_alias() const;
1052 
1053   bool
1054   has_aliases() const;
1055 
1056   int
1057   get_number_of_aliases() const;
1058 
1059   void
1060   add_alias(const elf_symbol_sptr&);
1061 
1062   bool
1063   is_common_symbol() const;
1064 
1065   bool
1066   has_other_common_instances() const;
1067 
1068   elf_symbol_sptr
1069   get_next_common_instance() const;
1070 
1071   void
1072   add_common_instance(const elf_symbol_sptr&);
1073 
1074   const string&
1075   get_id_string() const;
1076 
1077   elf_symbol_sptr
1078   get_alias_from_name(const string& name) const;
1079 
1080   elf_symbol_sptr
1081   get_alias_which_equals(const elf_symbol& other) const;
1082 
1083   string
1084   get_aliases_id_string(const string_elf_symbols_map_type& symtab,
1085 			bool include_symbol_itself = true) const;
1086 
1087   string
1088   get_aliases_id_string(bool include_symbol_itself = true) const;
1089 
1090   static bool
1091   get_name_and_version_from_id(const string& id,
1092 			       string& name,
1093 			       string& ver);
1094 
1095   bool
1096   operator==(const elf_symbol&) const;
1097 
1098   bool
1099   does_alias(const elf_symbol&) const;
1100 }; // end class elf_symbol.
1101 
1102 std::ostream&
1103 operator<<(std::ostream& o, elf_symbol::type t);
1104 
1105 std::ostream&
1106 operator<<(std::ostream& o, elf_symbol::binding t);
1107 
1108 std::ostream&
1109 operator<<(std::ostream& o, elf_symbol::visibility t);
1110 
1111 bool
1112 string_to_elf_symbol_type(const string&, elf_symbol::type&);
1113 
1114 bool
1115 string_to_elf_symbol_binding(const string&, elf_symbol::binding&);
1116 
1117 bool
1118 string_to_elf_symbol_visibility(const string&, elf_symbol::visibility&);
1119 
1120 bool
1121 elf_symbol_is_function(elf_symbol::type);
1122 
1123 bool
1124 elf_symbol_is_variable(elf_symbol::type);
1125 
1126 bool
1127 operator==(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs);
1128 
1129 bool
1130 operator!=(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs);
1131 
1132 bool
1133 elf_symbols_alias(const elf_symbol& s1, const elf_symbol& s2);
1134 
1135 void
1136 compute_aliases_for_elf_symbol(const elf_symbol& symbol,
1137 			       const string_elf_symbols_map_type& symtab,
1138 			       vector<elf_symbol_sptr>& alias_set);
1139 
1140 /// The abstraction of the version of an ELF symbol.
1141 class elf_symbol::version
1142 {
1143   struct priv;
1144   std::unique_ptr<priv> priv_;
1145 
1146 public:
1147   version();
1148 
1149   version(const string& v,
1150 	  bool is_default);
1151 
1152   version(const version& v);
1153 
1154   ~version();
1155 
1156   operator const string&() const;
1157 
1158   const string&
1159   str() const;
1160 
1161   void
1162   str(const string& s);
1163 
1164   bool
1165   is_default() const;
1166 
1167   void
1168   is_default(bool f);
1169 
1170   bool
1171   is_empty() const;
1172 
1173   bool
1174   operator==(const version& o) const;
1175 
1176   bool
1177   operator!=(const version& o) const;
1178 
1179   version&
1180   operator=(const version& o);
1181 };// end class elf_symbol::version
1182 
1183 class context_rel;
1184 /// A convenience typedef for shared pointers to @ref context_rel
1185 typedef shared_ptr<context_rel> context_rel_sptr;
1186 
1187 /// The abstraction of the relationship between an entity and its
1188 /// containing scope (its context).  That relationship can carry
1189 /// properties like access rights (if the parent is a class_decl),
1190 /// etc.
1191 ///
1192 /// But importantly, this relationship carries a pointer to the
1193 /// actualy parent.
1194 class context_rel
1195 {
1196 protected:
1197   scope_decl*		scope_;
1198   enum access_specifier access_;
1199   bool			is_static_;
1200 
1201 public:
context_rel()1202   context_rel()
1203     : scope_(0),
1204       access_(no_access),
1205       is_static_(false)
1206   {}
1207 
context_rel(scope_decl * s)1208   context_rel(scope_decl* s)
1209     : scope_(s),
1210       access_(no_access),
1211       is_static_(false)
1212   {}
1213 
context_rel(scope_decl * s,access_specifier a,bool f)1214   context_rel(scope_decl* s,
1215 	      access_specifier a,
1216 	      bool f)
1217     : scope_(s),
1218       access_(a),
1219       is_static_(f)
1220   {}
1221 
1222   scope_decl*
get_scope()1223   get_scope() const
1224   {return scope_;}
1225 
1226   access_specifier
get_access_specifier()1227   get_access_specifier() const
1228   {return access_;}
1229 
1230   void
set_access_specifier(access_specifier a)1231   set_access_specifier(access_specifier a)
1232   {access_ = a;}
1233 
1234   bool
get_is_static()1235   get_is_static() const
1236   {return is_static_;}
1237 
1238   void
set_is_static(bool s)1239   set_is_static(bool s)
1240   {is_static_ = s;}
1241 
1242   void
set_scope(scope_decl * s)1243   set_scope(scope_decl* s)
1244   {scope_ = s;}
1245 
1246   bool
1247   operator==(const context_rel& o)const
1248   {
1249     return (access_ == o.access_
1250 	    && is_static_ == o.is_static_);
1251   }
1252 
1253   /// Inequality operator.
1254   ///
1255   /// @param o the other instance of @ref context_rel to compare the
1256   /// current instance against.
1257   ///
1258   /// @return true iff the current instance of @ref context_rel is
1259   /// different from @p o.
1260   bool
1261   operator!=(const context_rel& o) const
1262   {return !operator==(o);}
1263 
1264   virtual ~context_rel();
1265 };// end class context_rel
1266 
1267 /// A bitfield that gives callers of abigail::ir::equals() some
1268 /// insight about how different two internal representation artifacts
1269 /// are.
1270 enum change_kind
1271 {
1272   NO_CHANGE_KIND = 0,
1273 
1274   /// This means that a given IR artifact has a local type change.
1275   LOCAL_TYPE_CHANGE_KIND = 1 << 0,
1276 
1277   /// This means that a given IR artifact has a local non-type change.
1278   /// That is a change that is carried by the artifact itself, not by
1279   /// its type.
1280   LOCAL_NON_TYPE_CHANGE_KIND = 1 << 1,
1281 
1282   /// Testing (anding) against this mask means that a given IR artifact has
1283   /// local differences, with respect to the other artifact it was compared
1284   /// against. A local change is a change that is carried by the artifact
1285   /// itself (or its type), rather than by one off its sub-types.
1286   ALL_LOCAL_CHANGES_MASK = LOCAL_TYPE_CHANGE_KIND | LOCAL_NON_TYPE_CHANGE_KIND,
1287 
1288   /// This means that a given IR artifact has changes in some of its
1289   /// sub-types, with respect to the other artifact it was compared
1290   /// against.
1291   SUBTYPE_CHANGE_KIND = 1 << 2,
1292 };// end enum change_kind
1293 
1294 change_kind
1295 operator|(change_kind, change_kind);
1296 
1297 change_kind
1298 operator&(change_kind, change_kind);
1299 
1300 change_kind&
1301 operator|=(change_kind&, change_kind);
1302 
1303 change_kind&
1304 operator&=(change_kind&, change_kind);
1305 
1306 bool
1307 maybe_compare_as_member_decls(const decl_base& l,
1308 			      const decl_base& r,
1309 			      change_kind* k);
1310 
1311 bool
1312 equals(const decl_base&, const decl_base&, change_kind*);
1313 
1314 /// The base class of both types and declarations.
1315 class type_or_decl_base : public ir_traversable_base
1316 {
1317   struct priv;
1318   mutable std::unique_ptr<priv> priv_;
1319 
1320   type_or_decl_base();
1321 
1322 protected:
1323 
1324   /// This is a bitmap type which instance is meant to contain the
1325   /// runtime type of a given ABI artifact.  Bits of the identifiers
1326   /// of the type of a given artifact as well as the types it inherits
1327   /// from are to be set to 1.
1328   enum type_or_decl_kind
1329   {
1330     ABSTRACT_TYPE_OR_DECL,
1331     ABSTRACT_DECL_BASE = 1,
1332     ABSTRACT_SCOPE_DECL = 1 << 1,
1333     GLOBAL_SCOPE_DECL = 1 << 2,
1334     NAMESPACE_DECL = 1 << 3,
1335     VAR_DECL = 1 << 4,
1336     FUNCTION_DECL = 1 << 5,
1337     FUNCTION_PARAMETER_DECL = 1 << 6,
1338     METHOD_DECL = 1 << 7,
1339     TEMPLATE_DECL = 1 << 8,
1340     ABSTRACT_TYPE_BASE = 1 << 9,
1341     ABSTRACT_SCOPE_TYPE_DECL = 1 << 10,
1342     BASIC_TYPE = 1 << 11,
1343     QUALIFIED_TYPE = 1 << 12,
1344     POINTER_TYPE = 1 << 13,
1345     REFERENCE_TYPE = 1 << 14,
1346     ARRAY_TYPE = 1 << 15,
1347     ENUM_TYPE = 1 << 16,
1348     TYPEDEF_TYPE = 1 << 17,
1349     CLASS_TYPE = 1 << 18,
1350     UNION_TYPE = 1 << 19,
1351     FUNCTION_TYPE = 1 << 20,
1352     METHOD_TYPE = 1 << 21,
1353   }; // end enum type_or_decl_kind
1354 
1355   enum type_or_decl_kind
1356   kind() const;
1357 
1358   void
1359   kind(enum type_or_decl_kind);
1360 
1361   const void*
1362   runtime_type_instance() const;
1363 
1364   void*
1365   runtime_type_instance();
1366 
1367   void
1368   runtime_type_instance(void*);
1369 
1370   const void*
1371   type_or_decl_base_pointer() const;
1372 
1373   void*
1374   type_or_decl_base_pointer();
1375 
1376   bool hashing_started() const;
1377 
1378   void hashing_started(bool) const;
1379 
1380 public:
1381 
1382   type_or_decl_base(const environment*,
1383 		    enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL);
1384 
1385   type_or_decl_base(const type_or_decl_base&);
1386 
1387   virtual ~type_or_decl_base();
1388 
1389   bool
1390   get_is_artificial() const;
1391 
1392   void
1393   set_is_artificial(bool);
1394 
1395   const environment*
1396   get_environment() const;
1397 
1398   environment*
1399   get_environment();
1400 
1401   void
1402   set_environment(const environment*);
1403 
1404   void
1405   set_artificial_location(const location &);
1406 
1407   location&
1408   get_artificial_location() const;
1409 
1410   bool
1411   has_artificial_location() const;
1412 
1413   const corpus*
1414   get_corpus() const;
1415 
1416   corpus*
1417   get_corpus();
1418 
1419   void
1420   set_translation_unit(translation_unit*);
1421 
1422   const translation_unit*
1423   get_translation_unit() const;
1424 
1425   translation_unit*
1426   get_translation_unit();
1427 
1428   type_or_decl_base&
1429   operator=(const type_or_decl_base&);
1430 
1431   virtual bool
1432   traverse(ir_node_visitor&);
1433 
1434   virtual string
1435   get_pretty_representation(bool internal = false,
1436 			    bool qualified_name = true) const = 0;
1437 
1438   friend type_or_decl_base::type_or_decl_kind
1439   operator|(type_or_decl_base::type_or_decl_kind,
1440 	    type_or_decl_base::type_or_decl_kind);
1441 
1442   friend type_or_decl_base::type_or_decl_kind&
1443   operator|=(type_or_decl_base::type_or_decl_kind&,
1444 	     type_or_decl_base::type_or_decl_kind);
1445 
1446   friend type_or_decl_base::type_or_decl_kind
1447   operator&(type_or_decl_base::type_or_decl_kind,
1448 	    type_or_decl_base::type_or_decl_kind);
1449 
1450   friend type_or_decl_base::type_or_decl_kind&
1451   operator&=(type_or_decl_base::type_or_decl_kind&,
1452 	     type_or_decl_base::type_or_decl_kind);
1453 
1454   friend class_decl*
1455   is_class_type(const type_or_decl_base*);
1456 
1457   friend pointer_type_def*
1458   is_pointer_type(type_or_decl_base*);
1459 
1460   friend type_base*
1461   is_type(const type_or_decl_base*);
1462 
1463   friend decl_base*
1464   is_decl(const type_or_decl_base* d);
1465 }; // end class type_or_decl_base
1466 
1467 type_or_decl_base::type_or_decl_kind
1468 operator|(type_or_decl_base::type_or_decl_kind,
1469 	  type_or_decl_base::type_or_decl_kind);
1470 
1471 type_or_decl_base::type_or_decl_kind&
1472 operator|=(type_or_decl_base::type_or_decl_kind&,
1473 	   type_or_decl_base::type_or_decl_kind);
1474 
1475 type_or_decl_base::type_or_decl_kind
1476 operator&(type_or_decl_base::type_or_decl_kind,
1477 	  type_or_decl_base::type_or_decl_kind);
1478 
1479 type_or_decl_base::type_or_decl_kind&
1480 operator&=(type_or_decl_base::type_or_decl_kind&,
1481 	   type_or_decl_base::type_or_decl_kind);
1482 
1483 bool
1484 operator==(const type_or_decl_base&, const type_or_decl_base&);
1485 
1486 bool
1487 operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&);
1488 
1489 bool
1490 operator!=(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&);
1491 
1492 void
1493 set_environment_for_artifact(type_or_decl_base* artifact,
1494 			     const environment* env);
1495 
1496 void
1497 set_environment_for_artifact(type_or_decl_base_sptr artifact,
1498 			     const environment* env);
1499 
1500 /// The base type of all declarations.
1501 class decl_base : public virtual type_or_decl_base
1502 {
1503   // Forbidden
1504   decl_base();
1505 
1506   struct priv;
1507 
1508 protected:
1509 
1510   const interned_string&
1511   peek_qualified_name() const;
1512 
1513   void
1514   clear_qualified_name();
1515 
1516   void
1517   set_qualified_name(const interned_string&) const;
1518 
1519   const interned_string&
1520   peek_temporary_qualified_name() const;
1521 
1522   void
1523   set_temporary_qualified_name(const interned_string&) const;
1524 
1525 public:
1526   // This is public because some internals of the library need to
1527   // update it.  But it's opaque to client code anyway, so no big
1528   // deal.  Also, it's not handled by a shared_ptr because accessing
1529   // the data members of the priv struct for this decl_base shows up
1530   // on performance profiles when dealing with big binaries with a lot
1531   // of types; dereferencing the shared_ptr involves locking of some
1532   // sort and that is slower than just dereferencing a pointer likere
1533   // here.  There are other types for which the priv pointer is
1534   // managed using shared_ptr just fine, because those didn't show up
1535   // during our performance profiling.
1536   priv* priv_;
1537 
1538   /// Facility to hash instances of decl_base.
1539   struct hash;
1540 
1541   /// ELF visibility
1542   enum visibility
1543   {
1544     VISIBILITY_NONE,
1545     VISIBILITY_DEFAULT,
1546     VISIBILITY_PROTECTED,
1547     VISIBILITY_HIDDEN,
1548     VISIBILITY_INTERNAL
1549   };
1550 
1551   /// ELF binding
1552   enum binding
1553   {
1554     BINDING_NONE,
1555     BINDING_LOCAL,
1556     BINDING_GLOBAL,
1557     BINDING_WEAK
1558   };
1559 
1560   virtual void
1561   set_scope(scope_decl*);
1562 
1563 protected:
1564   const context_rel*
1565   get_context_rel() const;
1566 
1567   context_rel*
1568   get_context_rel();
1569 
1570   void
1571   set_context_rel(context_rel *c);
1572 
1573 public:
1574   decl_base(const environment* e,
1575 	    const string& name,
1576 	    const location& locus,
1577 	    const string& mangled_name = "",
1578 	    visibility vis = VISIBILITY_DEFAULT);
1579 
1580   decl_base(const environment* e,
1581 	    const interned_string& name,
1582 	    const location& locus,
1583 	    const interned_string& mangled_name = interned_string(),
1584 	    visibility vis = VISIBILITY_DEFAULT);
1585 
1586   decl_base(const environment*, const location&);
1587 
1588   decl_base(const decl_base&);
1589 
1590   virtual bool
1591   operator==(const decl_base&) const;
1592 
1593   virtual bool
1594   operator!=(const decl_base&) const;
1595 
1596   virtual bool
1597   traverse(ir_node_visitor& v);
1598 
1599   virtual ~decl_base();
1600 
1601   virtual size_t
1602   get_hash() const;
1603 
1604   virtual string
1605   get_pretty_representation(bool internal = false,
1606 			    bool qualified_name = true) const;
1607 
1608   virtual void
1609   get_qualified_name(interned_string& qualified_name,
1610 		     bool internal = false) const;
1611 
1612   virtual const interned_string&
1613   get_qualified_name(bool internal = false) const;
1614 
1615   virtual const interned_string&
1616   get_scoped_name() const;
1617 
1618   bool
1619   get_is_in_public_symbol_table() const;
1620 
1621   void
1622   set_is_in_public_symbol_table(bool);
1623 
1624   const location&
1625   get_location() const;
1626 
1627   void
1628   set_location(const location& l);
1629 
1630   const interned_string&
1631   get_name() const;
1632 
1633   const interned_string&
1634   get_qualified_parent_name() const;
1635 
1636   void
1637   set_name(const string& n);
1638 
1639   bool
1640   get_is_anonymous() const;
1641 
1642   void
1643   set_is_anonymous(bool);
1644 
1645   bool
1646   get_has_anonymous_parent() const;
1647 
1648   bool
1649   get_is_anonymous_or_has_anonymous_parent() const;
1650 
1651   typedef_decl_sptr
1652   get_naming_typedef() const;
1653 
1654   void
1655   set_naming_typedef(const typedef_decl_sptr&);
1656 
1657   const interned_string&
1658   get_linkage_name() const;
1659 
1660   virtual void
1661   set_linkage_name(const string& m);
1662 
1663   scope_decl*
1664   get_scope() const;
1665 
1666   visibility
1667   get_visibility() const;
1668 
1669   void
1670   set_visibility(visibility v);
1671 
1672   const decl_base_sptr
1673   get_earlier_declaration() const;
1674 
1675   void
1676   set_earlier_declaration(const decl_base_sptr&);
1677 
1678   const decl_base_sptr
1679   get_definition_of_declaration() const;
1680 
1681   void
1682   set_definition_of_declaration(const decl_base_sptr&);
1683 
1684   const decl_base*
1685   get_naked_definition_of_declaration() const;
1686 
1687   bool
1688   get_is_declaration_only() const;
1689 
1690   void
1691   set_is_declaration_only(bool f);
1692 
1693   friend type_base_sptr
1694   canonicalize(type_base_sptr);
1695 
1696   friend bool
1697   equals(const decl_base&, const decl_base&, change_kind*);
1698 
1699   friend bool
1700   equals(const var_decl&, const var_decl&, change_kind*);
1701 
1702   friend bool
1703   maybe_compare_as_member_decls(const decl_base& l,
1704 				const decl_base& r,
1705 				change_kind* k);
1706 
1707   friend decl_base_sptr
1708   add_decl_to_scope(decl_base_sptr decl, scope_decl* scpe);
1709 
1710   friend void
1711   remove_decl_from_scope(decl_base_sptr);
1712 
1713   friend decl_base_sptr
1714   insert_decl_into_scope(decl_base_sptr,
1715 			 vector<shared_ptr<decl_base> >::iterator,
1716 			 scope_decl*);
1717 
1718   friend enum access_specifier
1719   get_member_access_specifier(const decl_base& d);
1720 
1721   friend enum access_specifier
1722   get_member_access_specifier(const decl_base_sptr& d);
1723 
1724   friend void
1725   set_member_access_specifier(decl_base& d,
1726 			      access_specifier a);
1727 
1728   friend bool
1729   get_member_is_static(const decl_base& d);
1730 
1731   friend bool
1732   get_member_is_static(const decl_base_sptr& d);
1733 
1734   friend void
1735   set_member_is_static(const decl_base_sptr& d, bool s);
1736 
1737   friend void
1738   set_member_is_static(decl_base& d, bool s);
1739 
1740   friend bool
1741   get_member_function_is_virtual(const function_decl& f);
1742 
1743   friend void
1744   set_member_function_is_virtual(function_decl&, bool);
1745 
1746   friend class class_or_union;
1747   friend class class_decl;
1748   friend class scope_decl;
1749 };// end class decl_base
1750 
1751 bool
1752 operator==(const decl_base_sptr&, const decl_base_sptr&);
1753 
1754 bool
1755 operator!=(const decl_base_sptr&, const decl_base_sptr&);
1756 
1757 bool
1758 operator==(const type_base_sptr&, const type_base_sptr&);
1759 
1760 bool
1761 operator!=(const type_base_sptr&, const type_base_sptr&);
1762 
1763 std::ostream&
1764 operator<<(std::ostream&, decl_base::visibility);
1765 
1766 std::ostream&
1767 operator<<(std::ostream&, decl_base::binding);
1768 
1769 bool
1770 equals(const scope_decl&, const scope_decl&, change_kind*);
1771 
1772 /// A declaration that introduces a scope.
1773 class scope_decl : public virtual decl_base
1774 {
1775   struct priv;
1776   std::unique_ptr<priv> priv_;
1777 
1778 public:
1779 
1780   /// Convenience typedef for a vector of @ref decl_base_sptr.
1781   typedef std::vector<decl_base_sptr >	declarations;
1782   /// Convenience typedef for a vector of @ref function_type_sptr.
1783   typedef std::vector<function_type_sptr >	function_types;
1784   /// Convenience typedef for a vector of @ref scope_decl_sptr.
1785   typedef std::vector<scope_decl_sptr>	scopes;
1786 
1787   scope_decl();
1788 
1789 protected:
1790   virtual decl_base_sptr
1791   add_member_decl(const decl_base_sptr& member);
1792 
1793   virtual decl_base_sptr
1794   insert_member_decl(decl_base_sptr member, declarations::iterator before);
1795 
1796   virtual void
1797   remove_member_decl(decl_base_sptr member);
1798 
1799 public:
1800   struct hash;
1801 
1802   scope_decl(const environment* env,
1803 	     const string& name, const location& locus,
1804 	     visibility	vis = VISIBILITY_DEFAULT);
1805 
1806   scope_decl(const environment* env, location& l);
1807 
1808   virtual size_t
1809   get_hash() const;
1810 
1811   virtual bool
1812   operator==(const decl_base&) const;
1813 
1814   const canonical_type_sptr_set_type&
1815   get_canonical_types() const;
1816 
1817   canonical_type_sptr_set_type&
1818   get_canonical_types();
1819 
1820   const type_base_sptrs_type&
1821   get_sorted_canonical_types() const;
1822 
1823   const declarations&
1824   get_member_decls() const;
1825 
1826   declarations&
1827   get_member_decls();
1828 
1829   const declarations&
1830   get_sorted_member_decls() const;
1831 
1832   virtual size_t
1833   get_num_anonymous_member_classes() const;
1834 
1835   virtual size_t
1836   get_num_anonymous_member_unions() const;
1837 
1838   virtual size_t
1839   get_num_anonymous_member_enums() const;
1840 
1841   scopes&
1842   get_member_scopes();
1843 
1844   const scopes&
1845   get_member_scopes() const;
1846 
1847   bool
1848   is_empty() const;
1849 
1850   bool
1851   find_iterator_for_member(const decl_base*, declarations::iterator&);
1852 
1853   bool
1854   find_iterator_for_member(const decl_base_sptr, declarations::iterator&);
1855 
1856   virtual bool
1857   traverse(ir_node_visitor&);
1858 
1859   virtual ~scope_decl();
1860 
1861   friend decl_base_sptr
1862   add_decl_to_scope(decl_base_sptr decl, scope_decl* scope);
1863 
1864   friend decl_base_sptr
1865   insert_decl_into_scope(decl_base_sptr decl,
1866 			 scope_decl::declarations::iterator before,
1867 			 scope_decl* scope);
1868 
1869   friend void
1870   remove_decl_from_scope(decl_base_sptr decl);
1871 
1872   friend type_base_sptr
1873   canonicalize(type_base_sptr);
1874 };//end class scope_decl
1875 
1876 bool
1877 operator==(const scope_decl_sptr&, const scope_decl_sptr&);
1878 
1879 bool
1880 operator!=(const scope_decl_sptr&, const scope_decl_sptr&);
1881 
1882 /// Hasher for the @ref scope_decl type.
1883 struct scope_decl::hash
1884 {
1885   size_t
1886   operator()(const scope_decl& d) const;
1887 
1888   size_t
1889   operator()(const scope_decl* d) const;
1890 };
1891 
1892 /// This abstracts the global scope of a given translation unit.
1893 ///
1894 /// Only one instance of this class must be present in a given
1895 /// translation_unit.  That instance is implicitely created the first
1896 /// time translatin_unit::get_global_scope is invoked.
1897 class global_scope : public scope_decl
1898 {
1899   translation_unit* translation_unit_;
1900 
1901   global_scope(translation_unit *tu);
1902 
1903 public:
1904 
1905   friend class translation_unit;
1906 
1907   translation_unit*
get_translation_unit()1908   get_translation_unit() const
1909   {return translation_unit_;}
1910 
1911   virtual ~global_scope();
1912 };
1913 
1914 bool
1915 equals(const type_base&, const type_base&, change_kind*);
1916 
1917 /// An abstraction helper for type declarations
1918 class type_base : public virtual type_or_decl_base
1919 {
1920   struct priv;
1921 
1922 public:
1923   // This priv pointer is not handled by a shared_ptr because
1924   // accessing the data members of the priv struct for this type_base
1925   // shows up on performance profiles when dealing with big binaries
1926   // with a lot of types; dereferencing the shared_ptr involves
1927   // locking of some sort and that is slower than just dereferencing a
1928   // pointer likere here.  There are other types for which the priv
1929   // pointer is managed using shared_ptr just fine, because those
1930   // didn't show up during our performance profiling.
1931   priv* priv_;
1932 
1933 private:
1934   // Forbid this.
1935   type_base();
1936 
1937   static type_base_sptr
1938   get_canonical_type_for(type_base_sptr);
1939 
1940 protected:
1941   virtual void
1942   on_canonical_type_set();
1943 
1944 public:
1945 
1946   /// A hasher for type_base types.
1947   struct hash;
1948 
1949   /// A hasher for types.  It gets the dynamic type of the current
1950   /// instance of type and hashes it accordingly.  Note that the hashing
1951   /// function of this hasher must be updated each time a new kind of
1952   /// type is added to the IR.
1953   struct dynamic_hash;
1954 
1955   /// A hasher for shared_ptr<type_base> that will hash it based on the
1956   /// runtime type of the type pointed to.
1957   struct shared_ptr_hash;
1958 
1959   type_base(const environment* e, size_t s, size_t a);
1960 
1961   friend type_base_sptr canonicalize(type_base_sptr);
1962 
1963   type_base_sptr
1964   get_canonical_type() const;
1965 
1966   type_base*
1967   get_naked_canonical_type() const;
1968 
1969   const interned_string&
1970   get_cached_pretty_representation(bool internal = false) const;
1971 
1972   virtual bool
1973   operator==(const type_base&) const;
1974 
1975   virtual bool
1976   operator!=(const type_base&) const;
1977 
1978   virtual bool
1979   traverse(ir_node_visitor&);
1980 
1981   virtual ~type_base();
1982 
1983   virtual void
1984   set_size_in_bits(size_t);
1985 
1986   virtual size_t
1987   get_size_in_bits() const;
1988 
1989   virtual void
1990   set_alignment_in_bits(size_t);
1991 
1992   virtual size_t
1993   get_alignment_in_bits() const;
1994 };//end class type_base
1995 
1996 /// Hash functor for instances of @ref type_base.
1997 struct type_base::hash
1998 {
1999   size_t
2000   operator()(const type_base& t) const;
2001 
2002   size_t
2003   operator()(const type_base* t) const;
2004 
2005   size_t
2006   operator()(const type_base_sptr t) const;
2007 }; // end struct type_base::hash
2008 
2009 /// A predicate for deep equality of instances of
2010 /// type_base*
2011 struct type_ptr_equal
2012 {
2013   bool
operatortype_ptr_equal2014   operator()(const type_base* l, const type_base* r) const
2015   {
2016     if (!!l != !!r)
2017       return false;
2018 
2019     if (l == r)
2020       return true;
2021 
2022     if (l)
2023       return *l == *r;
2024 
2025     return true;
2026   }
2027 };
2028 
2029 /// A predicate for deep equality of instances of
2030 /// shared_ptr<type_base>
2031 struct type_shared_ptr_equal
2032 {
2033   bool
operatortype_shared_ptr_equal2034   operator()(const type_base_sptr l, const type_base_sptr r) const
2035   {
2036     if (!!l != !!r)
2037       return false;
2038 
2039     if (l.get() == r.get())
2040       return true;
2041 
2042     if (l)
2043       return *l == *r;
2044 
2045     return true;
2046   }
2047 };
2048 
2049 bool
2050 equals(const type_decl&, const type_decl&, change_kind*);
2051 
2052 /// A basic type declaration that introduces no scope.
2053 class type_decl : public virtual decl_base, public virtual type_base
2054 {
2055   // Forbidden.
2056   type_decl();
2057 
2058 public:
2059 
2060   /// Facility to hash instance of type_decl
2061   struct hash;
2062 
2063   type_decl(const environment*	env,
2064 	    const string&	name,
2065 	    size_t		size_in_bits,
2066 	    size_t		alignment_in_bits,
2067 	    const location&	locus,
2068 	    const string&	mangled_name = "",
2069 	    visibility		vis = VISIBILITY_DEFAULT);
2070 
2071   virtual bool
2072   operator==(const type_base&) const;
2073 
2074   virtual bool
2075   operator==(const decl_base&) const;
2076 
2077   virtual bool
2078   operator==(const type_decl&) const;
2079 
2080   bool operator!=(const type_decl&)const;
2081 
2082   virtual string
2083   get_pretty_representation(bool internal = false,
2084 			    bool qualified_name = true) const;
2085 
2086   virtual bool
2087   traverse(ir_node_visitor&);
2088 
2089   virtual ~type_decl();
2090 };// end class type_decl.
2091 
2092 bool
2093 equals(const scope_type_decl&, const scope_type_decl&, change_kind*);
2094 
2095 bool
2096 operator==(const type_decl_sptr&, const type_decl_sptr&);
2097 
2098 bool
2099 operator!=(const type_decl_sptr&, const type_decl_sptr&);
2100 
2101 /// A type that introduces a scope.
2102 class scope_type_decl : public scope_decl, public virtual type_base
2103 {
2104   scope_type_decl();
2105 
2106 public:
2107 
2108   /// Hasher for instances of scope_type_decl
2109   struct hash;
2110 
2111   scope_type_decl(const environment* env, const string& name,
2112 		  size_t size_in_bits, size_t alignment_in_bits,
2113 		  const location& locus, visibility vis = VISIBILITY_DEFAULT);
2114 
2115   virtual bool
2116   operator==(const decl_base&) const;
2117 
2118   virtual bool
2119   operator==(const type_base&) const;
2120 
2121   virtual bool
2122   traverse(ir_node_visitor&);
2123 
2124   virtual ~scope_type_decl();
2125 };
2126 
2127 /// The abstraction of a namespace declaration
2128 class namespace_decl : public scope_decl
2129 {
2130 public:
2131 
2132   namespace_decl(const environment* env, const string& name,
2133 		 const location& locus, visibility vis = VISIBILITY_DEFAULT);
2134 
2135   virtual string
2136   get_pretty_representation(bool internal = false,
2137 			    bool qualified_name = true) const;
2138 
2139   virtual bool
2140   operator==(const decl_base&) const;
2141 
2142   virtual bool
2143   traverse(ir_node_visitor&);
2144 
2145   virtual ~namespace_decl();
2146 
2147   bool is_empty_or_has_empty_sub_namespaces() const;
2148 };// end class namespace_decl
2149 
2150 bool
2151 equals(const qualified_type_def&, const qualified_type_def&, change_kind*);
2152 
2153 /// The abstraction of a qualified type.
2154 class qualified_type_def : public virtual type_base, public virtual decl_base
2155 {
2156   class priv;
2157   std::unique_ptr<priv> priv_;
2158 
2159   // Forbidden.
2160   qualified_type_def();
2161 
2162 protected:
2163   string build_name(bool, bool internal = false) const;
2164   virtual void on_canonical_type_set();
2165 
2166 public:
2167 
2168   /// A Hasher for instances of qualified_type_def
2169   struct hash;
2170 
2171   /// Bit field values representing the cv qualifiers of the
2172   /// underlying type.
2173   enum CV
2174   {
2175     CV_NONE = 0,
2176     CV_CONST = 1,
2177     CV_VOLATILE = 1 << 1,
2178     CV_RESTRICT = 1 << 2
2179   };
2180 
2181   qualified_type_def(type_base_sptr type, CV quals, const location& locus);
2182 
2183   qualified_type_def(environment* env, CV quals, const location& locus);
2184 
2185   virtual size_t
2186   get_size_in_bits() const;
2187 
2188   virtual bool
2189   operator==(const decl_base&) const;
2190 
2191   virtual bool
2192   operator==(const type_base&) const;
2193 
2194   virtual bool
2195   operator==(const qualified_type_def&) const;
2196 
2197   CV
2198   get_cv_quals() const;
2199 
2200   void
2201   set_cv_quals(CV cv_quals);
2202 
2203   string
2204   get_cv_quals_string_prefix() const;
2205 
2206   type_base_sptr
2207   get_underlying_type() const;
2208 
2209   void
2210   set_underlying_type(const type_base_sptr&);
2211 
2212   virtual void
2213   get_qualified_name(interned_string& qualified_name,
2214 		     bool internal = false) const;
2215 
2216   virtual const interned_string&
2217   get_qualified_name(bool internal = false) const;
2218 
2219   virtual bool
2220   traverse(ir_node_visitor& v);
2221 
2222   virtual ~qualified_type_def();
2223 }; // end class qualified_type_def.
2224 
2225 bool
2226 operator==(const qualified_type_def_sptr&, const qualified_type_def_sptr&);
2227 
2228 bool
2229 operator!=(const qualified_type_def_sptr&, const qualified_type_def_sptr&);
2230 
2231 qualified_type_def::CV
2232 operator|(qualified_type_def::CV, qualified_type_def::CV);
2233 
2234 qualified_type_def::CV&
2235 operator|=(qualified_type_def::CV&, qualified_type_def::CV);
2236 
2237 qualified_type_def::CV
2238 operator&(qualified_type_def::CV, qualified_type_def::CV);
2239 
2240 qualified_type_def::CV
2241 operator~(qualified_type_def::CV);
2242 
2243 std::ostream&
2244 operator<<(std::ostream&, qualified_type_def::CV);
2245 
2246 string
2247 get_string_representation_of_cv_quals(const qualified_type_def::CV);
2248 
2249 interned_string
2250 get_name_of_qualified_type(const type_base_sptr& underlying_type,
2251 			   qualified_type_def::CV quals,
2252 			   bool qualified = true, bool internal = false);
2253 
2254 qualified_type_def_sptr
2255 lookup_qualified_type(const type_base_sptr&,
2256 		      qualified_type_def::CV,
2257 		      const translation_unit&);
2258 bool
2259 equals(const pointer_type_def&, const pointer_type_def&, change_kind*);
2260 
2261 /// The abstraction of a pointer type.
2262 class pointer_type_def : public virtual type_base, public virtual decl_base
2263 {
2264   struct priv;
2265   std::unique_ptr<priv> priv_;
2266 
2267   // Forbidden.
2268   pointer_type_def();
2269 
2270 protected:
2271   virtual void on_canonical_type_set();
2272 
2273 public:
2274 
2275   /// A hasher for instances of pointer_type_def
2276   struct hash;
2277 
2278   pointer_type_def(const type_base_sptr& pointed_to_type, size_t size_in_bits,
2279 		   size_t alignment_in_bits, const location& locus);
2280 
2281   pointer_type_def(environment* env, size_t size_in_bits,
2282 		   size_t alignment_in_bits, const location& locus);
2283 
2284 
2285   void
2286   set_pointed_to_type(const type_base_sptr&);
2287 
2288   virtual bool
2289   operator==(const decl_base&) const;
2290 
2291   virtual bool
2292   operator==(const type_base&) const;
2293 
2294   bool
2295   operator==(const pointer_type_def&) const;
2296 
2297   const type_base_sptr
2298   get_pointed_to_type() const;
2299 
2300   type_base*
2301   get_naked_pointed_to_type() const;
2302 
2303   virtual void
2304   get_qualified_name(interned_string&, bool internal = false) const;
2305 
2306   virtual const interned_string&
2307   get_qualified_name(bool internal = false) const;
2308 
2309   virtual bool
2310   traverse(ir_node_visitor& v);
2311 
2312   virtual ~pointer_type_def();
2313 }; // end class pointer_type_def
2314 
2315 bool
2316 operator==(const pointer_type_def_sptr&, const pointer_type_def_sptr&);
2317 
2318 bool
2319 operator!=(const pointer_type_def_sptr&, const pointer_type_def_sptr&);
2320 
2321 bool
2322 equals(const reference_type_def&, const reference_type_def&, change_kind*);
2323 
2324 
2325 /// Abstracts a reference type.
2326 class reference_type_def : public virtual type_base, public virtual decl_base
2327 {
2328   type_base_wptr	pointed_to_type_;
2329   bool			is_lvalue_;
2330 
2331   // Forbidden.
2332   reference_type_def();
2333 
2334 protected:
2335   virtual void on_canonical_type_set();
2336 
2337 public:
2338 
2339   /// Hasher for intances of reference_type_def.
2340   struct hash;
2341 
2342   reference_type_def(const type_base_sptr pointed_to_type,
2343 		     bool lvalue, size_t size_in_bits,
2344 		     size_t alignment_in_bits, const location& locus);
2345 
2346   reference_type_def(const environment* env, bool lvalue, size_t size_in_bits,
2347 		     size_t alignment_in_bits, const location& locus);
2348 
2349   void
2350   set_pointed_to_type(type_base_sptr& pointed_to_type);
2351 
2352   virtual bool
2353   operator==(const decl_base&) const;
2354 
2355   virtual bool
2356   operator==(const type_base&) const;
2357 
2358   bool
2359   operator==(const reference_type_def&) const;
2360 
2361   type_base_sptr
2362   get_pointed_to_type() const;
2363 
2364   bool
2365   is_lvalue() const;
2366 
2367   virtual void
2368   get_qualified_name(interned_string& qualified_name,
2369 		     bool internal = false) const;
2370 
2371   virtual const interned_string&
2372   get_qualified_name(bool internal = false) const;
2373 
2374   virtual bool
2375   traverse(ir_node_visitor& v);
2376 
2377   virtual ~reference_type_def();
2378 }; // end class reference_type_def
2379 
2380 bool
2381 operator==(const reference_type_def_sptr&, const reference_type_def_sptr&);
2382 
2383 bool
2384 operator!=(const reference_type_def_sptr&, const reference_type_def_sptr&);
2385 
2386 bool
2387 equals(const array_type_def&, const array_type_def&, change_kind*);
2388 
2389 /// The abstraction of an array type.
2390 class array_type_def : public virtual type_base, public virtual decl_base
2391 {
2392   struct priv;
2393   std::unique_ptr<priv> priv_;
2394 
2395   // Forbidden.
2396   array_type_def();
2397 
2398   void update_size();
2399 
2400 public:
2401 
2402   /// Hasher for intances of array_type_def.
2403   struct hash;
2404 
2405   class subrange_type;
2406 
2407   /// Convenience typedef for a shared pointer on a @ref
2408   /// function_decl::subrange
2409   typedef shared_ptr<subrange_type> subrange_sptr;
2410 
2411   /// Convenience typedef for a vector of @ref subrange_sptr
2412   typedef std::vector<subrange_sptr> subranges_type;
2413 
2414   /// Abstraction for an array range type, like in Ada, or just for an
2415   /// array dimension like in C or C++.
2416   class subrange_type : public virtual type_base,  public virtual decl_base
2417   {
2418     struct priv;
2419     std::unique_ptr<priv> priv_;
2420 
2421     // Forbidden.
2422     subrange_type();
2423   public:
2424 
2425     virtual ~subrange_type();
2426     /// This class is to hold the value of the bound of a subrange.
2427     /// The value can be either signed or unsigned, at least when it
2428     /// comes from DWARF.  The class keeps the sign information, but
2429     /// allows users to access the value as signed or unsigned as they
2430     /// see fit.
2431     class bound_value
2432     {
2433     public:
2434       enum signedness
2435       {
2436 	UNSIGNED_SIGNEDNESS,
2437 	SIGNED_SIGNEDNESS
2438       };
2439 
2440     private:
2441       signedness s_;
2442 
2443     public:
2444       union
2445       {
2446 	uint64_t unsigned_;
2447 	int64_t signed_;
2448       } v_;
2449       bound_value();
2450       bound_value(uint64_t);
2451       bound_value(int64_t);
2452       enum signedness get_signedness() const;
2453       void set_signedness(enum signedness s);
2454       int64_t get_signed_value() const;
2455       uint64_t get_unsigned_value();
2456       void set_unsigned(uint64_t v);
2457       void set_signed(int64_t v);
2458       bool operator==(const bound_value&) const;
2459     }; //end class bound_value
2460 
2461     /// Hasher for an instance of array::subrange
2462     struct hash;
2463 
2464     subrange_type(const environment*	env,
2465 		  const string&	name,
2466 		  bound_value		lower_bound,
2467 		  bound_value		upper_bound,
2468 		  const type_base_sptr& underlying_type,
2469 		  const location&	loc,
2470 		  translation_unit::language l = translation_unit::LANG_C11);
2471 
2472     subrange_type(const environment* env,
2473 		  const string& name,
2474 		  bound_value lower_bound,
2475 		  bound_value upper_bound,
2476 		  const location& loc,
2477 		  translation_unit::language l = translation_unit::LANG_C11);
2478 
2479     subrange_type(const environment* env,
2480 		  const string& name,
2481 		  bound_value upper_bound,
2482 		  const location& loc,
2483 		  translation_unit::language l = translation_unit::LANG_C11);
2484 
2485     type_base_sptr
2486     get_underlying_type() const;
2487 
2488     void
2489     set_underlying_type(const type_base_sptr &);
2490 
2491     int64_t
2492     get_upper_bound() const;
2493 
2494     int64_t
2495     get_lower_bound() const;
2496 
2497     void
2498     set_upper_bound(int64_t ub);
2499 
2500     void
2501     set_lower_bound(int64_t lb);
2502 
2503     uint64_t
2504     get_length() const;
2505 
2506     bool
2507     is_infinite() const;
2508 
2509     void
2510     is_infinite(bool);
2511 
2512     translation_unit::language
2513     get_language() const;
2514 
2515     virtual bool
2516     operator==(const decl_base&) const;
2517 
2518     virtual bool
2519     operator==(const type_base&) const;
2520 
2521     bool
2522     operator==(const subrange_type& o) const;
2523 
2524     bool
2525     operator!=(const subrange_type& o) const;
2526 
2527     string
2528     as_string() const;
2529 
2530     static string
2531     vector_as_string(const vector<subrange_sptr>&);
2532 
2533     virtual string
2534     get_pretty_representation(bool internal = false,
2535 			      bool qualified_name = true) const;
2536 
2537     virtual bool
2538     traverse(ir_node_visitor&);
2539   }; // end class subrange_type
2540 
2541   array_type_def(const type_base_sptr type,
2542 		 const std::vector<subrange_sptr>& subs,
2543 		 const location& locus);
2544 
2545   array_type_def(environment* env,
2546 		 const std::vector<subrange_sptr>& subs,
2547 		 const location& locus);
2548 
2549   translation_unit::language
2550   get_language() const;
2551 
2552   virtual bool
2553   operator==(const decl_base&) const;
2554 
2555   virtual bool
2556   operator==(const type_base&) const;
2557 
2558   virtual void
2559   get_qualified_name(interned_string& qualified_name,
2560 		     bool internal = false) const;
2561 
2562   virtual const interned_string&
2563   get_qualified_name(bool internal = false) const;
2564 
2565   const type_base_sptr
2566   get_element_type() const;
2567 
2568   void
2569   set_element_type(const type_base_sptr& element_type);
2570 
2571   virtual void
2572   append_subranges(const std::vector<subrange_sptr>& subs);
2573 
2574   virtual int
2575   get_dimension_count() const;
2576 
2577   virtual bool
2578   is_infinite() const;
2579 
2580   virtual string
2581   get_pretty_representation(bool internal = false,
2582 			    bool qualified_name = true) const;
2583 
2584   virtual string
2585   get_subrange_representation() const;
2586 
2587   virtual bool
2588   traverse(ir_node_visitor& v);
2589 
2590   const location&
2591   get_location() const;
2592 
2593   const std::vector<subrange_sptr>&
2594   get_subranges() const;
2595 
2596   virtual ~array_type_def();
2597 
2598 }; // end class array_type_def
2599 
2600 array_type_def::subrange_type*
2601 is_subrange_type(const type_or_decl_base *type);
2602 
2603 array_type_def::subrange_sptr
2604 is_subrange_type(const type_or_decl_base_sptr &type);
2605 
2606 bool
2607 equals(const enum_type_decl&, const enum_type_decl&, change_kind*);
2608 
2609 /// Abstracts a declaration for an enum type.
2610 class enum_type_decl : public virtual type_base, public virtual decl_base
2611 {
2612   class priv;
2613   std::unique_ptr<priv> priv_;
2614 
2615   // Forbidden
2616   enum_type_decl();
2617 
2618 public:
2619 
2620   /// A hasher for an enum_type_decl.
2621   struct hash;
2622 
2623   /// Enumerator Datum.
2624   class enumerator;
2625 
2626   /// Convenience typedef for a list of @ref enumerator.
2627   typedef std::vector<enumerator> enumerators;
2628 
2629   /// Constructor of an enum type declaration.
2630   ///
2631   /// @param name the name of the enum
2632   ///
2633   /// @param locus the locus at which the enum appears in the source
2634   /// code.
2635   ///
2636   /// @param underlying_type the underlying type of the enum
2637   ///
2638   /// @param enms a list of enumerators for this enum.
2639   ///
2640   /// @param mangled_name the mangled name of the enum type.
2641   ///
2642   /// @param vis the visibility of instances of this type.
2643   enum_type_decl(const string&		name,
2644 		 const location&	locus,
2645 		 type_base_sptr	underlying_type,
2646 		 enumerators&		enms,
2647 		 const string&		mangled_name = "",
2648 		 visibility		vis = VISIBILITY_DEFAULT);
2649 
2650   type_base_sptr
2651   get_underlying_type() const;
2652 
2653   const enumerators&
2654   get_enumerators() const;
2655 
2656   enumerators&
2657   get_enumerators();
2658 
2659   virtual string
2660   get_pretty_representation(bool internal = false,
2661 			    bool qualified_name = true) const;
2662 
2663   virtual bool
2664   operator==(const decl_base&) const;
2665 
2666   virtual bool
2667   operator==(const type_base&) const;
2668 
2669   virtual bool
2670   traverse(ir_node_visitor& v);
2671 
2672   virtual ~enum_type_decl();
2673 
2674   friend bool
2675   enum_has_non_name_change(const enum_type_decl& l,
2676 			   const enum_type_decl& r,
2677 			   change_kind* k);
2678 }; // end class enum_type_decl
2679 
2680 bool
2681 operator==(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r);
2682 
2683 bool
2684 operator!=(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r);
2685 
2686 bool
2687 enum_has_non_name_change(const enum_type_decl& l,
2688 			 const enum_type_decl& r,
2689 			 change_kind* k);
2690 
2691 /// The abstraction of an enumerator
2692 class enum_type_decl::enumerator
2693 {
2694   class priv;
2695   std::unique_ptr<priv> priv_;
2696 
2697 public:
2698 
2699   enumerator();
2700 
2701   ~enumerator();
2702 
2703   enumerator(const environment* env, const string& name, int64_t value);
2704 
2705   enumerator(const enumerator&);
2706 
2707   enumerator&
2708   operator=(const enumerator&);
2709 
2710   bool
2711   operator==(const enumerator& other) const;
2712 
2713   bool
2714   operator!=(const enumerator& other) const;
2715 
2716   const environment*
2717   get_environment() const;
2718 
2719   const interned_string&
2720   get_name() const;
2721 
2722   const interned_string&
2723   get_qualified_name(bool internal = false) const;
2724 
2725   void
2726   set_name(const string& n);
2727 
2728   int64_t
2729   get_value() const;
2730 
2731   void
2732   set_value(int64_t v);
2733 
2734   enum_type_decl*
2735   get_enum_type() const;
2736 
2737   void
2738   set_enum_type(enum_type_decl*);
2739 }; // end class enum_type_def::enumerator
2740 
2741 bool
2742 equals(const typedef_decl&, const typedef_decl&, change_kind*);
2743 
2744 /// The abstraction of a typedef declaration.
2745 class typedef_decl : public virtual type_base, public virtual decl_base
2746 {
2747   struct priv;
2748   std::unique_ptr<priv> priv_;
2749 
2750   // Forbidden
2751   typedef_decl();
2752 
2753 public:
2754 
2755   /// Hasher for the typedef_decl type.
2756   struct hash;
2757 
2758   typedef_decl(const string& name,
2759 	       const type_base_sptr underlying_type,
2760 	       const location& locus,
2761 	       const string& mangled_name = "",
2762 	       visibility vis = VISIBILITY_DEFAULT);
2763 
2764   typedef_decl(const string& name,
2765 	       environment* env,
2766 	       const location& locus,
2767 	       const string& mangled_name = "",
2768 	       visibility vis = VISIBILITY_DEFAULT);
2769 
2770   virtual size_t
2771   get_size_in_bits() const;
2772 
2773   virtual size_t
2774   get_alignment_in_bits() const;
2775 
2776   virtual bool
2777   operator==(const decl_base&) const;
2778 
2779   virtual bool
2780   operator==(const type_base&) const;
2781 
2782   virtual string
2783   get_pretty_representation(bool internal = false,
2784 			    bool qualified_name = true) const;
2785 
2786   type_base_sptr
2787   get_underlying_type() const;
2788 
2789   void
2790   set_underlying_type(const type_base_sptr&);
2791 
2792   virtual bool
2793   traverse(ir_node_visitor&);
2794 
2795   virtual ~typedef_decl();
2796 };// end class typedef_decl
2797 
2798 /// The abstraction for a data member context relationship.  This
2799 /// relates a data member to its parent class.
2800 ///
2801 /// The relationship carries properties like the offset of the data
2802 /// member, if applicable.
2803 class dm_context_rel : public context_rel
2804 {
2805 protected:
2806   struct priv;
2807   std::unique_ptr<priv> priv_;
2808 
2809 public:
2810   dm_context_rel();
2811 
2812   dm_context_rel(scope_decl* s,
2813 		 bool is_laid_out,
2814 		 size_t offset_in_bits,
2815 		 access_specifier a,
2816 		 bool is_static);
2817 
2818   dm_context_rel(scope_decl* s);
2819 
2820   bool
2821   get_is_laid_out() const;
2822 
2823   void
2824   set_is_laid_out(bool f);
2825 
2826   size_t
2827   get_offset_in_bits() const;
2828 
2829   void
2830   set_offset_in_bits(size_t o);
2831 
2832   const var_decl*
2833   get_anonymous_data_member() const;
2834 
2835   void
2836   set_anonymous_data_member(var_decl *);
2837 
2838   bool
2839   operator==(const dm_context_rel& o) const;
2840 
2841   bool
2842   operator!=(const dm_context_rel& o) const;
2843 
2844   virtual ~dm_context_rel();
2845 };// end class class_decl::dm_context_rel
2846 
2847 bool
2848 equals(const var_decl&, const var_decl&, change_kind*);
2849 
2850 bool
2851 equals_modulo_cv_qualifier(const array_type_def*, const array_type_def*);
2852 
2853 /// Abstracts a variable declaration.
2854 class var_decl : public virtual decl_base
2855 {
2856   struct priv;
2857   std::unique_ptr<priv> priv_;
2858 
2859   // Forbidden
2860   var_decl();
2861 
2862   virtual void
2863   set_scope(scope_decl*);
2864 
2865 public:
2866 
2867   /// Hasher for a var_decl type.
2868   struct hash;
2869 
2870   /// Equality functor to compare pointers to variable_decl.
2871   struct ptr_equal;
2872 
2873   var_decl(const string&	name,
2874 	   type_base_sptr	type,
2875 	   const location&	locus,
2876 	   const string&	mangled_name,
2877 	   visibility		vis = VISIBILITY_DEFAULT,
2878 	   binding		bind = BINDING_NONE);
2879 
2880   virtual bool
2881   operator==(const decl_base&) const;
2882 
2883   const type_base_sptr
2884   get_type() const;
2885 
2886   const type_base*
2887   get_naked_type() const;
2888 
2889   binding
2890   get_binding() const;
2891 
2892   void
2893   set_binding(binding b);
2894 
2895   void
2896   set_symbol(const elf_symbol_sptr& sym);
2897 
2898   const elf_symbol_sptr&
2899   get_symbol() const;
2900 
2901   var_decl_sptr
2902   clone() const;
2903 
2904   interned_string
2905   get_id() const;
2906 
2907   virtual const interned_string&
2908   get_qualified_name(bool internal = false) const;
2909 
2910   virtual size_t
2911   get_hash() const;
2912 
2913   virtual string
2914   get_pretty_representation(bool internal = false,
2915 			    bool qualified_name = true) const;
2916 
2917   string
2918   get_anon_dm_reliable_name(bool qualified = true) const;
2919 
2920   virtual bool
2921   traverse(ir_node_visitor& v);
2922 
2923   virtual ~var_decl();
2924 
2925   friend void
2926   set_data_member_offset(var_decl_sptr m, uint64_t o);
2927 
2928   friend uint64_t
2929   get_data_member_offset(const var_decl_sptr m);
2930 
2931   friend uint64_t
2932   get_data_member_offset(const var_decl& m);
2933 
2934   friend uint64_t
2935   get_absolute_data_member_offset(const var_decl& m);
2936 
2937   friend uint64_t
2938   get_absolute_data_member_offset(const var_decl_sptr& m);
2939 
2940   friend void
2941   set_data_member_is_laid_out(var_decl_sptr m, bool l);
2942 
2943   friend bool
2944   get_data_member_is_laid_out(const var_decl& m);
2945 
2946   friend bool
2947   get_data_member_is_laid_out(const var_decl_sptr m);
2948 }; // end class var_decl
2949 
2950 bool
2951 equals(const function_decl&, const function_decl&, change_kind*);
2952 
2953 /// Abstraction for a function declaration.
2954 class function_decl : public virtual decl_base
2955 {
2956   struct priv;
2957   // This priv pointer is not handled by a shared_ptr because
2958   // accessing the data members of the priv struct for this
2959   // function_decl shows up on performance profiles when dealing with
2960   // big binaries with a lot of types; dereferencing the shared_ptr
2961   // involves locking of some sort and that is slower than just
2962   // dereferencing a pointer likere here.  There are other types for
2963   // which the priv pointer is managed using shared_ptr just fine,
2964   // because those didn't show up during our performance profiling.
2965   priv* priv_;
2966 
2967 public:
2968   /// Hasher for function_decl
2969   struct hash;
2970 
2971   /// Equality functor to compare pointers to function_decl
2972   struct ptr_equal;
2973 
2974   /// Abstraction for the parameter of a function.
2975   class parameter;
2976 
2977   /// Convenience typedef for a shared pointer on a @ref
2978   /// function_decl::parameter
2979   typedef shared_ptr<parameter> parameter_sptr;
2980 
2981   /// Convenience typedef for a vector of @ref parameter_sptr
2982   typedef std::vector<parameter_sptr> parameters;
2983 
2984   function_decl(const string& name,
2985 		function_type_sptr function_type,
2986 		bool declared_inline,
2987 		const location& locus,
2988 		const string& mangled_name,
2989 		visibility vis,
2990 		binding bind);
2991 
2992   function_decl(const string& name,
2993 		type_base_sptr fn_type,
2994 		bool declared_inline,
2995 		const location& locus,
2996 		const string& mangled_name = "",
2997 		visibility vis = VISIBILITY_DEFAULT,
2998 		binding bind = BINDING_GLOBAL);
2999 
3000   virtual string
3001   get_pretty_representation(bool internal = false,
3002 			    bool qualified_name = true) const;
3003 
3004   string
3005   get_pretty_representation_of_declarator (bool internal = false) const;
3006 
3007   const std::vector<parameter_sptr >&
3008   get_parameters() const;
3009 
3010   void
3011   append_parameter(parameter_sptr parm);
3012 
3013   void
3014   append_parameters(std::vector<parameter_sptr >& parms);
3015 
3016   parameters::const_iterator
3017   get_first_non_implicit_parm() const;
3018 
3019   const function_type_sptr
3020   get_type() const;
3021 
3022   const function_type*
3023   get_naked_type() const;
3024 
3025   const type_base_sptr
3026   get_return_type() const;
3027 
3028   void
3029   set_type(const function_type_sptr& fn_type);
3030 
3031   void
3032   set_symbol(const elf_symbol_sptr& sym);
3033 
3034   const elf_symbol_sptr&
3035   get_symbol() const;
3036 
3037   bool
3038   is_declared_inline() const;
3039 
3040   binding
3041   get_binding() const;
3042 
3043   function_decl_sptr
3044   clone() const;
3045 
3046   virtual bool
3047   operator==(const decl_base& o) const;
3048 
3049   /// Return true iff the function takes a variable number of
3050   /// parameters.
3051   ///
3052   /// @return true if the function taks a variable number
3053   /// of parameters.
3054   bool
3055   is_variadic() const;
3056 
3057   virtual size_t
3058   get_hash() const;
3059 
3060   interned_string
3061   get_id() const;
3062 
3063   virtual bool
3064   traverse(ir_node_visitor&);
3065 
3066   virtual ~function_decl();
3067 }; // end class function_decl
3068 
3069 bool
3070 operator==(const function_decl_sptr& l, const function_decl_sptr& r);
3071 
3072 bool
3073 operator!=(const function_decl_sptr& l, const function_decl_sptr& r);
3074 
3075 bool
3076 function_decls_alias(const function_decl& f1, const function_decl& f2);
3077 
3078 bool
3079 equals(const function_decl::parameter&,
3080        const function_decl::parameter&,
3081        change_kind*);
3082 
3083 /// A comparison functor to compare pointer to instances of @ref
3084 /// type_or_decl_base.
3085 struct type_or_decl_base_comp
3086 {
3087   /// Comparison operator for ABI artifacts.
3088   ///
3089   /// @param f the first ABI artifact to consider for the comparison.
3090   ///
3091   /// @param s the second  ABI artifact to consider for the comparison.
3092   ///
3093   /// @return true iff @p f is lexicographically less than than @p s.
3094   bool
operatortype_or_decl_base_comp3095   operator()(const type_or_decl_base *f,
3096 	     const type_or_decl_base *s)
3097   {
3098     function_decl *f_fn = is_function_decl(f), *s_fn = is_function_decl(s);
3099     if (f_fn && s_fn)
3100       return function_decl_is_less_than(*f_fn, *s_fn);
3101 
3102     var_decl *f_var = is_var_decl(f), *s_var = is_var_decl(s);
3103     if (f_var && s_var)
3104       return get_name(f_var) < get_name(s_var);
3105 
3106     string l_repr = get_pretty_representation(f),
3107       r_repr = get_pretty_representation(s);
3108 
3109     return l_repr < r_repr;
3110   }
3111 
3112   /// Comparison operator for ABI artifacts.
3113   ///
3114   /// @param f the first ABI artifact to consider for the comparison.
3115   ///
3116   /// @param s the second  ABI artifact to consider for the comparison.
3117   ///
3118   /// @return true iff @p f is lexicographically less than than @p s.
3119   bool
operatortype_or_decl_base_comp3120   operator()(const type_or_decl_base_sptr& f,
3121 	     const type_or_decl_base_sptr& s)
3122   {return operator()(f.get(), s.get());}
3123 }; // end struct type_or_decl_base_comp
3124 
3125 /// Abstraction of a function parameter.
3126 class function_decl::parameter : public decl_base
3127 {
3128   struct priv;
3129   std::unique_ptr<priv> priv_;
3130 
3131 public:
3132 
3133   /// Hasher for an instance of function::parameter
3134   struct hash;
3135 
3136   parameter(const type_base_sptr	type,
3137 	    unsigned			index,
3138 	    const string&		name,
3139 	    const location&		loc,
3140 	    bool			variadic_marker = false);
3141 
3142   parameter(const type_base_sptr	type,
3143 	    unsigned			index,
3144 	    const string&		name,
3145 	    const location&		loc,
3146 	    bool			variadic_marker,
3147 	    bool			is_artificial);
3148 
3149   parameter(const type_base_sptr	type,
3150 	    const string&		name,
3151 	    const location&		loc,
3152 	    bool			variadic_marker = false,
3153 	    bool			is_artificial	= false);
3154 
3155   parameter(const type_base_sptr	type,
3156 	    unsigned			index = 0,
3157 	    bool			variadic_marker = false);
3158 
3159   virtual ~parameter();
3160 
3161   const type_base_sptr
3162   get_type()const;
3163 
3164   interned_string
3165   get_type_name() const;
3166 
3167   const string
3168   get_type_pretty_representation() const;
3169 
3170   interned_string
3171   get_name_id() const;
3172 
3173   unsigned
3174   get_index() const;
3175 
3176   void
3177   set_index(unsigned i);
3178 
3179   bool
3180   get_variadic_marker() const;
3181 
3182   bool
3183   operator==(const parameter& o) const;
3184 
3185   virtual bool
3186   operator==(const decl_base&) const;
3187 
3188   virtual bool
3189   traverse(ir_node_visitor& v);
3190 
3191   virtual size_t
3192   get_hash() const;
3193 
3194   virtual void
3195   get_qualified_name(interned_string& qualified_name,
3196 		     bool internal = false) const;
3197 
3198   virtual string
3199   get_pretty_representation(bool internal = false,
3200 			    bool qualified_name = true) const;
3201 }; // end class function_decl::parameter
3202 
3203 bool
3204 operator==(const function_decl::parameter_sptr&,
3205 	   const function_decl::parameter_sptr&);
3206 
3207 /// A hashing functor for a function_decl::parameter.
3208 struct function_decl::parameter::hash
3209 {
3210   size_t
3211   operator()(const function_decl::parameter&) const;
3212 
3213   size_t
3214   operator()(const function_decl::parameter*) const;
3215 
3216   size_t
3217   operator()(const function_decl::parameter_sptr) const;
3218 }; // end struct function_decl::parameter::hash
3219 
3220 function_decl::parameter*
3221 is_function_parameter(const type_or_decl_base*);
3222 
3223 function_decl::parameter_sptr
3224 is_function_parameter(const type_or_decl_base_sptr tod);
3225 
3226 bool
3227 equals(const function_type&, const function_type&, change_kind*);
3228 
3229 /// Abstraction of a function type.
3230 class function_type : public virtual type_base
3231 {
3232 protected:
3233   virtual void on_canonical_type_set();
3234 
3235 public:
3236   /// Hasher for an instance of function_type
3237   struct hash;
3238 
3239   /// Convenience typedef for a shared pointer on a @ref
3240   /// function_decl::parameter
3241   typedef shared_ptr<function_decl::parameter>	parameter_sptr;
3242   /// Convenience typedef for a vector of @ref parameter_sptr
3243   typedef std::vector<parameter_sptr>		parameters;
3244 
3245   struct priv;
3246   std::unique_ptr<priv> priv_;
3247 
3248 private:
3249   function_type();
3250 
3251 public:
3252 
3253   function_type(type_base_sptr		return_type,
3254 		const parameters&	parms,
3255 		size_t			size_in_bits,
3256 		size_t			alignment_in_bits);
3257 
3258   function_type(type_base_sptr	return_type,
3259 		size_t		size_in_bits,
3260 		size_t		alignment_in_bits);
3261 
3262   function_type(const environment*	env,
3263 		size_t		size_in_bits,
3264 		size_t		alignment_in_bits);
3265 
3266   type_base_sptr
3267   get_return_type() const;
3268 
3269   void
3270   set_return_type(type_base_sptr t);
3271 
3272   const parameters&
3273   get_parameters() const;
3274 
3275   const parameter_sptr
3276   get_parm_at_index_from_first_non_implicit_parm(size_t) const;
3277 
3278   void
3279   set_parameters(const parameters &p);
3280 
3281   void
3282   append_parameter(parameter_sptr parm);
3283 
3284   bool
3285   is_variadic() const;
3286 
3287   parameters::const_iterator
3288   get_first_non_implicit_parm() const;
3289 
3290   parameters::const_iterator
3291   get_first_parm() const;
3292 
3293   const interned_string&
3294   get_cached_name(bool internal = false) const;
3295 
3296   virtual bool
3297   operator==(const type_base&) const;
3298 
3299   virtual string
3300   get_pretty_representation(bool internal = false,
3301 			    bool qualified_name = true) const;
3302 
3303   virtual bool
3304   traverse(ir_node_visitor&);
3305 
3306   virtual ~function_type();
3307 
3308   friend bool
3309   equals(const function_type&, const function_type&, change_kind*);
3310 };//end class function_type
3311 
3312 /// The hashing functor for @ref function_type.
3313 struct function_type::hash
3314 {
3315   size_t
3316   operator()(const function_type& t) const;
3317 
3318   size_t
3319   operator()(const function_type* t) const;
3320 
3321   size_t
3322   operator()(const function_type_sptr t) const;
3323 };// end struct function_type::hash
3324 
3325 /// Abstracts the type of a class member function.
3326 class method_type : public function_type
3327 {
3328   struct priv;
3329   std::unique_ptr<priv> priv_;
3330 
3331   method_type();
3332 
3333 public:
3334 
3335   /// Hasher for intances of method_type
3336   struct hash;
3337 
3338   method_type(type_base_sptr return_type,
3339 	      class_or_union_sptr class_type,
3340 	      const std::vector<function_decl::parameter_sptr>& parms,
3341 	      bool is_const,
3342 	      size_t size_in_bits,
3343 	      size_t alignment_in_bits);
3344 
3345   method_type(type_base_sptr return_type,
3346 	      type_base_sptr class_type,
3347 	      const std::vector<function_decl::parameter_sptr>& parms,
3348 	      bool is_const,
3349 	      size_t size_in_bits,
3350 	      size_t alignment_in_bits);
3351 
3352   method_type(class_or_union_sptr class_type,
3353 	      bool is_const,
3354 	      size_t size_in_bits,
3355 	      size_t alignment_in_bits);
3356 
3357   method_type(const environment* env,
3358 	      size_t size_in_bits,
3359 	      size_t alignment_in_bits);
3360 
3361   class_or_union_sptr
3362   get_class_type() const;
3363 
3364   void
3365   set_class_type(const class_or_union_sptr& t);
3366 
3367   void set_is_const(bool);
3368 
3369   bool get_is_const() const;
3370 
3371   virtual ~method_type();
3372 
3373   virtual string
3374   get_pretty_representation(bool internal = false,
3375 			    bool qualified_name = true) const;
3376 
3377   friend interned_string
3378   get_method_type_name(const method_type& fn_type, bool internal);
3379 };// end class method_type.
3380 
3381 /// The base class of templates.
3382 class template_decl : public virtual decl_base
3383 {
3384   class priv;
3385   std::unique_ptr<priv> priv_;
3386 
3387   template_decl();
3388 
3389 public:
3390 
3391   /// Hasher.
3392   struct hash;
3393 
3394   template_decl(const environment*	env,
3395 		const string&		name,
3396 		const location&	locus,
3397 		visibility		vis = VISIBILITY_DEFAULT);
3398 
3399   void
3400   add_template_parameter(const template_parameter_sptr p);
3401 
3402   const std::list<template_parameter_sptr>&
3403   get_template_parameters() const;
3404 
3405   virtual bool
3406   operator==(const template_decl& o) const;
3407 
3408   virtual ~template_decl();
3409 };//end class template_decl
3410 
3411 /// Base class for a template parameter.  Client code should use the
3412 /// more specialized type_template_parameter,
3413 /// non_type_template_parameter and template_template_parameter below.
3414 class template_parameter
3415 {
3416   class priv;
3417   std::unique_ptr<priv> priv_;
3418 
3419   // Forbidden
3420   template_parameter();
3421 
3422  public:
3423 
3424   /// Hashers.
3425   struct hash;
3426   struct dynamic_hash;
3427   struct shared_ptr_hash;
3428 
3429   template_parameter(unsigned			index,
3430 		     template_decl_sptr	enclosing_tdecl);
3431 
3432   virtual bool
3433   operator==(const template_parameter&) const;
3434 
3435   bool
3436   operator!=(const template_parameter&) const;
3437 
3438   unsigned
3439   get_index() const;
3440 
3441   const template_decl_sptr
3442   get_enclosing_template_decl() const;
3443 
3444   bool
3445   get_hashing_has_started() const;
3446 
3447   void
3448   set_hashing_has_started(bool f) const;
3449 
3450   virtual ~template_parameter();
3451 };//end class template_parameter
3452 
3453 struct template_decl::hash
3454 {
3455     size_t
3456     operator()(const template_decl& t) const;
3457 };// end struct template_decl::hash
3458 
3459 /// Abstracts a type template parameter.
3460 class type_tparameter : public template_parameter, public virtual type_decl
3461 {
3462   class priv;
3463   std::unique_ptr<priv> priv_;
3464 
3465   // Forbidden
3466   type_tparameter();
3467 
3468 public:
3469 
3470   /// Hasher.
3471   struct hash;
3472 
3473   type_tparameter(unsigned		index,
3474 		  template_decl_sptr	enclosing_tdecl,
3475 		  const string&	name,
3476 		  const location&	locus);
3477 
3478   virtual bool
3479   operator==(const type_base&) const;
3480 
3481   virtual bool
3482   operator==(const template_parameter&) const;
3483 
3484   virtual bool
3485   operator==(const type_tparameter&) const;
3486 
3487   virtual ~type_tparameter();
3488 };// end class type_tparameter.
3489 
3490 /// Abstracts non type template parameters.
3491 class non_type_tparameter : public template_parameter, public virtual decl_base
3492 {
3493   class priv;
3494   std::unique_ptr<priv> priv_;
3495 
3496   type_base_wptr type_;
3497 
3498   // Forbidden
3499   non_type_tparameter();
3500 
3501 public:
3502   /// Hasher.
3503   struct hash;
3504 
3505   non_type_tparameter(unsigned			index,
3506 		      template_decl_sptr	enclosing_tdecl,
3507 		      const string&		name,
3508 		      type_base_sptr		type,
3509 		      const location&		locus);
3510   virtual size_t
3511   get_hash() const;
3512 
3513   virtual bool
3514   operator==(const decl_base&) const;
3515 
3516   virtual bool
3517   operator==(const template_parameter&) const;
3518 
3519   const type_base_sptr
3520   get_type() const;
3521 
3522   virtual ~non_type_tparameter();
3523 };// end class non_type_tparameter
3524 
3525 /// Hasher for the @ref non_type_tparameter type.
3526 struct non_type_tparameter::hash
3527 {
3528   size_t
3529   operator()(const non_type_tparameter& t) const;
3530 
3531   size_t
3532   operator()(const non_type_tparameter* t) const;
3533 };
3534 
3535 class template_tparameter;
3536 
3537 /// Abstracts a template template parameter.
3538 class template_tparameter : public type_tparameter, public template_decl
3539 {
3540   class priv;
3541   std::unique_ptr<priv> priv_;
3542 
3543   // Forbidden
3544   template_tparameter();
3545 
3546 public:
3547 
3548   /// A hasher for instances of template_tparameter
3549   struct hash;
3550 
3551   template_tparameter(unsigned			index,
3552 		      template_decl_sptr	enclosing_tdecl,
3553 		      const string&		name,
3554 		      const location&		locus);
3555 
3556   virtual bool
3557   operator==(const type_base&) const;
3558 
3559   virtual bool
3560   operator==(const template_parameter&) const;
3561 
3562   virtual bool
3563   operator==(const template_decl&) const;
3564 
3565   virtual ~template_tparameter();
3566 };
3567 
3568 /// This abstracts a composition of types based on template type
3569 /// parameters.  The result of the composition is a type that can be
3570 /// referred to by a template non-type parameter.  Instances of this
3571 /// type can appear at the same level as template parameters, in the
3572 /// scope of a template_decl.
3573 class type_composition : public template_parameter, public virtual decl_base
3574 {
3575   class priv;
3576   std::unique_ptr<priv> priv_;
3577 
3578   type_composition();
3579 
3580 public:
3581   struct hash;
3582 
3583   type_composition(unsigned		index,
3584 		   template_decl_sptr	tdecl,
3585 		   type_base_sptr	composed_type);
3586 
3587   const type_base_sptr
3588   get_composed_type() const;
3589 
3590   void
3591   set_composed_type(type_base_sptr t);
3592 
3593   virtual size_t
3594   get_hash() const;
3595 
3596   virtual ~type_composition();
3597 };
3598 
3599 /// Hasher for the @ref type_composition type.
3600 struct type_composition::hash
3601 {
3602   size_t
3603   operator()(const type_composition& t) const;
3604 
3605   size_t
3606   operator()(const type_composition* t) const;
3607 
3608 }; //struct type_composition::hash
3609 
3610 /// Abstract a function template declaration.
3611 class function_tdecl : public template_decl, public scope_decl
3612 {
3613   class priv;
3614   std::unique_ptr<priv> priv_;
3615 
3616   // Forbidden
3617   function_tdecl();
3618 
3619 public:
3620 
3621   /// Hash functor for function templates.
3622   struct hash;
3623   struct shared_ptr_hash;
3624 
3625   function_tdecl(const environment*	env,
3626 		 const location&	locus,
3627 		 visibility		vis = VISIBILITY_DEFAULT,
3628 		 binding		bind = BINDING_NONE);
3629 
3630   function_tdecl(function_decl_sptr	pattern,
3631 		 const location&	locus,
3632 		 visibility		vis = VISIBILITY_DEFAULT,
3633 		 binding		bind = BINDING_NONE);
3634 
3635   virtual bool
3636   operator==(const decl_base&) const;
3637 
3638   virtual bool
3639   operator==(const template_decl&) const;
3640 
3641   virtual bool
3642   operator==(const function_tdecl&) const;
3643 
3644   void
3645   set_pattern(shared_ptr<function_decl> p);
3646 
3647   shared_ptr<function_decl>
3648   get_pattern() const;
3649 
3650   binding
3651   get_binding() const;
3652 
3653   virtual bool
3654   traverse(ir_node_visitor& v);
3655 
3656   virtual ~function_tdecl();
3657 }; // end class function_tdecl.
3658 
3659 /// Abstract a class template.
3660 class class_tdecl : public template_decl, public scope_decl
3661 {
3662   class priv;
3663   std::unique_ptr<priv> priv_;
3664 
3665   // Forbidden
3666   class_tdecl();
3667 
3668 public:
3669 
3670   /// Hashers.
3671   struct hash;
3672   struct shared_ptr_hash;
3673 
3674   class_tdecl(const environment* env, const location& locus,
3675 	      visibility vis = VISIBILITY_DEFAULT);
3676 
3677   class_tdecl(class_decl_sptr	pattern,
3678 	      const location&	locus,
3679 	      visibility	vis = VISIBILITY_DEFAULT);
3680 
3681   virtual bool
3682   operator==(const decl_base&) const;
3683 
3684   virtual bool
3685   operator==(const template_decl&) const;
3686 
3687   virtual bool
3688   operator==(const class_tdecl&) const;
3689 
3690   void
3691   set_pattern(class_decl_sptr p);
3692 
3693   shared_ptr<class_decl>
3694   get_pattern() const;
3695 
3696   virtual bool
3697   traverse(ir_node_visitor& v);
3698 
3699   virtual ~class_tdecl();
3700 };// end class class_tdecl
3701 
3702 /// The base class for member types, data members and member
3703 /// functions.  Its purpose is mainly to carry the access specifier
3704 /// (and possibly other properties that might be shared by all class
3705 /// members) for the member.
3706 class member_base
3707 {
3708 protected:
3709   enum access_specifier access_;
3710   bool			is_static_;
3711 
3712 private:
3713   // Forbidden
3714   member_base();
3715 
3716 public:
3717   /// Hasher.
3718   struct hash;
3719 
3720   member_base(access_specifier a, bool is_static = false)
access_(a)3721     : access_(a), is_static_(is_static)
3722   {}
3723 
3724   /// Getter for the access specifier of this member.
3725   ///
3726   /// @return the access specifier for this member.
3727   access_specifier
get_access_specifier()3728   get_access_specifier() const
3729   {return access_;}
3730 
3731   /// Setter for the access specifier of this member.
3732   ///
3733   /// @param a the new access specifier.
3734   void
set_access_specifier(access_specifier a)3735   set_access_specifier(access_specifier a)
3736   {access_ = a;}
3737 
3738   /// @return true if the member is static, false otherwise.
3739   bool
get_is_static()3740   get_is_static() const
3741   {return is_static_;}
3742 
3743   /// Set a flag saying if the parameter is static or not.
3744   ///
3745   /// @param f set to true if the member is static, false otherwise.
3746   void
set_is_static(bool f)3747   set_is_static(bool f)
3748   {is_static_ = f;}
3749 
3750   virtual bool
3751   operator==(const member_base& o) const;
3752 };// end class member_base
3753 
3754 /// Abstraction of the declaration of a method.
3755 class method_decl : public function_decl
3756 {
3757   method_decl();
3758 
3759   virtual void
3760   set_scope(scope_decl*);
3761 
3762 public:
3763 
3764   method_decl(const string& name, method_type_sptr type,
3765 	      bool declared_inline, const location& locus,
3766 	      const string& mangled_name = "",
3767 	      visibility vis = VISIBILITY_DEFAULT,
3768 	      binding	bind = BINDING_GLOBAL);
3769 
3770   method_decl(const string& name,
3771 	      function_type_sptr type,
3772 	      bool declared_inline,
3773 	      const location& locus,
3774 	      const string& mangled_name = "",
3775 	      visibility vis  = VISIBILITY_DEFAULT,
3776 	      binding	bind = BINDING_GLOBAL);
3777 
3778   method_decl(const string& name, type_base_sptr type,
3779 	      bool declared_inline, const location& locus,
3780 	      const string& mangled_name = "",
3781 	      visibility vis = VISIBILITY_DEFAULT,
3782 	      binding bind = BINDING_GLOBAL);
3783 
3784   virtual void
3785   set_linkage_name(const string&);
3786 
3787   /// @return the type of the current instance of the
3788   /// method_decl.
3789   const method_type_sptr
3790   get_type() const;
3791 
3792   void
set_type(const method_type_sptr fn_type)3793   set_type(const method_type_sptr fn_type)
3794   {function_decl::set_type(fn_type);}
3795 
3796   friend bool
3797   get_member_function_is_ctor(const function_decl&);
3798 
3799   friend void
3800   set_member_function_is_ctor(function_decl&, bool);
3801 
3802   friend void
3803   set_member_function_is_ctor(const function_decl_sptr&, bool);
3804 
3805   friend bool
3806   get_member_function_is_dtor(const function_decl&);
3807 
3808   friend void
3809   set_member_function_is_dtor(function_decl&, bool);
3810 
3811   friend void
3812   set_member_function_is_dtor(const function_decl_sptr&, bool);
3813 
3814   friend bool
3815   get_member_function_is_static(const function_decl&);
3816 
3817   friend void
3818   set_member_function_is_static(const function_decl&, bool);
3819 
3820   friend bool
3821   get_member_function_is_const(const function_decl&);
3822 
3823   friend void
3824   set_member_function_is_const(function_decl&, bool);
3825 
3826   friend void
3827   set_member_function_is_const(const function_decl_sptr&, bool);
3828 
3829   friend bool
3830   member_function_has_vtable_offset(const function_decl&);
3831 
3832   friend ssize_t
3833   get_member_function_vtable_offset(const function_decl&);
3834 
3835   friend void
3836   set_member_function_vtable_offset(function_decl&, ssize_t);
3837 
3838   friend void
3839   set_member_function_vtable_offset(const function_decl_sptr&, ssize_t);
3840 
3841   friend bool
3842   get_member_function_is_virtual(const function_decl&);
3843 
3844   friend void
3845   set_member_function_is_virtual(function_decl&, bool);
3846 
3847   virtual ~method_decl();
3848 };// end class method_decl
3849 
3850 bool
3851 operator==(const method_decl_sptr& l, const method_decl_sptr& r);
3852 
3853 bool
3854 operator!=(const method_decl_sptr& l, const method_decl_sptr& r);
3855 
3856 /// The base type of @ref class_decl and @ref union_decl
3857 class class_or_union : public scope_type_decl
3858 {
3859 public:
3860   struct priv;
3861   priv *priv_;
3862 
3863 private:
3864   // Forbidden
3865   class_or_union();
3866 
3867 protected:
3868 
3869   virtual decl_base_sptr
3870   add_member_decl(const decl_base_sptr&);
3871 
3872   virtual decl_base_sptr
3873   insert_member_decl(decl_base_sptr member, declarations::iterator before);
3874 
3875   virtual void
3876   remove_member_decl(decl_base_sptr);
3877 
3878   void
3879   maybe_fixup_members_of_anon_data_member(var_decl_sptr& anon_dm);
3880 
3881 public:
3882   /// Hasher.
3883   struct hash;
3884 
3885   /// Convenience typedef
3886   /// @{
3887   typedef vector<type_base_sptr>		member_types;
3888   typedef vector<var_decl_sptr>		data_members;
3889   typedef vector<method_decl_sptr>		member_functions;
3890   typedef unordered_map<ssize_t, member_functions> virtual_mem_fn_map_type;
3891   typedef unordered_map<string, method_decl*> string_mem_fn_ptr_map_type;
3892   typedef unordered_map<string, method_decl_sptr> string_mem_fn_sptr_map_type;
3893   /// @}
3894 
3895   class_or_union(const environment* env, const string& name,
3896 		 size_t size_in_bits, size_t align_in_bits,
3897 		 const location& locus, visibility vis,
3898 		 member_types& mbrs, data_members& data_mbrs,
3899 		 member_functions& member_fns);
3900 
3901   class_or_union(const environment* env, const string& name,
3902 		 size_t size_in_bits, size_t align_in_bits,
3903 		 const location& locus, visibility vis);
3904 
3905   class_or_union(const environment* env, const string& name,
3906 		 bool is_declaration_only = true);
3907 
3908   virtual void
3909   set_size_in_bits(size_t);
3910 
3911   virtual size_t
3912   get_size_in_bits() const;
3913 
3914   virtual size_t
3915   get_alignment_in_bits() const;
3916 
3917   virtual void
3918   set_alignment_in_bits(size_t);
3919 
3920  void
3921   insert_member_type(type_base_sptr t,
3922 		     declarations::iterator before);
3923 
3924   void
3925   add_member_type(type_base_sptr t);
3926 
3927   type_base_sptr
3928   add_member_type(type_base_sptr t, access_specifier a);
3929 
3930   void
3931   remove_member_type(type_base_sptr t);
3932 
3933   const member_types&
3934   get_member_types() const;
3935 
3936   virtual size_t
3937   get_num_anonymous_member_classes() const;
3938 
3939   virtual size_t
3940   get_num_anonymous_member_unions() const;
3941 
3942   virtual size_t
3943   get_num_anonymous_member_enums() const;
3944 
3945   type_base_sptr
3946   find_member_type(const string& name) const;
3947 
3948   void
3949   add_data_member(var_decl_sptr v, access_specifier a,
3950 		  bool is_laid_out, bool is_static,
3951 		  size_t offset_in_bits);
3952 
3953   const data_members&
3954   get_data_members() const;
3955 
3956   const var_decl_sptr
3957   find_data_member(const string&) const;
3958 
3959   const var_decl_sptr
3960   find_data_member(const var_decl_sptr&) const;
3961 
3962   const var_decl_sptr
3963   find_anonymous_data_member(const var_decl_sptr&) const;
3964 
3965   const data_members&
3966   get_non_static_data_members() const;
3967 
3968   void
3969   add_member_function(method_decl_sptr f,
3970 		      access_specifier a,
3971 		      bool is_static, bool is_ctor,
3972 		      bool is_dtor, bool is_const);
3973 
3974   void
3975   add_member_function(method_decl_sptr f,
3976 		      access_specifier a,
3977 		      bool is_virtual,
3978 		      size_t vtable_offset,
3979 		      bool is_static, bool is_ctor,
3980 		      bool is_dtor, bool is_const);
3981 
3982   const member_functions&
3983   get_member_functions() const;
3984 
3985   const method_decl*
3986   find_member_function(const string& mangled_name) const;
3987 
3988   method_decl*
3989   find_member_function(const string& mangled_name);
3990 
3991   method_decl_sptr
3992   find_member_function_sptr(const string& mangled_name);
3993 
3994   const method_decl*
3995   find_member_function_from_signature(const string& s) const;
3996 
3997   method_decl*
3998   find_member_function_from_signature(const string& s);
3999 
4000   void
4001   add_member_function_template(member_function_template_sptr);
4002 
4003   const member_function_templates&
4004   get_member_function_templates() const;
4005 
4006   void
4007   add_member_class_template(member_class_template_sptr m);
4008 
4009   const member_class_templates&
4010   get_member_class_templates() const;
4011 
4012   bool
4013   has_no_member() const;
4014 
4015   virtual bool
4016   operator==(const decl_base&) const;
4017 
4018   virtual bool
4019   operator==(const type_base&) const;
4020 
4021   virtual bool
4022   operator==(const class_or_union&) const;
4023 
4024   virtual bool
4025   traverse(ir_node_visitor& v);
4026 
4027   virtual ~class_or_union();
4028 
4029   friend method_decl_sptr
4030   copy_member_function(class_or_union_sptr& t,
4031 		       const method_decl*m);
4032 
4033   friend method_decl_sptr
4034   copy_member_function(class_or_union_sptr& t,
4035 		       const method_decl_sptr& m);
4036 
4037   friend void
4038   fixup_virtual_member_function(method_decl_sptr method);
4039 
4040   friend void
4041   set_member_is_static(decl_base& d, bool s);
4042 
4043   friend bool
4044   equals(const class_or_union&, const class_or_union&, change_kind*);
4045 
4046   friend bool
4047   equals(const class_decl&, const class_decl&, change_kind*);
4048 
4049   friend class method_decl;
4050   friend class class_decl;
4051 }; // end class class_or_union
4052 
4053 method_decl_sptr
4054 copy_member_function(const class_or_union_sptr& clazz,
4055 		     const method_decl_sptr& f);
4056 
4057 method_decl_sptr
4058 copy_member_function(const class_or_union_sptr& clazz,
4059 		     const method_decl* f);
4060 
4061 bool
4062 operator==(const class_or_union_sptr& l, const class_or_union_sptr& r);
4063 
4064 bool
4065 operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r);
4066 
4067 /// Hasher for the @ref class_or_union type
4068 struct class_or_union::hash
4069 {
4070   size_t
4071   operator()(const class_or_union& t) const;
4072 
4073   size_t
4074   operator()(const class_or_union* t) const;
4075 }; // end struct class_decl::hash
4076 
4077 /// Abstracts a class declaration.
4078 class class_decl : public class_or_union
4079 {
4080   // Forbidden
4081   class_decl();
4082 
4083 protected:
4084 
4085   virtual decl_base_sptr
4086   insert_member_decl(decl_base_sptr member, declarations::iterator before);
4087 
4088 public:
4089   /// Hasher.
4090   struct hash;
4091 
4092   /// Forward declarations.
4093   class base_spec;
4094 
4095   /// Convenience typedef
4096   /// @{
4097   typedef shared_ptr<base_spec>			base_spec_sptr;
4098   typedef vector<base_spec_sptr>			base_specs;
4099 
4100   /// @}
4101 
4102 protected:
4103   virtual void
4104   on_canonical_type_set();
4105 
4106 private:
4107   struct priv;
4108   // This priv it's not handled by a shared_ptr because accessing the
4109   // data members of the priv struct for this class_decl shows up on
4110   // performance profiles when dealing with big binaries with a lot of
4111   // types; dereferencing the shared_ptr involves locking of some sort
4112   // and that is slower than just dereferencing a pointer likere here.
4113   // There are other types for which the priv pointer is managed using
4114   // shared_ptr just fine, because those didn't show up during our
4115   // performance profiling.
4116   priv * priv_;
4117 
4118 public:
4119 
4120   class_decl(const environment* env, const string& name,
4121 	     size_t size_in_bits, size_t align_in_bits,
4122 	     bool is_struct, const location& locus,
4123 	     visibility vis, base_specs& bases,
4124 	     member_types& mbrs, data_members& data_mbrs,
4125 	     member_functions& member_fns);
4126 
4127   class_decl(const environment* env, const string& name,
4128 	     size_t size_in_bits, size_t align_in_bits,
4129 	     bool is_struct, const location& locus,
4130 	     visibility vis, base_specs& bases,
4131 	     member_types& mbrs, data_members& data_mbrs,
4132 	     member_functions& member_fns, bool is_anonymous);
4133 
4134   class_decl(const environment* env, const string& name,
4135 	     size_t size_in_bits, size_t align_in_bits,
4136 	     bool is_struct, const location& locus, visibility vis);
4137 
4138   class_decl(const environment* env, const string& name,
4139 	     size_t size_in_bits, size_t align_in_bits,
4140 	     bool is_struct, const location& locus,
4141 	     visibility vis, bool is_anonymous);
4142 
4143   class_decl(const environment* env, const string& name, bool is_struct,
4144 	     bool is_declaration_only = true);
4145 
4146   virtual string
4147   get_pretty_representation(bool internal = false,
4148 			    bool qualified_name = true) const;
4149 
4150   void
4151   is_struct(bool f);
4152 
4153   bool
4154   is_struct() const;
4155 
4156   void
4157   add_base_specifier(shared_ptr<base_spec> b);
4158 
4159   const base_specs&
4160   get_base_specifiers() const;
4161 
4162   class_decl_sptr
4163   find_base_class(const string&) const;
4164 
4165   const member_functions&
4166   get_virtual_mem_fns() const;
4167 
4168   const virtual_mem_fn_map_type&
4169   get_virtual_mem_fns_map() const;
4170 
4171   void
4172   sort_virtual_mem_fns();
4173 
4174   bool
4175   has_no_base_nor_member() const;
4176 
4177   bool
4178   has_virtual_member_functions() const;
4179 
4180   bool
4181   has_virtual_bases() const;
4182 
4183   bool
4184   has_vtable() const;
4185 
4186   ssize_t
4187   get_biggest_vtable_offset() const;
4188 
4189   virtual size_t
4190   get_hash() const;
4191 
4192   virtual bool
4193   operator==(const decl_base&) const;
4194 
4195   virtual bool
4196   operator==(const type_base&) const;
4197 
4198   virtual bool
4199   operator==(const class_decl&) const;
4200 
4201   virtual bool
4202   traverse(ir_node_visitor& v);
4203 
4204   virtual ~class_decl();
4205 
4206   friend void
4207   fixup_virtual_member_function(method_decl_sptr method);
4208 
4209   friend void
4210   set_member_is_static(decl_base& d, bool s);
4211 
4212   friend bool
4213   equals(const class_decl&, const class_decl&, change_kind*);
4214 
4215   friend class method_decl;
4216   friend class class_or_union;
4217 };// end class class_decl
4218 
4219 bool
4220 equals(const class_decl&, const class_decl&, change_kind*);
4221 
4222 method_decl_sptr
4223 copy_member_function(const class_decl_sptr& clazz,
4224 		     const method_decl_sptr& f);
4225 
4226 method_decl_sptr
4227 copy_member_function(const class_decl_sptr& clazz,
4228 		     const method_decl* f);
4229 void
4230 fixup_virtual_member_function(method_decl_sptr method);
4231 
4232 /// Hasher for the @ref class_decl type
4233 struct class_decl::hash
4234 {
4235   size_t
4236   operator()(const class_decl& t) const;
4237 
4238   size_t
4239   operator()(const class_decl* t) const;
4240 }; // end struct class_decl::hash
4241 
4242 enum access_specifier
4243 get_member_access_specifier(const decl_base&);
4244 
4245 enum access_specifier
4246 get_member_access_specifier(const decl_base_sptr&);
4247 
4248 void
4249 set_member_access_specifier(decl_base&,
4250 			    access_specifier);
4251 
4252 void
4253 set_member_access_specifier(const decl_base_sptr&,
4254 			    access_specifier);
4255 
4256 std::ostream&
4257 operator<<(std::ostream&, access_specifier);
4258 
4259 bool
4260 operator==(const class_decl_sptr& l, const class_decl_sptr& r);
4261 
4262 bool
4263 operator!=(const class_decl_sptr& l, const class_decl_sptr& r);
4264 
4265 bool
4266 equals(const class_decl::base_spec&,
4267        const class_decl::base_spec&,
4268        change_kind*);
4269 
4270 /// Abstraction of a base specifier in a class declaration.
4271 class class_decl::base_spec : public member_base,
4272 			      public virtual decl_base
4273 {
4274   struct priv;
4275   std::unique_ptr<priv> priv_;
4276 
4277   // Forbidden
4278   base_spec();
4279 
4280 public:
4281 
4282   /// Hasher.
4283   struct hash;
4284 
4285   base_spec(const class_decl_sptr& base, access_specifier a,
4286 	    long offset_in_bits = -1, bool is_virtual = false);
4287 
4288   base_spec(const type_base_sptr& base, access_specifier a,
4289 	    long offset_in_bits = -1, bool is_virtual = false);
4290 
4291   virtual ~base_spec();
4292 
4293   class_decl_sptr
4294   get_base_class() const;
4295 
4296   bool
4297   get_is_virtual() const;
4298 
4299   long
4300   get_offset_in_bits() const;
4301 
4302   virtual bool
4303   operator==(const decl_base&) const;
4304 
4305   virtual bool
4306   operator==(const member_base&) const;
4307 
4308   virtual size_t
4309   get_hash() const;
4310 
4311   virtual bool
4312   traverse(ir_node_visitor&);
4313 };// end class class_decl::base_spec
4314 
4315 bool
4316 operator==(const class_decl::base_spec_sptr& l,
4317 	   const class_decl::base_spec_sptr& r);
4318 
4319 bool
4320 operator!=(const class_decl::base_spec_sptr& l,
4321 	   const class_decl::base_spec_sptr& r);
4322 
4323 class_decl::base_spec*
4324 is_class_base_spec(type_or_decl_base*);
4325 
4326 class_decl::base_spec_sptr
4327 is_class_base_spec(type_or_decl_base_sptr);
4328 
4329 /// Abstracts a union type declaration.
4330 class union_decl : public class_or_union
4331 {
4332   // Forbid
4333   union_decl();
4334 
4335 public:
4336 
4337   union_decl(const environment* env, const string& name,
4338 	     size_t size_in_bits, const location& locus,
4339 	     visibility vis, member_types& mbrs,
4340 	     data_members& data_mbrs, member_functions& member_fns);
4341 
4342   union_decl(const environment* env, const string& name,
4343 	     size_t size_in_bits, const location& locus,
4344 	     visibility vis, member_types& mbrs,
4345 	     data_members& data_mbrs, member_functions& member_fns,
4346 	     bool is_anonymous);
4347 
4348   union_decl(const environment* env, const string& name,
4349 	     size_t size_in_bits, const location& locus,
4350 	     visibility vis);
4351 
4352   union_decl(const environment* env, const string& name,
4353 	     size_t size_in_bits, const location& locus,
4354 	     visibility vis, bool is_anonymous);
4355 
4356   union_decl(const environment* env, const string& name,
4357 	     bool is_declaration_only = true);
4358 
4359   virtual string
4360   get_pretty_representation(bool internal = false,
4361 			    bool qualified_name = true) const;
4362 
4363   virtual bool
4364   operator==(const decl_base&) const;
4365 
4366   virtual bool
4367   operator==(const type_base&) const;
4368 
4369   virtual bool
4370   operator==(const union_decl&) const;
4371 
4372   virtual bool
4373   traverse(ir_node_visitor& v);
4374 
4375   virtual ~union_decl();
4376 }; // union_decl
4377 
4378 bool
4379 equals(const union_decl&, const union_decl&, change_kind*);
4380 
4381 method_decl_sptr
4382 copy_member_function(const union_decl_sptr& union_type,
4383 		     const method_decl_sptr& f);
4384 
4385 method_decl_sptr
4386 copy_member_function(const union_decl_sptr& union_type,
4387 		     const method_decl* f);
4388 
4389 bool
4390 operator==(const union_decl_sptr& l, const union_decl_sptr& r);
4391 
4392 bool
4393 operator!=(const union_decl_sptr& l, const union_decl_sptr& r);
4394 
4395 /// Abstraction of a member function context relationship.  This
4396 /// relates a member function to its parent class.
4397 class mem_fn_context_rel : public context_rel
4398 {
4399 protected:
4400   bool		is_virtual_;
4401   ssize_t	vtable_offset_in_bits_;
4402   bool		is_constructor_;
4403   bool		is_destructor_;
4404   bool		is_const_;
4405 
4406 public:
mem_fn_context_rel()4407   mem_fn_context_rel()
4408     : context_rel(),
4409       is_virtual_(false),
4410       vtable_offset_in_bits_(-1),
4411       is_constructor_(false),
4412       is_destructor_(false),
4413       is_const_(false)
4414   {}
4415 
mem_fn_context_rel(scope_decl * s)4416   mem_fn_context_rel(scope_decl* s)
4417     : context_rel(s),
4418       is_virtual_(false),
4419       vtable_offset_in_bits_(-1),
4420       is_constructor_(false),
4421       is_destructor_(false),
4422       is_const_(false)
4423   {}
4424 
mem_fn_context_rel(scope_decl * s,bool is_constructor,bool is_destructor,bool is_const,bool is_virtual,size_t vtable_offset_in_bits,access_specifier access,bool is_static)4425   mem_fn_context_rel(scope_decl* s,
4426 		     bool is_constructor,
4427 		     bool is_destructor,
4428 		     bool is_const,
4429 		     bool is_virtual,
4430 		     size_t vtable_offset_in_bits,
4431 		     access_specifier access,
4432 		     bool is_static)
4433     : context_rel(s, access, is_static),
4434       is_virtual_(is_virtual),
4435       vtable_offset_in_bits_(vtable_offset_in_bits),
4436       is_constructor_(is_constructor),
4437       is_destructor_(is_destructor),
4438       is_const_(is_const)
4439   {}
4440 
4441   bool
is_virtual()4442   is_virtual() const
4443   {return is_virtual_;}
4444 
4445   void
is_virtual(bool is_virtual)4446   is_virtual(bool is_virtual)
4447   {is_virtual_ = is_virtual;}
4448 
4449   /// Getter for the vtable offset property.
4450   ///
4451   /// This is the vtable offset of the member function of this
4452   /// relation.
4453   ///
4454   /// @return the vtable offset property of the relation.
4455   size_t
vtable_offset()4456   vtable_offset() const
4457   {return vtable_offset_in_bits_;}
4458 
4459   /// Setter for the vtable offset property.
4460   ///
4461   /// This is the vtable offset of the member function of this
4462   /// relation.
4463   ///
4464   /// @partam s the new vtable offset.
4465   void
vtable_offset(size_t s)4466   vtable_offset(size_t s)
4467   {vtable_offset_in_bits_ = s;}
4468 
4469   /// Getter for the 'is-constructor' property.
4470   ///
4471   /// This tells if the member function of this relation is a
4472   /// constructor.
4473   ///
4474   /// @return the is-constructor property of the relation.
4475   bool
is_constructor()4476   is_constructor() const
4477   {return is_constructor_;}
4478 
4479   /// Setter for the 'is-constructor' property.
4480   ///
4481   /// @param f the new value of the the property.  Is true if this is
4482   /// for a constructor, false otherwise.
4483   void
is_constructor(bool f)4484   is_constructor(bool f)
4485   {is_constructor_ = f;}
4486 
4487   /// Getter for the 'is-destructor' property.
4488   ///
4489   /// Tells if the member function of this relation is a destructor.
4490   ///
4491   /// @return the is-destructor property of the relation;
4492   bool
is_destructor()4493   is_destructor() const
4494   {return is_destructor_;}
4495 
4496   /// Setter for the 'is-destructor' property.
4497   ///
4498   /// @param f the new value of the property.  Is true if this is for
4499   /// a destructor, false otherwise.
4500   void
is_destructor(bool f)4501   is_destructor(bool f)
4502   {is_destructor_ = f;}
4503 
4504   /// Getter for the 'is-const' property.
4505   ///
4506   /// Tells if the member function of this relation is a const member
4507   /// function.
4508   ///
4509   /// @return the 'is-const' property of the relation.
4510   bool
is_const()4511   is_const() const
4512   {return is_const_;}
4513 
4514   /// Setter for the 'is-const' property.
4515   ///
4516   /// @param f the new value of the property.  Is true if this is for
4517   /// a const entity, false otherwise.
4518   void
is_const(bool f)4519   is_const(bool f)
4520   {is_const_ = f;}
4521 
4522   virtual ~mem_fn_context_rel();
4523 }; // end class mem_fn_context_rel
4524 
4525 method_decl*
4526 is_method_decl(const type_or_decl_base*);
4527 
4528 method_decl*
4529 is_method_decl(const type_or_decl_base&);
4530 
4531 method_decl_sptr
4532 is_method_decl(const type_or_decl_base_sptr&);
4533 
4534 const var_decl*
4535 lookup_data_member(const type_base* type,
4536 		   const char* dm_name);
4537 
4538 const function_decl::parameter*
4539 get_function_parameter(const decl_base* fun,
4540 		       unsigned parm_num);
4541 
4542 /// Abstract a member function template.
4543 class member_function_template : public member_base, public virtual decl_base
4544 {
4545   bool is_constructor_;
4546   bool is_const_;
4547   shared_ptr<function_tdecl> fn_tmpl_;
4548 
4549   // Forbiden
4550   member_function_template();
4551 
4552 public:
4553   /// Hasher.
4554   struct hash;
4555 
member_function_template(function_tdecl_sptr f,access_specifier access,bool is_static,bool is_constructor,bool is_const)4556   member_function_template(function_tdecl_sptr f,
4557 			   access_specifier access, bool is_static,
4558 			   bool is_constructor, bool is_const)
4559     : type_or_decl_base(f->get_environment()),
4560       decl_base(f->get_environment(), f->get_name(), location()),
4561       member_base(access, is_static), is_constructor_(is_constructor),
4562       is_const_(is_const), fn_tmpl_(f)
4563   {}
4564 
4565   bool
is_constructor()4566   is_constructor() const
4567   {return is_constructor_;}
4568 
4569   bool
is_const()4570   is_const() const
4571   {return is_const_;}
4572 
4573   operator const function_tdecl& () const
4574   {return *fn_tmpl_;}
4575 
4576   function_tdecl_sptr
as_function_tdecl()4577   as_function_tdecl() const
4578   {return fn_tmpl_;}
4579 
4580   virtual bool
4581   operator==(const member_base& o) const;
4582 
4583   virtual bool
4584   traverse(ir_node_visitor&);
4585 };// end class member_function_template
4586 
4587 bool
4588 operator==(const member_function_template_sptr& l,
4589 	   const member_function_template_sptr& r);
4590 
4591 bool
4592 operator!=(const member_function_template_sptr& l,
4593 	   const member_function_template_sptr& r);
4594 
4595 /// Abstracts a member class template template
4596 class member_class_template
4597   : public member_base,
4598     public virtual decl_base
4599 {
4600   shared_ptr<class_tdecl> class_tmpl_;
4601 
4602   // Forbidden
4603   member_class_template();
4604 
4605 public:
4606 
4607   /// Hasher.
4608   struct hash;
4609 
member_class_template(class_tdecl_sptr c,access_specifier access,bool is_static)4610   member_class_template(class_tdecl_sptr c,
4611 			access_specifier access, bool is_static)
4612     : type_or_decl_base(c->get_environment()),
4613       decl_base(c->get_environment(), c->get_name(), location()),
4614       member_base(access, is_static),
4615       class_tmpl_(c)
4616   {}
4617 
4618   operator const class_tdecl& () const
4619   { return *class_tmpl_; }
4620 
4621   class_tdecl_sptr
as_class_tdecl()4622   as_class_tdecl() const
4623   {return class_tmpl_;}
4624 
4625   virtual bool
4626   operator==(const member_base& o) const;
4627 
4628   virtual bool
4629   operator==(const member_class_template&) const;
4630 
4631   virtual bool
4632   traverse(ir_node_visitor& v);
4633 };// end class member_class_template
4634 
4635 bool
4636 operator==(const member_class_template_sptr& l,
4637 	   const member_class_template_sptr& r);
4638 
4639 bool
4640 operator!=(const member_class_template_sptr& l,
4641 	   const member_class_template_sptr& r);
4642 
4643 // Forward declarations for select nested hashers.
4644 struct type_base::shared_ptr_hash
4645 {
4646   size_t
4647   operator()(const shared_ptr<type_base> t) const;
4648 };
4649 
4650 struct type_base::dynamic_hash
4651 {
4652   size_t
4653   operator()(const type_base* t) const;
4654 };
4655 
4656 /// A hashing functor for instances and pointers of @ref var_decl.
4657 struct var_decl::hash
4658 {
4659   size_t
4660   operator()(const var_decl& t) const;
4661 
4662   size_t
4663   operator()(const var_decl* t) const;
4664 }; //end struct var_decl::hash
4665 
4666 /// A comparison functor for pointers to @ref var_decl.
4667 struct var_decl::ptr_equal
4668 {
4669   /// Return true if the two instances of @ref var_decl are equal.
4670   ///
4671   /// @param l the first variable to compare.
4672   ///
4673   /// @param r the second variable to compare.
4674   ///
4675   /// @return true if @p l equals @p r.
4676   bool
operatorptr_equal4677   operator()(const var_decl* l, const var_decl* r) const
4678   {
4679     if (l == r)
4680       return true;
4681     if (!!l != !!r)
4682       return false;
4683     return (*l == *r);
4684   }
4685 };// end struct var_decl::ptr_equal
4686 
4687 /// A hashing functor fo instances and pointers of @ref function_decl.
4688 struct function_decl::hash
4689 {
4690   size_t
4691   operator()(const function_decl& t) const;
4692 
4693   size_t
4694   operator()(const function_decl* t) const;
4695 };//end struct function_decl::hash
4696 
4697 /// Equality functor for instances of @ref function_decl
4698 struct function_decl::ptr_equal
4699 {
4700   /// Tests if two pointers to @ref function_decl are equal.
4701   ///
4702   /// @param l the first pointer to @ref function_decl to consider in
4703   /// the comparison.
4704   ///
4705   /// @param r the second pointer to @ref function_decl to consider in
4706   /// the comparison.
4707   ///
4708   /// @return true if the two functions @p l and @p r are equal, false
4709   /// otherwise.
4710   bool
operatorptr_equal4711   operator()(const function_decl* l, const function_decl* r) const
4712   {
4713     if (l == r)
4714       return true;
4715     if (!!l != !!r)
4716       return false;
4717     return (*l == *r);
4718   }
4719 };// function_decl::ptr_equal
4720 
4721 /// The hashing functor for class_decl::base_spec.
4722 struct class_decl::base_spec::hash
4723 {
4724   size_t
4725   operator()(const base_spec& t) const;
4726 };
4727 
4728 /// The hashing functor for member_base.
4729 struct member_base::hash
4730 {
4731   size_t
4732   operator()(const member_base& m) const;
4733 };
4734 
4735 /// The hashing functor for member_function_template.
4736 struct member_function_template::hash
4737 {
4738   size_t
4739   operator()(const member_function_template& t) const;
4740 };
4741 
4742 /// The hashing functor for member_class_template
4743 struct member_class_template::hash
4744 {
4745   size_t
4746   operator()(const member_class_template& t) const;
4747 };
4748 
4749 struct function_tdecl::hash
4750 {
4751   size_t
4752   operator()(const function_tdecl& t) const;
4753 };
4754 
4755 struct function_tdecl::shared_ptr_hash
4756 {
4757   size_t
4758   operator()(const shared_ptr<function_tdecl> f) const;
4759 };
4760 
4761 struct class_tdecl::hash
4762 {
4763   size_t
4764   operator()(const class_tdecl& t) const;
4765 };
4766 
4767 struct class_tdecl::shared_ptr_hash
4768 {
4769   size_t
4770   operator()(const shared_ptr<class_tdecl> t) const;
4771 };
4772 
4773 /// The base class for the visitor type hierarchy used for traversing
4774 /// a translation unit.
4775 ///
4776 /// Client code willing to get notified for a certain kind of node
4777 /// during the IR traversal might want to define a visitor class that
4778 /// inherit ir_node_visitor, overload the ir_node_visitor::visit_begin()
4779 /// or ir_node_visitor::visit_end() method of its choice, and provide
4780 /// and implementation for it.  If either
4781 /// ir_node_visitor::visit_begin() or ir_node_visitor::visit_end()
4782 /// return false, it means the traversal has to stop immediately after
4783 /// the methods' return.  If the methods return true, it means the
4784 /// traversal keeps going.
4785 ///
4786 /// That new visitor class would then be passed to e.g,
4787 /// translation_unit::traverse or to the traverse method of any type
4788 /// where the traversal is supposed to start from.
4789 class ir_node_visitor : public node_visitor_base
4790 {
4791   struct priv;
4792   std::unique_ptr<priv> priv_;
4793 
4794 public:
4795 
4796   ir_node_visitor();
4797 
4798   virtual ~ir_node_visitor();
4799 
4800   void allow_visiting_already_visited_type_node(bool);
4801   bool allow_visiting_already_visited_type_node() const;
4802   void mark_type_node_as_visited(type_base *);
4803   void forget_visited_type_nodes();
4804   bool type_node_has_been_visited(type_base*) const;
4805 
4806   virtual bool visit_begin(decl_base*);
4807   virtual bool visit_end(decl_base*);
4808 
4809   virtual bool visit_begin(scope_decl*);
4810   virtual bool visit_end(scope_decl*);
4811 
4812   virtual bool visit_begin(type_base*);
4813   virtual bool visit_end(type_base*);
4814 
4815   virtual bool visit_begin(scope_type_decl*);
4816   virtual bool visit_end(scope_type_decl*);
4817 
4818   virtual bool visit_begin(type_decl*);
4819   virtual bool visit_end(type_decl*);
4820 
4821   virtual bool visit_begin(namespace_decl*);
4822   virtual bool visit_end(namespace_decl*);
4823 
4824   virtual bool visit_begin(qualified_type_def*);
4825   virtual bool visit_end(qualified_type_def*);
4826 
4827   virtual bool visit_begin(pointer_type_def*);
4828   virtual bool visit_end(pointer_type_def*);
4829 
4830   virtual bool visit_begin(reference_type_def*);
4831   virtual bool visit_end(reference_type_def*);
4832 
4833   virtual bool visit_begin(array_type_def*);
4834   virtual bool visit_end(array_type_def*);
4835 
4836   virtual bool visit_begin(array_type_def::subrange_type*);
4837   virtual bool visit_end(array_type_def::subrange_type*);
4838 
4839   virtual bool visit_begin(enum_type_decl*);
4840   virtual bool visit_end(enum_type_decl*);
4841 
4842   virtual bool visit_begin(typedef_decl*);
4843   virtual bool visit_end(typedef_decl*);
4844 
4845   virtual bool visit_begin(function_type*);
4846   virtual bool visit_end(function_type*);
4847 
4848   virtual bool visit_begin(var_decl*);
4849   virtual bool visit_end(var_decl*);
4850 
4851   virtual bool visit_begin(function_decl*);
4852   virtual bool visit_end(function_decl*);
4853 
4854   virtual bool visit_begin(function_decl::parameter*);
4855   virtual bool visit_end(function_decl::parameter*);
4856 
4857   virtual bool visit_begin(function_tdecl*);
4858   virtual bool visit_end(function_tdecl*);
4859 
4860   virtual bool visit_begin(class_tdecl*);
4861   virtual bool visit_end(class_tdecl*);
4862 
4863   virtual bool visit_begin(class_or_union *);
4864   virtual bool visit_end(class_or_union *);
4865 
4866   virtual bool visit_begin(class_decl*);
4867   virtual bool visit_end(class_decl*);
4868 
4869   virtual bool visit_begin(union_decl*);
4870   virtual bool visit_end(union_decl*);
4871 
4872   virtual bool visit_begin(class_decl::base_spec*);
4873   virtual bool visit_end(class_decl::base_spec*);
4874 
4875   virtual bool visit_begin(member_function_template*);
4876   virtual bool visit_end(member_function_template*);
4877 
4878   virtual bool visit_begin(member_class_template*);
4879   virtual bool visit_end(member_class_template*);
4880 }; // end struct ir_node_visitor
4881 
4882 // Debugging facility
4883 void
4884 fns_to_str(vector<function_decl*>::const_iterator a_begin,
4885 	   vector<function_decl*>::const_iterator a_end,
4886 	   vector<function_decl*>::const_iterator b_begin,
4887 	   vector<function_decl*>::const_iterator b_end,
4888 	   std::ostream& o);
4889 
4890 }// end namespace ir
4891 } // end namespace abigail
4892 #endif // __ABG_IR_H__
4893