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