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