libabigail
abg-comparison-priv.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2017-2023 Red Hat, Inc.
5 //
6 // Author: Dodji Seketeli
7 
8 /// @file
9 ///
10 /// The private data and functions of the @ref abigail::ir::comparison types.
11 ///
12 /// Interfaces declared/defined in this file are to be used by parts
13 /// of libabigail but *NOT* by clients of libabigail.
14 ///
15 
16 #ifndef __ABG_COMPARISON_PRIV_H__
17 #define __ABG_COMPARISON_PRIV_H__
18 
19 #include "abg-internal.h"
20 // <headers defining libabigail's API go under here>
21 #include <memory>
22 #include <unordered_set>
23 ABG_BEGIN_EXPORT_DECLARATIONS
24 
25 #include "abg-hash.h"
26 #include "abg-suppression.h"
27 #include "abg-comparison.h"
28 #include "abg-comp-filter.h"
29 #include "abg-sptr-utils.h"
30 #include "abg-tools-utils.h"
31 
33 // </headers defining libabigail's API>
34 
35 namespace abigail
36 {
37 
38 namespace comparison
39 {
40 
41 using std::unordered_set;
42 using namespace abigail::suppr;
43 
44 // Inject types from outside in here.
45 using std::vector;
46 using std::dynamic_pointer_cast;
47 using std::static_pointer_cast;
49 
50 /// Convenience typedef for a pair of decls or types.
51 typedef std::pair<const type_or_decl_base_sptr,
52  const type_or_decl_base_sptr> types_or_decls_type;
53 
54 /// A hashing functor for @ref types_or_decls_type.
56 {
57  size_t
58  operator()(const types_or_decls_type& d) const
59  {
60  size_t h1 = hash_type_or_decl(d.first);
61  size_t h2 = hash_type_or_decl(d.second);
62  return hashing::combine_hashes(h1, h2);
63  }
64 };
65 
66 /// An equality functor for @ref types_or_decls_type.
68 {
69  bool
70  operator()(const types_or_decls_type &d1, const types_or_decls_type &d2) const
71  {return d1.first == d2.first && d1.second == d2.second;}
72 };
73 
74 /// A convenience typedef for a map of @ref types_or_decls_type and
75 /// diff_sptr.
76 typedef unordered_map<types_or_decls_type, diff_sptr,
79 
80 /// A hashing functor for using @ref diff_sptr and @ref diff* in a
81 /// hash map or set.
82 struct diff_hash
83 {
84  /// The function-call operator to hash a @ref diff node.
85  ///
86  /// @param d the @ref diff node to hash.
87  ///
88  /// @return the hash value of @p d.
89  size_t
90  operator()(const diff_sptr& d) const
91  {return operator()(*d);}
92 
93  /// The function-call operator to hash a @ref diff node.
94  ///
95  /// @param d the @ref diff node to hash.
96  ///
97  /// @return the hash value of @p d.
98  size_t
99  operator()(const diff *d) const
100  {return operator()(*d);}
101 
102  /// The function-call operator to hash a @ref diff node.
103  ///
104  /// @param d the @ref diff node to hash.
105  ///
106  /// @return the hash value of @p d.
107  size_t
108  operator()(const diff& d) const
109  {
110  diff* canonical_diff = d.get_canonical_diff();
111  ABG_ASSERT(canonical_diff);
112  return reinterpret_cast<size_t>(canonical_diff);
113  }
114 }; // end struct diff_hash
115 
116 /// A comparison functor for using @ref diff_sptr and @ref diff* in a
117 /// hash map or set.
119 {
120  /// The function-call operator to compare two @ref diff nodes.
121  ///
122  /// @param d1 the first diff node involved in the comparison.
123  ///
124  /// @param d2 the second diff node involved in the comparison.
125  ///
126  /// @return true iff @p d1 equals @p d2.
127  bool
128  operator()(const diff* d1, const diff* d2) const
129  {return operator()(*d1, *d2);}
130 
131  /// The function-call operator to compare two @ref diff nodes.
132  ///
133  /// @param d1 the first diff node involved in the comparison.
134  ///
135  /// @param d2 the second diff node involved in the comparison.
136  ///
137  /// @return true iff @p d1 equals @p d2.
138  bool
139  operator()(const diff_sptr& d1, const diff_sptr& d2) const
140  {return operator()(*d1, *d2);}
141 
142  /// The function-call operator to compare two @ref diff nodes.
143  ///
144  /// @param d1 the first diff node involved in the comparison.
145  ///
146  /// @param d2 the second diff node involved in the comparison.
147  ///
148  /// @return true iff @p d1 equals @p d2.
149  bool
150  operator()(const diff& d1, const diff& d2) const
151  {
152  diff* canonical_diff1 = d1.get_canonical_diff();
153  ABG_ASSERT(canonical_diff1);
154 
155  diff *canonical_diff2 = d2.get_canonical_diff();
156  ABG_ASSERT(canonical_diff2);
157 
158  return canonical_diff1 == canonical_diff2;
159  }
160 }; // end struct diff_equal
161 
162 /// A convenience typedef for an unordered_map which key is a @ref
163 /// diff* and which value is a @ref artifact_sptr_set_type.
164 typedef unordered_map<const diff*, artifact_sptr_set_type,
167 
168 /// The private member (pimpl) for @ref diff_context.
170 {
171  diff_category allowed_category_;
172  reporter_base_sptr reporter_;
173  types_or_decls_diff_map_type types_or_decls_diff_map;
174  unordered_diff_sptr_set live_diffs_;
175  vector<diff_sptr> canonical_diffs;
176  vector<filtering::filter_base_sptr> filters_;
177  // All the suppressions specifications are stored in this data
178  // member.
179  suppressions_type suppressions_;
180  // The negated suppressions specifications that are in
181  // suppressions_ are stored here. Each time suppressions_ is
182  // modified, this data member should be cleared.
183  suppressions_type negated_suppressions_;
184  // The non-negated suppressions specifications that are in
185  // suppressions_ are stored here. Each time suppressions_ is
186  // modified, this data member should be cleared.
187  suppressions_type direct_suppressions_;
188  pointer_map visited_diff_nodes_;
189  corpus_diff_sptr corpus_diff_;
190  ostream* default_output_stream_;
191  ostream* error_output_stream_;
192  bool perform_change_categorization_;
193  bool leaf_changes_only_;
194  bool forbid_visiting_a_node_twice_;
195  bool reset_visited_diffs_for_each_interface_;
196  bool hex_values_;
197  bool show_offsets_sizes_in_bits_;
198  bool show_relative_offset_changes_;
199  bool show_stats_only_;
200  bool show_soname_change_;
201  bool show_architecture_change_;
202  bool show_deleted_fns_;
203  bool show_changed_fns_;
204  bool show_added_fns_;
205  bool show_deleted_vars_;
206  bool show_changed_vars_;
207  bool show_added_vars_;
208  bool show_linkage_names_;
209  bool show_locs_;
210  bool show_redundant_changes_;
211  bool show_syms_unreferenced_by_di_;
212  bool show_added_syms_unreferenced_by_di_;
213  bool show_unreachable_types_;
214  bool show_impacted_interfaces_;
215  bool dump_diff_tree_;
216  bool do_log_;
217 
218  priv()
219  : allowed_category_(EVERYTHING_CATEGORY),
220  reporter_(),
221  default_output_stream_(),
222  error_output_stream_(),
223  perform_change_categorization_(true),
224  leaf_changes_only_(),
225  forbid_visiting_a_node_twice_(true),
226  reset_visited_diffs_for_each_interface_(),
227  hex_values_(),
228  show_offsets_sizes_in_bits_(true),
229  show_relative_offset_changes_(true),
230  show_stats_only_(false),
231  show_soname_change_(true),
232  show_architecture_change_(true),
233  show_deleted_fns_(true),
234  show_changed_fns_(true),
235  show_added_fns_(true),
236  show_deleted_vars_(true),
237  show_changed_vars_(true),
238  show_added_vars_(true),
239  show_linkage_names_(false),
240  show_locs_(true),
241  show_redundant_changes_(true),
242  show_syms_unreferenced_by_di_(true),
243  show_added_syms_unreferenced_by_di_(true),
244  show_unreachable_types_(false),
245  show_impacted_interfaces_(true),
246  dump_diff_tree_(),
247  do_log_()
248  {}
249 };// end struct diff_context::priv
250 
252 {
253 public:
254  friend class type_diff_base;
255 }; // end class type_diff_base
256 
257 /// Private data for the @ref diff type. The details of generic view
258 /// of the diff node are expressed here.
260 {
261  bool finished_;
262  bool traversing_;
263  type_or_decl_base_sptr first_subject_;
264  type_or_decl_base_sptr second_subject_;
265  vector<diff*> children_;
266  diff* parent_;
267  diff* parent_interface_;
268  diff* canonical_diff_;
269  diff_context_wptr ctxt_;
270  diff_category local_category_;
271  diff_category category_;
272  mutable bool reported_once_;
273  mutable bool currently_reporting_;
274  mutable string pretty_representation_;
275 
276  priv();
277 
278 public:
279 
280  priv(type_or_decl_base_sptr first_subject,
281  type_or_decl_base_sptr second_subject,
282  diff_context_sptr ctxt,
283  diff_category category,
284  bool reported_once,
285  bool currently_reporting)
286  : finished_(),
287  traversing_(),
288  first_subject_(first_subject),
289  second_subject_(second_subject),
290  parent_(),
291  parent_interface_(),
292  canonical_diff_(),
293  ctxt_(ctxt),
294  local_category_(category),
295  category_(category),
296  reported_once_(reported_once),
297  currently_reporting_(currently_reporting)
298  {}
299 
300  /// Getter of the diff context associated with this diff.
301  ///
302  /// @returnt a smart pointer to the diff context.
304  get_context() const
305  {return ctxt_.lock();}
306 
307  /// Check if a given categorization of a diff node should make it be
308  /// filtered out.
309  ///
310  /// @param category the categorization to take into account.
311  bool
313  {
314  diff_context_sptr ctxt = get_context();
315  if (!ctxt)
316  return false;
317 
318  if (ctxt->get_allowed_category() == EVERYTHING_CATEGORY)
319  return false;
320 
321  // If this node is on the path of a node that *must* be reported,
322  // then do not filter it.
326  return false;
327 
328  /// We don't want to display nodes suppressed by a user-provided
329  /// suppression specification or by a "private type" suppression
330  /// specification.
331  if (category & (SUPPRESSED_CATEGORY | PRIVATE_TYPE_CATEGORY))
332  return true;
333 
334  // We don't want to display redundant diff nodes, when the user
335  // asked to avoid seeing redundant diff nodes.
336  if (!ctxt->show_redundant_changes()
337  && (category & REDUNDANT_CATEGORY))
338  return true;
339 
340  if (category == NO_CHANGE_CATEGORY)
341  return false;
342 
343  // Ignore the REDUNDANT_CATEGORY bit when comparing allowed
344  // categories and the current set of categories.
345  return !((category & ~REDUNDANT_CATEGORY)
346  & (ctxt->get_allowed_category()
347  & ~REDUNDANT_CATEGORY));
348  }
349 };// end class diff::priv
350 
351 /// A functor to compare two instances of @ref diff_sptr.
353 {
354  /// An operator that takes two instances of @ref diff_sptr returns
355  /// true if its first operand compares less than its second operand.
356  ///
357  /// @param l the first operand to consider.
358  ///
359  /// @param r the second operand to consider.
360  ///
361  /// @return true if @p l compares less than @p r.
362  bool
363  operator()(const diff* l, const diff* r) const
364  {
365  if (!l || !r || !l->first_subject() || !r->first_subject())
366  return false;
367 
368  string l_qn = get_name(l->first_subject());
369  string r_qn = get_name(r->first_subject());
370 
371  return l_qn < r_qn;
372  }
373 
374  /// An operator that takes two instances of @ref diff_sptr returns
375  /// true if its first operand compares less than its second operand.
376  ///
377  /// @param l the first operand to consider.
378  ///
379  /// @param r the second operand to consider.
380  ///
381  /// @return true if @p l compares less than @p r.
382  bool
383  operator()(const diff_sptr& l, const diff_sptr& r) const
384  {return operator()(l.get(), r.get());}
385 }; // end struct diff_less_than_functor
386 
388 {
389 public:
390  friend class decl_diff_base;
391 };//end class priv
392 
393 /// The private data structure for @ref distinct_diff.
395 {
396  diff_sptr compatible_child_diff;
397 };// end struct distinct_diff
398 
399 /// The internal type for the impl idiom implementation of @ref
400 /// var_diff.
402 {
403  diff_wptr type_diff_;
404 };//end struct var_diff
405 
406 /// The internal type for the impl idiom implementation of @ref
407 /// pointer_diff.
409 {
410  diff_sptr underlying_type_diff_;
411 
412  priv(diff_sptr ud)
413  : underlying_type_diff_(ud)
414  {}
415 };//end struct pointer_diff::priv
416 
417 /// The internal type for the impl idiom implementation of @ref
418 /// subrange_diff.
420 {
421  diff_sptr underlying_type_diff_;
422 
423  priv(diff_sptr u)
424  : underlying_type_diff_(u)
425  {}
426 }; // end struct subrange_diff::priv
427 
429 {
430  /// The diff between the two array element types.
432 
433  priv(diff_sptr element_type_diff)
434  : element_type_diff_(element_type_diff)
435  {}
436 };//end struct array_diff::priv
437 
439 {
440  diff_sptr underlying_type_diff_;
441  priv(diff_sptr underlying)
442  : underlying_type_diff_(underlying)
443  {}
444 };//end struct reference_diff::priv
445 
447 {
448  diff_sptr underlying_type_diff;
449  mutable diff_sptr leaf_underlying_type_diff;
450 
451  priv(diff_sptr underlying)
452  : underlying_type_diff(underlying)
453  {}
454 };// end struct qualified_type_diff::priv
455 
457 {
458  diff_sptr underlying_type_diff_;
459  edit_script enumerators_changes_;
460  string_enumerator_map deleted_enumerators_;
461  string_enumerator_map inserted_enumerators_;
462  string_changed_enumerator_map changed_enumerators_;
463 
464  priv(diff_sptr underlying)
465  : underlying_type_diff_(underlying)
466  {}
467 };//end struct enum_diff::priv
468 
469 /// A functor to compare two enumerators based on their value. This
470 /// implements the "less than" operator.
472 {
473  bool
474  operator()(const enum_type_decl::enumerator& f,
475  const enum_type_decl::enumerator& s) const
476  {return f.get_value() < s.get_value();}
477 };//end struct enumerator_value_comp
478 
479 /// A functor to compare two changed enumerators, based on their
480 /// initial value.
482 {
483  bool
484  operator()(const changed_enumerator& f,
485  const changed_enumerator& s) const
486  {return f.first.get_value() < s.first.get_value();}
487 };// end struct changed_enumerator_comp.
488 
489 /// The type of private data of @ref class_or_union_diff.
491 {
492  edit_script member_types_changes_;
493  edit_script data_members_changes_;
494  edit_script member_fns_changes_;
495  edit_script member_fn_tmpls_changes_;
496  edit_script member_class_tmpls_changes_;
497 
498  string_decl_base_sptr_map deleted_member_types_;
499  string_decl_base_sptr_map inserted_member_types_;
500  string_diff_sptr_map changed_member_types_;
501  diff_sptrs_type sorted_changed_member_types_;
502  string_decl_base_sptr_map deleted_data_members_;
503  unsigned_decl_base_sptr_map deleted_dm_by_offset_;
504  string_decl_base_sptr_map inserted_data_members_;
505  unsigned_decl_base_sptr_map inserted_dm_by_offset_;
506  // This map contains the data member which sub-type changed.
507  string_var_diff_sptr_map subtype_changed_dm_;
508  var_diff_sptrs_type sorted_subtype_changed_dm_;
509  // This one contains the list of data members changes that can be
510  // represented as a data member foo that got removed from offset N,
511  // and a data member bar that got inserted at offset N; IOW, this
512  // can be translated as data member foo that got changed into data
513  // member bar at offset N.
514  unsigned_var_diff_sptr_map changed_dm_;
515  var_diff_sptrs_type sorted_changed_dm_;
516 
517  // This is a data structure to represent data members that have been
518  // replaced by anonymous data members. It's a map that associates
519  // the name of the data member to the anonymous data member that
520  // replaced it.
521  string_decl_base_sptr_map dms_replaced_by_adms_;
522  mutable changed_var_sptrs_type dms_replaced_by_adms_ordered_;
523  string_member_function_sptr_map deleted_member_functions_;
524  class_or_union::member_functions sorted_deleted_member_functions_;
525  string_member_function_sptr_map inserted_member_functions_;
526  class_or_union::member_functions sorted_inserted_member_functions_;
527  string_function_decl_diff_sptr_map changed_member_functions_;
528  function_decl_diff_sptrs_type sorted_changed_member_functions_;
529  string_decl_base_sptr_map deleted_member_class_tmpls_;
530  string_decl_base_sptr_map inserted_member_class_tmpls_;
531  string_diff_sptr_map changed_member_class_tmpls_;
532  diff_sptrs_type sorted_changed_member_class_tmpls_;
533 
534  type_or_decl_base_sptr
535  member_type_has_changed(decl_base_sptr) const;
536 
537  decl_base_sptr
538  subtype_changed_dm(decl_base_sptr) const;
539 
540  decl_base_sptr
541  member_class_tmpl_has_changed(decl_base_sptr) const;
542 
543  size_t
544  get_deleted_non_static_data_members_number() const;
545 
546  size_t
547  get_inserted_non_static_data_members_number() const;
548 
549  size_t
550  count_filtered_subtype_changed_dm(bool local_only = false);
551 
552  size_t
553  count_filtered_changed_dm(bool local_only = false);
554 
555  size_t
556  count_filtered_changed_mem_fns(const diff_context_sptr&);
557 
558  size_t
559  count_filtered_inserted_mem_fns(const diff_context_sptr&);
560 
561  size_t
562  count_filtered_deleted_mem_fns(const diff_context_sptr&);
563 
564  priv()
565  {}
566 }; // end struct class_or_union_diff::priv
567 
568 /// A comparison functor to compare two data members based on their
569 /// offset.
571 {
572 
573  /// Compare two data members.
574  ///
575  /// First look at their offset and then their name.
576  ///
577  /// @parm first_dm the first data member to consider.
578  ///
579  /// @param second_dm the second data member to consider.
580  bool
582  const var_decl_sptr& second_dm) const
583  {
584  ABG_ASSERT(first_dm);
585  ABG_ASSERT(second_dm);
586 
587  size_t first_offset = get_data_member_offset(first_dm);
588  size_t second_offset = get_data_member_offset(second_dm);
589 
590  // The data member at the smallest offset comes first.
591  if (first_offset != second_offset)
592  return first_offset < second_offset;
593 
594  string first_dm_name = first_dm->get_name();
595  string second_dm_name = second_dm->get_name();
596 
597  // But in case the two data members are at the same offset, then
598  // sort them lexicographically.
599  return first_dm_name < second_dm_name;
600  }
601 
602  /// Compare two data members.
603  ///
604  /// First look at their offset and then their name.
605  ///
606  /// @parm first_dm the first data member to consider.
607  ///
608  /// @param second_dm the second data member to consider.
609  bool
610  operator()(const decl_base_sptr& f,
611  const decl_base_sptr& s) const
612  {
613  var_decl_sptr first_dm = is_data_member(f);
614  var_decl_sptr second_dm = is_data_member(s);
615 
616  return compare_data_members(first_dm, second_dm);
617  }
618 
619  /// Compare two data members.
620  ///
621  /// First look at their offset and then their name.
622  ///
623  /// @parm first_dm the first data member to consider.
624  ///
625  /// @param second_dm the second data member to consider.
626  bool
628  const changed_var_sptr& s) const
629  {
630  var_decl_sptr first_dm = is_data_member(is_decl(f.first));
631  var_decl_sptr second_dm = is_data_member(is_decl(s.first));
632 
633  return compare_data_members(first_dm, second_dm);
634  }
635 };//end struct data_member_comp
636 
637 /// The type of the private data (pimpl sub-object) of the @ref
638 /// class_diff type.
640 {
641  edit_script base_changes_;
642  string_base_sptr_map deleted_bases_;
643  class_decl::base_specs sorted_deleted_bases_;
644  string_base_sptr_map inserted_bases_;
645  class_decl::base_specs sorted_inserted_bases_;
646  string_base_diff_sptr_map changed_bases_;
647  base_diff_sptrs_type sorted_changed_bases_;
648  vector<class_decl::base_spec_sptr> moved_bases_;
649 
651  base_has_changed(class_decl::base_spec_sptr) const;
652 
653  size_t
654  count_filtered_bases();
655 
656  priv()
657  {}
658 };//end struct class_diff::priv
659 
660 /// A functor to compare instances of @ref class_decl::base_spec.
662 {
663  bool
664  operator()(const class_decl::base_spec&l,
665  const class_decl::base_spec&r)
666  {
667  string str1 = l.get_pretty_representation();
668  string str2 = r.get_pretty_representation();
669  return str1 < str2;
670  }
671  bool
672  operator()(const class_decl::base_spec_sptr&l,
674  {return operator()(*l, *r);}
675 }; // end base_spec_comp
676 
677 /// A comparison function for instances of @ref base_diff.
679 {
680  bool
681  operator()(const base_diff& l, const base_diff& r) const
682  {
684  if (f->get_offset_in_bits() >= 0
685  && s->get_offset_in_bits() >= 0)
686  return f->get_offset_in_bits() < s->get_offset_in_bits();
687  else
688  return (f->get_base_class()->get_pretty_representation()
689  < s->get_base_class()->get_pretty_representation());
690  }
691 
692  bool
693  operator()(const base_diff* l, const base_diff* r) const
694  {return operator()(*l, *r);}
695 
696  bool
697  operator()(const base_diff_sptr l, const base_diff_sptr r) const
698  {return operator()(l.get(), r.get());}
699 }; // end struct base_diff_comp
700 
701 /// A comparison functor to compare two instances of @ref var_diff
702 /// that represent changed data members based on the offset of the
703 /// initial data members, or if equal, based on their qualified name.
704 /// If equal again, then the offset and qualified name of the new data
705 /// members are considered.
707 {
708  /// @param f the first change to data member to take into account
709  ///
710  /// @param s the second change to data member to take into account.
711  ///
712  /// @return true iff f is before s.
713  bool
715  const var_diff_sptr s) const
716  {
717  var_decl_sptr first_dm = f->first_var();
718  var_decl_sptr second_dm = s->first_var();
719 
720  ABG_ASSERT(is_data_member(first_dm));
721  ABG_ASSERT(is_data_member(second_dm));
722 
723  size_t off1 = get_data_member_offset(first_dm);
724  size_t off2 = get_data_member_offset(second_dm);
725 
726  if (off1 != off2)
727  return off1 < off2;
728 
729  // The two offsets of the initial data members are the same. So
730  // lets compare the qualified name of these initial data members.
731 
732  string name1 = first_dm->get_qualified_name();
733  string name2 = second_dm->get_qualified_name();
734 
735  if (name1 != name2)
736  return name1 < name2;
737 
738  // The offsets and the qualified names of the initial data members
739  // are the same. Let's now compare the offsets of the *new* data
740  // members.
741 
742  first_dm = f->second_var();
743  second_dm = s->second_var();
744 
745  ABG_ASSERT(is_data_member(first_dm));
746  ABG_ASSERT(is_data_member(second_dm));
747 
748  off1 = get_data_member_offset(first_dm);
749  off2 = get_data_member_offset(second_dm);
750 
751  if (off1 != off2)
752  return off1 < off2;
753 
754  // The offsets of the new data members are the same, dang! Let's
755  // compare the qualified names of these new data members then.
756 
757  name1 = first_dm->get_qualified_name();
758  name2 = second_dm->get_qualified_name();
759 
760  return name1 < name2;
761  }
762 }; // end struct var_diff_comp
763 
764 /// A comparison functor for instances of @ref function_decl_diff that
765 /// represent changes between two virtual member functions.
767 {
768  bool
769  operator()(const function_decl_diff& l,
770  const function_decl_diff& r) const
771  {
774 
777  }
778 
779  bool
780  operator()(const function_decl_diff* l,
781  const function_decl_diff* r)
782  {return operator()(*l, *r);}
783 
784  bool
785  operator()(const function_decl_diff_sptr l,
786  const function_decl_diff_sptr r)
787  {return operator()(l.get(), r.get());}
788 }; // end struct virtual_member_function_diff_comp
789 
791 {
792  class_diff_sptr underlying_class_diff_;
793 
794  priv(class_diff_sptr underlying)
795  : underlying_class_diff_(underlying)
796  {}
797 }; // end struct base_diff::priv
798 
800 {
801  // The edit script built by the function compute_diff.
802  edit_script member_changes_;
803 
804  // Below are the useful lookup tables.
805  //
806  // If you add a new lookup table, please update member functions
807  // clear_lookup_tables, lookup_tables_empty and
808  // ensure_lookup_tables_built.
809 
810  // The deleted/inserted types/decls. These basically map what is
811  // inside the member_changes_ data member. Note that for instance,
812  // a given type T might be deleted from the first scope and added to
813  // the second scope again; this means that the type was *changed*.
814  string_decl_base_sptr_map deleted_types_;
815  string_decl_base_sptr_map deleted_decls_;
816  string_decl_base_sptr_map inserted_types_;
817  string_decl_base_sptr_map inserted_decls_;
818 
819  // The changed types/decls lookup tables.
820  //
821  // These lookup tables are populated from the lookup tables above.
822  //
823  // Note that the value stored in each of these tables is a pair
824  // containing the old decl/type and the new one. That way it is
825  // easy to run a diff between the old decl/type and the new one.
826  //
827  // A changed type/decl is one that has been deleted from the first
828  // scope and that has been inserted into the second scope.
829  string_diff_sptr_map changed_types_;
830  diff_sptrs_type sorted_changed_types_;
831  string_diff_sptr_map changed_decls_;
832  diff_sptrs_type sorted_changed_decls_;
833 
834  // The removed types/decls lookup tables.
835  //
836  // A removed type/decl is one that has been deleted from the first
837  // scope and that has *NOT* been inserted into it again.
838  string_decl_base_sptr_map removed_types_;
839  string_decl_base_sptr_map removed_decls_;
840 
841  // The added types/decls lookup tables.
842  //
843  // An added type/decl is one that has been inserted to the first
844  // scope but that has not been deleted from it.
845  string_decl_base_sptr_map added_types_;
846  string_decl_base_sptr_map added_decls_;
847 };//end struct scope_diff::priv
848 
849 /// A comparison functor for instances of @ref diff.
850 struct diff_comp
851 {
852  /// Lexicographically compare two diff nodes.
853  ///
854  /// Compare the pretty representation of the first subjects of two
855  /// diff nodes.
856  ///
857  /// @return true iff @p l is less than @p r.
858  bool
859  operator()(const diff& l, diff& r) const
860  {
861  return (get_pretty_representation(l.first_subject(), true)
862  <
864  }
865 
866  /// Lexicographically compare two diff nodes.
867  ///
868  /// Compare the pretty representation of the first subjects of two
869  /// diff nodes.
870  ///
871  /// @return true iff @p l is less than @p r.
872  bool
873  operator()(const diff* l, diff* r) const
874  {return operator()(*l, *r);}
875 
876  /// Lexicographically compare two diff nodes.
877  ///
878  /// Compare the pretty representation of the first subjects of two
879  /// diff nodes.
880  ///
881  /// @return true iff @p l is less than @p r.
882  bool
883  operator()(const diff_sptr l, diff_sptr r) const
884  {return operator()(l.get(), r.get());}
885 }; // end struct diff_comp;
886 
888 {
889  mutable diff_sptr type_diff;
890 }; // end struct fn_parm_diff::priv
891 
893 {
894  diff_sptr return_type_diff_;
895  edit_script parm_changes_;
896 
897  // useful lookup tables.
898  string_parm_map deleted_parms_;
899  vector<function_decl::parameter_sptr> sorted_deleted_parms_;
900  string_parm_map added_parms_;
901  vector<function_decl::parameter_sptr> sorted_added_parms_;
902  // This map contains parameters sub-type changes that don't change
903  // the name of the type of the parameter.
904  string_fn_parm_diff_sptr_map subtype_changed_parms_;
905  vector<fn_parm_diff_sptr> sorted_subtype_changed_parms_;
906  // This map contains parameter type changes that actually change the
907  // name of the type of the parameter, but in a compatible way;
908  // otherwise, the mangling of the function would have changed (in
909  // c++ at least).
910  unsigned_fn_parm_diff_sptr_map changed_parms_by_id_;
911  vector<fn_parm_diff_sptr> sorted_changed_parms_by_id_;
912  unsigned_parm_map deleted_parms_by_id_;
913  unsigned_parm_map added_parms_by_id_;
914 
915  priv()
916  {}
917 }; // end struct function_type_diff::priv
918 
920 {
921  function_type_diff_sptr type_diff_;
922 
923  priv()
924  {}
925 };// end struct function_decl_diff::priv
926 
927 /// A comparison functor to compare two instances of @ref fn_parm_diff
928 /// based on their indexes.
930 {
931  /// @param f the first diff
932  ///
933  /// @param s the second diff
934  ///
935  /// @return true if the index of @p f is less than the index of @p
936  /// s.
937  bool
939  {return f.first_parameter()->get_index() < s.first_parameter()->get_index();}
940 
941  bool
942  operator()(const fn_parm_diff_sptr& f, const fn_parm_diff_sptr& s)
943  {return operator()(*f, *s);}
944 }; // end struct fn_parm_diff_comp
945 
946 /// Functor that compares two function parameters for the purpose of
947 /// sorting them.
948 struct parm_comp
949 {
950  /// Returns true iff the index of the first parameter is smaller
951  /// than the of the second parameter.
952  ///
953  /// @param l the first parameter to compare.
954  ///
955  /// @param r the second parameter to compare.
956  ///
957  /// @return true iff the index of the first parameter is smaller
958  /// than the of the second parameter.
959  bool
961  const function_decl::parameter& r)
962  {return l.get_index() < r.get_index();}
963 
964  /// Returns true iff the index of the first parameter is smaller
965  /// than the of the second parameter.
966  ///
967  /// @param l the first parameter to compare.
968  ///
969  /// @param r the second parameter to compare.
970  ///
971  /// @return true iff the index of the first parameter is smaller
972  /// than the of the second parameter.
973  bool
976  {return operator()(*l, *r);}
977 }; // end struct parm_comp
978 
979 /// A functor to compare instances of @ref var_decl base on their
980 /// qualified names.
981 struct var_comp
982 {
983  bool
984  operator() (const var_decl& l, const var_decl& r) const
985  {
986  string name1 = l.get_qualified_name(), name2 = r.get_qualified_name();
987  return name1 < name2;
988  }
989 
990  bool
991  operator() (const var_decl* l, const var_decl* r) const
992  {return operator()(*l, *r);}
993 };// end struct var_comp
994 
995 /// A functor to compare instances of @ref elf_symbol base on their
996 /// names.
998 {
999  bool
1000  operator()(const elf_symbol& l, const elf_symbol& r)
1001  {
1002  string name1 = l.get_id_string(), name2 = r.get_id_string();
1003  return name1 < name2;
1004  }
1005 
1006  bool
1007  operator()(const elf_symbol* l, const elf_symbol* r)
1008  {return operator()(*l, *r);}
1009 
1010  bool
1011  operator()(const elf_symbol_sptr& l, const elf_symbol_sptr& r)
1012  {return operator()(l.get(), r.get());}
1013 }; //end struct elf_symbol_comp
1014 
1016 {
1017  diff_sptr underlying_type_diff_;
1018 
1019  priv(const diff_sptr underlying_type_diff)
1020  : underlying_type_diff_(underlying_type_diff)
1021  {}
1022 };//end struct typedef_diff::priv
1023 
1025 {
1026  translation_unit_sptr first_;
1027  translation_unit_sptr second_;
1028 
1030  : first_(f), second_(s)
1031  {}
1032 };//end struct translation_unit_diff::priv
1033 
1035 {
1036  bool finished_;
1037  string pretty_representation_;
1038  vector<diff*> children_;
1039  corpus_sptr first_;
1040  corpus_sptr second_;
1041  diff_context_wptr ctxt_;
1042  corpus_diff::diff_stats_sptr diff_stats_;
1043  bool sonames_equal_;
1044  bool architectures_equal_;
1045  edit_script fns_edit_script_;
1046  edit_script vars_edit_script_;
1047  edit_script unrefed_fn_syms_edit_script_;
1048  edit_script unrefed_var_syms_edit_script_;
1049  string_function_ptr_map deleted_fns_;
1050  string_function_ptr_map suppressed_deleted_fns_;
1051  string_function_ptr_map added_fns_;
1052  string_function_ptr_map suppressed_added_fns_;
1053  string_function_decl_diff_sptr_map changed_fns_map_;
1054  function_decl_diff_sptrs_type changed_fns_;
1055  string_var_ptr_map deleted_vars_;
1056  string_var_ptr_map suppressed_deleted_vars_;
1057  string_var_ptr_map added_vars_;
1058  string_var_ptr_map suppressed_added_vars_;
1059  string_var_diff_sptr_map changed_vars_map_;
1060  var_diff_sptrs_type sorted_changed_vars_;
1061  string_elf_symbol_map added_unrefed_fn_syms_;
1062  string_elf_symbol_map suppressed_added_unrefed_fn_syms_;
1063  string_elf_symbol_map deleted_unrefed_fn_syms_;
1064  string_elf_symbol_map suppressed_deleted_unrefed_fn_syms_;
1065  string_elf_symbol_map added_unrefed_var_syms_;
1066  string_elf_symbol_map suppressed_added_unrefed_var_syms_;
1067  string_elf_symbol_map deleted_unrefed_var_syms_;
1068  string_elf_symbol_map suppressed_deleted_unrefed_var_syms_;
1069  edit_script unreachable_types_edit_script_;
1070  string_type_base_sptr_map deleted_unreachable_types_;
1071  vector<type_base_sptr> deleted_unreachable_types_sorted_;
1072  string_type_base_sptr_map suppressed_deleted_unreachable_types_;
1073  string_type_base_sptr_map added_unreachable_types_;
1074  vector<type_base_sptr> added_unreachable_types_sorted_;
1075  string_type_base_sptr_map suppressed_added_unreachable_types_;
1076  string_diff_sptr_map changed_unreachable_types_;
1077  mutable vector<diff_sptr> changed_unreachable_types_sorted_;
1078  diff_maps leaf_diffs_;
1079 
1080  /// Default constructor of corpus_diff::priv.
1082  : finished_(false),
1083  sonames_equal_(false),
1084  architectures_equal_(false)
1085  {}
1086 
1087  /// Constructor of corpus_diff::priv.
1088  ///
1089  /// @param first the first corpus of this diff.
1090  ///
1091  /// @param second the second corpus of this diff.
1092  ///
1093  /// @param ctxt the context of the diff.
1094  priv(corpus_sptr first,
1095  corpus_sptr second,
1096  diff_context_sptr ctxt)
1097  : finished_(false),
1098  first_(first),
1099  second_(second),
1100  ctxt_(ctxt),
1101  sonames_equal_(false),
1102  architectures_equal_(false)
1103  {}
1104 
1106  get_context();
1107 
1108  bool
1109  lookup_tables_empty() const;
1110 
1111  void
1112  clear_lookup_tables();
1113 
1114  void
1115  ensure_lookup_tables_populated();
1116 
1117  void
1118  apply_supprs_to_added_removed_fns_vars_unreachable_types();
1119 
1120  bool
1121  deleted_function_is_suppressed(const function_decl* fn) const;
1122 
1123  bool
1124  added_function_is_suppressed(const function_decl* fn) const;
1125 
1126  bool
1127  deleted_variable_is_suppressed(const var_decl* var) const;
1128 
1129  bool
1130  added_variable_is_suppressed(const var_decl* var) const;
1131 
1132  bool
1133  added_unreachable_type_is_suppressed(const type_base *t)const ;
1134 
1135  bool
1136  deleted_unreachable_type_is_suppressed(const type_base *t)const ;
1137 
1138  bool
1139  deleted_unrefed_fn_sym_is_suppressed(const elf_symbol*) const;
1140 
1141  bool
1142  added_unrefed_fn_sym_is_suppressed(const elf_symbol*) const;
1143 
1144  bool
1145  deleted_unrefed_var_sym_is_suppressed(const elf_symbol*) const;
1146 
1147  bool
1148  added_unrefed_var_sym_is_suppressed(const elf_symbol*) const;
1149 
1150  void count_leaf_changes(size_t &num_changes, size_t &num_filtered);
1151 
1152  void count_leaf_type_changes(size_t &num_type_changes,
1153  size_t &num_type_changes_filtered);
1154 
1155  void count_unreachable_types(size_t &num_added,
1156  size_t &num_removed,
1157  size_t &num_changed,
1158  size_t &num_filtered_added,
1159  size_t &num_filtered_removed,
1160  size_t &num_filtered_changed);
1161 
1162  const string_diff_sptr_map&
1163  changed_unreachable_types() const;
1164 
1165  const vector<diff_sptr>&
1166  changed_unreachable_types_sorted() const;
1167 
1168  void
1169  apply_filters_and_compute_diff_stats(corpus_diff::diff_stats&);
1170 
1171  void
1172  emit_diff_stats(const diff_stats& stats,
1173  ostream& out,
1174  const string& indent);
1175 
1176  void
1177  categorize_redundant_changed_sub_nodes();
1178 
1179  void
1181 
1182  void
1183  maybe_dump_diff_tree();
1184 }; // end corpus::priv
1185 
1186 /// "Less than" functor to compare instances of @ref function_decl.
1188 {
1189  /// The actual "less than" operator for instances of @ref
1190  /// function_decl. It returns true if the first @ref function_decl
1191  /// is lest than the second one.
1192  ///
1193  /// @param f the first @ref function_decl to take in account.
1194  ///
1195  /// @param s the second @ref function_decl to take in account.
1196  ///
1197  /// @return true iff @p f is less than @p s.
1198  bool
1201 
1202  /// The actual "less than" operator for instances of @ref
1203  /// function_decl. It returns true if the first @ref function_decl
1204  /// is lest than the second one.
1205  ///
1206  /// @param f the first @ref function_decl to take in account.
1207  ///
1208  /// @param s the second @ref function_decl to take in account.
1209  ///
1210  /// @return true iff @p f is less than @p s.
1211  bool
1213  {return operator()(*f, *s);}
1214 
1215  /// The actual "less than" operator for instances of @ref
1216  /// function_decl. It returns true if the first @ref function_decl
1217  /// is lest than the second one.
1218  ///
1219  /// @param f the first @ref function_decl to take in account.
1220  ///
1221  /// @param s the second @ref function_decl to take in account.
1222  ///
1223  /// @return true iff @p f is less than @p s.
1224  bool
1226  {return operator()(f.get(), s.get());}
1227 }; // end function_comp
1228 
1229 /// A "Less Than" functor to compare instance of @ref
1230 /// function_decl_diff.
1232 {
1233  /// The actual less than operator.
1234  ///
1235  /// It returns true if the first @ref function_decl_diff is less
1236  /// than the second one.
1237  ///
1238  /// param first the first @ref function_decl_diff to consider.
1239  ///
1240  /// @param second the second @ref function_decl_diff to consider.
1241  ///
1242  /// @return true iff @p first is less than @p second.
1243  bool
1245  const function_decl_diff& second)
1246  {
1248  s = second.first_function_decl();
1249 
1250  string fr = f->get_qualified_name(),
1251  sr = s->get_qualified_name();
1252 
1253  if (fr == sr)
1254  {
1255  if (f->get_symbol())
1256  fr = f->get_symbol()->get_id_string();
1257  else if (!f->get_linkage_name().empty())
1258  fr = f->get_linkage_name();
1259  else
1260  fr = f->get_pretty_representation();
1261 
1262  if (s->get_symbol())
1263  sr = s->get_symbol()->get_id_string();
1264  else if (!s->get_linkage_name().empty())
1265  sr = s->get_linkage_name();
1266  else
1267  sr = s->get_pretty_representation();
1268  }
1269 
1270  return (fr.compare(sr) < 0);
1271  }
1272 
1273  /// The actual less than operator.
1274  ///
1275  /// It returns true if the first @ref function_decl_diff_sptr is
1276  /// less than the second one.
1277  ///
1278  /// param first the first @ref function_decl_diff_sptr to consider.
1279  ///
1280  /// @param second the second @ref function_decl_diff_sptr to
1281  /// consider.
1282  ///
1283  /// @return true iff @p first is less than @p second.
1284  bool
1286  const function_decl_diff_sptr second)
1287  {return operator()(*first, *second);}
1288 }; // end struct function_decl_diff_comp
1289 
1290 /// Functor to sort instances of @ref var_diff_sptr
1292 {
1293  /// Return true if the first argument is less than the second one.
1294  ///
1295  /// @param f the first argument to consider.
1296  ///
1297  /// @param s the second argument to consider.
1298  ///
1299  /// @return true if @p f is less than @p s.
1300  bool
1302  const var_diff_sptr s)
1303  {
1304  return (f->first_var()->get_qualified_name()
1305  < s->first_var()->get_qualified_name());
1306  }
1307 }; // end struct var_diff_sptr_comp
1308 
1309 /// The type of the private data of corpus_diff::diff_stats.
1311 {
1312  friend class corpus_diff::diff_stats;
1313 
1314  diff_context_wptr ctxt_;
1315  size_t num_func_removed;
1316  size_t num_removed_func_filtered_out;
1317  size_t num_func_added;
1318  size_t num_added_func_filtered_out;
1319  size_t num_func_changed;
1320  size_t num_changed_func_filtered_out;
1321  size_t num_func_with_virt_offset_changes;
1322  size_t num_vars_removed;
1323  size_t num_removed_vars_filtered_out;
1324  size_t num_vars_added;
1325  size_t num_added_vars_filtered_out;
1326  size_t num_vars_changed;
1327  size_t num_changed_vars_filtered_out;
1328  size_t num_func_syms_removed;
1329  size_t num_removed_func_syms_filtered_out;
1330  size_t num_func_syms_added;
1331  size_t num_added_func_syms_filtered_out;
1332  size_t num_var_syms_removed;
1333  size_t num_removed_var_syms_filtered_out;
1334  size_t num_var_syms_added;
1335  size_t num_added_var_syms_filtered_out;
1336  size_t num_leaf_changes;
1337  size_t num_leaf_changes_filtered_out;
1338  size_t num_leaf_type_changes;
1339  size_t num_leaf_type_changes_filtered_out;
1340  size_t num_leaf_func_changes;
1341  size_t num_leaf_func_changes_filtered_out;
1342  size_t num_leaf_var_changes;
1343  size_t num_leaf_var_changes_filtered_out;
1344  size_t num_added_unreachable_types;
1345  size_t num_added_unreachable_types_filtered_out;
1346  size_t num_removed_unreachable_types;
1347  size_t num_removed_unreachable_types_filtered_out;
1348  size_t num_changed_unreachable_types;
1349  size_t num_changed_unreachable_types_filtered_out;
1350 
1351  priv(diff_context_sptr ctxt)
1352  : ctxt_(ctxt),
1353  num_func_removed(),
1354  num_removed_func_filtered_out(),
1355  num_func_added(),
1356  num_added_func_filtered_out(),
1357  num_func_changed(),
1358  num_changed_func_filtered_out(),
1359  num_func_with_virt_offset_changes(),
1360  num_vars_removed(),
1361  num_removed_vars_filtered_out(),
1362  num_vars_added(),
1363  num_added_vars_filtered_out(),
1364  num_vars_changed(),
1365  num_changed_vars_filtered_out(),
1366  num_func_syms_removed(),
1367  num_removed_func_syms_filtered_out(),
1368  num_func_syms_added(),
1369  num_added_func_syms_filtered_out(),
1370  num_var_syms_removed(),
1371  num_removed_var_syms_filtered_out(),
1372  num_var_syms_added(),
1373  num_added_var_syms_filtered_out(),
1374  num_leaf_changes(),
1375  num_leaf_changes_filtered_out(),
1376  num_leaf_type_changes(),
1377  num_leaf_type_changes_filtered_out(),
1378  num_leaf_func_changes(),
1379  num_leaf_func_changes_filtered_out(),
1380  num_leaf_var_changes(),
1381  num_leaf_var_changes_filtered_out(),
1382  num_added_unreachable_types(),
1383  num_added_unreachable_types_filtered_out(),
1384  num_removed_unreachable_types(),
1385  num_removed_unreachable_types_filtered_out(),
1386  num_changed_unreachable_types(),
1387  num_changed_unreachable_types_filtered_out()
1388  {}
1389 
1391  ctxt()
1392  {return ctxt_.lock();}
1393 }; // end class corpus_diff::diff_stats::priv
1394 
1395 void
1396 sort_enumerators(const string_enumerator_map& enumerators_map,
1397  enum_type_decl::enumerators& sorted);
1398 
1399 void
1401  changed_enumerators_type& sorted);
1402 
1403 void
1404 sort_data_members(const string_decl_base_sptr_map &data_members,
1405  vector<decl_base_sptr>& sorted);
1406 
1407 void
1409 
1410 void
1412  vector<function_decl*>& sorted);
1413 
1414 void
1417 
1418 void
1420  vector<type_base_sptr>& sorted);
1421 
1422 void
1426 
1427 void
1429  var_diff_sptrs_type& sorted);
1430 
1431 void
1433  vector<elf_symbol_sptr>& sorted);
1434 
1435 void
1437  vector<var_decl*>& sorted);
1438 
1439 void
1441  var_diff_sptrs_type& sorted);
1442 
1443 void
1445  var_diff_sptrs_type& sorted);
1446 
1447 void
1451 
1452 void
1454  diff_sptrs_type& sorted);
1455 
1456 void
1458  diff_ptrs_type& sorted);
1459 
1460 void
1462  base_diff_sptrs_type& sorted);
1463 
1464 void
1466  class_decl::base_specs& sorted);
1467 
1468 void
1470  vector<fn_parm_diff_sptr>& sorted);
1471 void
1473  vector<fn_parm_diff_sptr>& sorted);
1474 void
1476  vector<function_decl::parameter_sptr>& sorted);
1477 
1478 void
1479 sort_artifacts_set(const artifact_sptr_set_type& set,
1480  vector<type_or_decl_base_sptr>& sorted);
1481 
1482 type_base_sptr
1483 get_leaf_type(qualified_type_def_sptr t);
1484 
1485 diff*
1486 get_fn_decl_or_var_decl_diff_ancestor(const diff *);
1487 
1488 bool
1489 is_diff_of_global_decls(const diff*);
1490 
1491 } // end namespace comparison
1492 
1493 } // namespace abigail
1494 
1495 #endif // __ABG_COMPARISON_PRIV_H__
vector< diff * > diff_ptrs_type
Convenience typedef for a vector of diff*.
std::pair< var_decl_sptr, var_decl_sptr > changed_var_sptr
Convenience typedef for a pair of var_decl_sptr representing a var_decl change. The first member of t...
A comparison function for instances of base_diff.
priv()
Default constructor of corpus_diff::priv.
bool operator()(const diff *l, const diff *r) const
An operator that takes two instances of diff_sptr returns true if its first operand compares less tha...
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6723
void sort_enumerators(const string_enumerator_map &enumerators_map, enum_type_decl::enumerators &sorted)
Sort a map of enumerators by their value.
shared_ptr< function_type_diff > function_type_diff_sptr
A convenience typedef for a shared pointer to function_type_type_diff.
A comparison functor for instances of diff.
vector< function_decl_diff_sptr > function_decl_diff_sptrs_type
Convenience typedef for a vector of function_decl_diff_sptr.
A "Less Than" functor to compare instance of function_decl_diff.
void sort_string_member_function_sptr_map(const string_member_function_sptr_map &map, class_or_union::member_functions &sorted)
Sort a map that's an instance of string_member_function_sptr_map and fill a vector of member function...
This header declares filters for the diff trees resulting from comparing ABI Corpora.
bool operator()(const diff_sptr l, diff_sptr r) const
Lexicographically compare two diff nodes.
The abstraction of a change between two ABI artifacts, a.k.a an artifact change.
shared_ptr< class_diff > class_diff_sptr
Convenience typedef for a shared pointer on a class_diff type.
vector< var_diff_sptr > var_diff_sptrs_type
Convenience typedef for a vector of var_diff_sptr.
const function_decl_sptr first_function_decl() const
The internal type for the impl idiom implementation of pointer_diff.
bool operator()(const diff *d1, const diff *d2) const
The function-call operator to compare two diff nodes.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition: abg-ir.cc:5763
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representatin of the current declaration.
Definition: abg-ir.cc:4995
Utilities to ease the wrapping of C types into std::shared_ptr.
An equality functor for types_or_decls_type.
bool operator()(const var_diff_sptr f, const var_diff_sptr s)
Return true if the first argument is less than the second one.
void sort_string_var_diff_sptr_map(const string_var_diff_sptr_map &map, var_diff_sptrs_type &sorted)
Sort of an instance of string_var_diff_sptr_map map.
bool operator()(const function_decl *f, const function_decl *s)
The actual "less than" operator for instances of function_decl. It returns true if the first function...
vector< changed_var_sptr > changed_var_sptrs_type
Convenience typedef for a vector of .gg381.
A special enumerator that is the logical 'or' all the enumerators above.
An abstraction helper for type declarations.
Definition: abg-ir.h:1959
A functor to compare instances of elf_symbol base on their names.
size_t operator()(const diff &d) const
The function-call operator to hash a diff node.
void clear_redundancy_categorization(diff *diff_tree)
Walk a given diff sub-tree to clear the REDUNDANT_CATEGORY out of the category of the nodes...
This means that a diff node was marked as suppressed by a user-provided suppression specification...
void sort_string_data_member_diff_sptr_map(const string_var_diff_sptr_map &map, var_diff_sptrs_type &sorted)
Sort the values of a string_var_diff_sptr_map and store the result in a vector of var_diff_sptr...
bool operator()(const var_diff_sptr f, const var_diff_sptr s) const
type_or_decl_base_sptr first_subject() const
Getter of the first subject of the diff.
This means the diff node does not carry any (meaningful) change, or that it carries changes that have...
Abstraction of a base specifier in a class declaration.
Definition: abg-ir.h:4359
unordered_map< string, class_decl::base_spec_sptr > string_base_sptr_map
Convenience typedef for a map of string and class_decl::basse_spec_sptr.
shared_ptr< diff_context > diff_context_sptr
Convenience typedef for a shared pointer of diff_context.
Definition: abg-fwd.h:68
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition: abg-ir.cc:6660
void sort_data_members(const string_decl_base_sptr_map &data_members, vector< decl_base_sptr > &sorted)
Sort a map of data members by the offset of their initial value.
bool operator()(const function_decl &f, const function_decl &s)
The actual "less than" operator for instances of function_decl. It returns true if the first function...
bool compare_data_members(const var_decl_sptr &first_dm, const var_decl_sptr &second_dm) const
Compare two data members.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition: abg-fwd.h:246
A diff node in this category has a parent node that is in the HAS_ALLOWED_CHANGE_CATEGORY category...
bool operator()(const fn_parm_diff &f, const fn_parm_diff &s)
class_decl::base_spec_sptr first_base() const
Getter for the first base spec of the diff object.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition: abg-fwd.h:134
Abstraction of a diff between two function_decl.
void sort_string_diff_sptr_map(const string_diff_sptr_map &map, diff_sptrs_type &sorted)
Sort a map ofg string -> diff_sptr into a vector of diff_sptr. The diff_sptr are sorted lexicographic...
unordered_map< string, diff * > string_diff_ptr_map
Convenience typedef for a map which value is a diff*. The key of the map is the qualified name of the...
unordered_set< diff_sptr, diff_sptr_hasher > unordered_diff_sptr_set
Convenience typedef for an unoredered set of diff_sptr.
Abstracts a variable declaration.
Definition: abg-ir.h:2943
void sort_string_elf_symbol_map(const string_elf_symbol_map &map, vector< elf_symbol_sptr > &sorted)
Sort a map of string -> pointer to elf_symbol.
The private data structure for distinct_diff.
void sort_string_parm_map(const string_parm_map &map, vector< function_decl::parameter_sptr > &sorted)
Sort a map of string -> function parameters.
A functor to compare instances of var_decl base on their qualified names.
diff_context_sptr get_context() const
Getter of the diff context associated with this diff.
bool is_diff_of_global_decls(const diff *)
Tests if a given diff node is to represent the changes between two gobal decls.
Abstraction of a function parameter.
Definition: abg-ir.h:3218
The base class of diff between decls.
The base class of diff between types.
bool operator()(const function_decl_diff &first, const function_decl_diff &second)
The actual less than operator.
void sort_string_var_ptr_map(const string_var_ptr_map &map, vector< var_decl * > &sorted)
Sort a map of string -> pointer to var_decl.
unordered_map< string, var_decl * > string_var_ptr_map
Convenience typedef for a map which key is a string and which value is a point to var_decl...
unordered_map< string, var_diff_sptr > string_var_diff_sptr_map
Convenience typedef for a map whose key is a string and whose value is a changed variable of type var...
unordered_map< string, base_diff_sptr > string_base_diff_sptr_map
Convenience typedef for a map of string and base_diff_sptr.
unordered_map< string, elf_symbol_sptr > string_elf_symbol_map
Convenience typedef for a map whose key is a string and whose value is an elf_symbol_sptr.
The internal type for the impl idiom implementation of subrange_diff.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition: abg-ir.h:2699
unordered_map< unsigned, fn_parm_diff_sptr > unsigned_fn_parm_diff_sptr_map
Convenience typedef for a map which key is an integer and which value is a changed parameter...
void sort_string_base_diff_sptr_map(const string_base_diff_sptr_map &map, base_diff_sptrs_type &sorted)
Sort a map of string -> base_diff_sptr into a sorted vector of base_diff_sptr. The base_diff_sptr are...
A functor to compare instances of class_decl::base_spec.
A functor to compare two instances of diff_sptr.
void sort_unsigned_data_member_diff_sptr_map(const unsigned_var_diff_sptr_map map, var_diff_sptrs_type &sorted)
Sort the values of a unsigned_var_diff_sptr_map map and store the result into a vector of var_diff_sp...
vector< changed_enumerator > changed_enumerators_type
Convenience typedef for a vector of changed enumerators.
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition: abg-ir.cc:6266
diff_category
An enum for the different categories that a diff tree node falls into, regarding the kind of changes ...
Toplevel namespace for libabigail.
bool operator()(const changed_var_sptr &f, const changed_var_sptr &s) const
Compare two data members.
unordered_set< type_or_decl_base_sptr, type_or_decl_hash, type_or_decl_equal > artifact_sptr_set_type
A convenience typedef for a hash set of type_or_decl_base_sptr.
Definition: abg-ir.h:550
unordered_map< string, changed_enumerator > string_changed_enumerator_map
Convenience typedef for a map which value is a changed enumerator. The key is the name of the changed...
An abstraction of a diff between two instances of class_decl::base_spec.
size_t operator()(const diff_sptr &d) const
The function-call operator to hash a diff node.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition: abg-fwd.h:263
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10409
type_base_sptr get_leaf_type(qualified_type_def_sptr t)
Return the first underlying type that is not a qualified type.
virtual const interned_string & get_qualified_name(bool internal=false) const
Get the qualified name of a given variable or data member.
Definition: abg-ir.cc:20293
void sort_string_base_sptr_map(const string_base_sptr_map &m, class_decl::base_specs &sorted)
Lexicographically sort base specifications found in instances of string_base_sptr_map.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3067
The type of the private data of corpus_diff::diff_stats.
shared_ptr< diff_stats > diff_stats_sptr
A convenience typedef for a shared pointer to diff_stats.
size_t hash_type_or_decl(const type_or_decl_base *tod)
Hash an ABI artifact that is either a type or a decl.
Definition: abg-ir.cc:27023
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
Definition: abg-ir.h:4178
diff_sptr element_type_diff_
The diff between the two array element types.
unordered_map< string, type_base_sptr > string_type_base_sptr_map
Convenience typedef for a map which key is a string and which value is a type_base_sptr.
This means that a diff node was warked as being for a private type. That is, the diff node is meant t...
Abstraction of a diff between two function parameters.
const function_decl::parameter_sptr first_parameter() const
Getter for the first subject of this diff node.
Abstraction for a function declaration.
Definition: abg-ir.h:3046
bool operator()(const diff &l, diff &r) const
Lexicographically compare two diff nodes.
unordered_map< string, diff_sptr > string_diff_sptr_map
Convenience typedef for a map which value is a diff_sptr. The key of the map is the qualified name of...
unordered_map< string, function_decl_diff_sptr > string_function_decl_diff_sptr_map
Convenience typedef for a map which key is a string and which value is a function_decl_diff_sptr.
bool operator()(const diff *l, diff *r) const
Lexicographically compare two diff nodes.
A hashing functor for types_or_decls_type.
priv(corpus_sptr first, corpus_sptr second, diff_context_sptr ctxt)
Constructor of corpus_diff::priv.
A diff node in this category is redundant. That means it's present as a child of a other nodes in the...
shared_ptr< function_decl_diff > function_decl_diff_sptr
Convenience typedef for a shared pointer to a function_decl type.
Functor to sort instances of var_diff_sptr.
unordered_map< unsigned, function_decl::parameter_sptr > unsigned_parm_map
Convenience typedef for a map which key is an integer and which value is a parameter.
diff * get_canonical_diff() const
Getter for the canonical diff of the current instance of diff.
unordered_map< const diff *, artifact_sptr_set_type, diff_hash, diff_equal > diff_artifact_set_map_type
A convenience typedef for an unordered_map which key is a diff* and which value is a artifact_sptr_se...
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
Definition: abg-fwd.h:119
A hashing functor for using diff_sptr and diff* in a hash map or set.
bool operator()(const function_decl::parameter_sptr &l, const function_decl::parameter_sptr &r)
Returns true iff the index of the first parameter is smaller than the of the second parameter...
Abstraction of an elf symbol.
Definition: abg-ir.h:908
vector< method_decl_sptr > member_functions
Convenience typedef.
Definition: abg-ir.h:3993
unordered_map< string, decl_base_sptr > string_decl_base_sptr_map
Convenience typedef for a map which key is a string and which value is a decl_base_sptr.
shared_ptr< var_diff > var_diff_sptr
Convenience typedef for a shared pointer to a var_diff type.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition: abg-ir.h:872
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
Definition: abg-fwd.h:1659
vector< suppression_sptr > suppressions_type
Convenience typedef for a vector of suppression_sptr.
Definition: abg-fwd.h:1603
A functor to compare two enumerators based on their value. This implements the "less than" operator...
A diff node in this category has a descendant node that is in the HAS_ALLOWED_CHANGE_CATEGORY categor...
bool operator()(const function_decl::parameter &l, const function_decl::parameter &r)
Returns true iff the index of the first parameter is smaller than the of the second parameter...
A comparison functor to compare two instances of fn_parm_diff based on their indexes.
unordered_map< unsigned, decl_base_sptr > unsigned_decl_base_sptr_map
Convenience typedef for a map which key is an unsigned integer and which value is a decl_base_sptr...
std::pair< enum_type_decl::enumerator, enum_type_decl::enumerator > changed_enumerator
Convenience typedef for a changed enumerator. The first element of the pair is the old enumerator and...
A comparison functor to compare two instances of var_diff that represent changed data members based o...
bool operator()(const diff_sptr &l, const diff_sptr &r) const
An operator that takes two instances of diff_sptr returns true if its first operand compares less tha...
This type contains maps. Each map associates a type name to a diff of that type. Not all kinds of dif...
unordered_map< unsigned, var_diff_sptr > unsigned_var_diff_sptr_map
Convenience typedef for a map whose key is an unsigned int and whose value is a changed variable of t...
The private member (pimpl) for diff_context.
bool operator()(const function_decl_diff_sptr first, const function_decl_diff_sptr second)
The actual less than operator.
unordered_map< types_or_decls_type, diff_sptr, types_or_decls_hash, types_or_decls_equal > types_or_decls_diff_map_type
A convenience typedef for a map of types_or_decls_type and diff_sptr.
void sort_changed_data_members(changed_var_sptrs_type &input)
Sort (in place) a vector of changed data members.
shared_ptr< base_diff > base_diff_sptr
Convenience typedef for a shared pointer to a base_diff type.
void sort_changed_enumerators(const string_changed_enumerator_map &enumerators_map, changed_enumerators_type &sorted)
Sort a map of changed enumerators.
bool is_filtered_out(diff_category category)
Check if a given categorization of a diff node should make it be filtered out.
A comparison functor to compare two data members based on their offset.
shared_ptr< fn_parm_diff > fn_parm_diff_sptr
Convenience typedef for a shared pointer to a fn_parm_diff type.
string get_name(const type_or_decl_base *tod, bool qualified)
Build and return a copy of the name of an ABI artifact that is either a type or a decl...
Definition: abg-ir.cc:8632
unordered_map< string, method_decl_sptr > string_member_function_sptr_map
Convenience typedef for a hash map of strings and member functions.
bool function_decl_is_less_than(const function_decl &f, const function_decl &s)
Test if the pretty representation of a given function_decl is lexicographically less then the pretty ...
Definition: abg-ir.cc:27288
The type of private data of class_or_union_diff.
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer...
std::pair< const type_or_decl_base_sptr, const type_or_decl_base_sptr > types_or_decls_type
Convenience typedef for a pair of decls or types.
unordered_map< size_t, size_t > pointer_map
Convenience typedef for a map of pointer values. The Key is a pointer value and the value is potentia...
unordered_map< string, fn_parm_diff_sptr > string_fn_parm_diff_sptr_map
Convenience typedef for a map which value is a changed function parameter and which key is the name o...
void sort_string_fn_parm_diff_sptr_map(const unsigned_fn_parm_diff_sptr_map &map, vector< fn_parm_diff_sptr > &sorted)
Sort a map of fn_parm_diff by the indexes of the function parameters.
void sort_string_virtual_member_function_diff_sptr_map(const string_function_decl_diff_sptr_map &map, function_decl_diff_sptrs_type &sorted)
Sort an map of string -> virtual member function into a vector of virtual member functions. The virtual member functions are sorted by increasing order of their virtual index.
an engine to suppress the parts of the result of comparing two sets of ABI artifacts.
void sort_string_function_decl_diff_sptr_map(const string_function_decl_diff_sptr_map &map, function_decl_diff_sptrs_type &sorted)
Sort the values of a string_function_decl_diff_sptr_map map and store the result in a vector of funct...
A diff node in this category carries a change that must be reported, even if the diff node is also in...
vector< diff_sptr > diff_sptrs_type
Convenience typedef for a vector of diff_sptr.
A functor to compare two changed enumerators, based on their initial value.
shared_ptr< corpus_diff > corpus_diff_sptr
A convenience typedef for a shared pointer to corpus_diff.
weak_ptr< diff_context > diff_context_wptr
Convenience typedef for a weak pointer of diff_context.
Definition: abg-fwd.h:74
A comparison functor for using diff_sptr and diff* in a hash map or set.
vector< base_diff_sptr > base_diff_sptrs_type
Convenience typedef for a vector of base_diff_sptr.
unordered_map< string, function_decl::parameter_sptr > string_parm_map
Convenience typedef for a map which value is a function parameter. The key is the name of the functio...
bool operator()(const diff &d1, const diff &d2) const
The function-call operator to compare two diff nodes.
"Less than" functor to compare instances of function_decl.
void sort_string_type_base_sptr_map(string_type_base_sptr_map &map, vector< type_base_sptr > &sorted)
Sort a map of string to type_base_sptr entities.
Functor that compares two function parameters for the purpose of sorting them.
void sort_string_diff_ptr_map(const string_diff_ptr_map &map, diff_ptrs_type &sorted)
Sort a map ofg string -> diff* into a vector of diff_ptr. The diff_ptr are sorted lexicographically w...
bool operator()(const diff_sptr &d1, const diff_sptr &d2) const
The function-call operator to compare two diff nodes.
unordered_map< string, enum_type_decl::enumerator > string_enumerator_map
Convenience typedef for a map which value is an enumerator. The key is the name of the enumerator...
size_t operator()(const diff *d) const
The function-call operator to hash a diff node.
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
Definition: abg-ir.cc:2437
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition: abg-ir.h:4183
This is a document class that aims to capture statistics about the changes carried by a corpus_diff t...
The type of the private data (pimpl sub-object) of the class_diff type.
The internal type for the impl idiom implementation of var_diff.
shared_ptr< diff > diff_sptr
Convenience typedef for a shared_ptr for the diff class.
Definition: abg-fwd.h:76
shared_ptr< reporter_base > reporter_base_sptr
A convenience typedef for a shared pointer to a reporter_base.
Definition: abg-reporter.h:49
unordered_map< string, function_decl * > string_function_ptr_map
Convenience typedef for a map which key is a string and which value is a pointer to decl_base...
void sort_artifacts_set(const artifact_sptr_set_type &set, vector< type_or_decl_base_sptr > &sorted)
Sort the set of ABI artifacts contained in a artifact_sptr_set_type.
bool operator()(const function_decl_sptr f, const function_decl_sptr s)
The actual "less than" operator for instances of function_decl. It returns true if the first function...
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
weak_ptr< diff > diff_wptr
Convenience typedef for a weak_ptr for the diff class.
Definition: abg-fwd.h:82
A comparison functor for instances of function_decl_diff that represent changes between two virtual m...
Private data for the diff type. The details of generic view of the diff node are expressed here...
void sort_string_function_ptr_map(const string_function_ptr_map &map, vector< function_decl * > &sorted)
Sort an instance of string_function_ptr_map map and stuff a resulting sorted vector of pointers to fu...
bool operator()(const decl_base_sptr &f, const decl_base_sptr &s) const
Compare two data members.