3 // Copyright (C) 2013-2019 Red Hat, Inc.
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
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.
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/>.
21 // Author: Dodji Seketeli
23 #ifndef __ABG_COMPARISON_H__
24 #define __ABG_COMPARISON_H__
28 #include <tr1/unordered_map>
29 #include <tr1/unordered_set>
31 #include "abg-corpus.h"
32 #include "abg-diff-utils.h"
33 #include "abg-reporter.h"
38 /// @brief utilities to compare abi artifacts
40 /// The main entry points of the namespace are the compute_diff()
41 /// overloads used to compute the difference between two abi artifacts.
48 typedef shared_ptr<filter_base> filter_base_sptr;
49 typedef std::vector<filter_base_sptr> filters;
52 // Inject types we need into this namespace.
55 using std::tr1::unordered_map;
56 using std::tr1::unordered_set;
59 using diff_utils::insertion;
60 using diff_utils::deletion;
61 using diff_utils::edit_script;
65 /// Convenience typedef for a shared_ptr for the @ref diff class
66 typedef shared_ptr<diff> diff_sptr;
68 /// Convenience typedef for a weak_ptr for the @ref diff class
69 typedef weak_ptr<diff> diff_wptr;
71 /// Hasher for @ref diff_sptr.
72 struct diff_sptr_hasher
74 /// The actual hashing functor.
76 operator()(const diff_sptr& t) const
77 {return reinterpret_cast<size_t>(t.get());}
78 }; // end struct diff_sptr_hasher
80 /// Convenience typedef for a vector of @ref diff_sptr.
81 typedef vector<diff_sptr> diff_sptrs_type;
83 /// Convenience typedef for a vector of @ref diff*.
84 typedef vector<diff*> diff_ptrs_type;
86 /// Convenience typedef for an unoredered set of @ref diff_sptr
87 typedef unordered_set<diff_sptr, diff_sptr_hasher> unordered_diff_sptr_set;
91 /// Convenience typedef for a shared_ptr of @ref decl_diff_base.
92 typedef shared_ptr<decl_diff_base> decl_diff_base_sptr;
94 /// Convenience typedef for a vector of @ref decl_diff_base_sptr.
95 typedef vector<decl_diff_base_sptr> decl_diff_base_sptrs_type;
98 /// Convenience pointer for a shared pointer to a type_diff_base
99 typedef shared_ptr<type_diff_base> type_diff_base_sptr;
101 /// Convenience typedef for a vector of @ref type_diff_base_sptr
102 typedef vector<type_diff_base_sptr> type_diff_base_sptrs_type;
104 class function_decl_diff;
106 /// Convenience typedef for a shared pointer to a @ref function_decl type.
107 typedef shared_ptr<function_decl_diff> function_decl_diff_sptr;
109 /// Convenience typedef for a vector of @ref function_decl_diff_sptr
110 typedef vector<function_decl_diff_sptr> function_decl_diff_sptrs_type;
114 /// Convenience typedef for a shared pointer to a @ref fn_parm_diff
116 typedef shared_ptr<fn_parm_diff> fn_parm_diff_sptr;
120 /// Convenience typedef for a shared pointer to a @ref var_diff type.
121 typedef shared_ptr<var_diff> var_diff_sptr;
123 /// Convenience typedef for a vector of @ref var_diff_sptr.
124 typedef vector<var_diff_sptr> var_diff_sptrs_type;
128 /// Convenience typedef for a shared pointer to a @ref base_diff type.
129 typedef shared_ptr<base_diff> base_diff_sptr;
131 /// Convenience typedef for a vector of @ref base_diff_sptr.
132 typedef vector<base_diff_sptr> base_diff_sptrs_type;
136 /// Convenience typedef for a shared pointer on a @ref class_diff type.
137 typedef shared_ptr<class_diff> class_diff_sptr;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
215 /// Convenience typedef for a vector of changed enumerators.
216 typedef vector<changed_enumerator> changed_enumerators_type;
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;
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;
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;
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
236 typedef pair<method_decl_sptr,
237 method_decl_sptr> changed_member_function_sptr;
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;
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;
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;
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;
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;
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;
267 /// Convenience typedef for a shared pointer of @ref diff_context.
268 typedef shared_ptr<diff_context> diff_context_sptr;
270 /// Convenience typedef for a weak pointer of @ref diff_context.
271 typedef weak_ptr<diff_context> diff_context_wptr;
273 class diff_node_visitor;
275 class diff_traversable_base;
277 /// Convenience typedef for shared_ptr on diff_traversable_base.
278 typedef shared_ptr<diff_traversable_base> diff_traversable_base_sptr;
280 /// An enum for the different ways to visit a diff tree node.
282 /// This is used by the node traversing code, to know when to avoid
283 /// visiting children nodes, for instance.
286 /// The default enumerator value of this enum. It doesn't have any
287 /// particular meaning yet.
288 DEFAULT_VISITING_KIND = 0,
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,
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
301 operator|(visiting_kind l, visiting_kind r);
304 operator&(visiting_kind l, visiting_kind r);
307 operator~(visiting_kind l);
309 /// The base class for the diff classes that are to be traversed.
310 class diff_traversable_base : public traversable_base
314 traverse(diff_node_visitor& v);
315 }; // end struct diff_traversable_base
317 /// An enum for the different categories that a diff tree node falls
318 /// into, regarding the kind of changes it represents.
320 /// Note that if you add an enumerator to this enum, you need to
321 /// update a few spots accordingly:
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.
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.
331 /// * update the get_default_harmless_categories_bitmap or
332 /// get_default_harmful_categories_bitmap function as well, just
335 /// * update the "operator<<(ostream& o, diff_category c)" streaming
336 /// operator so that it can stream the new enumerator to a textual
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,
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,
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,
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,
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,
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,
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,
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,
375 HARMLESS_UNION_CHANGE_CATEGORY = 1 << 7,
377 /// This means that a diff node was marked as suppressed by a
378 /// user-provided suppression specification.
379 SUPPRESSED_CATEGORY = 1 << 8,
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,
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,
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,
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,
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
404 CLASS_DECL_ONLY_DEF_CHANGE_CATEGORY = 1 << 13,
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,
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,
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,
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,
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,
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.
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
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
459 operator|(diff_category c1, diff_category c2);
462 operator|=(diff_category& c1, diff_category c2);
465 operator&=(diff_category& c1, diff_category c2);
468 operator^(diff_category c1, diff_category c2);
471 operator&(diff_category c1, diff_category c2);
474 operator~(diff_category c);
477 get_default_harmless_categories_bitmap();
480 get_default_harmful_categories_bitmap();
483 operator<<(ostream& o, diff_category);
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.
493 typedef shared_ptr<priv> priv_sptr;
500 const string_diff_ptr_map&
501 get_type_decl_diff_map() const;
504 get_type_decl_diff_map();
506 const string_diff_ptr_map&
507 get_enum_diff_map() const;
512 const string_diff_ptr_map&
513 get_class_diff_map() const;
516 get_class_diff_map();
518 const string_diff_ptr_map&
519 get_union_diff_map() const;
522 get_union_diff_map();
524 const string_diff_ptr_map&
525 get_typedef_diff_map() const;
528 get_typedef_diff_map();
530 const string_diff_ptr_map&
531 get_array_diff_map() const;
534 get_array_diff_map();
536 const string_diff_ptr_map&
537 get_reference_diff_map() const;
540 get_reference_diff_map();
542 const string_diff_ptr_map&
543 get_fn_parm_diff_map() const;
546 get_fn_parm_diff_map();
548 const string_diff_ptr_map&
549 get_function_type_diff_map() const;
552 get_function_type_diff_map();
554 const string_diff_ptr_map&
555 get_function_decl_diff_map() const;
558 get_function_decl_diff_map();
560 const string_diff_ptr_map&
561 get_var_decl_diff_map() const;
564 get_var_decl_diff_map();
566 const string_diff_ptr_map&
567 get_distinct_diff_map() const;
570 get_distinct_diff_map();
573 insert_diff_node(const diff *d,
574 const type_or_decl_base_sptr& impacted_iface);
576 artifact_sptr_set_type*
577 lookup_impacted_interfaces(const diff *d) const;
578 }; // end class diff_maps
580 /// A convenience typedef for a shared pointer to @ref corpus_diff.
581 typedef shared_ptr<corpus_diff> corpus_diff_sptr;
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.
589 shared_ptr<priv> priv_;
592 has_diff_for(const type_or_decl_base_sptr first,
593 const type_or_decl_base_sptr second) const;
596 has_diff_for_types(const type_base_sptr first,
597 const type_base_sptr second) const;
600 has_diff_for(const diff* d) const;
603 has_diff_for(const diff_sptr d) const;
606 add_diff(const type_or_decl_base_sptr first,
607 const type_or_decl_base_sptr second,
611 add_diff(const diff_sptr d);
614 add_diff(const diff* d);
617 set_canonical_diff_for(const type_or_decl_base_sptr first,
618 const type_or_decl_base_sptr second,
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);
630 set_corpus_diff(const corpus_diff_sptr&);
632 const corpus_diff_sptr&
633 get_corpus_diff() const;
636 get_first_corpus() const;
639 get_second_corpus() const;
642 get_reporter() const;
645 set_reporter(reporter_base_sptr&);
648 get_canonical_diff_for(const type_or_decl_base_sptr first,
649 const type_or_decl_base_sptr second) const;
652 get_canonical_diff_for(const diff_sptr d) const;
655 initialize_canonical_diff(const diff_sptr diff);
658 keep_diff_alive(diff_sptr&);
661 diff_has_been_visited(const diff*) const;
664 diff_has_been_visited(const diff_sptr) const;
667 mark_diff_as_visited(const diff*);
670 forget_visited_diffs();
673 mark_last_diff_visited_per_class_of_equivalence(const diff*);
676 clear_last_diffs_visited_per_class_of_equivalence();
679 get_last_visited_diff_of_class_of_equivalence(const diff*);
682 forbid_visiting_a_node_twice(bool f);
685 visiting_a_node_twice_is_forbidden() const;
688 forbid_visiting_a_node_twice_per_interface(bool);
691 visiting_a_node_twice_is_forbidden_per_interface() const;
694 get_allowed_category() const;
697 set_allowed_category(diff_category c);
700 switch_categories_on(diff_category c);
703 switch_categories_off(diff_category c);
705 const filtering::filters&
706 diff_filters() const;
709 add_diff_filter(filtering::filter_base_sptr);
712 maybe_apply_filters(diff_sptr diff);
715 maybe_apply_filters(corpus_diff_sptr diff);
717 suppr::suppressions_type&
718 suppressions() const;
721 add_suppression(const suppr::suppression_sptr suppr);
724 add_suppressions(const suppr::suppressions_type& supprs);
727 show_leaf_changes_only(bool f);
730 show_leaf_changes_only() const;
733 show_hex_values() const;
736 show_hex_values(bool f);
739 show_offsets_sizes_in_bits() const;
742 show_offsets_sizes_in_bits(bool f);
745 show_relative_offset_changes(bool f);
748 show_relative_offset_changes(void);
751 show_stats_only(bool f);
754 show_stats_only() const;
757 show_soname_change(bool f);
760 show_soname_change() const;
763 show_architecture_change(bool f);
766 show_architecture_change() const;
769 show_deleted_fns(bool f);
772 show_deleted_fns() const;
775 show_changed_fns(bool f);
778 show_changed_fns() const;
781 show_added_fns(bool f);
784 show_added_fns() const;
787 show_deleted_vars(bool f);
790 show_deleted_vars() const;
793 show_changed_vars(bool f);
796 show_changed_vars() const;
799 show_added_vars(bool f);
802 show_added_vars() const;
805 show_linkage_names() const;
808 show_linkage_names(bool f);
817 show_redundant_changes() const;
820 show_redundant_changes(bool f);
823 show_symbols_unreferenced_by_debug_info() const;
826 show_symbols_unreferenced_by_debug_info(bool f);
829 show_added_symbols_unreferenced_by_debug_info() const;
832 show_added_symbols_unreferenced_by_debug_info(bool f);
835 show_impacted_interfaces() const;
838 show_impacted_interfaces(bool f);
841 default_output_stream(ostream*);
844 default_output_stream();
847 error_output_stream(ostream*);
850 error_output_stream() const;
853 dump_diff_tree() const;
856 dump_diff_tree(bool f);
859 do_dump_diff_tree(const diff_sptr) const;
862 do_dump_diff_tree(const corpus_diff_sptr) const;
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.
870 /// The abstraction of a change between two ABI artifacts.
872 /// Please read more about the @ref DiffNode "IR" of the comparison
873 /// engine to learn more about this.
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
880 friend class diff_context;
883 typedef shared_ptr<priv> priv_sptr;
891 diff(type_or_decl_base_sptr first_subject,
892 type_or_decl_base_sptr second_subject);
894 diff(type_or_decl_base_sptr first_subject,
895 type_or_decl_base_sptr second_subject,
896 diff_context_sptr ctxt);
908 set_canonical_diff(diff *);
911 type_or_decl_base_sptr
912 first_subject() const;
914 type_or_decl_base_sptr
915 second_subject() const;
918 children_nodes() const;
923 diff* get_canonical_diff() const;
926 is_traversing() const;
929 append_child_node(diff_sptr);
931 const diff_context_sptr
935 context(diff_context_sptr c);
938 currently_reporting() const;
941 currently_reporting(bool f) const;
944 reported_once() const;
947 reported_once(bool f) const;
950 get_category() const;
953 get_local_category() const;
956 get_class_of_equiv_category() const;
959 add_to_category(diff_category c);
962 add_to_local_category(diff_category c);
965 add_to_local_and_inherited_categories(diff_category c);
968 remove_from_category(diff_category c);
971 remove_from_local_category(diff_category c);
974 set_category(diff_category c);
977 set_local_category(diff_category c);
980 is_filtered_out() const;
983 is_filtered_out_wrt_non_inherited_categories() const;
986 is_suppressed() const;
989 is_suppressed(bool &is_private_type) const;
992 to_be_reported() const;
995 has_local_changes_to_be_reported() const;
997 virtual const string&
998 get_pretty_representation() const;
1001 chain_into_hierarchy();
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.
1007 /// This is to be implemented by all descendants of this type.
1009 has_changes() const = 0;
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.
1016 /// This is to be implemented by all descendants of this type.
1017 virtual enum change_kind
1018 has_local_changes() const = 0;
1020 /// Pure interface to report the diff in a serialized form that is
1021 /// legible for the user.
1023 /// Note that the serializd report has to leave one empty line at
1024 /// the end of its content.
1026 /// @param out the output stream to serialize the report to.
1028 /// @param indent the indentation string to use.
1030 report(ostream& out, const string& indent = "") const = 0;
1033 traverse(diff_node_visitor& v);
1037 compute_diff(const decl_base_sptr,
1038 const decl_base_sptr,
1039 diff_context_sptr ctxt);
1042 compute_diff(const type_base_sptr,
1043 const type_base_sptr,
1044 diff_context_sptr ctxt);
1046 /// The base class of diff between types.
1047 class type_diff_base : public diff
1050 typedef shared_ptr<priv> priv_sptr;
1057 type_diff_base(type_base_sptr first_subject,
1058 type_base_sptr second_subject,
1059 diff_context_sptr ctxt);
1063 virtual enum change_kind
1064 has_local_changes() const = 0;
1066 virtual ~type_diff_base();
1067 };// end class type_diff_base
1069 /// The base class of diff between decls.
1070 class decl_diff_base : public diff
1073 typedef shared_ptr<priv> priv_sptr;
1078 decl_diff_base(decl_base_sptr first_subject,
1079 decl_base_sptr second_subject,
1080 diff_context_sptr ctxt);
1084 virtual enum change_kind
1085 has_local_changes() const = 0;
1087 virtual ~decl_diff_base();
1088 };// end class decl_diff_base
1091 get_pretty_representation(diff*);
1093 class distinct_diff;
1095 /// Convenience typedef for a shared pointer to distinct_types_diff
1096 typedef shared_ptr<distinct_diff> distinct_diff_sptr;
1098 /// An abstraction of a diff between entities that are of a different
1099 /// kind (disctinct).
1100 class distinct_diff : public diff
1103 typedef shared_ptr<priv> priv_sptr;
1107 distinct_diff(type_or_decl_base_sptr first,
1108 type_or_decl_base_sptr second,
1109 diff_context_sptr ctxt = diff_context_sptr());
1116 const type_or_decl_base_sptr
1119 const type_or_decl_base_sptr
1123 compatible_child_diff() const;
1125 virtual const string&
1126 get_pretty_representation() const;
1129 has_changes() const;
1131 virtual enum change_kind
1132 has_local_changes() const;
1135 report(ostream& out, const string& indent = "") const;
1138 chain_into_hierarchy();
1141 entities_are_of_distinct_kinds(type_or_decl_base_sptr first,
1142 type_or_decl_base_sptr second);
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
1151 compute_diff_for_distinct_kinds(const type_or_decl_base_sptr,
1152 const type_or_decl_base_sptr,
1153 diff_context_sptr ctxt);
1155 /// Abstracts a diff between two instances of @ref var_decl
1156 class var_diff : public decl_diff_base
1159 typedef shared_ptr<priv> priv_sptr;
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());
1182 chain_into_hierarchy();
1185 has_changes() const;
1187 virtual enum change_kind
1188 has_local_changes() const;
1191 report(ostream& out, const string& indent = "") const;
1193 virtual const string&
1194 get_pretty_representation() const;
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
1203 compute_diff(const var_decl_sptr, const var_decl_sptr, diff_context_sptr);
1206 /// Convenience typedef for a shared pointer on a @ref
1207 /// pointer_diff type.
1208 typedef shared_ptr<pointer_diff> pointer_diff_sptr;
1210 /// The abstraction of a diff between two pointers.
1211 class pointer_diff : public type_diff_base
1214 shared_ptr<priv> priv_;
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());
1226 const pointer_type_def_sptr
1227 first_pointer() const;
1229 const pointer_type_def_sptr
1230 second_pointer() const;
1233 underlying_type_diff() const;
1236 underlying_type_diff(const diff_sptr);
1238 virtual const string&
1239 get_pretty_representation() const;
1242 has_changes() const;
1244 virtual enum change_kind
1245 has_local_changes() const;
1248 report(ostream&, const string& indent = "") const;
1251 chain_into_hierarchy();
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
1260 compute_diff(pointer_type_def_sptr first,
1261 pointer_type_def_sptr second,
1262 diff_context_sptr ctxt);
1264 class reference_diff;
1266 /// Convenience typedef for a shared pointer on a @ref
1267 /// reference_diff type.
1268 typedef shared_ptr<reference_diff> reference_diff_sptr;
1270 /// The abstraction of a diff between two references.
1271 class reference_diff : public type_diff_base
1274 shared_ptr<priv> priv_;
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());
1286 reference_type_def_sptr
1287 first_reference() const;
1289 reference_type_def_sptr
1290 second_reference() const;
1293 underlying_type_diff() const;
1296 underlying_type_diff(diff_sptr);
1298 virtual const string&
1299 get_pretty_representation() const;
1302 has_changes() const;
1304 virtual enum change_kind
1305 has_local_changes() const;
1308 report(ostream&, const string& indent = "") const;
1311 chain_into_hierarchy();
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
1320 compute_diff(reference_type_def_sptr first,
1321 reference_type_def_sptr second,
1322 diff_context_sptr ctxt);
1326 /// Convenience typedef for a shared pointer on a @ref
1327 /// array_diff type.
1328 typedef shared_ptr<array_diff> array_diff_sptr;
1330 /// The abstraction of a diff between two arrays.
1331 class array_diff : public type_diff_base
1334 shared_ptr<priv> priv_;
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());
1346 const array_type_def_sptr
1347 first_array() const;
1349 const array_type_def_sptr
1350 second_array() const;
1353 element_type_diff() const;
1356 element_type_diff(diff_sptr);
1358 virtual const string&
1359 get_pretty_representation() const;
1362 has_changes() const;
1364 virtual enum change_kind
1365 has_local_changes() const;
1368 report(ostream&, const string& indent = "") const;
1371 chain_into_hierarchy();
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
1380 compute_diff(array_type_def_sptr first,
1381 array_type_def_sptr second,
1382 diff_context_sptr ctxt);
1384 class qualified_type_diff;
1385 typedef class shared_ptr<qualified_type_diff> qualified_type_diff_sptr;
1387 /// Abstraction of a diff between two qualified types.
1388 class qualified_type_diff : public type_diff_base
1391 typedef shared_ptr<priv> priv_sptr;
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());
1404 const qualified_type_def_sptr
1405 first_qualified_type() const;
1407 const qualified_type_def_sptr
1408 second_qualified_type() const;
1411 underlying_type_diff() const;
1414 underlying_type_diff(const diff_sptr);
1417 leaf_underlying_type_diff() const;
1419 virtual const string&
1420 get_pretty_representation() const;
1423 has_changes() const;
1425 virtual enum change_kind
1426 has_local_changes() const;
1429 report(ostream&, const string& indent = "") const;
1432 chain_into_hierarchy();
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.
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);
1446 typedef shared_ptr<enum_diff> enum_diff_sptr;
1448 /// Abstraction of a diff between two enums.
1449 class enum_diff : public type_diff_base
1452 typedef shared_ptr<priv> priv_sptr;
1456 clear_lookup_tables();
1459 lookup_tables_empty() const;
1462 ensure_lookup_tables_populated();
1465 enum_diff(const enum_type_decl_sptr,
1466 const enum_type_decl_sptr,
1468 diff_context_sptr ctxt = diff_context_sptr());
1474 const enum_type_decl_sptr
1477 const enum_type_decl_sptr
1478 second_enum() const;
1481 underlying_type_diff() const;
1483 const string_enumerator_map&
1484 deleted_enumerators() const;
1486 const string_enumerator_map&
1487 inserted_enumerators() const;
1489 const string_changed_enumerator_map&
1490 changed_enumerators() const;
1492 virtual const string&
1493 get_pretty_representation() const;
1496 has_changes() const;
1498 virtual enum change_kind
1499 has_local_changes() const;
1502 report(ostream&, const string& indent = "") const;
1505 chain_into_hierarchy();
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;
1514 compute_diff(const enum_type_decl_sptr,
1515 const enum_type_decl_sptr,
1518 /// This is the base class of @ref class_diff and @ref union_diff.
1519 class class_or_union_diff : public type_diff_base
1523 typedef shared_ptr<priv> priv_sptr;
1527 clear_lookup_tables(void);
1530 lookup_tables_empty(void) const;
1533 ensure_lookup_tables_populated(void) const;
1536 allocate_priv_data();
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());
1548 const class_or_union_diff::priv_sptr&
1551 //TODO: add change of the name of the type.
1553 virtual ~class_or_union_diff();
1556 first_class_or_union() const;
1559 second_class_or_union() const;
1562 member_types_changes() const;
1565 member_types_changes();
1568 data_members_changes() const;
1571 data_members_changes();
1573 const string_decl_base_sptr_map&
1574 inserted_data_members() const;
1576 const string_decl_base_sptr_map&
1577 deleted_data_members() const;
1580 member_fns_changes() const;
1583 member_fns_changes();
1585 const function_decl_diff_sptrs_type&
1586 changed_member_fns() const;
1588 const string_member_function_sptr_map&
1589 deleted_member_fns() const;
1591 const string_member_function_sptr_map&
1592 inserted_member_fns() const;
1595 member_fn_tmpls_changes() const;
1598 member_fn_tmpls_changes();
1601 member_class_tmpls_changes() const;
1604 member_class_tmpls_changes();
1607 has_changes() const;
1609 virtual enum change_kind
1610 has_local_changes() const;
1613 report(ostream&, const string& indent = "") const;
1616 chain_into_hierarchy();
1618 friend class default_reporter;
1619 }; // end class_or_union_diff;
1621 /// This type abstracts changes for a class_decl.
1622 class class_diff : public class_or_union_diff
1625 typedef shared_ptr<priv> priv_sptr;
1628 const priv_sptr& get_priv()const;
1631 clear_lookup_tables(void);
1634 lookup_tables_empty(void) const;
1637 ensure_lookup_tables_populated(void) const;
1640 allocate_priv_data();
1643 class_diff(class_decl_sptr first_scope,
1644 class_decl_sptr second_scope,
1645 diff_context_sptr ctxt = diff_context_sptr());
1651 //TODO: add change of the name of the type.
1653 virtual ~class_diff();
1656 first_class_decl() const;
1659 second_class_decl() const;
1662 base_changes() const;
1667 const string_base_sptr_map&
1668 deleted_bases() const;
1670 const string_base_sptr_map&
1671 inserted_bases() const;
1673 const base_diff_sptrs_type&
1677 has_changes() const;
1679 virtual enum change_kind
1680 has_local_changes() const;
1682 virtual const string&
1683 get_pretty_representation() const;
1686 report(ostream&, const string& indent = "") const;
1689 chain_into_hierarchy();
1691 friend class_diff_sptr
1692 compute_diff(const class_decl_sptr first,
1693 const class_decl_sptr second,
1694 diff_context_sptr ctxt);
1696 friend class default_reporter;
1700 compute_diff(const class_decl_sptr first,
1701 const class_decl_sptr second,
1702 diff_context_sptr ctxt);
1705 typedef shared_ptr<union_diff> union_diff_sptr;
1707 class union_diff : public class_or_union_diff
1710 clear_lookup_tables(void);
1713 lookup_tables_empty(void) const;
1716 ensure_lookup_tables_populated(void) const;
1719 allocate_priv_data();
1722 union_diff(union_decl_sptr first_union,
1723 union_decl_sptr second_union,
1724 diff_context_sptr ctxt = diff_context_sptr());
1731 virtual ~union_diff();
1734 first_union_decl() const;
1737 second_union_decl() const;
1739 virtual const string&
1740 get_pretty_representation() const;
1743 report(ostream&, const string& indent = "") const;
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
1752 compute_diff(const union_decl_sptr first,
1753 const union_decl_sptr second,
1754 diff_context_sptr ctxt);
1756 /// An abstraction of a diff between two instances of class_decl::base_spec.
1757 class base_diff : public diff
1760 shared_ptr<priv> priv_;
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());
1772 class_decl::base_spec_sptr
1775 class_decl::base_spec_sptr
1776 second_base() const;
1778 const class_diff_sptr
1779 get_underlying_class_diff() const;
1782 set_underlying_class_diff(class_diff_sptr d);
1784 virtual const string&
1785 get_pretty_representation() const;
1788 has_changes() const;
1790 virtual enum change_kind
1791 has_local_changes() const;
1794 report(ostream&, const string& indent = "") const;
1797 chain_into_hierarchy();
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
1806 compute_diff(const class_decl::base_spec_sptr first,
1807 const class_decl::base_spec_sptr second,
1808 diff_context_sptr ctxt);
1812 /// Convenience typedef for a shared pointer on a @ref scope_diff.
1813 typedef shared_ptr<scope_diff> scope_diff_sptr;
1815 /// An abstractions of the changes between two scopes.
1816 class scope_diff : public diff
1819 shared_ptr<priv> priv_;
1822 lookup_tables_empty() const;
1825 clear_lookup_tables();
1828 ensure_lookup_tables_populated();
1831 scope_diff(scope_decl_sptr first_scope,
1832 scope_decl_sptr second_scope,
1833 diff_context_sptr ctxt = diff_context_sptr());
1840 friend scope_diff_sptr
1841 compute_diff(const scope_decl_sptr first,
1842 const scope_decl_sptr second,
1844 diff_context_sptr ctxt);
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);
1851 const scope_decl_sptr
1852 first_scope() const;
1854 const scope_decl_sptr
1855 second_scope() const;
1858 member_changes() const;
1863 const decl_base_sptr
1864 deleted_member_at(unsigned index) const;
1866 const decl_base_sptr
1867 deleted_member_at(vector<deletion>::const_iterator) const;
1869 const decl_base_sptr
1870 inserted_member_at(unsigned i);
1872 const decl_base_sptr
1873 inserted_member_at(vector<unsigned>::const_iterator i);
1875 const diff_sptrs_type&
1876 changed_types() const;
1878 const diff_sptrs_type&
1879 changed_decls() const;
1881 const string_decl_base_sptr_map&
1882 removed_types() const;
1884 const string_decl_base_sptr_map&
1885 removed_decls() const;
1887 const string_decl_base_sptr_map&
1888 added_types() const;
1890 const string_decl_base_sptr_map&
1891 added_decls() const;
1893 virtual const string&
1894 get_pretty_representation() const;
1897 has_changes() const;
1899 virtual enum change_kind
1900 has_local_changes() const;
1903 report(ostream& out, const string& indent = "") const;
1906 chain_into_hierarchy();
1908 friend class default_reporter;
1909 friend class leaf_reporter;
1910 };// end class scope_diff
1913 compute_diff(const scope_decl_sptr first,
1914 const scope_decl_sptr second,
1916 diff_context_sptr ctxt);
1919 compute_diff(const scope_decl_sptr first_scope,
1920 const scope_decl_sptr second_scope,
1921 diff_context_sptr ctxt);
1923 /// Abstraction of a diff between two function parameters.
1924 class fn_parm_diff : public decl_diff_base
1927 typedef shared_ptr<priv> priv_sptr;
1934 fn_parm_diff(const function_decl::parameter_sptr first,
1935 const function_decl::parameter_sptr second,
1936 diff_context_sptr ctxt);
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);
1944 const function_decl::parameter_sptr
1945 first_parameter() const;
1947 const function_decl::parameter_sptr
1948 second_parameter() const;
1953 virtual const string&
1954 get_pretty_representation() const;
1957 has_changes() const;
1959 virtual enum change_kind
1960 has_local_changes() const;
1963 report(ostream&, const string& indent = "") const;
1966 chain_into_hierarchy();
1967 }; // end class fn_parm_diff
1970 compute_diff(const function_decl::parameter_sptr first,
1971 const function_decl::parameter_sptr second,
1972 diff_context_sptr ctxt);
1974 class function_type_diff;
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;
1980 /// Abstraction of a diff between two function types.
1981 class function_type_diff: public type_diff_base
1984 typedef shared_ptr<priv> priv_sptr;
1988 ensure_lookup_tables_populated();
1990 const function_decl::parameter_sptr
1991 deleted_parameter_at(int i) const;
1993 const function_decl::parameter_sptr
1994 inserted_parameter_at(int i) const;
1997 function_type_diff(const function_type_sptr first,
1998 const function_type_sptr second,
1999 diff_context_sptr ctxt);
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);
2010 const function_type_sptr
2011 first_function_type() const;
2013 const function_type_sptr
2014 second_function_type() const;
2017 return_type_diff() const;
2019 const string_fn_parm_diff_sptr_map&
2020 subtype_changed_parms() const;
2022 const string_parm_map&
2023 removed_parms() const;
2025 const string_parm_map&
2026 added_parms() const;
2028 virtual const string&
2029 get_pretty_representation() const;
2032 has_changes() const;
2034 virtual enum change_kind
2035 has_local_changes() const;
2038 report(ostream&, const string& indent = "") const;
2041 chain_into_hierarchy();
2043 friend class default_reporter;
2044 friend class leaf_reporter;
2045 };// end class function_type_diff
2047 function_type_diff_sptr
2048 compute_diff(const function_type_sptr first,
2049 const function_type_sptr second,
2050 diff_context_sptr ctxt);
2052 /// Abstraction of a diff between two function_decl.
2053 class function_decl_diff : public decl_diff_base
2056 shared_ptr<priv> priv_;
2059 ensure_lookup_tables_populated();
2063 function_decl_diff(const function_decl_sptr first,
2064 const function_decl_sptr second,
2065 diff_context_sptr ctxt);
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);
2077 const function_decl_sptr
2078 first_function_decl() const;
2080 const function_decl_sptr
2081 second_function_decl() const;
2083 const function_type_diff_sptr
2086 virtual const string&
2087 get_pretty_representation() const;
2090 has_changes() const;
2092 virtual enum change_kind
2093 has_local_changes() const;
2096 report(ostream&, const string& indent = "") const;
2099 chain_into_hierarchy();
2100 }; // end class function_decl_diff
2102 function_decl_diff_sptr
2103 compute_diff(const function_decl_sptr first,
2104 const function_decl_sptr second,
2105 diff_context_sptr ctxt);
2107 class type_decl_diff;
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;
2112 /// Abstraction of a diff between two basic type declarations.
2113 class type_decl_diff : public type_diff_base
2118 type_decl_diff(const type_decl_sptr first,
2119 const type_decl_sptr second,
2120 diff_context_sptr ctxt = diff_context_sptr());
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);
2131 const type_decl_sptr
2132 first_type_decl() const;
2134 const type_decl_sptr
2135 second_type_decl() const;
2137 virtual const string&
2138 get_pretty_representation() const;
2141 has_changes() const;
2143 virtual enum change_kind
2144 has_local_changes() const;
2147 report(ostream& out, const string& indent = "") const;
2148 };// end type_decl_diff
2151 compute_diff(const type_decl_sptr,
2152 const type_decl_sptr,
2157 /// Convenience typedef for a shared pointer on a typedef_diff type.
2158 typedef shared_ptr<typedef_diff> typedef_diff_sptr;
2160 /// Abstraction of a diff between two typedef_decl.
2161 class typedef_diff : public type_diff_base
2164 shared_ptr<priv> priv_;
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());
2178 friend typedef_diff_sptr
2179 compute_diff(const typedef_decl_sptr first,
2180 const typedef_decl_sptr second,
2181 diff_context_sptr ctxt);
2183 const typedef_decl_sptr
2184 first_typedef_decl() const;
2186 const typedef_decl_sptr
2187 second_typedef_decl() const;
2190 underlying_type_diff() const;
2193 underlying_type_diff(const diff_sptr);
2195 virtual const string&
2196 get_pretty_representation() const;
2199 has_changes() const;
2201 virtual enum change_kind
2202 has_local_changes() const;
2205 report(ostream&, const string& indent = "") const;
2208 chain_into_hierarchy();
2209 };// end class typedef_diff
2212 compute_diff(const typedef_decl_sptr,
2213 const typedef_decl_sptr,
2214 diff_context_sptr ctxt);
2217 get_typedef_diff_underlying_type_diff(const diff* diff);
2219 class translation_unit_diff;
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;
2225 /// An abstraction of a diff between two translation units.
2226 class translation_unit_diff : public scope_diff
2229 typedef shared_ptr<priv> priv_sptr;
2233 translation_unit_diff(translation_unit_sptr first,
2234 translation_unit_sptr second,
2235 diff_context_sptr ctxt = diff_context_sptr());
2239 const translation_unit_sptr
2240 first_translation_unit() const;
2242 const translation_unit_sptr
2243 second_translation_unit() const;
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);
2251 has_changes() const;
2253 virtual enum change_kind
2254 has_local_changes() const;
2257 report(ostream& out, const string& indent = "") const;
2258 };//end class translation_unit_diff
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());
2265 /// An abstraction of a diff between between two abi corpus.
2269 typedef shared_ptr<priv> priv_sptr;
2273 corpus_diff(corpus_sptr first,
2275 diff_context_sptr ctxt = diff_context_sptr());
2284 virtual ~corpus_diff() {}
2286 /// A convenience typedef for a shared pointer to @ref diff_stats
2287 typedef shared_ptr<diff_stats> diff_stats_sptr;
2290 first_corpus() const;
2293 second_corpus() const;
2295 const vector<diff*>&
2296 children_nodes() const;
2299 append_child_node(diff_sptr);
2302 function_changes() const;
2305 variable_changes() const;
2308 soname_changed() const;
2311 architecture_changed() const;
2313 const string_function_ptr_map&
2314 deleted_functions() const;
2316 const string_function_ptr_map&
2319 const string_function_decl_diff_sptr_map&
2320 changed_functions();
2322 const function_decl_diff_sptrs_type&
2323 changed_functions_sorted();
2325 const string_var_ptr_map&
2326 deleted_variables() const;
2328 const string_var_ptr_map&
2329 added_variables() const;
2331 const string_var_diff_sptr_map&
2332 changed_variables();
2334 const var_diff_sptrs_type&
2335 changed_variables_sorted();
2337 const string_elf_symbol_map&
2338 deleted_unrefed_function_symbols() const;
2340 const string_elf_symbol_map&
2341 added_unrefed_function_symbols() const;
2343 const string_elf_symbol_map&
2344 deleted_unrefed_variable_symbols() const;
2346 const string_elf_symbol_map&
2347 added_unrefed_variable_symbols() const;
2349 const diff_context_sptr
2353 get_pretty_representation() const;
2356 has_changes() const;
2359 has_incompatible_changes() const;
2362 has_net_subtype_changes() const;
2365 has_net_changes() const;
2368 apply_filters_and_suppressions_before_reporting();
2371 mark_leaf_diff_nodes();
2377 get_leaf_diffs() const;
2380 report(ostream& out, const string& indent = "") const;
2383 traverse(diff_node_visitor& v);
2386 chain_into_hierarchy();
2388 friend corpus_diff_sptr
2389 compute_diff(const corpus_sptr f,
2390 const corpus_sptr s,
2391 diff_context_sptr ctxt);
2394 apply_suppressions(const corpus_diff* diff_tree);
2396 friend class default_reporter;
2397 friend class leaf_reporter;
2398 }; // end class corpus_diff
2401 compute_diff(const corpus_sptr,
2403 diff_context_sptr = diff_context_sptr());
2406 compute_diff(const corpus_group_sptr&,
2407 const corpus_group_sptr&,
2408 diff_context_sptr ctxt);
2410 /// This is a document class that aims to capture statistics about the
2411 /// changes carried by a @ref corpus_diff type.
2413 /// Its values are populated by the member function
2414 /// corpus_diff::apply_filters_and_suppressions_before_reporting()
2415 class corpus_diff::diff_stats
2418 typedef shared_ptr<priv> priv_sptr;
2426 diff_stats(diff_context_sptr);
2428 size_t num_func_removed() const;
2429 void num_func_removed(size_t);
2431 size_t num_removed_func_filtered_out() const;
2432 void num_removed_func_filtered_out(size_t);
2434 size_t net_num_func_removed() const;
2436 size_t num_func_added() const;
2437 void num_func_added(size_t);
2439 size_t num_added_func_filtered_out() const;
2440 void num_added_func_filtered_out(size_t);
2442 size_t net_num_func_added() const;
2444 size_t num_func_changed() const;
2445 void num_func_changed(size_t);
2447 size_t num_changed_func_filtered_out() const;
2448 void num_changed_func_filtered_out(size_t);
2450 size_t num_func_with_virtual_offset_changes() const;
2451 void num_func_with_virtual_offset_changes(size_t);
2453 size_t net_num_func_changed() const;
2455 size_t num_vars_removed() const;
2456 void num_vars_removed(size_t);
2458 size_t num_removed_vars_filtered_out() const;
2459 void num_removed_vars_filtered_out(size_t) const;
2461 size_t net_num_vars_removed() const;
2463 size_t num_vars_added() const;
2464 void num_vars_added(size_t);
2466 size_t num_added_vars_filtered_out() const;
2467 void num_added_vars_filtered_out(size_t);
2469 size_t net_num_vars_added() const;
2471 size_t num_vars_changed() const;
2472 void num_vars_changed(size_t);
2474 size_t num_changed_vars_filtered_out() const;
2475 void num_changed_vars_filtered_out(size_t);
2477 size_t net_num_vars_changed() const;
2479 size_t num_func_syms_removed() const;
2480 void num_func_syms_removed(size_t);
2482 size_t num_removed_func_syms_filtered_out() const;
2483 void num_removed_func_syms_filtered_out(size_t);
2485 size_t num_func_syms_added() const;
2486 void num_func_syms_added(size_t);
2488 size_t num_added_func_syms_filtered_out() const;
2489 void num_added_func_syms_filtered_out(size_t);
2491 size_t net_num_removed_func_syms() const;
2492 size_t net_num_added_func_syms() const;
2494 size_t num_var_syms_removed() const;
2495 void num_var_syms_removed(size_t);
2497 size_t num_removed_var_syms_filtered_out() const;
2498 void num_removed_var_syms_filtered_out(size_t);
2500 size_t num_var_syms_added() const;
2501 void num_var_syms_added(size_t);
2503 size_t num_added_var_syms_filtered_out() const;
2504 void num_added_var_syms_filtered_out(size_t);
2506 size_t net_num_removed_var_syms() const;
2507 size_t net_num_added_var_syms() const;
2509 size_t num_leaf_changes() const;
2510 void num_leaf_changes(size_t);
2512 size_t num_leaf_changes_filtered_out() const;
2513 void num_leaf_changes_filtered_out(size_t);
2515 size_t net_num_leaf_changes() const;
2517 size_t num_leaf_type_changes() const;
2518 void num_leaf_type_changes(size_t);
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;
2524 size_t num_leaf_func_changes() const;
2525 void num_leaf_func_changes(size_t);
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;
2531 size_t num_leaf_var_changes() const;
2532 void num_leaf_var_changes(size_t);
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
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
2545 typedef shared_ptr<priv> priv_sptr;
2550 diff_node_visitor();
2552 virtual ~diff_node_visitor() {}
2554 diff_node_visitor(visiting_kind k);
2557 get_visiting_kind() const;
2560 set_visiting_kind(visiting_kind v);
2563 or_visiting_kind(visiting_kind v);
2566 set_current_topmost_iface_diff(diff*);
2569 get_current_topmost_iface_diff() const;
2575 visit_begin(corpus_diff*);
2581 visit_end(corpus_diff*);
2587 visit(distinct_diff*, bool);
2590 visit(var_diff*, bool);
2593 visit(pointer_diff*, bool);
2596 visit(reference_diff*, bool);
2599 visit(qualified_type_diff*, bool);
2602 visit(enum_diff*, bool);
2605 visit(class_diff*, bool);
2608 visit(base_diff*, bool);
2611 visit(scope_diff*, bool);
2614 visit(function_decl_diff*, bool);
2617 visit(type_decl_diff*, bool);
2620 visit(typedef_diff*, bool);
2623 visit(translation_unit_diff*, bool);
2626 visit(corpus_diff*, bool);
2627 }; // end struct diff_node_visitor
2630 propagate_categories(diff* diff_tree);
2633 propagate_categories(diff_sptr diff_tree);
2636 propagate_categories(corpus_diff* diff_tree);
2639 propagate_categories(corpus_diff_sptr diff_tree);
2642 apply_suppressions(diff* diff_tree);
2645 apply_suppressions(const corpus_diff* diff_tree);
2648 apply_suppressions(diff_sptr diff_tree);
2651 apply_suppressions(corpus_diff_sptr diff_tree);
2654 print_diff_tree(diff* diff_tree, std::ostream&);
2657 print_diff_tree(corpus_diff* diff_tree,
2661 print_diff_tree(diff_sptr diff_tree,
2665 print_diff_tree(corpus_diff_sptr diff_tree,
2669 categorize_redundancy(diff* diff_tree);
2672 categorize_redundancy(diff_sptr diff_tree);
2675 categorize_redundancy(corpus_diff* diff_tree);
2678 categorize_redundancy(corpus_diff_sptr diff_tree);
2681 clear_redundancy_categorization(diff* diff_tree);
2684 clear_redundancy_categorization(diff_sptr diff_tree);
2687 clear_redundancy_categorization(corpus_diff* diff_tree);
2690 clear_redundancy_categorization(corpus_diff_sptr diff_tree);
2693 apply_filters(corpus_diff_sptr diff_tree);
2696 is_diff_of_variadic_parameter_type(const diff*);
2699 is_diff_of_variadic_parameter_type(const diff_sptr&);
2702 is_diff_of_variadic_parameter(const diff*);
2705 is_diff_of_variadic_parameter(const diff_sptr&);
2707 const type_diff_base*
2708 is_type_diff(const diff* diff);
2710 const decl_diff_base*
2711 is_decl_diff(const diff* diff);
2713 const type_decl_diff*
2714 is_diff_of_basic_type(const diff* diff);
2716 const type_decl_diff*
2717 is_diff_of_basic_type(const diff* diff, bool);
2719 const class_or_union_diff*
2720 is_diff_of_class_or_union_type(const diff *d);
2723 has_basic_type_change_only(const diff* diff);
2726 is_enum_diff(const diff *diff);
2729 is_class_diff(const diff* diff);
2732 is_union_diff(const diff* diff);
2734 const class_or_union_diff*
2735 is_class_or_union_diff(const diff* d);
2737 const class_or_union_diff*
2738 is_anonymous_class_or_union_diff(const diff* d);
2741 is_array_diff(const diff* diff);
2743 const function_type_diff*
2744 is_function_type_diff(const diff* diff);
2746 const function_type_diff*
2747 is_function_type_diff_with_local_changes(const diff* diff);
2750 is_typedef_diff(const diff *diff);
2753 is_var_diff(const diff* diff);
2755 const function_decl_diff*
2756 is_function_decl_diff(const diff* diff);
2759 is_pointer_diff(const diff* diff);
2761 const reference_diff*
2762 is_reference_diff(const diff* diff);
2764 const qualified_type_diff*
2765 is_qualified_type_diff(const diff* diff);
2767 is_reference_or_pointer_diff(const diff* diff);
2770 is_reference_or_pointer_diff_to_non_basic_distinct_types(const diff* diff);
2773 is_fn_parm_diff(const diff* diff);
2776 is_base_diff(const diff* diff);
2778 const distinct_diff*
2779 is_distinct_diff(const diff *diff);
2782 is_child_node_of_function_parm_diff(const diff* diff);
2785 is_child_node_of_base_diff(const diff* diff);
2788 is_corpus_diff(const diff* diff);
2791 peel_typedef_diff(const diff* dif);
2794 peel_pointer_diff(const diff* dif);
2797 peel_reference_diff(const diff* dif);
2800 peel_qualified_diff(const diff* dif);
2803 peel_pointer_or_qualified_type(const diff*dif);
2804 }// end namespace comparison
2806 }// end namespace abigail
2808 #endif //__ABG_COMPARISON_H__