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