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