• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2013-2022 Red Hat, Inc.
5 //
6 // Author: Dodji Seketeli
7 
8 #ifndef __ABG_COMPARISON_H__
9 #define __ABG_COMPARISON_H__
10 
11 /// @file
12 
13 #include <memory>
14 #include <ostream>
15 #include <unordered_map>
16 #include <unordered_set>
17 #include "abg-corpus.h"
18 #include "abg-diff-utils.h"
19 #include "abg-reporter.h"
20 
21 namespace abigail
22 {
23 
24 /// @brief utilities to compare abi artifacts
25 ///
26 /// The main entry points of the namespace are the compute_diff()
27 /// overloads used to compute the difference between two abi artifacts.
28 namespace comparison
29 {
30 
31 namespace filtering
32 {
33 struct filter_base;
34 typedef shared_ptr<filter_base> filter_base_sptr;
35 typedef std::vector<filter_base_sptr> filters;
36 }
37 
38 // Inject types we need into this namespace.
39 using std::ostream;
40 using std::vector;
41 using std::unordered_map;
42 using std::unordered_set;
43 using std::pair;
44 
45 using diff_utils::insertion;
46 using diff_utils::deletion;
47 using diff_utils::edit_script;
48 
49 class diff;
50 
51 /// Convenience typedef for a shared_ptr for the @ref diff class
52 typedef shared_ptr<diff> diff_sptr;
53 
54 /// Convenience typedef for a weak_ptr for the @ref diff class
55 typedef weak_ptr<diff> diff_wptr;
56 
57 /// Hasher for @ref diff_sptr.
58 struct diff_sptr_hasher
59 {
60   /// The actual hashing functor.
61   size_t
operatordiff_sptr_hasher62   operator()(const diff_sptr& t) const
63   {return reinterpret_cast<size_t>(t.get());}
64 }; // end struct diff_sptr_hasher
65 
66 /// Convenience typedef for a vector of @ref diff_sptr.
67 typedef vector<diff_sptr> diff_sptrs_type;
68 
69 /// Convenience typedef for a vector of @ref diff*.
70 typedef vector<diff*> diff_ptrs_type;
71 
72 /// Convenience typedef for an unoredered set of @ref diff_sptr
73 typedef unordered_set<diff_sptr, diff_sptr_hasher> unordered_diff_sptr_set;
74 
75 class decl_diff_base;
76 
77 /// Convenience typedef for a shared_ptr of @ref decl_diff_base.
78 typedef shared_ptr<decl_diff_base> decl_diff_base_sptr;
79 
80 /// Convenience typedef for a vector of @ref decl_diff_base_sptr.
81 typedef vector<decl_diff_base_sptr> decl_diff_base_sptrs_type;
82 
83 class type_diff_base;
84 /// Convenience pointer for a shared pointer to a type_diff_base
85 typedef shared_ptr<type_diff_base> type_diff_base_sptr;
86 
87 /// Convenience typedef for a vector of @ref type_diff_base_sptr
88 typedef vector<type_diff_base_sptr> type_diff_base_sptrs_type;
89 
90 class function_decl_diff;
91 
92 /// Convenience typedef for a shared pointer to a @ref function_decl type.
93 typedef shared_ptr<function_decl_diff> function_decl_diff_sptr;
94 
95 /// Convenience typedef for a vector of @ref function_decl_diff_sptr
96 typedef vector<function_decl_diff_sptr> function_decl_diff_sptrs_type;
97 
98 class fn_parm_diff;
99 
100 /// Convenience typedef for a shared pointer to a @ref fn_parm_diff
101 /// type.
102 typedef shared_ptr<fn_parm_diff> fn_parm_diff_sptr;
103 
104 class var_diff;
105 
106 /// Convenience typedef for a shared pointer to a @ref var_diff type.
107 typedef shared_ptr<var_diff> var_diff_sptr;
108 
109 /// Convenience typedef for a vector of @ref var_diff_sptr.
110 typedef vector<var_diff_sptr> var_diff_sptrs_type;
111 
112 class base_diff;
113 
114 /// Convenience typedef for a shared pointer to a @ref base_diff type.
115 typedef shared_ptr<base_diff> base_diff_sptr;
116 
117 /// Convenience typedef for a vector of @ref base_diff_sptr.
118 typedef vector<base_diff_sptr> base_diff_sptrs_type;
119 
120 class class_diff;
121 
122 /// Convenience typedef for a shared pointer on a @ref class_diff type.
123 typedef shared_ptr<class_diff> class_diff_sptr;
124 
125 /// Convenience typedef for a map of pointer values.  The Key is a
126 /// pointer value and the value is potentially another pointer value
127 /// associated to the first one.
128 typedef unordered_map<size_t, size_t> pointer_map;
129 
130 /// Convenience typedef for a map which key is a string and which
131 /// value is a @ref decl_base_sptr.
132 typedef unordered_map<string, decl_base_sptr> string_decl_base_sptr_map;
133 
134 /// Convenience typedef for a map which key is a string and which
135 /// value is a @ref type_base_sptr.
136 typedef unordered_map<string, type_base_sptr> string_type_base_sptr_map;
137 
138 /// Convenience typedef for a map which key is an unsigned integer and
139 /// which value is a @ref decl_base_sptr
140 typedef unordered_map<unsigned, decl_base_sptr> unsigned_decl_base_sptr_map;
141 
142 /// Convenience typedef for a map of string and class_decl::basse_spec_sptr.
143 typedef unordered_map<string, class_decl::base_spec_sptr> string_base_sptr_map;
144 
145 /// Convenience typedef for a map of string and @ref base_diff_sptr.
146 typedef unordered_map<string, base_diff_sptr> string_base_diff_sptr_map;
147 
148 /// Convenience typedef for a map which value is a changed function
149 /// parameter and which key is the name of the function parameter.
150 typedef unordered_map<string, fn_parm_diff_sptr> string_fn_parm_diff_sptr_map;
151 
152 /// Convenience typedef for a map which key is an integer and which
153 /// value is a changed parameter.
154 typedef unordered_map<unsigned, fn_parm_diff_sptr>
155 unsigned_fn_parm_diff_sptr_map;
156 
157 /// Convenience typedef for a map which key is an integer and which
158 /// value is a parameter.
159 typedef unordered_map<unsigned,
160 		      function_decl::parameter_sptr> unsigned_parm_map;
161 
162 /// Convenience typedef for a map which value is a
163 /// type_diff_base_sptr.  The key of the map is the qualified name of
164 /// the changed type.
165 typedef unordered_map<string,
166 		      type_diff_base_sptr> string_type_diff_base_sptr_map;
167 
168 /// Convenience typedef for a map which value is a
169 /// decl_diff_base_sptr.  The key of the map is the qualified name of
170 /// the changed type.
171 typedef unordered_map<string,
172 		      decl_diff_base_sptr> string_decl_diff_base_sptr_map;
173 
174 /// Convenience typedef for a map which value is a diff_sptr.  The key
175 /// of the map is the qualified name of the changed type.
176 typedef unordered_map<string, diff_sptr> string_diff_sptr_map;
177 
178 /// Convenience typedef for a map which value is a diff*.  The key of
179 /// the map is the qualified name of the changed type.
180 typedef unordered_map<string, diff*> string_diff_ptr_map;
181 
182 /// Convenience typedef for a map whose key is a string and whose
183 /// value is a changed variable of type @ref var_diff_sptr.
184 typedef unordered_map<string,
185 		      var_diff_sptr> string_var_diff_sptr_map;
186 
187 
188 /// Convenience typedef for a map whose key is an unsigned int and
189 /// whose value is a changed variable of type @ref var_diff_sptr.
190 typedef unordered_map<unsigned, var_diff_sptr> unsigned_var_diff_sptr_map;
191 
192 /// Convenience typedef for a map which value is a function
193 /// parameter.  The key is the name of the function parm.
194 typedef unordered_map<string, function_decl::parameter_sptr> string_parm_map;
195 
196 /// Convenience typedef for a map which value is an enumerator.  The
197 /// key is the name of the enumerator.
198 typedef unordered_map<string, enum_type_decl::enumerator> string_enumerator_map;
199 
200 /// Convenience typedef for a changed enumerator.  The first element
201 /// of the pair is the old enumerator and the second one is the new enumerator.
202 typedef std::pair<enum_type_decl::enumerator,
203 		  enum_type_decl::enumerator> changed_enumerator;
204 
205 /// Convenience typedef for a vector of changed enumerators.
206 typedef vector<changed_enumerator> changed_enumerators_type;
207 
208 /// Convenience typedef for a map which value is a changed enumerator.
209 /// The key is the name of the changed enumerator.
210 typedef unordered_map<string, changed_enumerator> string_changed_enumerator_map;
211 
212 /// Convenience typedef for a map which key is a string and which
213 /// value is a pointer to @ref decl_base.
214 typedef unordered_map<string, function_decl*> string_function_ptr_map;
215 
216 /// Convenience typedef for a map which key is a string and which
217 /// value is a @ref function_decl_diff_sptr.
218 typedef unordered_map<string,
219 		      function_decl_diff_sptr>
220 				string_function_decl_diff_sptr_map;
221 
222 /// Convenience typedef for a pair of class_decl::member_function_sptr
223 /// representing a changed member function.  The first element of the
224 /// pair is the initial member function and the second element is the
225 /// changed one.
226 typedef pair<method_decl_sptr,
227 	     method_decl_sptr> changed_member_function_sptr;
228 
229 /// Convenience typedef for a hash map of strings and changed member functions.
230 typedef unordered_map<string,
231 		      changed_member_function_sptr>
232 				string_changed_member_function_sptr_map;
233 
234 /// Convenience typedef for a hash map of strings  and member functions.
235 typedef unordered_map<string, method_decl_sptr> string_member_function_sptr_map;
236 
237 /// Convenience typedef for a map which key is a string and which
238 /// value is a point to @ref var_decl.
239 typedef unordered_map<string, var_decl*> string_var_ptr_map;
240 
241 /// Convenience typedef for a pair of pointer to @ref var_decl
242 /// representing a @ref var_decl change.  The first member of the pair
243 /// represents the initial variable and the second member represents
244 /// the changed variable.
245 typedef std::pair<var_decl*, var_decl*> changed_var_ptr;
246 
247 /// Convenience typedef for a pair of @ref var_decl_sptr representing
248 /// a @ref var_decl change.  The first member of the pair represents
249 /// the initial variable and the second member represents the changed
250 /// variable.
251 typedef std::pair<var_decl_sptr, var_decl_sptr> changed_var_sptr;
252 
253 /// Convenience typedef for a vector of @changed_var_sptr.gg381
254 typedef vector<changed_var_sptr> changed_var_sptrs_type;
255 
256 /// Convenience typedef for a map whose key is a string and whose
257 /// value is an @ref elf_symbol_sptr.
258 typedef unordered_map<string, elf_symbol_sptr> string_elf_symbol_map;
259 
260 /// Convenience typedef for a map which key is a string and which
261 /// value is a @ref var_diff_sptr.
262 typedef unordered_map<string, var_diff_sptr> string_var_diff_ptr_map;
263 
264 class diff_context;
265 
266 /// Convenience typedef for a shared pointer of @ref diff_context.
267 typedef shared_ptr<diff_context> diff_context_sptr;
268 
269 /// Convenience typedef for a weak pointer of @ref diff_context.
270 typedef weak_ptr<diff_context> diff_context_wptr;
271 
272 class diff_node_visitor;
273 
274 class diff_traversable_base;
275 
276 /// Convenience typedef for shared_ptr on diff_traversable_base.
277 typedef shared_ptr<diff_traversable_base> diff_traversable_base_sptr;
278 
279 /// An enum for the different ways to visit a diff tree node.
280 ///
281 /// This is used by the node traversing code, to know when to avoid
282 /// visiting children nodes, for instance.
283 enum visiting_kind
284 {
285   /// The default enumerator value of this enum.  It doesn't have any
286   /// particular meaning yet.
287   DEFAULT_VISITING_KIND = 0,
288 
289   /// This says that the traversing code should avoid visiting the
290   /// children nodes of the current node being visited.
291   SKIP_CHILDREN_VISITING_KIND = 1,
292 
293   /// This says that the traversing code should not mark visited nodes
294   /// as having been traversed.  This is useful, for instance, for
295   /// visitors which have debugging purposes.
296   DO_NOT_MARK_VISITED_NODES_AS_VISITED = 1 << 1
297 };
298 
299 visiting_kind
300 operator|(visiting_kind l, visiting_kind r);
301 
302 visiting_kind
303 operator&(visiting_kind l, visiting_kind r);
304 
305 visiting_kind
306 operator~(visiting_kind l);
307 
308 ///  The base class for the diff classes that are to be traversed.
309 class diff_traversable_base : public traversable_base
310 {
311 public:
312   virtual bool
313   traverse(diff_node_visitor& v);
314 }; // end struct diff_traversable_base
315 
316 /// An enum for the different categories that a diff tree node falls
317 /// into, regarding the kind of changes it represents.
318 ///
319 /// Note that if you add an enumerator to this enum, you need to
320 /// update a few spots accordingly:
321 ///
322 ///   * update the ACCESS_CHANGE_CATEGORY enumerator (which is the
323 ///     last enumerator of this enum by OR-ing its initializer with
324 ///     the new enumerator.
325 ///
326 ///   * update the categorize_harmless_diff_node or
327 ///     categorize_harmful_diff_node function depending on if the new
328 ///     enumerator classifies diff nodes as harmless or harmful.
329 ///
330 ///   * update the get_default_harmless_categories_bitmap or
331 ///    get_default_harmful_categories_bitmap function as well, just
332 ///    like above.
333 ///
334 ///   * update the "operator<<(ostream& o, diff_category c)" streaming
335 ///     operator so that it can stream the new enumerator to a textual
336 ///     output stream.
337 enum diff_category
338 {
339   /// This means the diff node does not carry any (meaningful) change,
340   /// or that it carries changes that have not yet been categorized.
341   NO_CHANGE_CATEGORY = 0,
342 
343   /// This means the diff node (or at least one of its descendant
344   /// nodes) carries access related changes, e.g, a private member
345   /// that becomes public.
346   ACCESS_CHANGE_CATEGORY = 1,
347 
348   /// This means the diff node (or at least one of its descendant
349   /// nodes) carries a change involving two compatible types.  For
350   /// instance a type and its typedefs.
351   COMPATIBLE_TYPE_CHANGE_CATEGORY = 1 << 1,
352 
353   /// This means that a diff node in the sub-tree carries a harmless
354   /// declaration name change.  This is set only for name changes for
355   /// data members and typedefs.
356   HARMLESS_DECL_NAME_CHANGE_CATEGORY = 1 << 2,
357 
358   /// This means that a diff node in the sub-tree carries an addition
359   /// or removal of a non-virtual member function.
360   NON_VIRT_MEM_FUN_CHANGE_CATEGORY = 1 << 3,
361 
362   /// This means that a diff node in the sub-tree carries an addition
363   /// or removal of a static data member.
364   STATIC_DATA_MEMBER_CHANGE_CATEGORY = 1 << 4,
365 
366   /// This means that a diff node in the sub-tree carries an addition
367   /// of enumerator to an enum type.
368   HARMLESS_ENUM_CHANGE_CATEGORY = 1 << 5,
369 
370   /// This means that a diff node in the sub-tree carries an a symbol
371   /// alias change that is harmless.
372   HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY = 1 << 6,
373 
374   /// This means that a diff node in the sub-tree carries a harmless
375   /// union change.
376   HARMLESS_UNION_CHANGE_CATEGORY = 1 << 7,
377 
378   /// This means that a diff node in the sub-tree carries a harmless
379   /// data member change.  An example of harmless data member change
380   /// is an anonymous data member that replaces a given data member
381   /// without locally changing the layout.
382   HARMLESS_DATA_MEMBER_CHANGE_CATEGORY = 1 << 8,
383 
384   /// This means that a diff node was marked as suppressed by a
385   /// user-provided suppression specification.
386   SUPPRESSED_CATEGORY = 1 << 9,
387 
388   /// This means that a diff node was warked as being for a private
389   /// type.  That is, the diff node is meant to be suppressed by a
390   /// suppression specification that was auto-generated to filter out
391   /// changes to private types.
392   PRIVATE_TYPE_CATEGORY = 1 << 10,
393 
394   /// This means the diff node (or at least one of its descendant
395   /// nodes) carries a change that modifies the size of a type or an
396   /// offset of a type member.  Removal or changes of enumerators in a
397   /// enum fall in this category too.
398   SIZE_OR_OFFSET_CHANGE_CATEGORY = 1 << 11,
399 
400   /// This means that a diff node in the sub-tree carries an
401   /// incompatible change to a vtable.
402   VIRTUAL_MEMBER_CHANGE_CATEGORY = 1 << 12,
403 
404   /// A diff node in this category is redundant.  That means it's
405   /// present as a child of a other nodes in the diff tree.
406   REDUNDANT_CATEGORY = 1 << 13,
407 
408   /// This means that a diff node in the sub-tree carries a type that
409   /// was declaration-only and that is now defined, or vice versa.
410   TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY = 1 << 14,
411 
412   /// A diff node in this category is a function parameter type which
413   /// top cv-qualifiers change.
414   FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY = 1 << 15,
415 
416   /// A diff node in this category has a function parameter type with a
417   /// cv-qualifiers change.
418   FN_PARM_TYPE_CV_CHANGE_CATEGORY = 1 << 16,
419 
420   /// A diff node in this category is a function return type with a
421   /// cv-qualifier change.
422   FN_RETURN_TYPE_CV_CHANGE_CATEGORY = 1 << 17,
423 
424   /// A diff node in this category is a function (or function type)
425   /// with at least one parameter added or removed.
426   FN_PARM_ADD_REMOVE_CHANGE_CATEGORY = 1 << 18,
427 
428   /// A diff node in this category is for a variable which type holds
429   /// a cv-qualifier change.
430   VAR_TYPE_CV_CHANGE_CATEGORY = 1 << 19,
431 
432   /// A diff node in this category carries a change from void pointer
433   /// to non-void pointer.
434   VOID_PTR_TO_PTR_CHANGE_CATEGORY = 1 << 20,
435 
436   /// A diff node in this category carries a change in the size of the
437   /// array type of a global variable, but the ELF size of the
438   /// variable didn't change.
439   BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY = 1 << 21,
440 
441   /// A special enumerator that is the logical 'or' all the
442   /// enumerators above.
443   ///
444   /// This one must stay the last enumerator.  Please update it each
445   /// time you add a new enumerator above.
446   EVERYTHING_CATEGORY =
447   ACCESS_CHANGE_CATEGORY
448   | COMPATIBLE_TYPE_CHANGE_CATEGORY
449   | HARMLESS_DECL_NAME_CHANGE_CATEGORY
450   | NON_VIRT_MEM_FUN_CHANGE_CATEGORY
451   | STATIC_DATA_MEMBER_CHANGE_CATEGORY
452   | HARMLESS_ENUM_CHANGE_CATEGORY
453   | HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY
454   | HARMLESS_UNION_CHANGE_CATEGORY
455   | HARMLESS_DATA_MEMBER_CHANGE_CATEGORY
456   | SUPPRESSED_CATEGORY
457   | PRIVATE_TYPE_CATEGORY
458   | SIZE_OR_OFFSET_CHANGE_CATEGORY
459   | VIRTUAL_MEMBER_CHANGE_CATEGORY
460   | REDUNDANT_CATEGORY
461   | TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY
462   | FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY
463   | FN_PARM_TYPE_CV_CHANGE_CATEGORY
464   | FN_RETURN_TYPE_CV_CHANGE_CATEGORY
465   | FN_PARM_ADD_REMOVE_CHANGE_CATEGORY
466   | VAR_TYPE_CV_CHANGE_CATEGORY
467   | VOID_PTR_TO_PTR_CHANGE_CATEGORY
468   | BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY
469 }; // enum diff_category
470 
471 diff_category
472 operator|(diff_category c1, diff_category c2);
473 
474 diff_category&
475 operator|=(diff_category& c1, diff_category c2);
476 
477 diff_category&
478 operator&=(diff_category& c1, diff_category c2);
479 
480 diff_category
481 operator^(diff_category c1, diff_category c2);
482 
483 diff_category
484 operator&(diff_category c1, diff_category c2);
485 
486 diff_category
487 operator~(diff_category c);
488 
489 diff_category
490 get_default_harmless_categories_bitmap();
491 
492 diff_category
493 get_default_harmful_categories_bitmap();
494 
495 ostream&
496 operator<<(ostream& o, diff_category);
497 
498 class corpus_diff;
499 
500 /// This type contains maps.  Each map associates a type name to a
501 /// diff of that type. Not all kinds of diffs are present; only those
502 /// that carry leaf changes are, for now.
503 class diff_maps
504 {
505   struct priv;
506   std::unique_ptr<priv> priv_;
507 
508 public:
509 
510   diff_maps();
511 
512   ~diff_maps();
513 
514   const string_diff_ptr_map&
515   get_type_decl_diff_map() const;
516 
517   string_diff_ptr_map&
518   get_type_decl_diff_map();
519 
520   const string_diff_ptr_map&
521   get_enum_diff_map() const;
522 
523   string_diff_ptr_map&
524   get_enum_diff_map();
525 
526   const string_diff_ptr_map&
527   get_class_diff_map() const;
528 
529   string_diff_ptr_map&
530   get_class_diff_map();
531 
532   const string_diff_ptr_map&
533   get_union_diff_map() const;
534 
535   string_diff_ptr_map&
536   get_union_diff_map();
537 
538   const string_diff_ptr_map&
539   get_typedef_diff_map() const;
540 
541   string_diff_ptr_map&
542   get_typedef_diff_map();
543 
544   const string_diff_ptr_map&
545   get_array_diff_map() const;
546 
547   string_diff_ptr_map&
548   get_array_diff_map();
549 
550   const string_diff_ptr_map&
551   get_reference_diff_map() const;
552 
553   string_diff_ptr_map&
554   get_reference_diff_map();
555 
556   const string_diff_ptr_map&
557   get_fn_parm_diff_map() const;
558 
559   string_diff_ptr_map&
560   get_fn_parm_diff_map();
561 
562   const string_diff_ptr_map&
563   get_function_type_diff_map() const;
564 
565   string_diff_ptr_map&
566   get_function_type_diff_map();
567 
568   const string_diff_ptr_map&
569   get_function_decl_diff_map() const;
570 
571   string_diff_ptr_map&
572   get_function_decl_diff_map();
573 
574   const string_diff_ptr_map&
575   get_var_decl_diff_map() const;
576 
577   string_diff_ptr_map&
578   get_var_decl_diff_map();
579 
580   const string_diff_ptr_map&
581   get_distinct_diff_map() const;
582 
583   string_diff_ptr_map&
584   get_distinct_diff_map();
585 
586   bool
587   insert_diff_node(const diff *d,
588 		   const type_or_decl_base_sptr& impacted_iface);
589 
590   artifact_sptr_set_type*
591   lookup_impacted_interfaces(const diff *d) const;
592 }; // end class diff_maps
593 
594 /// A convenience typedef for a shared pointer to @ref corpus_diff.
595 typedef shared_ptr<corpus_diff> corpus_diff_sptr;
596 
597 /// The context of the diff.  This type holds various bits of
598 /// information that is going to be used throughout the diffing of two
599 /// entities and the reporting that follows.
600 class diff_context
601 {
602   struct priv;
603   std::unique_ptr<priv> priv_;
604 
605   diff_sptr
606   has_diff_for(const type_or_decl_base_sptr first,
607 	       const type_or_decl_base_sptr second) const;
608 
609   diff_sptr
610   has_diff_for_types(const type_base_sptr first,
611 		     const type_base_sptr second) const;
612 
613   const diff*
614   has_diff_for(const diff* d) const;
615 
616   diff_sptr
617   has_diff_for(const diff_sptr d) const;
618 
619   void
620   add_diff(const type_or_decl_base_sptr first,
621 	   const type_or_decl_base_sptr second,
622 	   const diff_sptr d);
623 
624   void
625   add_diff(const diff_sptr d);
626 
627   void
628   add_diff(const diff* d);
629 
630   void
631   set_canonical_diff_for(const type_or_decl_base_sptr first,
632 			 const type_or_decl_base_sptr second,
633 			 const diff_sptr);
634 
635   diff_sptr
636   set_or_get_canonical_diff_for(const type_or_decl_base_sptr first,
637 				const type_or_decl_base_sptr second,
638 				const diff_sptr canonical_diff);
639 
640 public:
641   diff_context();
642 
643   ~diff_context();
644 
645   void
646   set_corpus_diff(const corpus_diff_sptr&);
647 
648   const corpus_diff_sptr&
649   get_corpus_diff() const;
650 
651   corpus_sptr
652   get_first_corpus() const;
653 
654   corpus_sptr
655   get_second_corpus() const;
656 
657   reporter_base_sptr
658   get_reporter() const;
659 
660   void
661   set_reporter(reporter_base_sptr&);
662 
663   diff_sptr
664   get_canonical_diff_for(const type_or_decl_base_sptr first,
665 			 const type_or_decl_base_sptr second) const;
666 
667   diff_sptr
668   get_canonical_diff_for(const diff_sptr d) const;
669 
670   void
671   initialize_canonical_diff(const diff_sptr diff);
672 
673   void
674   keep_diff_alive(diff_sptr&);
675 
676   diff*
677   diff_has_been_visited(const diff*) const;
678 
679   diff_sptr
680   diff_has_been_visited(const diff_sptr) const;
681 
682   void
683   mark_diff_as_visited(const diff*);
684 
685   void
686   forget_visited_diffs();
687 
688   void
689   mark_last_diff_visited_per_class_of_equivalence(const diff*);
690 
691   void
692   clear_last_diffs_visited_per_class_of_equivalence();
693 
694   const diff*
695   get_last_visited_diff_of_class_of_equivalence(const diff*);
696 
697   void
698   forbid_visiting_a_node_twice(bool f);
699 
700   bool
701   visiting_a_node_twice_is_forbidden() const;
702 
703   void
704   forbid_visiting_a_node_twice_per_interface(bool);
705 
706   bool
707   visiting_a_node_twice_is_forbidden_per_interface() const;
708 
709   diff_category
710   get_allowed_category() const;
711 
712   void
713   set_allowed_category(diff_category c);
714 
715   void
716   switch_categories_on(diff_category c);
717 
718   void
719   switch_categories_off(diff_category c);
720 
721   const filtering::filters&
722   diff_filters() const;
723 
724   void
725   add_diff_filter(filtering::filter_base_sptr);
726 
727   void
728   maybe_apply_filters(diff_sptr diff);
729 
730   void
731   maybe_apply_filters(corpus_diff_sptr diff);
732 
733   suppr::suppressions_type&
734   suppressions() const;
735 
736   void
737   add_suppression(const suppr::suppression_sptr suppr);
738 
739   void
740   add_suppressions(const suppr::suppressions_type& supprs);
741 
742   void
743   show_leaf_changes_only(bool f);
744 
745   bool
746   show_leaf_changes_only() const;
747 
748   bool
749   show_hex_values() const;
750 
751   void
752   show_hex_values(bool f);
753 
754   bool
755   show_offsets_sizes_in_bits() const;
756 
757   void
758   show_offsets_sizes_in_bits(bool f);
759 
760   void
761   show_relative_offset_changes(bool f);
762 
763   bool
764   show_relative_offset_changes(void);
765 
766   void
767   show_stats_only(bool f);
768 
769   bool
770   show_stats_only() const;
771 
772   void
773   show_soname_change(bool f);
774 
775   bool
776   show_soname_change() const;
777 
778   void
779   show_architecture_change(bool f);
780 
781   bool
782   show_architecture_change() const;
783 
784   void
785   show_deleted_fns(bool f);
786 
787   bool
788   show_deleted_fns() const;
789 
790   void
791   show_changed_fns(bool f);
792 
793   bool
794   show_changed_fns() const;
795 
796   void
797   show_added_fns(bool f);
798 
799   bool
800   show_added_fns() const;
801 
802   void
803   show_deleted_vars(bool f);
804 
805   bool
806   show_deleted_vars() const;
807 
808   void
809   show_changed_vars(bool f);
810 
811   bool
812   show_changed_vars() const;
813 
814   void
815   show_added_vars(bool f);
816 
817   bool
818   show_added_vars() const;
819 
820   bool
821   show_linkage_names() const;
822 
823   void
824   show_linkage_names(bool f);
825 
826   bool
827   show_locs() const;
828 
829   void
830   show_locs(bool f);
831 
832   bool
833   show_redundant_changes() const;
834 
835   void
836   show_redundant_changes(bool f);
837 
838   bool
839   show_symbols_unreferenced_by_debug_info() const;
840 
841   void
842   show_symbols_unreferenced_by_debug_info(bool f);
843 
844   bool
845   show_added_symbols_unreferenced_by_debug_info() const;
846 
847   void
848   show_added_symbols_unreferenced_by_debug_info(bool f);
849 
850   void show_unreachable_types(bool f);
851 
852   bool show_unreachable_types();
853 
854   bool
855   show_impacted_interfaces() const;
856 
857   void
858   show_impacted_interfaces(bool f);
859 
860   void
861   default_output_stream(ostream*);
862 
863   ostream*
864   default_output_stream();
865 
866   void
867   error_output_stream(ostream*);
868 
869   ostream*
870   error_output_stream() const;
871 
872   bool
873   dump_diff_tree() const;
874 
875   void
876   dump_diff_tree(bool f);
877 
878   void
879   do_dump_diff_tree(const diff_sptr) const;
880 
881   void
882   do_dump_diff_tree(const corpus_diff_sptr) const;
883 
884   friend class_diff_sptr
885   compute_diff(const class_decl_sptr	first,
886 	       const class_decl_sptr	second,
887 	       diff_context_sptr	ctxt);
888 };//end struct diff_context.
889 
890 /// The abstraction of a change between two ABI artifacts, a.k.a an
891 /// artifact change.
892 ///
893 /// In the grand scheme of things, a diff is strongly typed; for
894 /// instance, a change between two enums is represented by an
895 /// enum_diff type.  A change between two function_type is represented
896 /// by a function_type_diff type and a change between two class_decl
897 /// is represented by a class_diff type.  All of these types derive
898 /// from the @ref diff parent class.
899 ///
900 /// An artifact change D can have one (or more) details named D'. A
901 /// detail is an artifact change that "belongs" to another one.  Here,
902 /// D' belongs to D.  Or said otherwise, D' is a child change of D.
903 /// Said otherwise, D and D' are related, and the relation is a
904 /// "child relation".
905 ///
906 /// For instance, if we consider a change carried by a class_diff, the
907 /// detail change might be a change on one data member of the class.
908 /// In other word, the class_diff change might have a child diff node
909 /// that would be a var_diff node.
910 ///
911 /// There are two ways to get the child var_diff node (for the data
912 /// member change detail) of the class_diff.
913 ///
914 /// The first way is through the typed API, that is, through the
915 /// class_diff::sorted_changed_data_members() member function which
916 /// returns var_diff nodes.
917 ///
918 /// The second way is through the generic API, that is, through the
919 /// diff::children_nodes() member function which returns generic diff
920 /// nodes.  This second way enables us to walk the diff nodes graph in
921 /// a generic way, regardless of the types of the diff nodes.
922 ///
923 /// Said otherwise, there are two views for a given diff node.  There
924 /// is typed view, and there is the generic view.  In the typed view,
925 /// the details are accessed through the typed API.  In the generic
926 /// view, the details are gathered through the generic view.
927 ///
928 ///
929 /// Please read more about the @ref DiffNode "IR" of the comparison
930 /// engine to learn more about this.
931 ///
932 /// This type encapsulates an edit script (a set of insertions and
933 /// deletions) for two constructs that are to be diff'ed.  The two
934 /// constructs are called the "subjects" of the diff.
935 class diff : public diff_traversable_base
936 {
937   friend class diff_context;
938 
939   // Forbidden
940   diff();
941 
942 protected:
943   struct priv;
944   std::unique_ptr<priv> priv_;
945 
946   diff(type_or_decl_base_sptr first_subject,
947        type_or_decl_base_sptr second_subject);
948 
949   diff(type_or_decl_base_sptr	first_subject,
950        type_or_decl_base_sptr	second_subject,
951        diff_context_sptr	ctxt);
952 
953   void
954   begin_traversing();
955 
956   void
957   end_traversing();
958 
959   virtual void
960   finish_diff_type();
961 
962   void
963   set_canonical_diff(diff *);
964 
965 public:
966   type_or_decl_base_sptr
967   first_subject() const;
968 
969   type_or_decl_base_sptr
970   second_subject() const;
971 
972   const vector<diff*>&
973   children_nodes() const;
974 
975   const diff*
976   parent_node() const;
977 
978   diff* get_canonical_diff() const;
979 
980   bool
981   is_traversing() const;
982 
983   void
984   append_child_node(diff_sptr);
985 
986   const diff_context_sptr
987   context() const;
988 
989   void
990   context(diff_context_sptr c);
991 
992   bool
993   currently_reporting() const;
994 
995   void
996   currently_reporting(bool f) const;
997 
998   bool
999   reported_once() const;
1000 
1001   void
1002   reported_once(bool f) const;
1003 
1004   diff_category
1005   get_category() const;
1006 
1007   diff_category
1008   get_local_category() const;
1009 
1010   diff_category
1011   get_class_of_equiv_category() const;
1012 
1013   diff_category
1014   add_to_category(diff_category c);
1015 
1016   diff_category
1017   add_to_local_category(diff_category c);
1018 
1019   void
1020   add_to_local_and_inherited_categories(diff_category c);
1021 
1022   diff_category
1023   remove_from_category(diff_category c);
1024 
1025   diff_category
1026   remove_from_local_category(diff_category c);
1027 
1028   void
1029   set_category(diff_category c);
1030 
1031   void
1032   set_local_category(diff_category c);
1033 
1034   bool
1035   is_filtered_out() const;
1036 
1037   bool
1038   is_filtered_out_wrt_non_inherited_categories() const;
1039 
1040   bool
1041   is_suppressed() const;
1042 
1043   bool
1044   is_suppressed(bool &is_private_type) const;
1045 
1046   bool
1047   to_be_reported() const;
1048 
1049   bool
1050   has_local_changes_to_be_reported() const;
1051 
1052   virtual const string&
1053   get_pretty_representation() const;
1054 
1055   /// This constructs the relation between this diff node and its
1056   /// detail diff nodes, in the generic view of the diff node.
1057   ///
1058   /// Each specific typed diff node should implement how the typed
1059   /// view "links" itself to its detail nodes in the generic sense.
1060   virtual void
1061   chain_into_hierarchy();
1062 
1063   /// Pure interface to get the length of the changes encapsulated by
1064   /// this diff.  A length of zero means that the current instance of
1065   /// @ref diff doesn't carry any change.
1066   ///
1067   /// This is to be implemented by all descendants of this type.
1068   virtual bool
1069   has_changes() const = 0;
1070 
1071   /// Pure interface to know if the current instance of @diff carries
1072   /// a local change.  A local change is a change that is on the @ref
1073   /// diff object itself, as opposed to a change that is carried by
1074   /// some of its children nodes.
1075   ///
1076   /// This is to be implemented by all descendants of this type.
1077   virtual enum change_kind
1078   has_local_changes() const = 0;
1079 
1080   /// Pure interface to report the diff in a serialized form that is
1081   /// legible for the user.
1082   ///
1083   /// Note that the serializd report has to leave one empty line at
1084   /// the end of its content.
1085   ///
1086   /// @param out the output stream to serialize the report to.
1087   ///
1088   /// @param indent the indentation string to use.
1089   virtual void
1090   report(ostream& out, const string& indent = "") const = 0;
1091 
1092   virtual bool
1093   traverse(diff_node_visitor& v);
1094 };// end class diff
1095 
1096 diff_sptr
1097 compute_diff(const decl_base_sptr,
1098 	     const decl_base_sptr,
1099 	     diff_context_sptr ctxt);
1100 
1101 diff_sptr
1102 compute_diff(const type_base_sptr,
1103 	     const type_base_sptr,
1104 	     diff_context_sptr ctxt);
1105 
1106 /// The base class of diff between types.
1107 class type_diff_base : public diff
1108 {
1109   struct priv;
1110   std::unique_ptr<priv> priv_;
1111 
1112   type_diff_base();
1113 
1114 protected:
1115   type_diff_base(type_base_sptr	first_subject,
1116 		 type_base_sptr	second_subject,
1117 		 diff_context_sptr	ctxt);
1118 
1119 public:
1120 
1121   virtual enum change_kind
1122   has_local_changes() const = 0;
1123 
1124   virtual ~type_diff_base();
1125 };// end class type_diff_base
1126 
1127 /// The base class of diff between decls.
1128 class decl_diff_base : public diff
1129 {
1130   struct priv;
1131   std::unique_ptr<priv> priv_;
1132 
1133 protected:
1134   decl_diff_base(decl_base_sptr	first_subject,
1135 		 decl_base_sptr	second_subject,
1136 		 diff_context_sptr	ctxt);
1137 
1138 public:
1139 
1140   virtual enum change_kind
1141   has_local_changes() const = 0;
1142 
1143   virtual ~decl_diff_base();
1144 };// end class decl_diff_base
1145 
1146 string
1147 get_pretty_representation(diff*);
1148 
1149 class distinct_diff;
1150 
1151 /// Convenience typedef for a shared pointer to distinct_types_diff
1152 typedef shared_ptr<distinct_diff> distinct_diff_sptr;
1153 
1154 /// An abstraction of a diff between entities that are of a different
1155 /// kind (disctinct).
1156 class distinct_diff : public diff
1157 {
1158   struct priv;
1159   std::unique_ptr<priv> priv_;
1160 
1161 protected:
1162   distinct_diff(type_or_decl_base_sptr first,
1163 		type_or_decl_base_sptr second,
1164 		diff_context_sptr ctxt = diff_context_sptr());
1165 
1166 public:
1167 
1168   const type_or_decl_base_sptr
1169   first() const;
1170 
1171   const type_or_decl_base_sptr
1172   second() const;
1173 
1174   const diff_sptr
1175   compatible_child_diff() const;
1176 
1177   virtual const string&
1178   get_pretty_representation() const;
1179 
1180   virtual bool
1181   has_changes() const;
1182 
1183   virtual enum change_kind
1184   has_local_changes() const;
1185 
1186   virtual void
1187   report(ostream& out, const string& indent = "") const;
1188 
1189   virtual void
1190   chain_into_hierarchy();
1191 
1192   static bool
1193   entities_are_of_distinct_kinds(type_or_decl_base_sptr first,
1194 				 type_or_decl_base_sptr second);
1195 
1196   friend distinct_diff_sptr
1197   compute_diff_for_distinct_kinds(const type_or_decl_base_sptr first,
1198 				  const type_or_decl_base_sptr second,
1199 				  diff_context_sptr ctxt);
1200 };// end class distinct_types_diff
1201 
1202 distinct_diff_sptr
1203 compute_diff_for_distinct_kinds(const type_or_decl_base_sptr,
1204 				const type_or_decl_base_sptr,
1205 				diff_context_sptr ctxt);
1206 
1207 /// Abstracts a diff between two instances of @ref var_decl
1208 class var_diff : public decl_diff_base
1209 {
1210   struct priv;
1211   std::unique_ptr<priv> priv_;
1212 
1213 protected:
1214   var_diff(var_decl_sptr first,
1215 	   var_decl_sptr second,
1216 	   diff_sptr type_diff,
1217 	   diff_context_sptr ctxt = diff_context_sptr());
1218 
1219 public:
1220   var_decl_sptr
1221   first_var() const;
1222 
1223   var_decl_sptr
1224   second_var() const;
1225 
1226   diff_sptr
1227   type_diff() const;
1228 
1229   virtual void
1230   chain_into_hierarchy();
1231 
1232   virtual bool
1233   has_changes() const;
1234 
1235   virtual enum change_kind
1236   has_local_changes() const;
1237 
1238   virtual void
1239   report(ostream& out, const string& indent = "") const;
1240 
1241   virtual const string&
1242   get_pretty_representation() const;
1243 
1244   friend var_diff_sptr
1245   compute_diff(const var_decl_sptr	first,
1246 	       const var_decl_sptr	second,
1247 	       diff_context_sptr	ctxt);
1248 };// end class var_diff
1249 
1250 var_diff_sptr
1251 compute_diff(const var_decl_sptr, const var_decl_sptr, diff_context_sptr);
1252 
1253 class pointer_diff;
1254 /// Convenience typedef for a shared pointer on a @ref
1255 /// pointer_diff type.
1256 typedef shared_ptr<pointer_diff> pointer_diff_sptr;
1257 
1258 /// The abstraction of a diff between two pointers.
1259 class pointer_diff : public type_diff_base
1260 {
1261   struct priv;
1262   std::unique_ptr<priv> priv_;
1263 
1264 protected:
1265   pointer_diff(pointer_type_def_sptr	first,
1266 	       pointer_type_def_sptr	second,
1267 	       diff_sptr		underlying_type_diff,
1268 	       diff_context_sptr	ctxt = diff_context_sptr());
1269 
1270 public:
1271   const pointer_type_def_sptr
1272   first_pointer() const;
1273 
1274   const pointer_type_def_sptr
1275   second_pointer() const;
1276 
1277   diff_sptr
1278   underlying_type_diff() const;
1279 
1280   void
1281   underlying_type_diff(const diff_sptr);
1282 
1283   virtual const string&
1284   get_pretty_representation() const;
1285 
1286   virtual bool
1287   has_changes() const;
1288 
1289   virtual enum change_kind
1290   has_local_changes() const;
1291 
1292   virtual void
1293   report(ostream&, const string& indent = "") const;
1294 
1295   virtual void
1296   chain_into_hierarchy();
1297 
1298   friend pointer_diff_sptr
1299   compute_diff(pointer_type_def_sptr	first,
1300 	       pointer_type_def_sptr	second,
1301 	       diff_context_sptr	ctxt);
1302 };// end class pointer_diff
1303 
1304 pointer_diff_sptr
1305 compute_diff(pointer_type_def_sptr first,
1306 	     pointer_type_def_sptr second,
1307 	     diff_context_sptr ctxt);
1308 
1309 class reference_diff;
1310 
1311 /// Convenience typedef for a shared pointer on a @ref
1312 /// reference_diff type.
1313 typedef shared_ptr<reference_diff> reference_diff_sptr;
1314 
1315 /// The abstraction of a diff between two references.
1316 class reference_diff : public type_diff_base
1317 {
1318   struct priv;
1319   std::unique_ptr<priv> priv_;
1320 
1321 protected:
1322   reference_diff(const reference_type_def_sptr	first,
1323 		 const reference_type_def_sptr	second,
1324 		 diff_sptr			underlying,
1325 		 diff_context_sptr		ctxt = diff_context_sptr());
1326 
1327 public:
1328   reference_type_def_sptr
1329   first_reference() const;
1330 
1331   reference_type_def_sptr
1332   second_reference() const;
1333 
1334   const diff_sptr&
1335   underlying_type_diff() const;
1336 
1337   diff_sptr&
1338   underlying_type_diff(diff_sptr);
1339 
1340   virtual const string&
1341   get_pretty_representation() const;
1342 
1343   virtual bool
1344   has_changes() const;
1345 
1346   virtual enum change_kind
1347   has_local_changes() const;
1348 
1349   virtual void
1350   report(ostream&, const string& indent = "") const;
1351 
1352   virtual void
1353   chain_into_hierarchy();
1354 
1355   friend reference_diff_sptr
1356   compute_diff(reference_type_def_sptr first,
1357 	       reference_type_def_sptr second,
1358 	       diff_context_sptr ctxt);
1359 };// end class reference_diff
1360 
1361 reference_diff_sptr
1362 compute_diff(reference_type_def_sptr first,
1363 	     reference_type_def_sptr second,
1364 	     diff_context_sptr ctxt);
1365 
1366 class array_diff;
1367 
1368 /// Convenience typedef for a shared pointer on a @ref
1369 /// array_diff type.
1370 typedef shared_ptr<array_diff> array_diff_sptr;
1371 
1372 /// The abstraction of a diff between two arrays.
1373 class array_diff : public type_diff_base
1374 {
1375   struct priv;
1376   std::unique_ptr<priv> priv_;
1377 
1378 protected:
1379   array_diff(const array_type_def_sptr	first,
1380 	     const array_type_def_sptr	second,
1381 	     diff_sptr			element_type_diff,
1382 	     diff_context_sptr		ctxt = diff_context_sptr());
1383 
1384 public:
1385   const array_type_def_sptr
1386   first_array() const;
1387 
1388   const array_type_def_sptr
1389   second_array() const;
1390 
1391   const diff_sptr&
1392   element_type_diff() const;
1393 
1394   void
1395   element_type_diff(diff_sptr);
1396 
1397   virtual const string&
1398   get_pretty_representation() const;
1399 
1400   virtual bool
1401   has_changes() const;
1402 
1403   virtual enum change_kind
1404   has_local_changes() const;
1405 
1406   virtual void
1407   report(ostream&, const string& indent = "") const;
1408 
1409   virtual void
1410   chain_into_hierarchy();
1411 
1412   friend array_diff_sptr
1413   compute_diff(array_type_def_sptr first,
1414 	       array_type_def_sptr second,
1415 	       diff_context_sptr ctxt);
1416 };// end class array_diff
1417 
1418 array_diff_sptr
1419 compute_diff(array_type_def_sptr first,
1420 	     array_type_def_sptr second,
1421 	     diff_context_sptr ctxt);
1422 
1423 class qualified_type_diff;
1424 typedef class shared_ptr<qualified_type_diff> qualified_type_diff_sptr;
1425 
1426 /// Abstraction of a diff between two qualified types.
1427 class qualified_type_diff : public type_diff_base
1428 {
1429   struct priv;
1430   std::unique_ptr<priv> priv_;
1431 
1432 protected:
1433   qualified_type_diff(qualified_type_def_sptr	first,
1434 		      qualified_type_def_sptr	second,
1435 		      diff_sptr		underling,
1436 		      diff_context_sptr	ctxt = diff_context_sptr());
1437 
1438 public:
1439   const qualified_type_def_sptr
1440   first_qualified_type() const;
1441 
1442   const qualified_type_def_sptr
1443   second_qualified_type() const;
1444 
1445   diff_sptr
1446   underlying_type_diff() const;
1447 
1448   void
1449   underlying_type_diff(const diff_sptr);
1450 
1451   diff_sptr
1452   leaf_underlying_type_diff() const;
1453 
1454   virtual const string&
1455   get_pretty_representation() const;
1456 
1457   virtual bool
1458   has_changes() const;
1459 
1460   virtual enum change_kind
1461   has_local_changes() const;
1462 
1463   virtual void
1464   report(ostream&, const string& indent = "") const;
1465 
1466   virtual void
1467   chain_into_hierarchy();
1468 
1469   friend qualified_type_diff_sptr
1470   compute_diff(const qualified_type_def_sptr first,
1471 	       const qualified_type_def_sptr second,
1472 	       diff_context_sptr ctxt);
1473 };// end class qualified_type_diff.
1474 
1475 qualified_type_diff_sptr
1476 compute_diff(const qualified_type_def_sptr first,
1477 	     const qualified_type_def_sptr second,
1478 	     diff_context_sptr ctxt);
1479 
1480 class enum_diff;
1481 typedef shared_ptr<enum_diff> enum_diff_sptr;
1482 
1483 /// Abstraction of a diff between two enums.
1484 class enum_diff : public type_diff_base
1485 {
1486   struct priv;
1487   std::unique_ptr<priv> priv_;
1488 
1489   void
1490   clear_lookup_tables();
1491 
1492   bool
1493   lookup_tables_empty() const;
1494 
1495   void
1496   ensure_lookup_tables_populated();
1497 
1498 protected:
1499   enum_diff(const enum_type_decl_sptr,
1500 	    const enum_type_decl_sptr,
1501 	    const diff_sptr,
1502 	    diff_context_sptr ctxt = diff_context_sptr());
1503 
1504 public:
1505   const enum_type_decl_sptr
1506   first_enum() const;
1507 
1508   const enum_type_decl_sptr
1509   second_enum() const;
1510 
1511   diff_sptr
1512   underlying_type_diff() const;
1513 
1514   const string_enumerator_map&
1515   deleted_enumerators() const;
1516 
1517   const string_enumerator_map&
1518   inserted_enumerators() const;
1519 
1520   const string_changed_enumerator_map&
1521   changed_enumerators() const;
1522 
1523   virtual const string&
1524   get_pretty_representation() const;
1525 
1526   virtual bool
1527   has_changes() const;
1528 
1529   virtual enum change_kind
1530   has_local_changes() const;
1531 
1532   virtual void
1533   report(ostream&, const string& indent = "") const;
1534 
1535   virtual void
1536   chain_into_hierarchy();
1537 
1538   friend enum_diff_sptr
1539   compute_diff(const enum_type_decl_sptr first,
1540 	       const enum_type_decl_sptr second,
1541 	       diff_context_sptr ctxt);
1542 };//end class enum_diff;
1543 
1544 enum_diff_sptr
1545 compute_diff(const enum_type_decl_sptr,
1546 	     const enum_type_decl_sptr,
1547 	     diff_context_sptr);
1548 
1549 /// This is the base class of @ref class_diff and @ref union_diff.
1550 class class_or_union_diff : public type_diff_base
1551 {
1552 protected:
1553   struct priv;
1554   typedef std::unique_ptr<priv> priv_ptr;
1555   priv_ptr priv_;
1556 
1557   void
1558   clear_lookup_tables(void);
1559 
1560   bool
1561   lookup_tables_empty(void) const;
1562 
1563   void
1564   ensure_lookup_tables_populated(void) const;
1565 
1566   void
1567   allocate_priv_data();
1568 
1569 protected:
1570   class_or_union_diff(class_or_union_sptr first_scope,
1571 		      class_or_union_sptr second_scope,
1572 		      diff_context_sptr ctxt = diff_context_sptr());
1573 
1574 public:
1575 
1576   const class_or_union_diff::priv_ptr&
1577   get_priv() const;
1578 
1579   //TODO: add change of the name of the type.
1580 
1581   virtual ~class_or_union_diff();
1582 
1583   class_or_union_sptr
1584   first_class_or_union() const;
1585 
1586   class_or_union_sptr
1587   second_class_or_union() const;
1588 
1589   const edit_script&
1590   member_types_changes() const;
1591 
1592   edit_script&
1593   member_types_changes();
1594 
1595   const edit_script&
1596   data_members_changes() const;
1597 
1598   edit_script&
1599   data_members_changes();
1600 
1601   const string_decl_base_sptr_map&
1602   inserted_data_members() const;
1603 
1604   const string_decl_base_sptr_map&
1605   deleted_data_members() const;
1606 
1607   const edit_script&
1608   member_fns_changes() const;
1609 
1610   edit_script&
1611   member_fns_changes();
1612 
1613   const function_decl_diff_sptrs_type&
1614   changed_member_fns() const;
1615 
1616   const string_member_function_sptr_map&
1617   deleted_member_fns() const;
1618 
1619   const string_member_function_sptr_map&
1620   inserted_member_fns() const;
1621 
1622   const var_diff_sptrs_type&
1623   sorted_changed_data_members() const;
1624 
1625   size_t
1626   count_filtered_changed_data_members(bool local_only = false) const;
1627 
1628   const var_diff_sptrs_type&
1629   sorted_subtype_changed_data_members() const;
1630 
1631   size_t
1632   count_filtered_subtype_changed_data_members(bool local_only = false) const;
1633 
1634   const string_decl_base_sptr_map&
1635   data_members_replaced_by_adms() const;
1636 
1637   const changed_var_sptrs_type&
1638   ordered_data_members_replaced_by_adms() const;
1639 
1640   const edit_script&
1641   member_fn_tmpls_changes() const;
1642 
1643   edit_script&
1644   member_fn_tmpls_changes();
1645 
1646   const edit_script&
1647   member_class_tmpls_changes() const;
1648 
1649   edit_script&
1650   member_class_tmpls_changes();
1651 
1652   virtual bool
1653   has_changes() const;
1654 
1655   virtual enum change_kind
1656   has_local_changes() const;
1657 
1658   virtual void
1659   report(ostream&, const string& indent = "") const;
1660 
1661   virtual void
1662   chain_into_hierarchy();
1663 
1664   friend class default_reporter;
1665 }; // end class_or_union_diff;
1666 
1667 /// This type abstracts changes for a class_decl.
1668 class class_diff : public class_or_union_diff
1669 {
1670   struct priv;
1671   typedef std::unique_ptr<priv> priv_ptr;
1672   priv_ptr priv_;
1673 
1674   const priv_ptr& get_priv()const;
1675 
1676   void
1677   clear_lookup_tables(void);
1678 
1679   bool
1680   lookup_tables_empty(void) const;
1681 
1682   void
1683   ensure_lookup_tables_populated(void) const;
1684 
1685   void
1686    allocate_priv_data();
1687 
1688 protected:
1689   class_diff(class_decl_sptr first_scope,
1690 	     class_decl_sptr second_scope,
1691 	     diff_context_sptr ctxt = diff_context_sptr());
1692 
1693 public:
1694   //TODO: add change of the name of the type.
1695 
1696   virtual ~class_diff();
1697 
1698   class_decl_sptr
1699   first_class_decl() const;
1700 
1701   class_decl_sptr
1702   second_class_decl() const;
1703 
1704   const edit_script&
1705   base_changes() const;
1706 
1707   edit_script&
1708   base_changes();
1709 
1710   const string_base_sptr_map&
1711   deleted_bases() const;
1712 
1713   const string_base_sptr_map&
1714   inserted_bases() const;
1715 
1716   const base_diff_sptrs_type&
1717   changed_bases();
1718 
1719   const vector<class_decl::base_spec_sptr>&
1720   moved_bases() const;
1721 
1722   virtual bool
1723   has_changes() const;
1724 
1725   virtual enum change_kind
1726   has_local_changes() const;
1727 
1728   virtual const string&
1729   get_pretty_representation() const;
1730 
1731   virtual void
1732   report(ostream&, const string& indent = "") const;
1733 
1734   virtual void
1735   chain_into_hierarchy();
1736 
1737   friend class_diff_sptr
1738   compute_diff(const class_decl_sptr	first,
1739 	       const class_decl_sptr	second,
1740 	       diff_context_sptr	ctxt);
1741 
1742   friend class default_reporter;
1743 };// end class_diff
1744 
1745 class_diff_sptr
1746 compute_diff(const class_decl_sptr	first,
1747 	     const class_decl_sptr	second,
1748 	     diff_context_sptr		ctxt);
1749 
1750 class union_diff;
1751 typedef shared_ptr<union_diff> union_diff_sptr;
1752 
1753 class union_diff : public class_or_union_diff
1754 {
1755   void
1756   clear_lookup_tables(void);
1757 
1758   bool
1759   lookup_tables_empty(void) const;
1760 
1761   void
1762   ensure_lookup_tables_populated(void) const;
1763 
1764   void
1765   allocate_priv_data();
1766 
1767 protected:
1768   union_diff(union_decl_sptr first_union,
1769 	     union_decl_sptr second_union,
1770 	     diff_context_sptr ctxt = diff_context_sptr());
1771 
1772 public:
1773 
1774   virtual ~union_diff();
1775 
1776   union_decl_sptr
1777   first_union_decl() const;
1778 
1779   union_decl_sptr
1780   second_union_decl() const;
1781 
1782   virtual const string&
1783   get_pretty_representation() const;
1784 
1785   virtual void
1786   report(ostream&, const string& indent = "") const;
1787 
1788   friend union_diff_sptr
1789   compute_diff(const union_decl_sptr	first,
1790 	       const union_decl_sptr	second,
1791 	       diff_context_sptr	ctxt);
1792 }; // end class union_diff
1793 
1794 union_diff_sptr
1795 compute_diff(const union_decl_sptr	first,
1796 	     const union_decl_sptr	second,
1797 	     diff_context_sptr	ctxt);
1798 
1799 /// An abstraction of a diff between two instances of class_decl::base_spec.
1800 class base_diff : public diff
1801 {
1802   struct priv;
1803   std::unique_ptr<priv> priv_;
1804 
1805 protected:
1806   base_diff(class_decl::base_spec_sptr	first,
1807 	    class_decl::base_spec_sptr	second,
1808 	    class_diff_sptr		underlying,
1809 	    diff_context_sptr		ctxt = diff_context_sptr());
1810 
1811 public:
1812   class_decl::base_spec_sptr
1813   first_base() const;
1814 
1815   class_decl::base_spec_sptr
1816   second_base() const;
1817 
1818   const class_diff_sptr
1819   get_underlying_class_diff() const;
1820 
1821   void
1822   set_underlying_class_diff(class_diff_sptr d);
1823 
1824   virtual const string&
1825   get_pretty_representation() const;
1826 
1827   virtual bool
1828   has_changes() const;
1829 
1830   virtual enum change_kind
1831   has_local_changes() const;
1832 
1833   virtual void
1834   report(ostream&, const string& indent = "") const;
1835 
1836   virtual void
1837   chain_into_hierarchy();
1838 
1839   friend base_diff_sptr
1840   compute_diff(const class_decl::base_spec_sptr first,
1841 	       const class_decl::base_spec_sptr second,
1842 	       diff_context_sptr		ctxt);
1843 };// end class base_diff
1844 
1845 base_diff_sptr
1846 compute_diff(const class_decl::base_spec_sptr first,
1847 	     const class_decl::base_spec_sptr second,
1848 	     diff_context_sptr		ctxt);
1849 
1850 class scope_diff;
1851 
1852 /// Convenience typedef for a shared pointer on a @ref scope_diff.
1853 typedef shared_ptr<scope_diff> scope_diff_sptr;
1854 
1855 /// An abstractions of the changes between two scopes.
1856 class scope_diff : public diff
1857 {
1858   struct priv;
1859   std::unique_ptr<priv> priv_;
1860 
1861   bool
1862   lookup_tables_empty() const;
1863 
1864   void
1865   clear_lookup_tables();
1866 
1867   void
1868   ensure_lookup_tables_populated();
1869 
1870 protected:
1871   scope_diff(scope_decl_sptr first_scope,
1872 	     scope_decl_sptr second_scope,
1873 	     diff_context_sptr ctxt = diff_context_sptr());
1874 
1875 public:
1876 
1877   friend scope_diff_sptr
1878   compute_diff(const scope_decl_sptr	first,
1879 	       const scope_decl_sptr	second,
1880 	       scope_diff_sptr		d,
1881 	       diff_context_sptr	ctxt);
1882 
1883   friend scope_diff_sptr
1884   compute_diff(const scope_decl_sptr	first_scope,
1885 	       const scope_decl_sptr	second_scope,
1886 	       diff_context_sptr	ctxt);
1887 
1888   const scope_decl_sptr
1889   first_scope() const;
1890 
1891   const scope_decl_sptr
1892   second_scope() const;
1893 
1894   const edit_script&
1895   member_changes() const;
1896 
1897   edit_script&
1898   member_changes();
1899 
1900   const decl_base_sptr
1901   deleted_member_at(unsigned index) const;
1902 
1903   const decl_base_sptr
1904   deleted_member_at(vector<deletion>::const_iterator) const;
1905 
1906   const decl_base_sptr
1907   inserted_member_at(unsigned i);
1908 
1909   const decl_base_sptr
1910   inserted_member_at(vector<unsigned>::const_iterator i);
1911 
1912   const diff_sptrs_type&
1913   changed_types() const;
1914 
1915   const diff_sptrs_type&
1916   changed_decls() const;
1917 
1918   const string_decl_base_sptr_map&
1919   removed_types() const;
1920 
1921   const string_decl_base_sptr_map&
1922   removed_decls() const;
1923 
1924   const string_decl_base_sptr_map&
1925   added_types() const;
1926 
1927   const string_decl_base_sptr_map&
1928   added_decls() const;
1929 
1930   virtual const string&
1931   get_pretty_representation() const;
1932 
1933   virtual bool
1934   has_changes() const;
1935 
1936   virtual enum change_kind
1937   has_local_changes() const;
1938 
1939   virtual void
1940   report(ostream& out, const string& indent = "") const;
1941 
1942   virtual void
1943   chain_into_hierarchy();
1944 
1945   friend class default_reporter;
1946   friend class leaf_reporter;
1947 };// end class scope_diff
1948 
1949 scope_diff_sptr
1950 compute_diff(const scope_decl_sptr first,
1951 	     const scope_decl_sptr second,
1952 	     scope_diff_sptr d,
1953 	     diff_context_sptr ctxt);
1954 
1955 scope_diff_sptr
1956 compute_diff(const scope_decl_sptr first_scope,
1957 	     const scope_decl_sptr second_scope,
1958 	     diff_context_sptr ctxt);
1959 
1960 /// Abstraction of a diff between two function parameters.
1961 class fn_parm_diff : public decl_diff_base
1962 {
1963   struct priv;
1964   std::unique_ptr<priv> priv_;
1965 
1966   fn_parm_diff(const function_decl::parameter_sptr	first,
1967 	       const function_decl::parameter_sptr	second,
1968 	       diff_context_sptr			ctxt);
1969 
1970 public:
1971   friend fn_parm_diff_sptr
1972   compute_diff(const function_decl::parameter_sptr	first,
1973 	       const function_decl::parameter_sptr	second,
1974 	       diff_context_sptr			ctxt);
1975 
1976   const function_decl::parameter_sptr
1977   first_parameter() const;
1978 
1979   const function_decl::parameter_sptr
1980   second_parameter() const;
1981 
1982   diff_sptr
1983   type_diff() const;
1984 
1985   virtual const string&
1986   get_pretty_representation() const;
1987 
1988   virtual bool
1989   has_changes() const;
1990 
1991   virtual enum change_kind
1992   has_local_changes() const;
1993 
1994   virtual void
1995   report(ostream&, const string& indent = "") const;
1996 
1997   virtual void
1998   chain_into_hierarchy();
1999 }; // end class fn_parm_diff
2000 
2001 fn_parm_diff_sptr
2002 compute_diff(const function_decl::parameter_sptr	first,
2003 	     const function_decl::parameter_sptr	second,
2004 	     diff_context_sptr				ctxt);
2005 
2006 class function_type_diff;
2007 
2008 /// A convenience typedef for a shared pointer to @ref
2009 /// function_type_type_diff
2010 typedef shared_ptr<function_type_diff> function_type_diff_sptr;
2011 
2012 /// Abstraction of a diff between two function types.
2013 class function_type_diff: public type_diff_base
2014 {
2015   struct priv;
2016   std::unique_ptr<priv> priv_;
2017 
2018   void
2019   ensure_lookup_tables_populated();
2020 
2021   const function_decl::parameter_sptr
2022   deleted_parameter_at(int i) const;
2023 
2024   const function_decl::parameter_sptr
2025   inserted_parameter_at(int i) const;
2026 
2027 protected:
2028   function_type_diff(const function_type_sptr	first,
2029 		     const function_type_sptr	second,
2030 		     diff_context_sptr		ctxt);
2031 
2032 public:
2033   friend function_type_diff_sptr
2034   compute_diff(const function_type_sptr	first,
2035 	       const function_type_sptr	second,
2036 	       diff_context_sptr		ctxt);
2037 
2038   const function_type_sptr
2039   first_function_type() const;
2040 
2041   const function_type_sptr
2042   second_function_type() const;
2043 
2044   const diff_sptr
2045   return_type_diff() const;
2046 
2047   const string_fn_parm_diff_sptr_map&
2048   subtype_changed_parms() const;
2049 
2050   const string_parm_map&
2051   removed_parms() const;
2052 
2053   const string_parm_map&
2054   added_parms() const;
2055 
2056   const vector<function_decl::parameter_sptr>&
2057   sorted_deleted_parms() const;
2058 
2059   const vector<function_decl::parameter_sptr>&
2060   sorted_added_parms() const;
2061 
2062   virtual const string&
2063   get_pretty_representation() const;
2064 
2065   virtual bool
2066   has_changes() const;
2067 
2068   virtual enum change_kind
2069   has_local_changes() const;
2070 
2071   virtual void
2072   report(ostream&, const string& indent = "") const;
2073 
2074   virtual void
2075   chain_into_hierarchy();
2076 
2077   friend class default_reporter;
2078   friend class leaf_reporter;
2079 };// end class function_type_diff
2080 
2081 function_type_diff_sptr
2082 compute_diff(const function_type_sptr	first,
2083 	     const function_type_sptr	second,
2084 	     diff_context_sptr		ctxt);
2085 
2086 /// Abstraction of a diff between two function_decl.
2087 class function_decl_diff : public decl_diff_base
2088 {
2089   struct priv;
2090   std::unique_ptr<priv> priv_;
2091 
2092   void
2093   ensure_lookup_tables_populated();
2094 
2095 
2096 protected:
2097   function_decl_diff(const function_decl_sptr	first,
2098 		     const function_decl_sptr	second,
2099 		     diff_context_sptr		ctxt);
2100 
2101 public:
2102 
2103 friend function_decl_diff_sptr
2104 compute_diff(const function_decl_sptr	first,
2105 	     const function_decl_sptr	second,
2106 	     diff_context_sptr		ctxt);
2107 
2108   const function_decl_sptr
2109   first_function_decl() const;
2110 
2111   const function_decl_sptr
2112   second_function_decl() const;
2113 
2114   const function_type_diff_sptr
2115   type_diff() const;
2116 
2117   virtual const string&
2118   get_pretty_representation() const;
2119 
2120   virtual bool
2121   has_changes() const;
2122 
2123   virtual enum change_kind
2124   has_local_changes() const;
2125 
2126   virtual void
2127   report(ostream&, const string& indent = "") const;
2128 
2129   virtual void
2130   chain_into_hierarchy();
2131 }; // end class function_decl_diff
2132 
2133 function_decl_diff_sptr
2134 compute_diff(const function_decl_sptr	first,
2135 	     const function_decl_sptr	second,
2136 	     diff_context_sptr		ctxt);
2137 
2138 class type_decl_diff;
2139 
2140 /// Convenience typedef for a shared pointer on a @ref type_decl_diff type.
2141 typedef shared_ptr<type_decl_diff> type_decl_diff_sptr;
2142 
2143 /// Abstraction of a diff between two basic type declarations.
2144 class type_decl_diff : public type_diff_base
2145 {
2146   type_decl_diff();
2147 
2148 protected:
2149   type_decl_diff(const type_decl_sptr first,
2150 		 const type_decl_sptr second,
2151 		 diff_context_sptr ctxt = diff_context_sptr());
2152 
2153 public:
2154   friend type_decl_diff_sptr
2155   compute_diff(const type_decl_sptr	first,
2156 	       const type_decl_sptr	second,
2157 	       diff_context_sptr	ctxt);
2158 
2159   const type_decl_sptr
2160   first_type_decl() const;
2161 
2162   const type_decl_sptr
2163   second_type_decl() const;
2164 
2165   virtual const string&
2166   get_pretty_representation() const;
2167 
2168   virtual bool
2169   has_changes() const;
2170 
2171   virtual enum change_kind
2172   has_local_changes() const;
2173 
2174   virtual void
2175   report(ostream& out, const string& indent = "") const;
2176 };// end type_decl_diff
2177 
2178 type_decl_diff_sptr
2179 compute_diff(const type_decl_sptr,
2180 	     const type_decl_sptr,
2181 	     diff_context_sptr);
2182 
2183 class typedef_diff;
2184 
2185 /// Convenience typedef for a shared pointer on a typedef_diff type.
2186 typedef shared_ptr<typedef_diff> typedef_diff_sptr;
2187 
2188 /// Abstraction of a diff between two typedef_decl.
2189 class typedef_diff : public type_diff_base
2190 {
2191   struct priv;
2192   std::unique_ptr<priv> priv_;
2193 
2194   typedef_diff();
2195 
2196 protected:
2197   typedef_diff(const typedef_decl_sptr	first,
2198 	       const typedef_decl_sptr	second,
2199 	       const diff_sptr		underlying_type_diff,
2200 	       diff_context_sptr	ctxt = diff_context_sptr());
2201 
2202 public:
2203   friend typedef_diff_sptr
2204   compute_diff(const typedef_decl_sptr	first,
2205 	       const typedef_decl_sptr	second,
2206 	       diff_context_sptr	ctxt);
2207 
2208   const typedef_decl_sptr
2209   first_typedef_decl() const;
2210 
2211   const typedef_decl_sptr
2212   second_typedef_decl() const;
2213 
2214   const diff_sptr
2215   underlying_type_diff() const;
2216 
2217   void
2218   underlying_type_diff(const diff_sptr);
2219 
2220   virtual const string&
2221   get_pretty_representation() const;
2222 
2223   virtual bool
2224   has_changes() const;
2225 
2226   virtual enum change_kind
2227   has_local_changes() const;
2228 
2229   virtual void
2230   report(ostream&, const string& indent = "") const;
2231 
2232   virtual void
2233   chain_into_hierarchy();
2234 };// end class typedef_diff
2235 
2236 typedef_diff_sptr
2237 compute_diff(const typedef_decl_sptr,
2238 	     const typedef_decl_sptr,
2239 	     diff_context_sptr ctxt);
2240 
2241 const diff*
2242 get_typedef_diff_underlying_type_diff(const diff* diff);
2243 
2244 class translation_unit_diff;
2245 
2246 /// Convenience typedef for a shared pointer on a
2247 /// @ref translation_unit_diff type.
2248 typedef shared_ptr<translation_unit_diff> translation_unit_diff_sptr;
2249 
2250 /// An abstraction of a diff between two translation units.
2251 class translation_unit_diff : public scope_diff
2252 {
2253   struct priv;
2254   std::unique_ptr<priv> priv_;
2255 
2256 protected:
2257   translation_unit_diff(translation_unit_sptr	first,
2258 			translation_unit_sptr	second,
2259 			diff_context_sptr	ctxt = diff_context_sptr());
2260 
2261 public:
2262 
2263   const translation_unit_sptr
2264   first_translation_unit() const;
2265 
2266   const translation_unit_sptr
2267   second_translation_unit() const;
2268 
2269   friend translation_unit_diff_sptr
2270   compute_diff(const translation_unit_sptr	first,
2271 	       const translation_unit_sptr	second,
2272 	       diff_context_sptr		ctxt);
2273 
2274   virtual bool
2275   has_changes() const;
2276 
2277   virtual enum change_kind
2278   has_local_changes() const;
2279 
2280   virtual void
2281   report(ostream& out, const string& indent = "") const;
2282 };//end class translation_unit_diff
2283 
2284 translation_unit_diff_sptr
2285 compute_diff(const translation_unit_sptr first,
2286 	     const translation_unit_sptr second,
2287 	     diff_context_sptr ctxt = diff_context_sptr());
2288 
2289 /// An abstraction of a diff between between two abi corpus.
2290 class corpus_diff
2291 {
2292   struct priv;
2293   std::unique_ptr<priv> priv_;
2294 
2295 protected:
2296   corpus_diff(corpus_sptr	first,
2297 	      corpus_sptr	second,
2298 	      diff_context_sptr ctxt = diff_context_sptr());
2299 
2300   void
2301   finish_diff_type();
2302 
2303 public:
2304 
2305   class diff_stats;
2306 
2307   virtual ~corpus_diff();
2308 
2309   /// A convenience typedef for a shared pointer to @ref diff_stats
2310   typedef shared_ptr<diff_stats> diff_stats_sptr;
2311 
2312   corpus_sptr
2313   first_corpus() const;
2314 
2315   corpus_sptr
2316   second_corpus() const;
2317 
2318   const vector<diff*>&
2319   children_nodes() const;
2320 
2321   void
2322   append_child_node(diff_sptr);
2323 
2324   edit_script&
2325   function_changes() const;
2326 
2327   edit_script&
2328   variable_changes() const;
2329 
2330   bool
2331   soname_changed() const;
2332 
2333   bool
2334   architecture_changed() const;
2335 
2336   const string_function_ptr_map&
2337   deleted_functions() const;
2338 
2339   const string_function_ptr_map&
2340   added_functions();
2341 
2342   const string_function_decl_diff_sptr_map&
2343   changed_functions();
2344 
2345   const function_decl_diff_sptrs_type&
2346   changed_functions_sorted();
2347 
2348   const string_var_ptr_map&
2349   deleted_variables() const;
2350 
2351   const string_var_ptr_map&
2352   added_variables() const;
2353 
2354   const string_var_diff_sptr_map&
2355   changed_variables();
2356 
2357   const var_diff_sptrs_type&
2358   changed_variables_sorted();
2359 
2360   const string_elf_symbol_map&
2361   deleted_unrefed_function_symbols() const;
2362 
2363   const string_elf_symbol_map&
2364   added_unrefed_function_symbols() const;
2365 
2366   const string_elf_symbol_map&
2367   deleted_unrefed_variable_symbols() const;
2368 
2369   const string_elf_symbol_map&
2370   added_unrefed_variable_symbols() const;
2371 
2372   const string_type_base_sptr_map&
2373   deleted_unreachable_types() const;
2374 
2375   const vector<type_base_sptr>&
2376   deleted_unreachable_types_sorted() const;
2377 
2378   const string_type_base_sptr_map&
2379   added_unreachable_types() const;
2380 
2381   const vector<type_base_sptr>&
2382   added_unreachable_types_sorted() const;
2383 
2384   const string_diff_sptr_map&
2385   changed_unreachable_types() const;
2386 
2387   const vector<diff_sptr>&
2388   changed_unreachable_types_sorted() const;
2389 
2390   const diff_context_sptr
2391   context() const;
2392 
2393   const string&
2394   get_pretty_representation() const;
2395 
2396   bool
2397   has_changes() const;
2398 
2399   bool
2400   has_incompatible_changes() const;
2401 
2402   bool
2403   has_net_subtype_changes() const;
2404 
2405   bool
2406   has_net_changes() const;
2407 
2408   const diff_stats&
2409   apply_filters_and_suppressions_before_reporting();
2410 
2411   void
2412   mark_leaf_diff_nodes();
2413 
2414   diff_maps&
2415   get_leaf_diffs();
2416 
2417   const diff_maps&
2418   get_leaf_diffs() const;
2419 
2420   virtual void
2421   report(ostream& out, const string& indent = "") const;
2422 
2423   virtual bool
2424   traverse(diff_node_visitor& v);
2425 
2426   virtual void
2427   chain_into_hierarchy();
2428 
2429   friend corpus_diff_sptr
2430   compute_diff(const corpus_sptr f,
2431 	       const corpus_sptr s,
2432 	       diff_context_sptr ctxt);
2433 
2434   friend void
2435   apply_suppressions(const corpus_diff* diff_tree);
2436 
2437   friend void
2438   maybe_report_unreachable_type_changes(const corpus_diff& d,
2439 					const corpus_diff::diff_stats &s,
2440 					const string& indent,
2441 					ostream& out);
2442 
2443   friend class default_reporter;
2444   friend class leaf_reporter;
2445 }; // end class corpus_diff
2446 
2447 corpus_diff_sptr
2448 compute_diff(const corpus_sptr,
2449 	     const corpus_sptr,
2450 	     diff_context_sptr = diff_context_sptr());
2451 
2452 corpus_diff_sptr
2453 compute_diff(const corpus_group_sptr&,
2454 	     const corpus_group_sptr&,
2455 	     diff_context_sptr	ctxt);
2456 
2457 /// This is a document class that aims to capture statistics about the
2458 /// changes carried by a @ref corpus_diff type.
2459 ///
2460 /// Its values are populated by the member function
2461 /// corpus_diff::apply_filters_and_suppressions_before_reporting()
2462 class corpus_diff::diff_stats
2463 {
2464   struct priv;
2465   std::unique_ptr<priv> priv_;
2466 
2467   diff_stats();
2468 
2469 public:
2470 
2471   diff_stats(diff_context_sptr);
2472 
2473   size_t num_func_removed() const;
2474   void num_func_removed(size_t);
2475 
2476   size_t num_removed_func_filtered_out() const;
2477   void num_removed_func_filtered_out(size_t);
2478 
2479   size_t net_num_func_removed() const;
2480 
2481   size_t num_func_added() const;
2482   void num_func_added(size_t);
2483 
2484   size_t num_added_func_filtered_out() const;
2485   void num_added_func_filtered_out(size_t);
2486 
2487   size_t net_num_func_added() const;
2488 
2489   size_t num_func_changed() const;
2490   void num_func_changed(size_t);
2491 
2492   size_t num_changed_func_filtered_out() const;
2493   void num_changed_func_filtered_out(size_t);
2494 
2495   size_t num_func_with_virtual_offset_changes() const;
2496   void num_func_with_virtual_offset_changes(size_t);
2497 
2498   size_t net_num_func_changed() const;
2499 
2500   size_t num_vars_removed() const;
2501   void num_vars_removed(size_t);
2502 
2503   size_t num_removed_vars_filtered_out() const;
2504   void num_removed_vars_filtered_out(size_t) const;
2505 
2506   size_t net_num_vars_removed() const;
2507 
2508   size_t num_vars_added() const;
2509   void num_vars_added(size_t);
2510 
2511   size_t num_added_vars_filtered_out() const;
2512   void num_added_vars_filtered_out(size_t);
2513 
2514   size_t net_num_vars_added() const;
2515 
2516   size_t num_vars_changed() const;
2517   void num_vars_changed(size_t);
2518 
2519   size_t num_changed_vars_filtered_out() const;
2520   void num_changed_vars_filtered_out(size_t);
2521 
2522   size_t net_num_vars_changed() const;
2523 
2524   size_t num_func_syms_removed() const;
2525   void num_func_syms_removed(size_t);
2526 
2527   size_t num_removed_func_syms_filtered_out() const;
2528   void num_removed_func_syms_filtered_out(size_t);
2529 
2530   size_t num_func_syms_added() const;
2531   void num_func_syms_added(size_t);
2532 
2533   size_t num_added_func_syms_filtered_out() const;
2534   void num_added_func_syms_filtered_out(size_t);
2535 
2536   size_t net_num_removed_func_syms() const;
2537   size_t net_num_added_func_syms() const;
2538 
2539   size_t num_var_syms_removed() const;
2540   void num_var_syms_removed(size_t);
2541 
2542   size_t num_removed_var_syms_filtered_out() const;
2543   void num_removed_var_syms_filtered_out(size_t);
2544 
2545   size_t num_var_syms_added() const;
2546   void num_var_syms_added(size_t);
2547 
2548   size_t num_added_var_syms_filtered_out() const;
2549   void num_added_var_syms_filtered_out(size_t);
2550 
2551   size_t net_num_removed_var_syms() const;
2552   size_t net_num_added_var_syms() const;
2553 
2554   size_t num_leaf_changes() const;
2555   void num_leaf_changes(size_t);
2556 
2557   size_t num_leaf_changes_filtered_out() const;
2558   void num_leaf_changes_filtered_out(size_t);
2559 
2560   size_t net_num_leaf_changes() const;
2561 
2562   size_t num_leaf_type_changes() const;
2563   void num_leaf_type_changes(size_t);
2564 
2565   size_t num_leaf_type_changes_filtered_out() const;
2566   void num_leaf_type_changes_filtered_out(size_t);
2567   size_t net_num_leaf_type_changes() const;
2568 
2569   size_t num_leaf_func_changes() const;
2570   void num_leaf_func_changes(size_t);
2571 
2572   size_t num_leaf_func_changes_filtered_out() const;
2573   void num_leaf_func_changes_filtered_out(size_t);
2574   size_t net_num_leaf_func_changes() const;
2575 
2576   size_t num_leaf_var_changes() const;
2577   void num_leaf_var_changes(size_t);
2578 
2579   size_t num_leaf_var_changes_filtered_out() const;
2580   void num_leaf_var_changes_filtered_out(size_t);
2581   size_t net_num_leaf_var_changes() const;
2582 
2583   size_t num_added_unreachable_types() const;
2584   void num_added_unreachable_types(size_t);
2585 
2586   size_t num_added_unreachable_types_filtered_out() const;
2587   void num_added_unreachable_types_filtered_out(size_t);
2588   size_t net_num_added_unreachable_types() const;
2589 
2590   size_t num_removed_unreachable_types() const;
2591   void num_removed_unreachable_types(size_t);
2592 
2593   size_t num_removed_unreachable_types_filtered_out() const;
2594   void num_removed_unreachable_types_filtered_out(size_t);
2595   size_t net_num_removed_unreachable_types() const;
2596 
2597   size_t num_changed_unreachable_types() const;
2598   void num_changed_unreachable_types(size_t);
2599 
2600   size_t num_changed_unreachable_types_filtered_out() const;
2601   void num_changed_unreachable_types_filtered_out(size_t);
2602   size_t net_num_changed_unreachable_types() const;
2603 
2604 }; // end class corpus_diff::diff_stats
2605 
2606 /// The base class for the node visitors.  These are the types used to
2607 /// visit each node traversed by the diff_traversable_base::traverse() method.
2608 class diff_node_visitor : public node_visitor_base
2609 {
2610 protected:
2611   struct priv;
2612   std::unique_ptr<priv> priv_;
2613 
2614 public:
2615 
2616   diff_node_visitor();
2617 
2618   virtual ~diff_node_visitor();
2619 
2620   diff_node_visitor(visiting_kind k);
2621 
2622   visiting_kind
2623   get_visiting_kind() const;
2624 
2625   void
2626   set_visiting_kind(visiting_kind v);
2627 
2628   void
2629   or_visiting_kind(visiting_kind v);
2630 
2631   void
2632   set_current_topmost_iface_diff(diff*);
2633 
2634   diff*
2635   get_current_topmost_iface_diff() const;
2636 
2637   virtual void
2638   visit_begin(diff*);
2639 
2640   virtual void
2641   visit_begin(corpus_diff*);
2642 
2643   virtual void
2644   visit_end(diff*);
2645 
2646   virtual void
2647   visit_end(corpus_diff*);
2648 
2649   virtual bool
2650   visit(diff*, bool);
2651 
2652   virtual bool
2653   visit(distinct_diff*, bool);
2654 
2655   virtual bool
2656   visit(var_diff*, bool);
2657 
2658   virtual bool
2659   visit(pointer_diff*, bool);
2660 
2661   virtual bool
2662   visit(reference_diff*, bool);
2663 
2664   virtual bool
2665   visit(qualified_type_diff*, bool);
2666 
2667   virtual bool
2668   visit(enum_diff*, bool);
2669 
2670   virtual bool
2671   visit(class_diff*, bool);
2672 
2673   virtual bool
2674   visit(base_diff*, bool);
2675 
2676   virtual bool
2677   visit(scope_diff*, bool);
2678 
2679   virtual bool
2680   visit(function_decl_diff*, bool);
2681 
2682   virtual bool
2683   visit(type_decl_diff*, bool);
2684 
2685   virtual bool
2686   visit(typedef_diff*, bool);
2687 
2688   virtual bool
2689   visit(translation_unit_diff*, bool);
2690 
2691   virtual bool
2692   visit(corpus_diff*, bool);
2693 }; // end struct diff_node_visitor
2694 
2695 void
2696 propagate_categories(diff* diff_tree);
2697 
2698 void
2699 propagate_categories(diff_sptr diff_tree);
2700 
2701 void
2702 propagate_categories(corpus_diff* diff_tree);
2703 
2704 void
2705 propagate_categories(corpus_diff_sptr diff_tree);
2706 
2707 void
2708 apply_suppressions(diff* diff_tree);
2709 
2710 void
2711 apply_suppressions(const corpus_diff* diff_tree);
2712 
2713 void
2714 apply_suppressions(diff_sptr diff_tree);
2715 
2716 void
2717 apply_suppressions(corpus_diff_sptr diff_tree);
2718 
2719 void
2720 print_diff_tree(diff* diff_tree, std::ostream&);
2721 
2722 void
2723 print_diff_tree(corpus_diff* diff_tree,
2724 		std::ostream&);
2725 
2726 void
2727 print_diff_tree(diff_sptr diff_tree,
2728 		std::ostream&);
2729 
2730 void
2731 print_diff_tree(corpus_diff_sptr diff_tree,
2732 		std::ostream&);
2733 
2734 void
2735 categorize_redundancy(diff* diff_tree);
2736 
2737 void
2738 categorize_redundancy(diff_sptr diff_tree);
2739 
2740 void
2741 categorize_redundancy(corpus_diff* diff_tree);
2742 
2743 void
2744 categorize_redundancy(corpus_diff_sptr diff_tree);
2745 
2746 void
2747 clear_redundancy_categorization(diff* diff_tree);
2748 
2749 void
2750 clear_redundancy_categorization(diff_sptr diff_tree);
2751 
2752 void
2753 clear_redundancy_categorization(corpus_diff* diff_tree);
2754 
2755 void
2756 clear_redundancy_categorization(corpus_diff_sptr diff_tree);
2757 
2758 void
2759 apply_filters(corpus_diff_sptr diff_tree);
2760 
2761 bool
2762 is_diff_of_variadic_parameter_type(const diff*);
2763 
2764 bool
2765 is_diff_of_variadic_parameter_type(const diff_sptr&);
2766 
2767 bool
2768 is_diff_of_variadic_parameter(const diff*);
2769 
2770 bool
2771 is_diff_of_variadic_parameter(const diff_sptr&);
2772 
2773 const type_diff_base*
2774 is_type_diff(const diff* diff);
2775 
2776 const decl_diff_base*
2777 is_decl_diff(const diff* diff);
2778 
2779 const type_decl_diff*
2780 is_diff_of_basic_type(const diff* diff);
2781 
2782 const type_decl_diff*
2783 is_diff_of_basic_type(const diff* diff, bool);
2784 
2785 const class_or_union_diff*
2786 is_diff_of_class_or_union_type(const diff *d);
2787 
2788 bool
2789 has_basic_type_change_only(const diff* diff);
2790 
2791 const enum_diff*
2792 is_enum_diff(const diff *diff);
2793 
2794 const class_diff*
2795 is_class_diff(const diff* diff);
2796 
2797 const union_diff*
2798 is_union_diff(const diff* diff);
2799 
2800 const class_or_union_diff*
2801 is_class_or_union_diff(const diff* d);
2802 
2803 const class_or_union_diff*
2804 is_anonymous_class_or_union_diff(const diff* d);
2805 
2806 const array_diff*
2807 is_array_diff(const diff* diff);
2808 
2809 const function_type_diff*
2810 is_function_type_diff(const diff* diff);
2811 
2812 const function_type_diff*
2813 is_function_type_diff_with_local_changes(const diff* diff);
2814 
2815 const typedef_diff*
2816 is_typedef_diff(const diff *diff);
2817 
2818 const var_diff*
2819 is_var_diff(const diff* diff);
2820 
2821 const function_decl_diff*
2822 is_function_decl_diff(const diff* diff);
2823 
2824 const pointer_diff*
2825 is_pointer_diff(const diff* diff);
2826 
2827 const reference_diff*
2828 is_reference_diff(const diff* diff);
2829 
2830 const qualified_type_diff*
2831 is_qualified_type_diff(const diff* diff);
2832 
2833 const fn_parm_diff*
2834 is_fn_parm_diff(const diff* diff);
2835 
2836 const base_diff*
2837 is_base_diff(const diff* diff);
2838 
2839 const distinct_diff*
2840 is_distinct_diff(const diff *diff);
2841 
2842 bool
2843 is_child_node_of_function_parm_diff(const diff* diff);
2844 
2845 bool
2846 is_child_node_of_base_diff(const diff* diff);
2847 
2848 const corpus_diff*
2849 is_corpus_diff(const diff* diff);
2850 
2851 const diff*
2852 peel_typedef_diff(const diff* dif);
2853 
2854 const diff*
2855 peel_pointer_diff(const diff* dif);
2856 
2857 const diff*
2858 peel_reference_diff(const diff* dif);
2859 
2860 const diff*
2861 peel_qualified_diff(const diff* dif);
2862 
2863 const diff*
2864 peel_fn_parm_diff(const diff* dif);
2865 
2866 const diff*
2867 peel_pointer_or_qualified_type_diff(const diff* dif);
2868 
2869 const diff*
2870 peel_typedef_or_qualified_type_diff(const diff* dif);
2871 
2872 const diff*
2873 peel_typedef_qualified_type_or_parameter_diff(const diff *dif);
2874 }// end namespace comparison
2875 
2876 }// end namespace abigail
2877 
2878 #endif //__ABG_COMPARISON_H__
2879