20 #include "abg-reporter-priv.h"
115 for (string_enumerator_map::const_iterator i = enumerators_map.begin();
116 i != enumerators_map.end();
118 sorted.push_back(i->second);
120 std::sort(sorted.begin(), sorted.end(), comp);
132 for (string_changed_enumerator_map::const_iterator i =
133 enumerators_map.begin();
134 i != enumerators_map.end();
136 sorted.push_back(i->second);
139 std::sort(sorted.begin(), sorted.end(), comp);
149 vector<decl_base_sptr>& sorted)
151 sorted.reserve(data_members.size());
152 for (string_decl_base_sptr_map::const_iterator i = data_members.begin();
153 i != data_members.end();
155 sorted.push_back(i->second);
158 std::sort(sorted.begin(), sorted.end(), comp);
168 std::sort(to_sort.begin(), to_sort.end(), comp);
179 vector<function_decl*>& sorted)
181 sorted.reserve(map.size());
182 for (string_function_ptr_map::const_iterator i = map.begin();
185 sorted.push_back(i->second);
188 std::sort(sorted.begin(), sorted.end(), comp);
202 sorted.reserve(map.size());
203 for (string_member_function_sptr_map::const_iterator i = map.begin();
206 sorted.push_back(i->second);
209 std::sort(sorted.begin(), sorted.end(), comp);
225 sorted.reserve(map.size());
226 for (string_function_decl_diff_sptr_map::const_iterator i = map.begin();
229 sorted.push_back(i->second);
231 std::sort(sorted.begin(), sorted.end(), comp);
244 sorted.reserve(map.size());
245 for (string_var_diff_sptr_map::const_iterator i = map.begin();
248 sorted.push_back(i->second);
251 std::sort(sorted.begin(), sorted.end(), comp);
265 vector<elf_symbol_sptr>& sorted)
267 for (string_elf_symbol_map::const_iterator i = map.begin();
270 sorted.push_back(i->second);
273 std::sort(sorted.begin(), sorted.end(), comp);
286 vector<var_decl*>& sorted)
288 for (string_var_ptr_map::const_iterator i = map.begin();
291 sorted.push_back(i->second);
294 std::sort(sorted.begin(), sorted.end(), comp);
307 sorted.reserve(map.size());
308 for (string_var_diff_sptr_map::const_iterator i = map.begin();
311 sorted.push_back(i->second);
313 std::sort(sorted.begin(), sorted.end(), comp);
326 sorted.reserve(map.size());
327 for (unsigned_var_diff_sptr_map::const_iterator i = map.begin();
330 sorted.push_back(i->second);
332 std::sort(sorted.begin(), sorted.end(), comp);
348 sorted.reserve(map.size());
349 for (string_function_decl_diff_sptr_map::const_iterator i = map.begin();
352 sorted.push_back(i->second);
355 sort(sorted.begin(), sorted.end(), comp);
369 sorted.reserve(map.size());
370 for (string_diff_sptr_map::const_iterator i = map.begin();
373 sorted.push_back(i->second);
376 sort(sorted.begin(), sorted.end(), comp);
390 sorted.reserve(map.size());
391 for (string_diff_ptr_map::const_iterator i = map.begin();
394 sorted.push_back(i->second);
397 sort(sorted.begin(), sorted.end(), comp);
411 for (string_base_diff_sptr_map::const_iterator i = map.begin();
414 sorted.push_back(i->second);
416 sort(sorted.begin(), sorted.end(), comp);
425 for (string_base_sptr_map::const_iterator i = m.begin();
428 sorted.push_back(i->second);
431 std::sort(sorted.begin(), sorted.end(), comp);
443 vector<fn_parm_diff_sptr>& sorted)
445 sorted.reserve(map.size());
446 for (unsigned_fn_parm_diff_sptr_map::const_iterator i = map.begin();
449 sorted.push_back(i->second);
452 std::sort(sorted.begin(), sorted.end(), comp);
464 vector<fn_parm_diff_sptr>& sorted)
466 sorted.reserve(map.size());
467 for (string_fn_parm_diff_sptr_map::const_iterator i = map.begin();
470 sorted.push_back(i->second);
473 std::sort(sorted.begin(), sorted.end(), comp);
484 vector<function_decl::parameter_sptr>& sorted)
486 for (string_parm_map::const_iterator i = map.begin();
489 sorted.push_back(i->second);
492 std::sort(sorted.begin(), sorted.end(), comp);
504 vector<type_or_decl_base_sptr>& sorted)
507 for (artifact_sptr_set_type::const_iterator it = set.begin();
510 sorted.push_back(*it);
513 std::sort(sorted.begin(), sorted.end(), comp);
528 vector<type_base_sptr>& sorted)
530 for (string_type_base_sptr_map::const_iterator i = map.begin();
533 sorted.push_back(i->second);
536 std::sort(sorted.begin(), sorted.end(), comp);
548 return type_base_sptr();
550 type_base_sptr ut = t->get_underlying_type();
579 if (decl_base_sptr decl =
is_decl(first))
596 | static_cast<unsigned>(r));}
603 & static_cast<unsigned>(r));
609 {
return static_cast<visiting_kind>(~static_cast<
unsigned>(l));}
639 {
return dynamic_cast<const class_diff*
>(diff);}
649 {
return dynamic_cast<const enum_diff*
>(diff);}
659 {
return dynamic_cast<const union_diff*
>(diff);}
683 if (dif->first_class_or_union()->get_is_anonymous())
716 {
return dynamic_cast<const array_diff*
>(diff);}
739 if (d->has_local_changes())
863 {
return dynamic_cast<const base_diff*
>(diff);}
913 diff_context::diff_context()
929 diff_context::~diff_context() =
default;
936 {
return priv_->do_log_;}
943 {priv_->do_log_ = f;}
950 {priv_->corpus_diff_ = d;}
957 {
return priv_->corpus_diff_;}
966 if (priv_->corpus_diff_)
967 return priv_->corpus_diff_->first_corpus();
968 return corpus_sptr();
979 if (priv_->corpus_diff_)
980 return priv_->corpus_diff_->second_corpus();
981 return corpus_sptr();
990 if (!priv_->reporter_)
998 return priv_->reporter_;
1006 {priv_->reporter_ = r;}
1020 types_or_decls_diff_map_type::const_iterator i =
1021 priv_->types_or_decls_diff_map.find(std::make_pair(first, second));
1022 if (i != priv_->types_or_decls_diff_map.end())
1036 diff_context::has_diff_for_types(
const type_base_sptr first,
1037 const type_base_sptr second)
const
1038 {
return has_diff_for(first, second);}
1046 diff_context::has_diff_for(
const diff* d)
const
1047 {
return has_diff_for(d->first_subject(), d->second_subject()).
get();}
1055 diff_context::has_diff_for(
const diff_sptr d)
const
1056 {
return has_diff_for(d->first_subject(), d->second_subject());}
1065 {
return priv_->allowed_category_;}
1074 {priv_->allowed_category_ = c;}
1087 {priv_->allowed_category_ = priv_->allowed_category_ | c;}
1098 {priv_->allowed_category_ = priv_->allowed_category_ & ~c;}
1114 {priv_->types_or_decls_diff_map[std::make_pair(first, second)] = d;}
1120 diff_context::add_diff(
const diff* d)
1133 diff_context::add_diff(
const diff_sptr d)
1136 add_diff(d->first_subject(), d->second_subject(), d);
1153 {
return has_diff_for(first, second);}
1165 {
return has_diff_for(d);}
1181 if (!has_diff_for(first, second))
1183 add_diff(first, second, d);
1184 priv_->canonical_diffs.push_back(d);
1209 canonical = canonical_diff;
1210 set_canonical_diff_for(first, second, canonical);
1233 if (diff->get_canonical_diff() == 0)
1236 set_or_get_canonical_diff_for(diff->first_subject(),
1237 diff->second_subject(),
1239 diff->set_canonical_diff(canonical.get());
1253 {priv_->live_diffs_.insert(d);}
1266 size_t ptr_value =
reinterpret_cast<size_t>(canonical);
1267 pointer_map::iterator it = priv_->visited_diff_nodes_.find(ptr_value);
1268 if (it != priv_->visited_diff_nodes_.end())
1269 return reinterpret_cast<diff*>(it->second);
1302 size_t canonical_ptr_value =
reinterpret_cast<size_t>(canonical);
1303 size_t diff_ptr_value =
reinterpret_cast<size_t>(d);
1304 priv_->visited_diff_nodes_[canonical_ptr_value] = diff_ptr_value;
1310 {priv_->visited_diff_nodes_.clear();}
1320 {priv_->forbid_visiting_a_node_twice_ = f;}
1330 {priv_->reset_visited_diffs_for_each_interface_ = f;}
1338 {
return priv_->forbid_visiting_a_node_twice_;}
1352 return (priv_->forbid_visiting_a_node_twice_
1353 && priv_->reset_visited_diffs_for_each_interface_);
1361 {
return priv_->filters_;}
1369 {priv_->filters_.push_back(f);}
1384 if (!diff->has_changes())
1387 for (filtering::filters::const_iterator i =
diff_filters().begin();
1394 std::cerr <<
"applying a filter to diff '"
1395 << diff->get_pretty_representation()
1405 std::cerr <<
"filter applied!:" << t <<
"\n";
1407 std::cerr <<
"propagating categories for the same diff node ... \n";
1416 std::cerr <<
"category propagated!: " << t <<
"\n";
1434 if (!diff || !diff->has_changes())
1437 for (filtering::filters::const_iterator i =
diff_filters().begin();
1452 {
return priv_->suppressions_;}
1463 priv_->negated_suppressions_.clear();
1464 priv_->direct_suppressions_.clear();
1465 return priv_->suppressions_;
1484 if (priv_->negated_suppressions_.empty())
1487 priv_->negated_suppressions_.push_back(s);
1489 return priv_->negated_suppressions_;
1507 if (priv_->direct_suppressions_.empty())
1511 priv_->direct_suppressions_.push_back(s);
1513 return priv_->direct_suppressions_;
1524 priv_->suppressions_.push_back(suppr);
1527 priv_->negated_suppressions_.clear();
1528 priv_->direct_suppressions_.clear();
1539 priv_->suppressions_.insert(priv_->suppressions_.end(),
1540 supprs.begin(), supprs.end());
1549 {
return priv_->perform_change_categorization_;}
1556 {priv_->perform_change_categorization_ = f;}
1570 priv_->leaf_changes_only_ = f;
1580 {
return priv_->leaf_changes_only_;}
1590 {
return priv_->hex_values_;}
1600 {priv_->hex_values_ = f;}
1609 {
return priv_->show_offsets_sizes_in_bits_;}
1618 {priv_->show_offsets_sizes_in_bits_ = f;}
1627 {priv_->show_relative_offset_changes_ = f;}
1636 {
return priv_->show_relative_offset_changes_;}
1644 {priv_->show_stats_only_ = f;}
1652 {
return priv_->show_stats_only_;}
1660 {priv_->show_soname_change_ = f;}
1668 {
return priv_->show_soname_change_;}
1676 {priv_->show_architecture_change_ = f;}
1684 {
return priv_->show_architecture_change_;}
1691 {priv_->show_deleted_fns_ = f;}
1697 {
return priv_->show_deleted_fns_;}
1704 {priv_->show_changed_fns_ = f;}
1709 {
return priv_->show_changed_fns_;}
1716 {priv_->show_added_fns_ = f;}
1722 {
return priv_->show_added_fns_;}
1729 {priv_->show_deleted_vars_ = f;}
1735 {
return priv_->show_deleted_vars_;}
1742 {priv_->show_changed_vars_ = f;}
1747 {
return priv_->show_changed_vars_;}
1754 {priv_->show_added_vars_ = f;}
1760 {
return priv_->show_added_vars_;}
1763 diff_context::show_linkage_names()
const
1764 {
return priv_->show_linkage_names_;}
1767 diff_context::show_linkage_names(
bool f)
1768 {priv_->show_linkage_names_= f;}
1775 {priv_->show_locs_= f;}
1781 {
return priv_->show_locs_;}
1790 {
return priv_->show_redundant_changes_;}
1799 {priv_->show_redundant_changes_ = f;}
1807 {
return priv_->show_syms_unreferenced_by_di_;}
1815 {priv_->show_syms_unreferenced_by_di_ = f;}
1824 {
return priv_->show_added_syms_unreferenced_by_di_;}
1833 {priv_->show_added_syms_unreferenced_by_di_ = f;}
1842 {priv_->show_unreachable_types_ = f;}
1851 {
return priv_->show_unreachable_types_;}
1862 {
return priv_->show_impacted_interfaces_;}
1873 {priv_->show_impacted_interfaces_ = f;}
1882 {priv_->default_output_stream_ = o;}
1891 {
return priv_->default_output_stream_;}
1899 {priv_->error_output_stream_ = o;}
1907 {
return priv_->error_output_stream_;}
1916 {
return priv_->dump_diff_tree_;}
1925 {priv_->dump_diff_tree_ = f;}
1964 : priv_(new priv(first_subject, second_subject,
1986 : priv_(new priv(first_subject, second_subject,
2025 if (priv_->canonical_diff_)
2026 priv_->canonical_diff_->priv_->traversing_ =
true;
2027 priv_->traversing_ =
true;
2044 if (priv_->canonical_diff_)
2045 return priv_->canonical_diff_->priv_->traversing_;
2046 return priv_->traversing_;
2060 if (priv_->canonical_diff_)
2061 priv_->canonical_diff_->priv_->traversing_ =
false;
2062 priv_->traversing_ =
false;
2078 if (diff::priv_->finished_)
2081 diff::priv_->finished_ =
true;
2101 const vector<diff*>&
2103 {
return priv_->children_;}
2110 {
return priv_->parent_;}
2123 {
return priv_->canonical_diff_;}
2131 {priv_->canonical_diff_ = d;}
2144 context()->keep_diff_alive(d);
2151 priv_->children_.push_back(d.get());
2153 d->priv_->parent_ =
this;
2161 {
return priv_->get_context();}
2178 if (priv_->canonical_diff_)
2179 return priv_->canonical_diff_->priv_->currently_reporting_;
2180 return priv_->currently_reporting_;
2191 if (priv_->canonical_diff_)
2192 priv_->canonical_diff_->priv_->currently_reporting_ = f;
2193 priv_->currently_reporting_ = f;
2204 return priv_->canonical_diff_->priv_->reported_once_;
2264 bool already_visited =
false;
2265 if (
context()->visiting_a_node_twice_is_forbidden()
2266 &&
context()->diff_has_been_visited(
this))
2267 already_visited =
true;
2269 bool mark_visited_nodes_as_traversed =
2272 if (!already_visited && !v.
visit(
this,
true))
2275 if (mark_visited_nodes_as_traversed)
2276 context()->mark_diff_as_visited(
this);
2282 && !already_visited)
2289 if (!(*i)->traverse(v))
2292 if (mark_visited_nodes_as_traversed)
2293 context()->mark_diff_as_visited(
this);
2301 if (!v.
visit(
this,
false))
2304 if (mark_visited_nodes_as_traversed)
2305 context()->mark_diff_as_visited(
this);
2310 if (!already_visited && mark_visited_nodes_as_traversed)
2311 context()->mark_diff_as_visited(
this);
2325 priv_->canonical_diff_->priv_->reported_once_ = f;
2326 priv_->reported_once_ = f;
2338 {
return priv_->local_category_;}
2364 {
return priv_->category_;}
2379 priv_->category_ = priv_->category_ | c;
2380 return priv_->category_;
2394 priv_->local_category_ = priv_->local_category_ | c;
2395 return priv_->local_category_;
2423 priv_->category_ = priv_->category_ & ~c;
2424 return priv_->category_;
2438 priv_->local_category_ = priv_->local_category_ & ~c;
2439 return priv_->local_category_;
2449 {priv_->category_ = c;}
2456 {priv_->local_category_ = c;}
2481 && !canonical->is_allowed_by_specific_negated_suppression()
2482 && !canonical->has_descendant_allowed_by_specific_negated_suppression()
2483 && !canonical->has_parent_allowed_by_specific_negated_suppression())
2524 return priv_->is_filtered_out(c);
2535 bool is_private =
false;
2564 bool do_suppress = !
context()->negated_suppressions().empty();
2568 for (
auto n :
context()->negated_suppressions())
2569 if (!n->suppresses_diff(
this))
2571 do_suppress =
false;
2578 for (
auto d :
context()->direct_suppressions())
2579 if (d->suppresses_diff(
this))
2583 is_private_type =
true;
2623 for (suppressions_type::const_iterator i = suppressions.begin();
2624 i != suppressions.end();
2628 && !(*i)->suppresses_diff(
this))
2668 if (priv_->pretty_representation_.empty())
2669 priv_->pretty_representation_ =
"empty_diff";
2670 return priv_->pretty_representation_;
2697 type_diff_base::type_diff_base(type_base_sptr first_subject,
2698 type_base_sptr second_subject,
2700 :
diff(first_subject, second_subject, ctxt),
2704 type_diff_base::~type_diff_base()
2720 decl_base_sptr second_subject,
2722 :
diff(first_subject, second_subject, ctxt),
2726 decl_diff_base::~decl_diff_base()
2737 if (diff::priv_->pretty_representation_.empty())
2739 std::ostringstream o;
2740 o <<
"distinct_diff[";
2751 diff::priv_->pretty_representation_ = o.str();
2753 return diff::priv_->pretty_representation_;
2786 :
diff(first, second, ctxt),
2820 if (!priv_->compatible_child_diff)
2832 return priv_->compatible_child_diff;
2847 if (!!first != !!second)
2849 if (!first && !second)
2853 if (first == second)
2857 return typeid(f) !=
typeid(s);
2875 return NO_CHANGE_KIND;
2886 context()->get_reporter()->report(*
this, out, indent);
2909 ctxt->initialize_canonical_diff(result);
2934 template<
typename DiffType>
2940 if (shared_ptr<DiffType> f =
2941 dynamic_pointer_cast<DiffType>(first))
2943 shared_ptr<DiffType> s =
2944 dynamic_pointer_cast<DiffType>(second);
2970 dynamic_pointer_cast<class_decl>(first))
2976 if (f->get_is_declaration_only())
2983 if (s->get_is_declaration_only())
3038 ((d = try_to_diff<type_decl>(f, s, ctxt))
3039 ||(d = try_to_diff<enum_type_decl>(f, s, ctxt))
3040 ||(d = try_to_diff<union_decl>(f, s,ctxt))
3042 ||(d = try_to_diff<pointer_type_def>(f, s, ctxt))
3043 ||(d = try_to_diff<reference_type_def>(f, s, ctxt))
3044 ||(d = try_to_diff<array_type_def::subrange_type>(f, s, ctxt))
3045 ||(d = try_to_diff<array_type_def>(f, s, ctxt))
3046 ||(d = try_to_diff<qualified_type_def>(f, s, ctxt))
3047 ||(d = try_to_diff<typedef_decl>(f, s, ctxt))
3048 ||(d = try_to_diff<function_type>(f, s, ctxt))
3049 ||(d = try_to_diff_distinct_kinds(f, s, ctxt)));
3058 {
return static_cast<diff_category>(
static_cast<unsigned>(c1)
3059 | static_cast<unsigned>(c2));}
3077 {
return static_cast<diff_category>(
static_cast<unsigned>(c1)
3078 ^ static_cast<unsigned>(c2));}
3082 {
return static_cast<diff_category>(
static_cast<unsigned>(c1)
3083 & static_cast<unsigned>(c2));}
3087 {
return static_cast<diff_category>(~static_cast<
unsigned>(c));}
3139 bool emitted_a_category =
false;
3143 o <<
"NO_CHANGE_CATEGORY";
3144 emitted_a_category =
true;
3149 if (emitted_a_category)
3151 o <<
"ACCESS_CHANGE_CATEGORY";
3152 emitted_a_category |=
true;
3157 if (emitted_a_category)
3159 o <<
"COMPATIBLE_TYPE_CHANGE_CATEGORY";
3160 emitted_a_category |=
true;
3165 if (emitted_a_category)
3167 o <<
"HARMLESS_DECL_NAME_CHANGE_CATEGORY";
3168 emitted_a_category |=
true;
3173 if (emitted_a_category)
3175 o <<
"NON_VIRT_MEM_FUN_CHANGE_CATEGORY";
3176 emitted_a_category |=
true;
3181 if (emitted_a_category)
3183 o <<
"STATIC_DATA_MEMBER_CHANGE_CATEGORY";
3184 emitted_a_category |=
true;
3189 if (emitted_a_category)
3191 o <<
"HARMLESS_ENUM_CHANGE_CATEGORY";
3192 emitted_a_category |=
true;
3197 if (emitted_a_category)
3199 o <<
"HARMLESS_DATA_MEMBER_CHANGE_CATEGORY";
3200 emitted_a_category |=
true;
3205 if (emitted_a_category)
3207 o <<
"HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY";
3208 emitted_a_category |=
true;
3213 if (emitted_a_category)
3215 o <<
"HARMLESS_UNION_CHANGE_CATEGORY";
3216 emitted_a_category |=
true;
3221 if (emitted_a_category)
3223 o <<
"SUPPRESSED_CATEGORY";
3224 emitted_a_category |=
true;
3229 if (emitted_a_category)
3231 o <<
"PRIVATE_TYPE_CATEGORY";
3232 emitted_a_category |=
true;
3237 if (emitted_a_category)
3239 o <<
"SIZE_OR_OFFSET_CHANGE_CATEGORY";
3240 emitted_a_category |=
true;
3245 if (emitted_a_category)
3247 o <<
"VIRTUAL_MEMBER_CHANGE_CATEGORY";
3248 emitted_a_category |=
true;
3253 if (emitted_a_category)
3255 o <<
"REDUNDANT_CATEGORY";
3256 emitted_a_category |=
true;
3261 if (emitted_a_category)
3263 o <<
"TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY";
3264 emitted_a_category |=
true;
3269 if (emitted_a_category)
3271 o <<
"FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY";
3272 emitted_a_category |=
true;
3277 if (emitted_a_category)
3279 o <<
"FN_PARM_TYPE_CV_CHANGE_CATEGORY";
3280 emitted_a_category |=
true;
3285 if (emitted_a_category)
3287 o <<
"FN_RETURN_TYPE_CV_CHANGE_CATEGORY";
3288 emitted_a_category |=
true;
3293 if (emitted_a_category)
3295 o <<
"FN_PARM_ADD_REMOVE_CHANGE_CATEGORY";
3296 emitted_a_category |=
true;
3301 if (emitted_a_category)
3303 o <<
"VAR_TYPE_CV_CHANGE_CATEGORY";
3304 emitted_a_category |=
true;
3309 if (emitted_a_category)
3311 o <<
"VOID_PTR_TO_PTR_CHANGE_CATEGORY";
3312 emitted_a_category |=
true;
3317 if (emitted_a_category)
3319 o <<
"BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY";
3320 emitted_a_category |=
true;
3325 if (emitted_a_category)
3327 o <<
"HAS_ALLOWED_CHANGE_CATEGORY";
3328 emitted_a_category |=
true;
3333 if (emitted_a_category)
3335 o <<
"HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY";
3336 emitted_a_category |=
true;
3341 if (emitted_a_category)
3343 o <<
"HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY";
3344 emitted_a_category |=
true;
3367 compute_diff_for_decls(
const decl_base_sptr first,
3368 const decl_base_sptr second,
3374 ((d = try_to_diff<function_decl>(first, second, ctxt))
3375 || (d = try_to_diff<var_decl>(first, second, ctxt))
3376 || (d = try_to_diff_distinct_kinds(first, second, ctxt)));
3399 const decl_base_sptr second,
3402 if (!first || !second)
3407 d = compute_diff_for_types(first, second, ctxt);
3409 d = compute_diff_for_decls(first, second, ctxt);
3429 const type_base_sptr second,
3435 diff_sptr d = compute_diff_for_types(f,s, ctxt);
3450 string prefix=
"diff of ";
3470 if (diff::priv_->pretty_representation_.empty())
3472 std::ostringstream o;
3478 diff::priv_->pretty_representation_ = o.str();
3480 return diff::priv_->pretty_representation_;
3523 if (
diff_sptr result = priv_->type_diff_.lock())
3530 context()->keep_diff_alive(result);
3531 priv_->type_diff_ = result;
3552 return ir::NO_CHANGE_KIND;
3564 context()->get_reporter()->report(*
this, out, indent);
3585 ctxt->initialize_canonical_diff(d);
3615 priv_(new
priv(underlying))
3637 if (diff::priv_->pretty_representation_.empty())
3639 std::ostringstream o;
3640 o <<
"pointer_diff["
3645 diff::priv_->pretty_representation_ = o.str();
3647 return diff::priv_->pretty_representation_;
3666 return ir::NO_CHANGE_KIND;
3675 {
return priv_->underlying_type_diff_;}
3684 {priv_->underlying_type_diff_ = d;}
3695 context()->get_reporter()->report(*
this, out, indent);
3715 diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
3716 second->get_pointed_to_type(),
3719 ctxt->initialize_canonical_diff(result);
3744 priv_(
new priv(underlying_type_diff))
3772 {
return priv_->underlying_type_diff_;}
3781 if (diff::priv_->pretty_representation_.empty())
3783 std::ostringstream o;
3784 o <<
"subrange_diff["
3789 diff::priv_->pretty_representation_ = o.str();
3791 return diff::priv_->pretty_representation_;
3813 return ir::NO_CHANGE_KIND;
3823 {
context()->get_reporter()->report(*
this, out, indent);}
3851 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
3852 second->get_underlying_type(),
3856 ctxt->initialize_canonical_diff(result);
3889 priv_(new
priv(element_type_diff))
3911 {
return priv_->element_type_diff_;}
3918 {priv_->element_type_diff_ = d;}
3925 if (diff::priv_->pretty_representation_.empty())
3927 std::ostringstream o;
3933 diff::priv_->pretty_representation_ = o.str();
3935 return diff::priv_->pretty_representation_;
3952 if (f->get_name() != s->get_name())
3954 if (f->get_size_in_bits() != s->get_size_in_bits())
3956 if (f->get_alignment_in_bits() != s->get_alignment_in_bits())
3976 return ir::NO_CHANGE_KIND;
3987 context()->get_reporter()->report(*
this, out, indent);
4005 diff_sptr d = compute_diff_for_types(first->get_element_type(),
4006 second->get_element_type(),
4009 ctxt->initialize_canonical_diff(result);
4037 priv_(new
priv(underlying))
4060 {
return priv_->underlying_type_diff_;}
4068 priv_->underlying_type_diff_ = d;
4069 return priv_->underlying_type_diff_;
4077 if (diff::priv_->pretty_representation_.empty())
4079 std::ostringstream o;
4080 o <<
"reference_diff["
4085 diff::priv_->pretty_representation_ = o.str();
4087 return diff::priv_->pretty_representation_;
4108 return ir::NO_CHANGE_KIND;
4119 context()->get_reporter()->report(*
this, out, indent);
4137 diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
4138 second->get_pointed_to_type(),
4141 ctxt->initialize_canonical_diff(result);
4165 qualified_type_def_sptr second,
4169 priv_(new
priv(under))
4175 const qualified_type_def_sptr
4182 const qualified_type_def_sptr
4193 {
return priv_->underlying_type_diff;}
4203 if (!priv_->leaf_underlying_type_diff)
4204 priv_->leaf_underlying_type_diff
4209 return priv_->leaf_underlying_type_diff;
4219 {priv_->underlying_type_diff = d;}
4226 if (diff::priv_->pretty_representation_.empty())
4228 std::ostringstream o;
4229 o <<
"qualified_type_diff["
4234 diff::priv_->pretty_representation_ = o.str();
4236 return diff::priv_->pretty_representation_;
4255 return ir::NO_CHANGE_KIND;
4266 context()->get_reporter()->report(*
this, out, indent);
4279 qualified_type_diff_sptr
4281 const qualified_type_def_sptr second,
4284 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
4285 second->get_underlying_type(),
4289 ctxt->initialize_canonical_diff(result);
4302 enum_diff::clear_lookup_tables()
4304 priv_->deleted_enumerators_.clear();
4305 priv_->inserted_enumerators_.clear();
4306 priv_->changed_enumerators_.clear();
4313 enum_diff::lookup_tables_empty()
const
4315 return (priv_->deleted_enumerators_.empty()
4316 && priv_->inserted_enumerators_.empty()
4317 && priv_->changed_enumerators_.empty());
4323 enum_diff::ensure_lookup_tables_populated()
4325 if (!lookup_tables_empty())
4329 edit_script e = priv_->enumerators_changes_;
4331 for (vector<deletion>::const_iterator it = e.deletions().begin();
4332 it != e.deletions().end();
4335 unsigned i = it->index();
4336 const enum_type_decl::enumerator& n =
4338 const string& name = n.get_name();
4339 ABG_ASSERT(priv_->deleted_enumerators_.find(n.get_name())
4340 == priv_->deleted_enumerators_.end());
4341 priv_->deleted_enumerators_[name] = n;
4344 for (vector<insertion>::const_iterator it = e.insertions().begin();
4345 it != e.insertions().end();
4348 for (vector<unsigned>::const_iterator iit =
4349 it->inserted_indexes().begin();
4350 iit != it->inserted_indexes().end();
4354 const enum_type_decl::enumerator& n =
4356 const string& name = n.get_name();
4357 ABG_ASSERT(priv_->inserted_enumerators_.find(n.get_name())
4358 == priv_->inserted_enumerators_.end());
4359 string_enumerator_map::const_iterator j =
4360 priv_->deleted_enumerators_.find(name);
4361 if (j == priv_->deleted_enumerators_.end())
4362 priv_->inserted_enumerators_[name] = n;
4366 priv_->changed_enumerators_[j->first] =
4367 std::make_pair(j->second, n);
4368 priv_->deleted_enumerators_.erase(j);
4399 priv_(new
priv(underlying_type_diff))
4415 {
return priv_->underlying_type_diff_;}
4420 {
return priv_->deleted_enumerators_;}
4425 {
return priv_->inserted_enumerators_;}
4430 {
return priv_->changed_enumerators_;}
4437 if (diff::priv_->pretty_representation_.empty())
4439 std::ostringstream o;
4445 diff::priv_->pretty_representation_ = o.str();
4447 return diff::priv_->pretty_representation_;
4466 return ir::NO_CHANGE_KIND;
4477 context()->get_reporter()->report(*
this, out, indent);
4499 diff_sptr ud = compute_diff_for_types(first->get_underlying_type(),
4500 second->get_underlying_type(),
4502 enum_diff_sptr d(
new enum_diff(first, second, ud, ctxt));
4503 if (first != second)
4506 first->get_enumerators().end(),
4507 second->get_enumerators().begin(),
4508 second->get_enumerators().end(),
4509 d->priv_->enumerators_changes_);
4510 d->ensure_lookup_tables_populated();
4512 ctxt->initialize_canonical_diff(d);
4534 string qname = d->get_qualified_name();
4535 string_diff_sptr_map::const_iterator it =
4536 changed_member_types_.find(qname);
4538 return ((it == changed_member_types_.end())
4540 : it->second->second_subject());
4557 string qname = d->get_qualified_name();
4558 string_var_diff_sptr_map::const_iterator it =
4559 subtype_changed_dm_.find(qname);
4561 if (it == subtype_changed_dm_.end())
4562 return decl_base_sptr();
4563 return it->second->second_var();
4581 string qname = d->get_qualified_name();
4582 string_diff_sptr_map::const_iterator it =
4583 changed_member_class_tmpls_.find(qname);
4585 return ((it == changed_member_class_tmpls_.end())
4587 : dynamic_pointer_cast<
decl_base>(it->second->second_subject()));
4598 for (string_decl_base_sptr_map::const_iterator i =
4599 deleted_data_members_.begin();
4600 i != deleted_data_members_.end();
4617 for (string_decl_base_sptr_map::const_iterator i =
4618 inserted_data_members_.begin();
4619 i != inserted_data_members_.end();
4639 size_t num_filtered= 0;
4640 for (var_diff_sptrs_type::const_iterator i =
4641 sorted_subtype_changed_dm_.begin();
4642 i != sorted_subtype_changed_dm_.end();
4647 if ((*i)->has_changes()
4648 && !(*i)->has_local_changes_to_be_reported())
4653 if ((*i)->is_filtered_out())
4657 return num_filtered;
4671 size_t num_filtered= 0;
4673 for (unsigned_var_diff_sptr_map::const_iterator i = changed_dm_.begin();
4674 i != changed_dm_.end();
4680 if ((diff->has_changes() && !diff->has_local_changes_to_be_reported())
4681 || diff->is_filtered_out())
4686 if (diff->is_filtered_out())
4690 return num_filtered;
4699 #define SKIP_MEM_FN_IF_VIRTUALITY_DISALLOWED \
4701 if (get_member_function_is_virtual(f) \
4702 || get_member_function_is_virtual(s)) \
4704 if (!(allowed_category | VIRTUAL_MEMBER_CHANGE_CATEGORY)) \
4709 if (!(allowed_category | NON_VIRT_MEM_FUN_CHANGE_CATEGORY)) \
4724 diff_category allowed_category = ctxt->get_allowed_category();
4726 for (function_decl_diff_sptrs_type::const_iterator i =
4727 sorted_changed_member_functions_.begin();
4728 i != sorted_changed_member_functions_.end();
4731 method_decl_sptr f =
4733 ((*i)->first_function_decl());
4736 method_decl_sptr s =
4738 ((*i)->second_function_decl());
4744 ctxt->maybe_apply_filters(diff);
4746 if (diff->is_filtered_out())
4763 diff_category allowed_category = ctxt->get_allowed_category();
4765 for (string_member_function_sptr_map::const_iterator i =
4766 inserted_member_functions_.begin();
4767 i != inserted_member_functions_.end();
4770 method_decl_sptr f = i->second,
4776 ctxt->maybe_apply_filters(diff);
4779 && diff->is_filtered_out())
4796 diff_category allowed_category = ctxt->get_allowed_category();
4798 for (string_member_function_sptr_map::const_iterator i =
4799 deleted_member_functions_.begin();
4800 i != deleted_member_functions_.end();
4803 method_decl_sptr f = i->second,
4809 ctxt->maybe_apply_filters(diff);
4812 && diff->is_filtered_out())
4826 priv_->deleted_member_types_.clear();
4827 priv_->inserted_member_types_.clear();
4828 priv_->changed_member_types_.clear();
4829 priv_->deleted_data_members_.clear();
4830 priv_->inserted_data_members_.clear();
4831 priv_->subtype_changed_dm_.clear();
4832 priv_->deleted_member_functions_.clear();
4833 priv_->inserted_member_functions_.clear();
4834 priv_->changed_member_functions_.clear();
4835 priv_->deleted_member_class_tmpls_.clear();
4836 priv_->inserted_member_class_tmpls_.clear();
4837 priv_->changed_member_class_tmpls_.clear();
4846 return (priv_->deleted_member_types_.empty()
4847 && priv_->inserted_member_types_.empty()
4848 && priv_->changed_member_types_.empty()
4849 && priv_->deleted_data_members_.empty()
4850 && priv_->inserted_data_members_.empty()
4851 && priv_->subtype_changed_dm_.empty()
4852 && priv_->inserted_member_functions_.empty()
4853 && priv_->deleted_member_functions_.empty()
4854 && priv_->changed_member_functions_.empty()
4855 && priv_->deleted_member_class_tmpls_.empty()
4856 && priv_->inserted_member_class_tmpls_.empty()
4857 && priv_->changed_member_class_tmpls_.empty());
4866 edit_script& e = priv_->member_types_changes_;
4868 for (vector<deletion>::const_iterator it = e.deletions().begin();
4869 it != e.deletions().end();
4872 unsigned i = it->index();
4876 if (record_type && record_type->get_is_declaration_only())
4878 string name = d->get_name();
4879 priv_->deleted_member_types_[name] = d;
4882 for (vector<insertion>::const_iterator it = e.insertions().begin();
4883 it != e.insertions().end();
4886 for (vector<unsigned>::const_iterator iit =
4887 it->inserted_indexes().begin();
4888 iit != it->inserted_indexes().end();
4895 if (record_type && record_type->get_is_declaration_only())
4897 string name = d->get_name();
4898 string_decl_base_sptr_map::const_iterator j =
4899 priv_->deleted_member_types_.find(name);
4900 if (j != priv_->deleted_member_types_.end())
4902 if (*j->second != *d)
4903 priv_->changed_member_types_[name] =
4906 priv_->deleted_member_types_.erase(j);
4909 priv_->inserted_member_types_[name] = d;
4915 edit_script& e = priv_->data_members_changes_;
4917 for (vector<deletion>::const_iterator it = e.deletions().begin();
4918 it != e.deletions().end();
4921 unsigned i = it->index();
4924 string name = data_member->get_anon_dm_reliable_name();
4926 ABG_ASSERT(priv_->deleted_data_members_.find(name)
4927 == priv_->deleted_data_members_.end());
4928 priv_->deleted_data_members_[name] = data_member;
4931 for (vector<insertion>::const_iterator it = e.insertions().begin();
4932 it != e.insertions().end();
4935 for (vector<unsigned>::const_iterator iit =
4936 it->inserted_indexes().begin();
4937 iit != it->inserted_indexes().end();
4944 string name = added_dm->get_anon_dm_reliable_name();
4945 ABG_ASSERT(priv_->inserted_data_members_.find(name)
4946 == priv_->inserted_data_members_.end());
4948 bool ignore_added_anonymous_data_member =
false;
4986 bool added_anon_dm_changes_dm =
false;
4989 vector<var_decl_sptr> dms_replaced_by_anon_dm;
4998 for (string_decl_base_sptr_map::const_iterator it =
4999 priv_->deleted_data_members_.begin();
5000 it != priv_->deleted_data_members_.end();
5009 string deleted_dm_name = it->second->get_name();
5025 size_t replaced_dm_offset =
5027 replacing_dm_offset =
5030 if (replaced_dm_offset != replacing_dm_offset)
5038 added_anon_dm_changes_dm =
true;
5042 if (replaced_dm->get_type()->get_size_in_bits()
5043 == replaced_dm->get_type()->get_size_in_bits())
5044 dms_replaced_by_anon_dm.push_back(replaced_dm);
5047 added_anon_dm_changes_dm =
true;
5056 if (!added_anon_dm_changes_dm
5057 && !dms_replaced_by_anon_dm.empty())
5060 type_base_sptr added_dm_type = added_dm->get_type();
5076 ignore_added_anonymous_data_member =
true;
5077 for (vector<var_decl_sptr>::const_iterator i =
5078 dms_replaced_by_anon_dm.begin();
5079 i != dms_replaced_by_anon_dm.end();
5082 string n = (*i)->get_name();
5083 priv_->dms_replaced_by_adms_[n] =
5085 priv_->deleted_data_members_.erase(n);
5091 if (!ignore_added_anonymous_data_member)
5104 string_decl_base_sptr_map::const_iterator j =
5105 priv_->deleted_data_members_.find(name);
5106 if (j != priv_->deleted_data_members_.end())
5108 if (*j->second != *d)
5111 priv_->subtype_changed_dm_[name]=
5114 priv_->deleted_data_members_.erase(j);
5117 priv_->inserted_data_members_[name] = d;
5125 for (string_decl_base_sptr_map::const_iterator i =
5126 priv_->deleted_data_members_.begin();
5127 i != priv_->deleted_data_members_.end();
5131 priv_->deleted_dm_by_offset_[offset] = i->second;
5134 for (string_decl_base_sptr_map::const_iterator i =
5135 priv_->inserted_data_members_.begin();
5136 i != priv_->inserted_data_members_.end();
5140 priv_->inserted_dm_by_offset_[offset] = i->second;
5143 for (unsigned_decl_base_sptr_map::const_iterator i =
5144 priv_->inserted_dm_by_offset_.begin();
5145 i != priv_->inserted_dm_by_offset_.end();
5148 unsigned_decl_base_sptr_map::const_iterator j =
5149 priv_->deleted_dm_by_offset_.find(i->first);
5150 if (j != priv_->deleted_dm_by_offset_.end())
5154 priv_->changed_dm_[i->first] =
5159 for (unsigned_var_diff_sptr_map::const_iterator i =
5160 priv_->changed_dm_.begin();
5161 i != priv_->changed_dm_.end();
5164 priv_->deleted_dm_by_offset_.erase(i->first);
5165 priv_->inserted_dm_by_offset_.erase(i->first);
5166 priv_->deleted_data_members_.erase
5167 (i->second->first_var()->get_anon_dm_reliable_name());
5168 priv_->inserted_data_members_.erase
5169 (i->second->second_var()->get_anon_dm_reliable_name());
5173 priv_->sorted_subtype_changed_dm_);
5175 priv_->sorted_changed_dm_);
5178 edit_script& e = priv_->member_class_tmpls_changes_;
5180 for (vector<deletion>::const_iterator it = e.deletions().begin();
5181 it != e.deletions().end();
5184 unsigned i = it->index();
5188 string name = d->get_name();
5189 ABG_ASSERT(priv_->deleted_member_class_tmpls_.find(name)
5190 == priv_->deleted_member_class_tmpls_.end());
5191 priv_->deleted_member_class_tmpls_[name] = d;
5194 for (vector<insertion>::const_iterator it = e.insertions().begin();
5195 it != e.insertions().end();
5198 for (vector<unsigned>::const_iterator iit =
5199 it->inserted_indexes().begin();
5200 iit != it->inserted_indexes().end();
5207 string name = d->get_name();
5208 ABG_ASSERT(priv_->inserted_member_class_tmpls_.find(name)
5209 == priv_->inserted_member_class_tmpls_.end());
5210 string_decl_base_sptr_map::const_iterator j =
5211 priv_->deleted_member_class_tmpls_.find(name);
5212 if (j != priv_->deleted_member_class_tmpls_.end())
5214 if (*j->second != *d)
5215 priv_->changed_member_types_[name]=
5217 priv_->deleted_member_class_tmpls_.erase(j);
5220 priv_->inserted_member_class_tmpls_[name] = d;
5225 priv_->sorted_changed_member_types_);
5234 priv_.reset(
new priv);
5245 class_or_union_sptr second_scope,
5263 const class_or_union_diff::priv_ptr&
5276 return canonical->priv_;
5298 {
return get_priv()->member_types_changes_;}
5304 {
return get_priv()->member_types_changes_;}
5310 {
return get_priv()->data_members_changes_;}
5316 {
return get_priv()->data_members_changes_;}
5323 {
return get_priv()->inserted_data_members_;}
5330 {
return get_priv()->deleted_data_members_;}
5336 {
return get_priv()->member_fns_changes_;}
5345 {
return get_priv()->sorted_changed_member_functions_;}
5351 {
return get_priv()->member_fns_changes_;}
5356 {
return get_priv()->deleted_member_functions_;}
5361 {
return get_priv()->inserted_member_functions_;}
5379 {
return get_priv()->sorted_changed_dm_;}
5387 {
return get_priv()->count_filtered_changed_dm(local);}
5394 {
return get_priv()->sorted_subtype_changed_dm_;}
5401 {
return get_priv()->count_filtered_subtype_changed_dm(local);}
5413 {
return get_priv()->dms_replaced_by_adms_;}
5425 if (priv_->dms_replaced_by_adms_ordered_.empty())
5427 for (string_decl_base_sptr_map::const_iterator it =
5428 priv_->dms_replaced_by_adms_.begin();
5429 it != priv_->dms_replaced_by_adms_.end();
5436 priv_->dms_replaced_by_adms_ordered_.push_back(changed_dm);
5441 return priv_->dms_replaced_by_adms_ordered_;
5448 {
return get_priv()->member_fn_tmpls_changes_;}
5454 {
return get_priv()->member_fn_tmpls_changes_;}
5460 {
return get_priv()->member_class_tmpls_changes_;}
5466 {
return get_priv()->member_class_tmpls_changes_;}
5482 return ir::NO_CHANGE_KIND;
5495 context()->get_reporter()->report(*
this, out, indent);
5507 for (var_diff_sptrs_type::const_iterator i =
5508 get_priv()->sorted_subtype_changed_dm_.begin();
5509 i !=
get_priv()->sorted_subtype_changed_dm_.end();
5514 for (var_diff_sptrs_type::const_iterator i =
5515 get_priv()->sorted_changed_dm_.begin();
5516 i !=
get_priv()->sorted_changed_dm_.end();
5522 for (diff_sptrs_type::const_iterator i =
5523 get_priv()->sorted_changed_member_types_.begin();
5524 i !=
get_priv()->sorted_changed_member_types_.end();
5530 for (function_decl_diff_sptrs_type::const_iterator i =
5531 get_priv()->sorted_changed_member_functions_.begin();
5532 i !=
get_priv()->sorted_changed_member_functions_.end();
5547 class_diff::clear_lookup_tables(
void)
5549 priv_->deleted_bases_.clear();
5550 priv_->inserted_bases_.clear();
5551 priv_->changed_bases_.clear();
5558 class_diff::lookup_tables_empty(
void)
const
5560 return (priv_->deleted_bases_.empty()
5561 && priv_->inserted_bases_.empty()
5562 && priv_->changed_bases_.empty());
5572 static string_member_function_sptr_map::const_iterator
5575 for (string_member_function_sptr_map::const_iterator i = map.begin();
5589 class_diff::ensure_lookup_tables_populated(
void)
const
5593 if (!lookup_tables_empty())
5597 edit_script& e = get_priv()->base_changes_;
5599 for (vector<deletion>::const_iterator it = e.deletions().begin();
5600 it != e.deletions().end();
5603 unsigned i = it->index();
5606 string name = b->get_base_class()->get_qualified_name();
5607 ABG_ASSERT(get_priv()->deleted_bases_.find(name)
5608 == get_priv()->deleted_bases_.end());
5609 get_priv()->deleted_bases_[name] = b;
5612 for (vector<insertion>::const_iterator it = e.insertions().begin();
5613 it != e.insertions().end();
5616 for (vector<unsigned>::const_iterator iit =
5617 it->inserted_indexes().begin();
5618 iit != it->inserted_indexes().end();
5624 string name = b->get_base_class()->get_qualified_name();
5625 ABG_ASSERT(get_priv()->inserted_bases_.find(name)
5626 == get_priv()->inserted_bases_.end());
5627 string_base_sptr_map::const_iterator j =
5628 get_priv()->deleted_bases_.find(name);
5629 if (j != get_priv()->deleted_bases_.end())
5632 get_priv()->changed_bases_[name] =
5638 get_priv()->moved_bases_.push_back(b);
5639 get_priv()->deleted_bases_.erase(j);
5642 get_priv()->inserted_bases_[name] = b;
5648 get_priv()->sorted_deleted_bases_);
5650 get_priv()->sorted_inserted_bases_);
5652 get_priv()->sorted_changed_bases_);
5657 edit_script& e = p->member_fns_changes_;
5659 for (vector<deletion>::const_iterator it = e.deletions().begin();
5660 it != e.deletions().end();
5663 unsigned i = it->index();
5664 method_decl_sptr mem_fn =
5666 string name = mem_fn->get_linkage_name();
5668 name = mem_fn->get_pretty_representation();
5670 if (p->deleted_member_functions_.find(name)
5671 != p->deleted_member_functions_.end())
5673 p->deleted_member_functions_[name] = mem_fn;
5676 for (vector<insertion>::const_iterator it = e.insertions().begin();
5677 it != e.insertions().end();
5680 for (vector<unsigned>::const_iterator iit =
5681 it->inserted_indexes().begin();
5682 iit != it->inserted_indexes().end();
5687 method_decl_sptr mem_fn =
5689 string name = mem_fn->get_linkage_name();
5691 name = mem_fn->get_pretty_representation();
5693 if (p->inserted_member_functions_.find(name)
5694 != p->inserted_member_functions_.end())
5696 string_member_function_sptr_map::const_iterator j =
5697 p->deleted_member_functions_.find(name);
5699 if (j != p->deleted_member_functions_.end())
5701 if (*j->second != *mem_fn)
5702 p->changed_member_functions_[name] =
5703 compute_diff(static_pointer_cast<function_decl>(j->second),
5704 static_pointer_cast<function_decl>(mem_fn),
5706 p->deleted_member_functions_.erase(j);
5709 p->inserted_member_functions_[name] = mem_fn;
5756 vector<string> to_delete;
5757 corpus_sptr f =
context()->get_first_corpus(),
5758 s =
context()->get_second_corpus();
5760 for (string_member_function_sptr_map::const_iterator i =
5779 find_virtual_dtor_in_map(p->inserted_member_functions_);
5780 if (it != p->inserted_member_functions_.end())
5788 (!i->second->get_linkage_name().empty())
5789 ? i->second->get_linkage_name()
5790 : i->second->get_pretty_representation();
5791 to_delete.push_back(name);
5792 p->inserted_member_functions_.erase(it);
5799 if (!i->second->get_symbol()
5800 || s->lookup_function_symbol(*i->second->get_symbol()))
5801 to_delete.push_back(i->first);
5805 for (vector<string>::const_iterator i = to_delete.begin();
5806 i != to_delete.end();
5808 p->deleted_member_functions_.erase(*i);
5813 for (string_member_function_sptr_map::const_iterator i =
5822 if (!i->second->get_symbol()
5823 || f->lookup_function_symbol(*i->second->get_symbol()))
5824 to_delete.push_back(i->first);
5827 for (vector<string>::const_iterator i = to_delete.begin();
5828 i != to_delete.end();
5830 p->inserted_member_functions_.erase(*i);
5833 p->sorted_deleted_member_functions_);
5836 p->sorted_inserted_member_functions_);
5839 (p->changed_member_functions_,
5840 p->sorted_changed_member_functions_);
5847 class_diff::allocate_priv_data()
5851 priv_.reset(
new priv);
5864 string qname = d->get_base_class()->get_qualified_name();
5865 string_base_diff_sptr_map::const_iterator it =
5866 changed_bases_.find(qname);
5868 return (it == changed_bases_.end())
5870 : it->second->second_base();
5881 size_t num_filtered = 0;
5882 for (base_diff_sptrs_type::const_iterator i = sorted_changed_bases_.begin();
5883 i != sorted_changed_bases_.end();
5887 if (diff && diff->is_filtered_out())
5890 return num_filtered;
5904 for (base_diff_sptrs_type::const_iterator i =
5905 get_priv()->sorted_changed_bases_.begin();
5906 i != get_priv()->sorted_changed_bases_.end();
5931 class_diff::~class_diff()
5945 const class_diff::priv_ptr&
5946 class_diff::get_priv()
const
5958 return canonical->priv_;
5966 if (diff::priv_->pretty_representation_.empty())
5968 std::ostringstream o;
5974 diff::priv_->pretty_representation_ = o.str();
5976 return diff::priv_->pretty_representation_;
5995 return ir::NO_CHANGE_KIND;
5999 shared_ptr<class_decl>
6006 shared_ptr<class_decl>
6013 {
return get_priv()->base_changes_;}
6021 {
return get_priv()->deleted_bases_;}
6029 {
return get_priv()->inserted_bases_;}
6036 {
return get_priv()->sorted_changed_bases_;}
6044 const vector<class_decl::base_spec_sptr>&
6046 {
return get_priv()->moved_bases_;}
6051 {
return get_priv()->base_changes_;}
6062 context()->get_reporter()->report(*
this, out, indent);
6087 ctxt->initialize_canonical_diff(changes);
6090 if (!ctxt->get_canonical_diff_for(first, second))
6094 diff_sptr canonical_diff = ctxt->get_canonical_diff_for(changes);
6096 ctxt->set_canonical_diff_for(first, second, canonical_diff);
6112 if (
is_class_diff(changes->get_canonical_diff()) == changes.get())
6115 changes->allocate_priv_data();
6127 f->get_base_specifiers().end(),
6128 s->get_base_specifiers().begin(),
6129 s->get_base_specifiers().end(),
6130 changes->base_changes());
6136 f->get_member_types().end(),
6137 s->get_member_types().begin(),
6138 s->get_member_types().end(),
6139 changes->member_types_changes());
6144 f->get_non_static_data_members().end(),
6145 s->get_non_static_data_members().begin(),
6146 s->get_non_static_data_members().end(),
6147 changes->data_members_changes());
6151 f->get_virtual_mem_fns().end(),
6152 s->get_virtual_mem_fns().begin(),
6153 s->get_virtual_mem_fns().end(),
6154 changes->member_fns_changes());
6157 compute_diff(f->get_member_function_templates().begin(),
6158 f->get_member_function_templates().end(),
6159 s->get_member_function_templates().begin(),
6160 s->get_member_function_templates().end(),
6161 changes->member_fn_tmpls_changes());
6166 f->get_member_class_templates().end(),
6167 s->get_member_class_templates().begin(),
6168 s->get_member_class_templates().end(),
6169 changes->member_class_tmpls_changes());
6172 changes->ensure_lookup_tables_populated();
6202 :
diff(first, second, ctxt),
6203 priv_(new
priv(underlying))
6227 {
return priv_->underlying_class_diff_;}
6236 {priv_->underlying_class_diff_ = d;}
6243 if (diff::priv_->pretty_representation_.empty())
6245 std::ostringstream o;
6251 diff::priv_->pretty_representation_ = o.str();
6253 return diff::priv_->pretty_representation_;
6272 return ir::NO_CHANGE_KIND;
6283 context()->get_reporter()->report(*
this, out, indent);
6305 second->get_base_class(),
6309 ctxt->initialize_canonical_diff(changes);
6324 union_diff::clear_lookup_tables(
void)
6331 union_diff::lookup_tables_empty(
void)
const
6337 union_diff::ensure_lookup_tables_populated(
void)
const
6343 union_diff::allocate_priv_data()
6356 union_decl_sptr second_union,
6379 if (diff::priv_->pretty_representation_.empty())
6381 std::ostringstream o;
6387 diff::priv_->pretty_representation_ = o.str();
6389 return diff::priv_->pretty_representation_;
6401 context()->get_reporter()->report(*
this, out, indent);
6416 const union_decl_sptr second,
6419 union_diff_sptr changes(
new union_diff(first, second, ctxt));
6421 ctxt->initialize_canonical_diff(changes);
6437 if (
is_union_diff(changes->get_canonical_diff()) == changes.get())
6440 changes->allocate_priv_data();
6451 compute_diff(first->get_non_static_data_members().begin(),
6452 first->get_non_static_data_members().end(),
6453 second->get_non_static_data_members().begin(),
6454 second->get_non_static_data_members().end(),
6455 changes->data_members_changes());
6460 first->get_mem_fns().end(),
6461 second->get_mem_fns().begin(),
6462 second->get_mem_fns().end(),
6463 changes->member_fns_changes());
6466 compute_diff(first->get_member_function_templates().begin(),
6467 first->get_member_function_templates().end(),
6468 second->get_member_function_templates().begin(),
6469 second->get_member_function_templates().end(),
6470 changes->member_fn_tmpls_changes());
6473 changes->ensure_lookup_tables_populated();
6487 scope_diff::clear_lookup_tables()
6489 priv_->deleted_types_.clear();
6490 priv_->deleted_decls_.clear();
6491 priv_->inserted_types_.clear();
6492 priv_->inserted_decls_.clear();
6493 priv_->changed_types_.clear();
6494 priv_->changed_decls_.clear();
6495 priv_->removed_types_.clear();
6496 priv_->removed_decls_.clear();
6497 priv_->added_types_.clear();
6498 priv_->added_decls_.clear();
6508 scope_diff::lookup_tables_empty()
const
6510 return (priv_->deleted_types_.empty()
6511 && priv_->deleted_decls_.empty()
6512 && priv_->inserted_types_.empty()
6513 && priv_->inserted_decls_.empty()
6514 && priv_->changed_types_.empty()
6515 && priv_->changed_decls_.empty()
6516 && priv_->removed_types_.empty()
6517 && priv_->removed_decls_.empty()
6518 && priv_->added_types_.empty()
6519 && priv_->added_decls_.empty());
6525 scope_diff::ensure_lookup_tables_populated()
6527 if (!lookup_tables_empty())
6530 edit_script& e = priv_->member_changes_;
6533 for (
const auto& deletion : e.deletions())
6535 unsigned i = deletion.index();
6537 string qname = decl->get_qualified_name();
6541 if (klass_decl && klass_decl->get_is_declaration_only())
6552 == priv_->deleted_types_.end());
6553 priv_->deleted_types_[qname] = decl;
6558 == priv_->deleted_decls_.end());
6559 priv_->deleted_decls_[qname] = decl;
6565 for (vector<insertion>::const_iterator it = e.insertions().begin();
6566 it != e.insertions().end();
6569 for (vector<unsigned>::const_iterator i = it->inserted_indexes().begin();
6570 i != it->inserted_indexes().end();
6574 string qname = decl->get_qualified_name();
6578 dynamic_pointer_cast<class_decl>(decl);
6579 if (klass_decl && klass_decl->get_is_declaration_only())
6589 ABG_ASSERT(priv_->inserted_types_.find(qname)
6590 == priv_->inserted_types_.end());
6591 string_decl_base_sptr_map::const_iterator j =
6592 priv_->deleted_types_.find(qname);
6593 if (j != priv_->deleted_types_.end())
6595 if (*j->second != *decl)
6596 priv_->changed_types_[qname] =
6598 priv_->deleted_types_.erase(j);
6601 priv_->inserted_types_[qname] = decl;
6605 ABG_ASSERT(priv_->inserted_decls_.find(qname)
6606 == priv_->inserted_decls_.end());
6607 string_decl_base_sptr_map::const_iterator j =
6608 priv_->deleted_decls_.find(qname);
6609 if (j != priv_->deleted_decls_.end())
6611 if (*j->second != *decl)
6612 priv_->changed_decls_[qname] =
6614 priv_->deleted_decls_.erase(j);
6617 priv_->inserted_decls_[qname] = decl;
6623 priv_->sorted_changed_decls_);
6625 priv_->sorted_changed_types_);
6628 for (string_decl_base_sptr_map::const_iterator i =
6629 priv_->deleted_types_.begin();
6630 i != priv_->deleted_types_.end();
6633 string_decl_base_sptr_map::const_iterator r =
6634 priv_->inserted_types_.find(i->first);
6635 if (r == priv_->inserted_types_.end())
6636 priv_->removed_types_[i->first] = i->second;
6638 for (string_decl_base_sptr_map::const_iterator i =
6639 priv_->deleted_decls_.begin();
6640 i != priv_->deleted_decls_.end();
6643 string_decl_base_sptr_map::const_iterator r =
6644 priv_->inserted_decls_.find(i->first);
6645 if (r == priv_->inserted_decls_.end())
6646 priv_->removed_decls_[i->first] = i->second;
6650 for (string_decl_base_sptr_map::const_iterator i =
6651 priv_->inserted_types_.begin();
6652 i != priv_->inserted_types_.end();
6655 string_decl_base_sptr_map::const_iterator r =
6656 priv_->deleted_types_.find(i->first);
6657 if (r == priv_->deleted_types_.end())
6658 priv_->added_types_[i->first] = i->second;
6660 for (string_decl_base_sptr_map::const_iterator i =
6661 priv_->inserted_decls_.begin();
6662 i != priv_->inserted_decls_.end();
6665 string_decl_base_sptr_map::const_iterator r =
6666 priv_->deleted_decls_.find(i->first);
6667 if (r == priv_->deleted_decls_.end())
6668 priv_->added_decls_[i->first] = i->second;
6680 for (diff_sptrs_type::const_iterator i =
changed_types().begin();
6686 for (diff_sptrs_type::const_iterator i =
changed_decls().begin();
6706 :
diff(first_scope, second_scope, ctxt),
6744 {
return priv_->member_changes_;}
6766 {
return priv_->member_changes_;}
6777 const decl_base_sptr
6794 const decl_base_sptr
6808 const decl_base_sptr
6825 const decl_base_sptr
6833 {
return priv_->sorted_changed_types_;}
6839 {
return priv_->sorted_changed_decls_;}
6842 scope_diff::removed_types()
const
6843 {
return priv_->removed_types_;}
6846 scope_diff::removed_decls()
const
6847 {
return priv_->removed_decls_;}
6850 scope_diff::added_types()
const
6851 {
return priv_->added_types_;}
6854 scope_diff::added_decls()
const
6855 {
return priv_->added_decls_;}
6862 if (diff::priv_->pretty_representation_.empty())
6864 std::ostringstream o;
6870 diff::priv_->pretty_representation_ = o.str();
6872 return diff::priv_->pretty_representation_;
6894 return ir::NO_CHANGE_KIND;
6905 context()->get_reporter()->report(*
this, out, indent);
6931 ABG_ASSERT(d->first_scope() == first && d->second_scope() == second);
6934 first->get_member_decls().end(),
6935 second->get_member_decls().begin(),
6936 second->get_member_decls().end(),
6937 d->member_changes());
6939 d->ensure_lookup_tables_populated();
6965 ctxt->initialize_canonical_diff(d);
6989 ABG_ASSERT(first->get_index() == second->get_index());
7020 {
return priv_->type_diff;}
7030 if (diff::priv_->pretty_representation_.empty())
7032 std::ostringstream o;
7033 o <<
"function_parameter_diff["
7038 diff::priv_->pretty_representation_ = o.str();
7040 return diff::priv_->pretty_representation_;
7061 return ir::NO_CHANGE_KIND;
7072 context()->get_reporter()->report(*
this, out, indent);
7106 if (!first || !second)
7110 ctxt->initialize_canonical_diff(result);
7119 function_type_diff::ensure_lookup_tables_populated()
7121 priv_->return_type_diff_ =
7128 for (vector<deletion>::const_iterator i =
7129 priv_->parm_changes_.deletions().begin();
7130 i != priv_->parm_changes_.deletions().end();
7135 parm_name = parm->get_name_id();
7139 priv_->deleted_parms_[parm_name] = parm;
7140 priv_->deleted_parms_by_id_[parm->get_index()] = parm;
7143 for (vector<insertion>::const_iterator i =
7144 priv_->parm_changes_.insertions().begin();
7145 i != priv_->parm_changes_.insertions().end();
7148 for (vector<unsigned>::const_iterator j =
7149 i->inserted_indexes().begin();
7150 j != i->inserted_indexes().end();
7154 parm_name = parm->get_name_id();
7159 string_parm_map::const_iterator k =
7160 priv_->deleted_parms_.find(parm_name);
7161 if (k != priv_->deleted_parms_.end())
7163 if (*k->second != *parm)
7164 priv_->subtype_changed_parms_[parm_name] =
7166 priv_->deleted_parms_.erase(parm_name);
7169 priv_->added_parms_[parm_name] = parm;
7172 unsigned_parm_map::const_iterator k =
7173 priv_->deleted_parms_by_id_.find(parm->get_index());
7174 if (k != priv_->deleted_parms_by_id_.end())
7176 if (*k->second != *parm
7177 && (k->second->get_name_id() != parm_name))
7178 priv_->changed_parms_by_id_[parm->get_index()] =
7180 priv_->added_parms_.erase(parm_name);
7181 priv_->deleted_parms_.erase(k->second->get_name_id());
7182 priv_->deleted_parms_by_id_.erase(parm->get_index());
7185 priv_->added_parms_by_id_[parm->get_index()] = parm;
7191 priv_->sorted_subtype_changed_parms_);
7193 priv_->sorted_changed_parms_by_id_);
7195 priv_->sorted_deleted_parms_);
7198 priv_->sorted_added_parms_);
7208 function_type_diff::deleted_parameter_at(
int i)
const
7214 const vector<function_decl::parameter_sptr>&
7216 {
return priv_->sorted_deleted_parms_;}
7221 const vector<function_decl::parameter_sptr>&
7223 {
return priv_->sorted_added_parms_;}
7232 function_type_diff::inserted_parameter_at(
int i)
const
7276 {
return priv_->return_type_diff_;}
7283 {
return priv_->subtype_changed_parms_;}
7290 {
return priv_->deleted_parms_;}
7297 {
return priv_->added_parms_;}
7307 if (diff::priv_->pretty_representation_.empty())
7309 std::ostringstream o;
7310 o <<
"function_type_diff["
7315 diff::priv_->pretty_representation_ = o.str();
7317 return diff::priv_->pretty_representation_;
7341 return ir::NO_CHANGE_KIND;
7353 context()->get_reporter()->report(*
this, out, indent);
7367 for (vector<fn_parm_diff_sptr>::const_iterator i =
7368 priv_->sorted_subtype_changed_parms_.begin();
7369 i != priv_->sorted_subtype_changed_parms_.end();
7374 for (vector<fn_parm_diff_sptr>::const_iterator i =
7375 priv_->sorted_changed_parms_by_id_.begin();
7376 i != priv_->sorted_changed_parms_by_id_.end();
7399 if (!first || !second)
7408 first->get_parameters().end(),
7409 second->get_first_parm(),
7410 second->get_parameters().end(),
7411 result->priv_->parm_changes_);
7413 result->ensure_lookup_tables_populated();
7415 ctxt->initialize_canonical_diff(result);
7425 function_decl_diff::ensure_lookup_tables_populated()
7470 function_decl_diff::type_diff()
const
7471 {
return priv_->type_diff_;}
7478 if (diff::priv_->pretty_representation_.empty())
7480 std::ostringstream o;
7481 o <<
"function_diff["
7486 diff::priv_->pretty_representation_ = o.str();
7488 return diff::priv_->pretty_representation_;
7507 return ir::NO_CHANGE_KIND;
7519 context()->get_reporter()->report(*
this, out, indent);
7539 if (!first || !second)
7551 result->priv_->type_diff_ = type_diff;
7553 result->ensure_lookup_tables_populated();
7555 ctxt->initialize_canonical_diff(result);
7599 if (diff::priv_->pretty_representation_.empty())
7601 std::ostringstream o;
7602 o <<
"type_decl_diff["
7607 diff::priv_->pretty_representation_ = o.str();
7609 return diff::priv_->pretty_representation_;
7627 return ir::NO_CHANGE_KIND;
7638 context()->get_reporter()->report(*
this, out, indent);
7676 ctxt->initialize_canonical_diff(result);
7713 priv_(new
priv(underlying))
7737 {
return priv_->underlying_type_diff_;}
7746 {priv_->underlying_type_diff_ = d;}
7753 if (diff::priv_->pretty_representation_.empty())
7755 std::ostringstream o;
7756 o <<
"typedef_diff["
7761 diff::priv_->pretty_representation_ = o.str();
7763 return diff::priv_->pretty_representation_;
7785 return ir::NO_CHANGE_KIND;
7797 context()->get_reporter()->report(*
this, out, indent);
7817 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
7818 second->get_underlying_type(),
7822 ctxt->initialize_canonical_diff(result);
7874 priv_(new
priv(first, second))
7883 {
return priv_->first_;}
7890 {
return priv_->second_;}
7904 {
return ir::NO_CHANGE_KIND;}
7943 compute_diff(static_pointer_cast<scope_decl>(first->get_global_scope()),
7944 static_pointer_cast<scope_decl>(second->get_global_scope()),
7948 ctxt->initialize_canonical_diff(tu_diff);
7958 struct diff_maps::priv
7981 diff_maps::~diff_maps() =
default;
7988 {
return priv_->type_decl_diff_map_;}
7995 {
return priv_->type_decl_diff_map_;}
8002 {
return priv_->enum_diff_map_;}
8009 {
return priv_->enum_diff_map_;}
8016 {
return priv_->class_diff_map_;}
8023 {
return priv_->class_diff_map_;}
8030 {
return priv_->union_diff_map_;}
8037 {
return priv_->union_diff_map_;}
8044 {
return priv_->typedef_diff_map_;}
8051 {
return priv_->typedef_diff_map_;}
8058 {
return priv_->subrange_diff_map_;}
8065 {
return priv_->subrange_diff_map_;}
8072 {
return priv_->array_diff_map_;}
8079 {
return priv_->array_diff_map_;}
8086 {
return priv_->reference_diff_map_;}
8093 {{
return priv_->reference_diff_map_;}}
8100 {
return priv_->fn_parm_diff_map_;}
8107 {
return priv_->fn_parm_diff_map_;}
8114 {
return priv_->function_type_diff_map_;}
8121 {
return priv_->function_type_diff_map_;}
8128 {
return priv_->function_decl_diff_map_;}
8135 {
return priv_->function_decl_diff_map_;}
8142 {
return priv_->var_decl_diff_map_;}
8149 {
return priv_->var_decl_diff_map_;}
8156 {
return priv_->distinct_diff_map_;}
8163 {
return priv_->distinct_diff_map_;}
8221 diff_artifact_set_map_type::iterator i =
8222 priv_->impacted_artifacts_map_.find(dif);
8224 if (i == priv_->impacted_artifacts_map_.end())
8227 set.insert(impacted_iface);
8228 priv_->impacted_artifacts_map_[dif] = set;
8231 i->second.insert(impacted_iface);
8245 diff_artifact_set_map_type::iterator i =
8246 priv_->impacted_artifacts_map_.find(d);
8248 if (i == priv_->impacted_artifacts_map_.end())
8264 : priv_(new
priv(ctxt))
8272 {
return priv_->num_func_removed;}
8279 {priv_->num_func_removed = n;}
8289 if (priv_->ctxt() && !priv_->ctxt()->show_deleted_fns())
8290 return num_func_removed();
8291 return priv_->num_removed_func_filtered_out;
8300 {priv_->num_removed_func_filtered_out = t;}
8311 ABG_ASSERT(num_func_removed() >= num_removed_func_filtered_out());
8312 return num_func_removed() - num_removed_func_filtered_out();
8320 {
return priv_->num_func_added;}
8327 {priv_->num_func_added = n;}
8335 if (priv_->ctxt() && !priv_->ctxt()->show_added_fns())
8336 return num_func_added();
8337 return priv_->num_added_func_filtered_out;
8346 {priv_->num_added_func_filtered_out = n;}
8358 ABG_ASSERT(num_func_added() >= num_added_func_filtered_out());
8359 return num_func_added() - num_added_func_filtered_out();
8369 {
return priv_->num_func_changed;}
8378 {priv_->num_func_changed = n;}
8387 {
return priv_->num_changed_func_filtered_out;}
8396 {priv_->num_changed_func_filtered_out = n;}
8404 {
return priv_->num_func_with_virt_offset_changes;}
8413 {priv_->num_func_with_virt_offset_changes = n;}
8424 {
return num_func_changed() - num_changed_func_filtered_out();}
8431 {
return priv_->num_vars_removed;}
8438 {priv_->num_vars_removed = n;}
8447 if (priv_->ctxt() && !priv_->ctxt()->show_deleted_vars())
8448 return num_vars_removed();
8449 return priv_->num_removed_vars_filtered_out;
8458 {priv_->num_removed_vars_filtered_out = n;}
8470 ABG_ASSERT(num_vars_removed() >= num_removed_vars_filtered_out());
8471 return num_vars_removed() - num_removed_vars_filtered_out();
8479 {
return priv_->num_vars_added;}
8486 {priv_->num_vars_added = n;}
8495 if (priv_->ctxt() && !priv_->ctxt()->show_added_vars())
8496 return num_vars_added();
8497 return priv_->num_added_vars_filtered_out;
8506 {priv_->num_added_vars_filtered_out = n;}
8518 ABG_ASSERT(num_vars_added() >= num_added_vars_filtered_out());
8519 return num_vars_added() - num_added_vars_filtered_out();
8529 {
return priv_->num_vars_changed;}
8538 {priv_->num_vars_changed = n;}
8547 {
return priv_->num_changed_vars_filtered_out;}
8556 {priv_->num_changed_vars_filtered_out = n;}
8567 {
return num_vars_changed() - num_changed_vars_filtered_out();}
8576 {
return priv_->num_func_syms_removed;}
8585 {priv_->num_func_syms_removed = n;}
8596 && !priv_->ctxt()->show_symbols_unreferenced_by_debug_info())
8597 return num_func_syms_removed();
8598 return priv_->num_removed_func_syms_filtered_out;
8608 {priv_->num_removed_func_syms_filtered_out = n;}
8623 ABG_ASSERT(num_func_syms_removed() >= num_removed_func_syms_filtered_out());
8624 return num_func_syms_removed() - num_removed_func_syms_filtered_out();
8634 {
return priv_->num_func_syms_added;}
8643 {priv_->num_func_syms_added = n;}
8654 && !(priv_->ctxt()->show_added_symbols_unreferenced_by_debug_info()
8655 && priv_->ctxt()->show_symbols_unreferenced_by_debug_info()))
8656 return num_func_syms_added();
8657 return priv_->num_added_func_syms_filtered_out;
8667 {priv_->num_added_func_syms_filtered_out = n;}
8682 ABG_ASSERT(num_func_syms_added() >= num_added_func_syms_filtered_out());
8683 return num_func_syms_added()- num_added_func_syms_filtered_out();
8693 {
return priv_->num_var_syms_removed;}
8702 {priv_->num_var_syms_removed = n;}
8713 && !priv_->ctxt()->show_symbols_unreferenced_by_debug_info())
8714 return num_var_syms_removed();
8715 return priv_->num_removed_var_syms_filtered_out;
8725 {priv_->num_removed_var_syms_filtered_out = n;}
8740 ABG_ASSERT(num_var_syms_removed() >= num_removed_var_syms_filtered_out());
8741 return num_var_syms_removed() - num_removed_var_syms_filtered_out();
8751 {
return priv_->num_var_syms_added;}
8760 {priv_->num_var_syms_added = n;}
8771 && !(priv_->ctxt()->show_added_symbols_unreferenced_by_debug_info()
8772 && priv_->ctxt()->show_symbols_unreferenced_by_debug_info()))
8773 return num_var_syms_added();
8774 return priv_->num_added_var_syms_filtered_out;
8784 {priv_->num_added_var_syms_filtered_out = n;}
8799 ABG_ASSERT(num_var_syms_added() >= num_added_var_syms_filtered_out());
8800 return num_var_syms_added() - num_added_var_syms_filtered_out();
8808 {
return priv_->num_leaf_changes;}
8815 {priv_->num_leaf_changes = n;}
8823 {
return priv_->num_leaf_changes_filtered_out;}
8832 {priv_->num_leaf_changes_filtered_out = n;}
8845 ABG_ASSERT(num_leaf_changes() >= num_leaf_changes_filtered_out());
8846 return num_leaf_changes() - num_leaf_changes_filtered_out();
8854 {
return priv_->num_leaf_type_changes;}
8861 {priv_->num_leaf_type_changes = n;}
8868 {
return priv_->num_leaf_type_changes_filtered_out;}
8874 {priv_->num_leaf_type_changes_filtered_out = n;}
8884 {
return num_leaf_type_changes() - num_leaf_type_changes_filtered_out();}
8891 {
return priv_->num_leaf_func_changes;}
8898 {priv_->num_leaf_func_changes = n;}
8907 {
return priv_->num_leaf_func_changes_filtered_out;}
8916 {priv_->num_leaf_func_changes_filtered_out = n;}
8927 {
return num_leaf_func_changes() - num_leaf_func_changes_filtered_out();}
8934 {
return priv_->num_leaf_var_changes;}
8941 {priv_->num_leaf_var_changes = n;}
8953 {
return priv_->num_added_unreachable_types;}
8966 {priv_->num_added_unreachable_types = n;}
8977 {
return priv_->num_added_unreachable_types_filtered_out;}
8988 {priv_->num_added_unreachable_types_filtered_out = n;}
9002 num_added_unreachable_types_filtered_out());
9004 return (num_added_unreachable_types()
9006 num_added_unreachable_types_filtered_out());
9019 {
return priv_->num_removed_unreachable_types;}
9031 {priv_->num_removed_unreachable_types = n;}
9042 {
return priv_->num_removed_unreachable_types_filtered_out;}
9053 {priv_->num_removed_unreachable_types_filtered_out = n;}
9067 num_removed_unreachable_types_filtered_out());
9069 return (num_removed_unreachable_types()
9071 num_removed_unreachable_types_filtered_out());
9084 {
return priv_->num_changed_unreachable_types;}
9096 {priv_->num_changed_unreachable_types = n;}
9107 {
return priv_->num_changed_unreachable_types_filtered_out;}
9118 {priv_->num_changed_unreachable_types_filtered_out = n;}
9132 num_changed_unreachable_types_filtered_out());
9134 return (num_changed_unreachable_types()
9136 num_changed_unreachable_types_filtered_out());
9146 {
return priv_->num_leaf_var_changes_filtered_out;}
9155 {priv_->num_leaf_var_changes_filtered_out = n;}
9166 {
return num_leaf_var_changes() - num_leaf_var_changes_filtered_out();}
9176 {
return ctxt_.lock();}
9184 return (deleted_fns_.empty()
9185 && added_fns_.empty()
9186 && changed_fns_map_.empty()
9187 && deleted_vars_.empty()
9188 && added_vars_.empty()
9189 && changed_vars_map_.empty());
9196 deleted_fns_.clear();
9198 changed_fns_map_.clear();
9199 deleted_vars_.clear();
9200 added_vars_.clear();
9201 changed_vars_map_.clear();
9209 if (!lookup_tables_empty())
9215 edit_script& e = fns_edit_script_;
9217 for (vector<deletion>::const_iterator it = e.deletions().begin();
9218 it != e.deletions().end();
9221 unsigned i = it->index();
9222 ABG_ASSERT(i < first_->get_functions().size());
9231 deleted_fns_[n] = deleted_fn;
9234 for (vector<insertion>::const_iterator it = e.insertions().begin();
9235 it != e.insertions().end();
9238 for (vector<unsigned>::const_iterator iit =
9239 it->inserted_indexes().begin();
9240 iit != it->inserted_indexes().end();
9251 string_function_ptr_map::const_iterator j =
9252 deleted_fns_.find(n);
9253 if (j != deleted_fns_.end())
9258 if (*j->second != *added_fn)
9259 changed_fns_map_[j->first] = d;
9260 deleted_fns_.erase(j);
9263 added_fns_[n] = added_fn;
9272 vector<string> to_delete;
9273 for (string_function_ptr_map::const_iterator i = deleted_fns_.begin();
9274 i != deleted_fns_.end();
9276 if (second_->lookup_function_symbol(*i->second->get_symbol()))
9277 to_delete.push_back(i->first);
9279 for (vector<string>::const_iterator i = to_delete.begin();
9280 i != to_delete.end();
9282 deleted_fns_.erase(*i);
9287 for (string_function_ptr_map::const_iterator i = added_fns_.begin();
9288 i != added_fns_.end();
9291 if (first_->lookup_function_symbol(*i->second->get_symbol()))
9292 to_delete.push_back(i->first);
9293 else if (! i->second->get_symbol()->get_version().is_empty()
9294 && i->second->get_symbol()->get_version().is_default())
9302 if (first_->lookup_function_symbol(i->second->get_symbol()->get_name(),
9304 to_delete.push_back(i->first);
9308 for (vector<string>::const_iterator i = to_delete.begin();
9309 i != to_delete.end();
9311 added_fns_.erase(*i);
9315 edit_script& e = vars_edit_script_;
9317 for (vector<deletion>::const_iterator it = e.deletions().begin();
9318 it != e.deletions().end();
9321 unsigned i = it->index();
9322 ABG_ASSERT(i < first_->get_variables().size());
9324 var_decl* deleted_var = first_->get_variables()[i];
9325 string n = deleted_var->
get_id();
9327 ABG_ASSERT(deleted_vars_.find(n) == deleted_vars_.end());
9328 deleted_vars_[n] = deleted_var;
9331 for (vector<insertion>::const_iterator it = e.insertions().begin();
9332 it != e.insertions().end();
9335 for (vector<unsigned>::const_iterator iit =
9336 it->inserted_indexes().begin();
9337 iit != it->inserted_indexes().end();
9341 var_decl* added_var = second_->get_variables()[i];
9342 string n = added_var->
get_id();
9345 string_var_ptr_map::const_iterator k = added_vars_.find(n);
9346 if ( k != added_vars_.end())
9353 string_var_ptr_map::const_iterator j =
9354 deleted_vars_.find(n);
9355 if (j != deleted_vars_.end())
9357 if (*j->second != *added_var)
9363 deleted_vars_.erase(j);
9366 added_vars_[n] = added_var;
9370 sorted_changed_vars_);
9376 vector<string> to_delete;
9377 for (string_var_ptr_map::const_iterator i = deleted_vars_.begin();
9378 i != deleted_vars_.end();
9380 if (second_->lookup_variable_symbol(*i->second->get_symbol()))
9381 to_delete.push_back(i->first);
9383 for (vector<string>::const_iterator i = to_delete.begin();
9384 i != to_delete.end();
9386 deleted_vars_.erase(*i);
9391 for (string_var_ptr_map::const_iterator i = added_vars_.begin();
9392 i != added_vars_.end();
9394 if (first_->lookup_variable_symbol(*i->second->get_symbol()))
9395 to_delete.push_back(i->first);
9396 else if (! i->second->get_symbol()->get_version().is_empty()
9397 && i->second->get_symbol()->get_version().is_default())
9405 if (first_->lookup_variable_symbol(i->second->get_symbol()->get_name(),
9407 to_delete.push_back(i->first);
9410 for (vector<string>::const_iterator i = to_delete.begin();
9411 i != to_delete.end();
9413 added_vars_.erase(*i);
9420 edit_script& e = unrefed_fn_syms_edit_script_;
9421 for (vector<deletion>::const_iterator it = e.deletions().begin();
9422 it != e.deletions().end();
9425 unsigned i = it->index();
9426 ABG_ASSERT(i < first_->get_unreferenced_function_symbols().size());
9428 first_->get_unreferenced_function_symbols()[i];
9429 if (!second_->lookup_function_symbol(*deleted_sym))
9430 deleted_unrefed_fn_syms_[deleted_sym->get_id_string()] = deleted_sym;
9433 for (vector<insertion>::const_iterator it = e.insertions().begin();
9434 it != e.insertions().end();
9437 for (vector<unsigned>::const_iterator iit =
9438 it->inserted_indexes().begin();
9439 iit != it->inserted_indexes().end();
9443 ABG_ASSERT(i < second_->get_unreferenced_function_symbols().size());
9445 second_->get_unreferenced_function_symbols()[i];
9446 if ((deleted_unrefed_fn_syms_.find(added_sym->get_id_string())
9447 == deleted_unrefed_fn_syms_.end()))
9449 if (!first_->lookup_function_symbol(*added_sym))
9452 if (! added_sym->get_version().is_empty()
9453 && added_sym->get_version().is_default())
9461 if (first_->lookup_function_symbol(added_sym->get_name(),
9467 added_unrefed_fn_syms_[added_sym->get_id_string()] =
9472 deleted_unrefed_fn_syms_.erase(added_sym->get_id_string());
9481 edit_script& e = unrefed_var_syms_edit_script_;
9482 for (vector<deletion>::const_iterator it = e.deletions().begin();
9483 it != e.deletions().end();
9486 unsigned i = it->index();
9487 ABG_ASSERT(i < first_->get_unreferenced_variable_symbols().size());
9489 first_->get_unreferenced_variable_symbols()[i];
9490 if (!second_->lookup_variable_symbol(*deleted_sym))
9491 deleted_unrefed_var_syms_[deleted_sym->get_id_string()] = deleted_sym;
9494 for (vector<insertion>::const_iterator it = e.insertions().begin();
9495 it != e.insertions().end();
9498 for (vector<unsigned>::const_iterator iit =
9499 it->inserted_indexes().begin();
9500 iit != it->inserted_indexes().end();
9504 ABG_ASSERT(i < second_->get_unreferenced_variable_symbols().size());
9506 second_->get_unreferenced_variable_symbols()[i];
9507 if (deleted_unrefed_var_syms_.find(added_sym->get_id_string())
9508 == deleted_unrefed_var_syms_.end())
9510 if (!first_->lookup_variable_symbol(*added_sym))
9513 if (! added_sym->get_version().is_empty()
9514 && added_sym->get_version().is_default())
9522 if (first_->lookup_variable_symbol(added_sym->get_name(),
9528 added_unrefed_var_syms_[added_sym->get_id_string()] =
9533 deleted_unrefed_var_syms_.erase(added_sym->get_id_string());
9540 edit_script& e = unreachable_types_edit_script_;
9544 for (vector<deletion>::const_iterator it = e.deletions().begin();
9545 it != e.deletions().end();
9548 unsigned i = it->index();
9550 (first_->get_types_not_reachable_from_public_interfaces()[i]);
9557 deleted_unreachable_types_[repr] = t;
9562 for (vector<insertion>::const_iterator it = e.insertions().begin();
9563 it != e.insertions().end();
9566 for (vector<unsigned>::const_iterator iit =
9567 it->inserted_indexes().begin();
9568 iit != it->inserted_indexes().end();
9573 (second_->get_types_not_reachable_from_public_interfaces()[i]);
9592 string_type_base_sptr_map::const_iterator j =
9593 deleted_unreachable_types_.find(repr);
9594 if (j != deleted_unreachable_types_.end())
9599 decl_base_sptr old_type =
is_decl(j->second);
9600 decl_base_sptr new_type =
is_decl(t);
9601 if (old_type != new_type)
9609 changed_unreachable_types_[repr]= d;
9615 deleted_unreachable_types_.erase(j);
9620 added_unreachable_types_[repr] = t;
9633 std::set<type_base_sptr> deleted_anon_types;
9634 std::set<type_base_sptr> added_anon_types;
9636 for (
auto entry : deleted_unreachable_types_)
9642 deleted_anon_types.insert(entry.second);
9646 for (
auto entry : added_unreachable_types_)
9651 added_anon_types.insert(entry.second);
9656 class_or_union_sptr deleted_class;
9661 for (
auto deleted: deleted_anon_types)
9670 for (
auto enr : deleted_enum->get_enumerators())
9672 bool this_enum_got_changed =
false;
9673 for (
auto t : added_anon_types)
9690 changed_unreachable_types_[repr]= d;
9691 this_enum_got_changed =
true;
9698 removed_anon_types_to_erase[r1] = deleted_enum;
9699 added_anon_types_to_erase[r2] = added_enum;
9703 if (this_enum_got_changed)
9707 else if (deleted_class)
9712 for (
auto dm : deleted_class->get_data_members())
9714 bool this_class_got_changed =
false;
9715 for (
auto klass : added_anon_types)
9717 if (class_or_union_sptr added_class =
9736 changed_unreachable_types_[repr]= d;
9737 this_class_got_changed =
true;
9744 removed_anon_types_to_erase[r1] = deleted_class;
9745 added_anon_types_to_erase[r2] = added_class;
9749 if (this_class_got_changed)
9758 for (
auto entry : added_anon_types_to_erase)
9759 added_unreachable_types_.erase(entry.first);
9761 for (
auto entry : removed_anon_types_to_erase)
9762 deleted_unreachable_types_.erase(entry.first);
9791 return fn_suppr->suppresses_function(fn, k, ctxt);
9810 variable_is_suppressed(
const var_decl* var,
9818 return var_suppr->suppresses_variable(var, k, ctxt);
9830 for (suppressions_type::const_iterator i = suppressions.begin();
9831 i != suppressions.end();
9838 for (string_function_ptr_map::const_iterator e = added_fns_.begin();
9839 e != added_fns_.end();
9841 if (function_is_suppressed(e->second, fn_suppr,
9844 suppressed_added_fns_[e->first] = e->second;
9847 for (string_function_ptr_map::const_iterator e = deleted_fns_.begin();
9848 e != deleted_fns_.end();
9850 if (function_is_suppressed(e->second, fn_suppr,
9853 suppressed_deleted_fns_[e->first] = e->second;
9856 for (string_elf_symbol_map::const_iterator e =
9857 added_unrefed_fn_syms_.begin();
9858 e != added_unrefed_fn_syms_.end();
9860 if (fn_suppr->suppresses_function_symbol(e->second,
9863 suppressed_added_unrefed_fn_syms_[e->first] = e->second;
9866 for (string_elf_symbol_map::const_iterator e =
9867 deleted_unrefed_fn_syms_.begin();
9868 e != deleted_unrefed_fn_syms_.end();
9870 if (fn_suppr->suppresses_function_symbol(e->second,
9873 suppressed_deleted_unrefed_fn_syms_[e->first] = e->second;
9881 for (string_function_ptr_map::const_iterator e = added_fns_.begin();
9882 e != added_fns_.end();
9891 if (type_suppr->suppresses_type(c, ctxt))
9892 suppressed_added_fns_[e->first] = e->second;
9895 for (string_function_ptr_map::const_iterator e = deleted_fns_.begin();
9896 e != deleted_fns_.end();
9905 if (type_suppr->suppresses_type(c, ctxt))
9906 suppressed_deleted_fns_[e->first] = e->second;
9911 for (string_type_base_sptr_map::const_iterator e =
9912 deleted_unreachable_types_.begin();
9913 e != deleted_unreachable_types_.end();
9915 if (type_suppr->suppresses_type(e->second, ctxt))
9916 suppressed_deleted_unreachable_types_[e->first] = e->second;
9920 for (string_type_base_sptr_map::const_iterator e =
9921 added_unreachable_types_.begin();
9922 e != added_unreachable_types_.end();
9924 if (type_suppr->suppresses_type(e->second, ctxt))
9925 suppressed_added_unreachable_types_[e->first] = e->second;
9932 for (string_var_ptr_map::const_iterator e = added_vars_.begin();
9933 e != added_vars_.end();
9935 if (variable_is_suppressed(e->second, var_suppr,
9938 suppressed_added_vars_[e->first] = e->second;
9941 for (string_var_ptr_map::const_iterator e = deleted_vars_.begin();
9942 e != deleted_vars_.end();
9944 if (variable_is_suppressed(e->second, var_suppr,
9947 suppressed_deleted_vars_[e->first] = e->second;
9950 for (string_elf_symbol_map::const_iterator e =
9951 added_unrefed_var_syms_.begin();
9952 e != added_unrefed_var_syms_.end();
9954 if (var_suppr->suppresses_variable_symbol(e->second,
9957 suppressed_added_unrefed_var_syms_[e->first] = e->second;
9960 for (string_elf_symbol_map::const_iterator e =
9961 deleted_unrefed_var_syms_.begin();
9962 e != deleted_unrefed_var_syms_.end();
9964 if (var_suppr->suppresses_variable_symbol(e->second,
9967 suppressed_deleted_unrefed_var_syms_[e->first] = e->second;
9985 string_function_ptr_map::const_iterator i =
9986 suppressed_deleted_fns_.find(fn->
get_id());
9988 return (i != suppressed_deleted_fns_.end());
10005 string_type_base_sptr_map::const_iterator i =
10006 suppressed_added_unreachable_types_.find(repr);
10007 if (i == suppressed_added_unreachable_types_.end())
10027 string_type_base_sptr_map::const_iterator i =
10028 suppressed_deleted_unreachable_types_.find(repr);
10029 if (i == suppressed_deleted_unreachable_types_.end())
10048 string_function_ptr_map::const_iterator i =
10049 suppressed_added_fns_.find(fn->
get_id());
10051 return (i != suppressed_added_fns_.end());
10067 string_var_ptr_map::const_iterator i =
10068 suppressed_deleted_vars_.find(var->
get_id());
10070 return (i != suppressed_deleted_vars_.end());
10086 string_var_ptr_map::const_iterator i =
10087 suppressed_added_vars_.find(var->
get_id());
10089 return (i != suppressed_added_vars_.end());
10105 string_elf_symbol_map::const_iterator i =
10106 suppressed_deleted_unrefed_fn_syms_.find(s->
get_id_string());
10108 return (i != suppressed_deleted_unrefed_fn_syms_.end());
10124 string_elf_symbol_map::const_iterator i =
10125 suppressed_added_unrefed_fn_syms_.find(s->
get_id_string());
10127 return (i != suppressed_added_unrefed_fn_syms_.end());
10143 string_elf_symbol_map::const_iterator i =
10144 suppressed_deleted_unrefed_var_syms_.find(s->
get_id_string());
10146 return (i != suppressed_deleted_unrefed_var_syms_.end());
10162 string_elf_symbol_map::const_iterator i =
10163 suppressed_added_unrefed_var_syms_.find(s->
get_id_string());
10165 return (i != suppressed_added_unrefed_var_syms_.end());
10168 #ifdef do_count_diff_map_changes
10169 #undef do_count_diff_map_changes
10171 #define do_count_diff_map_changes(diff_map, n_changes, n_filtered) \
10173 string_diff_ptr_map::const_iterator i; \
10174 for (i = diff_map.begin(); \
10175 i != diff_map.end(); \
10178 if (const var_diff* d = is_var_diff(i->second)) \
10179 if (is_data_member(d->first_var())) \
10182 if (i->second->has_local_changes()) \
10184 if (!i->second->get_canonical_diff()->to_be_reported()) \
10200 count_leaf_type_changes(num_changes, num_filtered);
10203 do_count_diff_map_changes(leaf_diffs_.get_function_decl_diff_map(),
10204 num_changes, num_filtered);
10205 do_count_diff_map_changes(leaf_diffs_.get_var_decl_diff_map(),
10206 num_changes, num_filtered);
10219 size_t &num_filtered)
10221 do_count_diff_map_changes(leaf_diffs_.get_type_decl_diff_map(),
10222 num_changes, num_filtered);
10223 do_count_diff_map_changes(leaf_diffs_.get_enum_diff_map(),
10224 num_changes, num_filtered);
10225 do_count_diff_map_changes(leaf_diffs_.get_class_diff_map(),
10226 num_changes, num_filtered);
10227 do_count_diff_map_changes(leaf_diffs_.get_union_diff_map(),
10228 num_changes, num_filtered);
10229 do_count_diff_map_changes(leaf_diffs_.get_typedef_diff_map(),
10230 num_changes, num_filtered);
10231 do_count_diff_map_changes(leaf_diffs_.get_subrange_diff_map(),
10232 num_changes, num_filtered);
10233 do_count_diff_map_changes(leaf_diffs_.get_array_diff_map(),
10234 num_changes, num_filtered);
10235 do_count_diff_map_changes(leaf_diffs_.get_distinct_diff_map(),
10236 num_changes, num_filtered);
10237 do_count_diff_map_changes(leaf_diffs_.get_fn_parm_diff_map(),
10238 num_changes, num_filtered);
10266 size_t &num_deleted,
10267 size_t &num_changed,
10268 size_t &num_filtered_added,
10269 size_t &num_filtered_deleted,
10270 size_t &num_filtered_changed)
10272 num_added = added_unreachable_types_.size();
10273 num_deleted = deleted_unreachable_types_.size();
10274 num_changed = changed_unreachable_types_.size();
10275 num_filtered_added = suppressed_added_unreachable_types_.size();
10276 num_filtered_deleted = suppressed_deleted_unreachable_types_.size();
10278 for (vector<diff_sptr>::const_iterator i =
10282 if (!(*i)->to_be_reported())
10283 ++num_filtered_changed;
10292 {
return changed_unreachable_types_;}
10303 const vector<diff_sptr>&
10306 if (changed_unreachable_types_sorted_.empty())
10307 if (!changed_unreachable_types_.empty())
10309 changed_unreachable_types_sorted_);
10311 return changed_unreachable_types_sorted_;
10346 if (ctxt->perform_change_categorization())
10348 if (get_context()->do_log())
10350 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10351 <<
"applying filters to "
10352 << changed_fns_.size()
10353 <<
" changed fns ...\n";
10359 for (function_decl_diff_sptrs_type::const_iterator i =
10360 changed_fns_.begin();
10361 i != changed_fns_.end();
10365 ctxt->maybe_apply_filters(diff);
10368 if (get_context()->
do_log())
10371 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10372 <<
"filters to changed fn applied!:" << t <<
"\n";
10374 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10375 <<
"applying filters to "
10376 << sorted_changed_vars_.size()
10377 <<
" changed vars ...\n";
10383 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
10384 i != sorted_changed_vars_.end();
10388 ctxt->maybe_apply_filters(diff);
10391 if (get_context()->
do_log())
10394 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10395 <<
"filters to changed vars applied!:" << t <<
"\n";
10397 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10398 <<
"applying filters to unreachable types ...\n";
10405 ctxt->maybe_apply_filters(diff);
10408 ctxt->maybe_apply_filters(entry.second);
10410 if (get_context()->
do_log())
10413 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10414 <<
"filters to unreachable types applied!:" << t <<
"\n";
10416 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10417 <<
"categorizing redundant changed sub nodes ...\n";
10421 categorize_redundant_changed_sub_nodes();
10423 if (get_context()->
do_log())
10426 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10427 <<
"redundant changed sub nodes categorized!:" << t <<
"\n";
10429 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10430 <<
"count changed fns ...\n";
10438 for (function_decl_diff_sptrs_type::const_iterator i =
10439 changed_fns_.begin();
10440 i != changed_fns_.end();
10443 if ((*i)->is_filtered_out())
10448 if ((*i)->has_local_changes())
10459 if ((*i)->has_local_changes())
10464 if (get_context()->do_log())
10467 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10468 <<
"changed fn counted!:" << t <<
"\n";
10470 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10471 <<
"count changed vars ...\n";
10477 for (var_diff_sptrs_type ::const_iterator i = sorted_changed_vars_.begin();
10478 i != sorted_changed_vars_.end();
10481 if ((*i)->is_filtered_out())
10486 if ((*i)->has_local_changes())
10490 if ((*i)->has_local_changes())
10495 if (get_context()->do_log())
10498 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10499 <<
"changed vars counted!:" << t <<
"\n";
10501 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10502 <<
"count leaf changed types ...\n";
10517 size_t num_type_changes = 0, num_type_filtered = 0;
10518 count_leaf_type_changes(num_type_changes, num_type_filtered);
10524 if (get_context()->
do_log())
10527 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10528 <<
"changed leaf types counted!:" << t <<
"\n";
10530 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10531 <<
"count leaf changed artefacts ...\n";
10537 size_t num_changes = 0, num_filtered = 0;
10538 count_leaf_changes(num_changes, num_filtered);
10544 if (get_context()->
do_log())
10547 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10548 <<
"changed leaf artefacts counted!:" << t <<
"\n";
10550 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10551 <<
"count unreachable types ...\n";
10557 size_t num_added_unreachable_types = 0,
10558 num_changed_unreachable_types = 0,
10559 num_deleted_unreachable_types = 0,
10560 num_added_unreachable_types_filtered = 0,
10561 num_changed_unreachable_types_filtered = 0,
10562 num_deleted_unreachable_types_filtered = 0;
10564 count_unreachable_types(num_added_unreachable_types,
10565 num_deleted_unreachable_types,
10566 num_changed_unreachable_types,
10567 num_added_unreachable_types_filtered,
10568 num_deleted_unreachable_types_filtered,
10569 num_changed_unreachable_types_filtered);
10571 if (get_context()->
do_log())
10574 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10575 <<
"unreachable types counted!:" << t <<
"\n";
10582 (num_added_unreachable_types_filtered);
10584 (num_deleted_unreachable_types_filtered);
10586 (num_changed_unreachable_types_filtered);
10602 const string& indent)
10605 size_t net_num_leaf_changes =
10618 if (!sonames_equal_)
10619 out << indent <<
"ELF SONAME changed\n";
10621 if (!architectures_equal_)
10622 out << indent <<
"ELF architecture changed\n";
10626 if (ctxt->show_leaf_changes_only())
10628 out <<
"Leaf changes summary: ";
10629 out << net_num_leaf_changes <<
" artifact";
10630 if (net_num_leaf_changes > 1)
10635 out <<
" (" << num_filtered <<
" filtered out)";
10638 out << indent <<
"Changed leaf types summary: "
10642 <<
" filtered out)";
10643 out <<
" leaf type";
10646 out <<
" changed\n";
10649 out << indent <<
"Removed/Changed/Added functions summary: ";
10654 <<
" filtered out)";
10661 <<
" filtered out)";
10668 out <<
"functions";
10674 out << indent <<
"Removed/Changed/Added variables summary: ";
10678 <<
" filtered out)";
10685 <<
" filtered out)";
10692 out <<
"variables";
10695 <<
" filtered out)";
10704 out << indent <<
"Functions changes summary: ";
10709 <<
" filtered out)";
10720 if (total_nb_function_changes <= 1)
10721 out <<
" function";
10723 out <<
" functions";
10730 out << indent <<
"Variables changes summary: ";
10734 <<
" filtered out)";
10745 <<
" filtered out)";
10746 if (total_nb_variable_changes <= 1)
10747 out <<
" variable";
10749 out <<
" variables";
10755 if (ctxt->show_unreachable_types())
10757 size_t total_nb_unreachable_type_changes =
10763 out << indent <<
"Unreachable types summary: "
10768 <<
" filtered out)";
10775 <<
" filtered out)";
10782 <<
" filtered out)";
10783 if (total_nb_unreachable_type_changes <= 1)
10790 if (ctxt->show_symbols_unreferenced_by_debug_info()
10798 if (!ctxt->show_added_symbols_unreferenced_by_debug_info()
10808 <<
"Function symbols changes summary: "
10812 <<
" filtered out)";
10817 <<
" filtered out)";
10818 out <<
" function symbol";
10821 out <<
" not referenced by debug info\n";
10826 if (!ctxt->show_added_symbols_unreferenced_by_debug_info()
10836 <<
"Variable symbols changes summary: "
10840 <<
" filtered out)";
10845 <<
" filtered out)";
10846 out <<
" variable symbol";
10849 out <<
" not referenced by debug info\n";
10863 ctxt->forget_visited_diffs();
10864 for (function_decl_diff_sptrs_type::const_iterator i =
10865 changed_fns_.begin();
10866 i!= changed_fns_.end();
10873 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
10874 i!= sorted_changed_vars_.end();
10881 for (diff_sptrs_type::const_iterator i =
10897 for (function_decl_diff_sptrs_type::const_iterator i = changed_fns_.begin();
10898 i!= changed_fns_.end();
10905 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
10906 i!= sorted_changed_vars_.end();
10924 if (!ctxt->dump_diff_tree()
10925 || ctxt->error_output_stream() == 0)
10928 if (!changed_fns_.empty())
10930 *ctxt->error_output_stream() <<
"changed functions diff tree: \n\n";
10931 for (function_decl_diff_sptrs_type::const_iterator i =
10932 changed_fns_.begin();
10933 i != changed_fns_.end();
10941 if (!sorted_changed_vars_.empty())
10943 *ctxt->error_output_stream() <<
"\nchanged variables diff tree: \n\n";
10944 for (var_diff_sptrs_type::const_iterator i =
10945 sorted_changed_vars_.begin();
10946 i != sorted_changed_vars_.end();
10956 *ctxt->error_output_stream() <<
"\nchanged unreachable "
10957 "types diff tree: \n\n";
10958 for (vector<diff_sptr>::const_iterator i =
10976 for (function_decl_diff_sptrs_type::const_iterator i =
10995 corpus_sptr second,
10997 : priv_(new
priv(first, second, ctxt))
11000 corpus_diff::~corpus_diff() =
default;
11006 if (priv_->finished_)
11009 priv_->finished_ =
true;
11017 {
return context()->do_log();}
11029 {
return priv_->first_;}
11034 {
return priv_->second_;}
11037 const vector<diff*>&
11039 {
return priv_->children_;}
11057 bool inserted =
false;
11058 for (vector<diff*>::iterator i = priv_->children_.begin();
11059 i != priv_->children_.end();
11062 if (!is_less_than(d.get(), *i))
11064 context()->keep_diff_alive(d);
11065 priv_->children_.insert(i, d.get());
11074 context()->keep_diff_alive(d);
11078 priv_->children_.push_back(d.get());
11086 {
return priv_->fns_edit_script_;}
11092 {
return priv_->vars_edit_script_;}
11099 {
return !priv_->sonames_equal_;}
11106 {
return !priv_->architectures_equal_;}
11113 {
return priv_->deleted_fns_;}
11120 {
return priv_->added_fns_;}
11132 {
return priv_->changed_fns_map_;}
11141 {
return priv_->changed_fns_;}
11149 {
return priv_->deleted_vars_;}
11156 {
return priv_->added_vars_;}
11164 {
return priv_->changed_vars_map_;}
11172 {
return priv_->sorted_changed_vars_;}
11181 {
return priv_->deleted_unrefed_fn_syms_;}
11190 {
return priv_->added_unrefed_fn_syms_;}
11199 {
return priv_->deleted_unrefed_var_syms_;}
11208 {
return priv_->added_unrefed_var_syms_;}
11217 {
return priv_->deleted_unreachable_types_;}
11225 const vector<type_base_sptr>&
11228 if (priv_->deleted_unreachable_types_sorted_.empty())
11229 if (!priv_->deleted_unreachable_types_.empty())
11231 priv_->deleted_unreachable_types_sorted_);
11233 return priv_->deleted_unreachable_types_sorted_;
11243 {
return priv_->added_unreachable_types_;}
11251 const vector<type_base_sptr>&
11254 if (priv_->added_unreachable_types_sorted_.empty())
11255 if (!priv_->added_unreachable_types_.empty())
11257 priv_->added_unreachable_types_sorted_);
11259 return priv_->added_unreachable_types_sorted_;
11269 {
return priv_->changed_unreachable_types_;}
11277 const vector<diff_sptr>&
11279 {
return priv_->changed_unreachable_types_sorted();}
11286 {
return priv_->get_context();}
11293 if (priv_->pretty_representation_.empty())
11295 std::ostringstream o;
11296 o <<
"corpus_diff["
11301 priv_->pretty_representation_ = o.str();
11303 return priv_->pretty_representation_;
11314 || !(priv_->deleted_fns_.empty()
11315 && priv_->added_fns_.empty()
11316 && priv_->changed_fns_map_.empty()
11317 && priv_->deleted_vars_.empty()
11318 && priv_->added_vars_.empty()
11319 && priv_->changed_vars_map_.empty()
11320 && priv_->added_unrefed_fn_syms_.empty()
11321 && priv_->deleted_unrefed_fn_syms_.empty()
11322 && priv_->added_unrefed_var_syms_.empty()
11323 && priv_->deleted_unrefed_var_syms_.empty()
11324 && priv_->deleted_unreachable_types_.empty()
11325 && priv_->added_unreachable_types_.empty()
11326 && priv_->changed_unreachable_types_.empty()));
11374 if (!has_incompatible_changes
11381 for (
auto &entry : priv_->changed_unreachable_types())
11389 has_incompatible_changes |=
true;
11425 {
return context()->get_reporter()->diff_has_net_changes(
this);}
11450 if (priv_->diff_stats_)
11451 return *priv_->diff_stats_;
11456 std::cerr <<
"Applying suppressions ...\n";
11465 std::cerr <<
"suppressions applied!:" << t <<
"\n";
11472 std::cerr <<
"Marking leaf nodes ...\n";
11481 std::cerr <<
"leaf nodes marked!:" << t <<
"\n";
11482 std::cerr <<
"Applying filters and computing diff stats ...\n";
11486 priv_->apply_filters_and_compute_diff_stats(*priv_->diff_stats_);
11491 std::cerr <<
"Filters applied and diff stats computed!: " << t <<
"\n";
11494 return *priv_->diff_stats_;
11516 visit_begin(
diff *d)
11561 const corpus_diff *corpus_diff_node = ctxt->get_corpus_diff().get();
11564 if (
diff *iface_diff = get_current_topmost_iface_diff())
11571 get_leaf_diffs().insert_diff_node(d, iface);
11589 if (!
context()->show_leaf_changes_only())
11592 leaf_diff_node_marker_visitor v;
11593 context()->forget_visited_diffs();
11594 bool s =
context()->visiting_a_node_twice_is_forbidden();
11595 context()->forbid_visiting_a_node_twice(
true);
11596 if (
context()->show_impacted_interfaces())
11597 context()->forbid_visiting_a_node_twice_per_interface(
true);
11599 context()->forbid_visiting_a_node_twice(s);
11600 context()->forbid_visiting_a_node_twice_per_interface(
false);
11610 {
return priv_->leaf_diffs_;}
11619 {
return priv_->leaf_diffs_;}
11630 context()->get_reporter()->report(*
this, out, indent);
11645 if (!v.
visit(
this,
true))
11651 for (function_decl_diff_sptrs_type::const_iterator i =
11659 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
11660 ctxt->forget_visited_diffs();
11673 for (var_diff_sptrs_type::const_iterator i =
11681 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
11682 ctxt->forget_visited_diffs();
11699 for (vector<diff_sptr>::const_iterator i =
11707 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
11708 ctxt->forget_visited_diffs();
11736 const corpus_sptr s,
11739 typedef corpus::functions::const_iterator fns_it_type;
11740 typedef corpus::variables::const_iterator vars_it_type;
11741 typedef elf_symbols::const_iterator symbols_it_type;
11743 typedef vector<type_base_wptr>::const_iterator type_base_wptr_it_type;
11752 ctxt->set_corpus_diff(r);
11754 if(ctxt->show_soname_change())
11755 r->priv_->sonames_equal_ = f->get_soname() == s->get_soname();
11757 r->priv_->sonames_equal_ =
true;
11759 r->priv_->architectures_equal_ =
11760 f->get_architecture_name() == s->get_architecture_name();
11763 diff_utils::compute_diff<fns_it_type, eq_type>(f->get_functions().begin(),
11764 f->get_functions().end(),
11765 s->get_functions().begin(),
11766 s->get_functions().end(),
11767 r->priv_->fns_edit_script_);
11770 diff_utils::compute_diff<vars_it_type, eq_type>
11771 (f->get_variables().begin(), f->get_variables().end(),
11772 s->get_variables().begin(), s->get_variables().end(),
11773 r->priv_->vars_edit_script_);
11777 diff_utils::compute_diff<symbols_it_type, eq_type>
11778 (f->get_unreferenced_function_symbols().begin(),
11779 f->get_unreferenced_function_symbols().end(),
11780 s->get_unreferenced_function_symbols().begin(),
11781 s->get_unreferenced_function_symbols().end(),
11782 r->priv_->unrefed_fn_syms_edit_script_);
11786 diff_utils::compute_diff<symbols_it_type, eq_type>
11787 (f->get_unreferenced_variable_symbols().begin(),
11788 f->get_unreferenced_variable_symbols().end(),
11789 s->get_unreferenced_variable_symbols().begin(),
11790 s->get_unreferenced_variable_symbols().end(),
11791 r->priv_->unrefed_var_syms_edit_script_);
11793 if (ctxt->show_unreachable_types())
11796 diff_utils::compute_diff<type_base_wptr_it_type, eq_type>
11797 (f->get_types_not_reachable_from_public_interfaces().begin(),
11798 f->get_types_not_reachable_from_public_interfaces().end(),
11799 s->get_types_not_reachable_from_public_interfaces().begin(),
11800 s->get_types_not_reachable_from_public_interfaces().end(),
11801 r->priv_->unreachable_types_edit_script_);
11803 r->priv_->ensure_lookup_tables_populated();
11824 const corpus_group_sptr& s,
11828 corpus_sptr c1 = f;
11829 corpus_sptr c2 = s;
11840 struct diff_node_visitor::priv
11842 diff* topmost_interface_diff;
11846 : topmost_interface_diff(),
11851 : topmost_interface_diff(),
11861 diff_node_visitor::~diff_node_visitor() =
default;
11867 : priv_(new priv(k))
11877 {
return priv_->kind;}
11897 {priv_->kind = priv_->kind | v;}
11905 {priv_->topmost_interface_diff = d;}
11913 {
return priv_->topmost_interface_diff;}
12140 bool already_visited = d->
context()->diff_has_been_visited(d);
12148 bool update_canonical = !already_visited && canonical;
12150 for (vector<diff*>::const_iterator i = d->
children_nodes().begin();
12183 if (!already_visited && canonical)
12184 if (update_canonical)
12185 canonical->add_to_category(c);
12199 category_propagation_visitor v;
12200 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12201 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
12202 diff_tree->
context()->forget_visited_diffs();
12204 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12226 category_propagation_visitor v;
12227 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12228 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
12230 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12255 visit_begin(diff* d)
12257 bool is_private_type =
false;
12268 if (canonical_diff != d)
12324 bool has_non_suppressed_child =
false;
12325 bool has_non_empty_child =
false;
12326 bool has_suppressed_child =
false;
12327 bool has_non_private_child =
false;
12328 bool has_private_child =
false;
12329 bool has_descendant_with_allowed_change =
false;
12362 && (!d->has_local_changes()
12387 for (vector<diff*>::const_iterator i = d->children_nodes().begin();
12388 i != d->children_nodes().end();
12392 if (child->has_changes())
12394 has_non_empty_child =
true;
12396 has_suppressed_child =
true;
12397 else if (child->get_class_of_equiv_category()
12403 has_non_suppressed_child =
true;
12405 if (child->get_class_of_equiv_category()
12407 has_private_child =
true;
12408 else if (child->get_class_of_equiv_category()
12414 has_non_private_child =
true;
12418 if (has_non_empty_child
12419 && has_suppressed_child
12420 && !has_non_suppressed_child)
12426 if (canonical_diff != d)
12442 if (has_non_empty_child
12443 && has_private_child
12444 && !has_non_private_child)
12450 if (canonical_diff != d)
12460 && has_private_child
12461 && has_non_empty_child)
12467 if (canonical_diff != d)
12484 if (fn_type_diff->is_suppressed())
12490 if (canonical_diff != d)
12499 for (
auto child_node : d->children_nodes())
12505 has_descendant_with_allowed_change =
true;
12507 if (has_descendant_with_allowed_change)
12510 d->add_to_category(c);
12511 d->get_canonical_diff()->add_to_category(c);
12525 if (diff_tree && !diff_tree->
context()->suppressions().empty())
12529 suppression_categorization_visitor v;
12530 diff_tree->
context()->forget_visited_diffs();
12531 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12532 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
12534 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12557 if (diff_tree && !diff_tree->
context()->suppressions().empty())
12562 suppression_categorization_visitor v;
12563 diff_tree->
context()->forget_visited_diffs();
12564 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12565 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
12566 const_cast<corpus_diff*
>(diff_tree)->traverse(v);
12567 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12573 apply_supprs_to_added_removed_fns_vars_unreachable_types();
12603 do_indent(
unsigned level)
12605 for (
unsigned i = 0; i < level; ++i)
12609 diff_node_printer(ostream& out)
12628 visit_begin(corpus_diff*)
12634 visit_end(corpus_diff*)
12640 visit(diff* d,
bool pre)
12649 out_ << d->get_pretty_representation();
12653 do_indent(level_ + 1);
12654 out_ <<
"category: "<< d->get_category() <<
"\n";
12655 do_indent(level_ + 1);
12656 out_ <<
"@: " << std::hex << d << std::dec <<
"\n";
12657 do_indent(level_ + 1);
12658 out_ <<
"@-canonical: " << std::hex
12659 << d->get_canonical_diff()
12660 << std::dec <<
"\n";
12668 visit(corpus_diff* d,
bool pre)
12677 for (
unsigned i = 0; i < level_; ++i)
12679 out_ << d->get_pretty_representation();
12698 diff_node_printer p(out);
12699 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12700 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
12702 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12716 diff_node_printer p(out);
12717 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12718 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
12720 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12759 bool skip_children_nodes_;
12761 redundancy_marking_visitor()
12762 : skip_children_nodes_()
12766 visit_begin(diff* d)
12768 if (d->to_be_reported())
12774 if ((d->context()->diff_has_been_visited(d)
12775 || d->get_canonical_diff()->is_traversing())
12776 && d->has_changes())
12791 bool redundant_with_sibling_node =
false;
12796 if (p && dynamic_cast<const fn_parm_diff*>(p))
12800 for (vector<diff*>::const_iterator s =
12801 p->children_nodes().begin();
12802 s != p->children_nodes().end();
12810 if (fn_parm_diff* f = dynamic_cast<fn_parm_diff*>(*s))
12811 sib = f->type_diff().get();
12814 if (sib->get_canonical_diff() == d->get_canonical_diff()
12819 redundant_with_sibling_node =
true;
12823 if (!redundant_with_sibling_node
12844 && (!d->get_canonical_diff()->is_filtered_out()
12845 || (d->get_canonical_diff()->get_category()
12852 && d->context()->diff_has_been_visited(d) != d
12874 skip_children_nodes_ =
true;
12882 skip_children_nodes_ =
true;
12887 visit_begin(corpus_diff*)
12894 if (skip_children_nodes_)
12901 skip_children_nodes_ =
false;
12909 && (!d->has_local_changes_to_be_reported()
12935 && (!(d->has_local_changes()
12946 && (!(d->has_local_changes()
12953 && (!(d->has_local_changes()
12957 bool has_non_redundant_child =
false;
12958 bool has_non_empty_child =
false;
12959 for (vector<diff*>::const_iterator i =
12960 d->children_nodes().begin();
12961 i != d->children_nodes().end();
12964 if ((*i)->has_changes())
12966 has_non_empty_child =
true;
12973 if ((*i)->to_be_reported()
12975 has_non_redundant_child =
true;
12977 if (has_non_redundant_child)
12984 if (has_non_empty_child
12985 && !has_non_redundant_child)
12992 visit_end(corpus_diff*)
13001 visit(corpus_diff*,
bool)
13009 struct redundancy_clearing_visitor :
public diff_node_visitor
13012 visit(corpus_diff*,
bool)
13016 visit(diff* d,
bool)
13021 d->set_category(c);
13033 if (diff_tree->
context()->show_redundant_changes())
13035 redundancy_marking_visitor v;
13036 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13037 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13039 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13057 redundancy_marking_visitor v;
13058 diff_tree->
context()->forget_visited_diffs();
13059 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13060 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13062 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13082 redundancy_clearing_visitor v;
13083 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13084 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13086 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13087 diff_tree->
context()->forget_visited_diffs();
13105 redundancy_clearing_visitor v;
13106 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13107 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13109 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13110 diff_tree->
context()->forget_visited_diffs();
13131 diff_tree->context()->maybe_apply_filters(diff_tree);
13149 if (t && t->get_environment().is_variadic_parameter_type(t))
13153 if (t && t->get_environment().is_variadic_parameter_type(t))
13218 if (allow_indirect_type)
13419 has_local_type_change_only(
const diff *d)
13446 else if (
const var_diff * v = dynamic_cast<const var_diff*>(d))
13447 return (has_local_type_change_only(v)
13449 else if (
const fn_parm_diff * p = dynamic_cast<const fn_parm_diff*>(d))
13450 return (has_local_type_change_only(p)
13453 dynamic_cast<const function_decl_diff*>(d))
13454 return (has_local_type_change_only(f)
bool show_deleted_vars() const
Testing (anding) against this mask means that a given IR artifact has local differences, with respect to the other artifact it was compared against. A local change is a change that is carried by the artifact itself (or its type), rather than by one off its sub-types.
qualified_type_diff(qualified_type_def_sptr first, qualified_type_def_sptr second, diff_sptr underling, diff_context_sptr ctxt=diff_context_sptr())
Constructor for qualified_type_diff.
void set_allowed_category(diff_category c)
Setter for the bitmap that represents the set of categories that the user wants to see reported...
bool is_filtered_out_without_looking_at_allowed_changes() const
Test if this diff tree node is to be filtered out for reporting purposes, but without considering the...
bool is_child_node_of_function_parm_diff(const diff *diff)
Test if a diff node is a child node of a function parameter diff node.
vector< diff * > diff_ptrs_type
Convenience typedef for a vector of diff*.
const string_diff_ptr_map & get_class_diff_map() const
Getter of the map that contains class type diffs.
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...
const string_var_ptr_map & added_variables() const
Getter for the added variables of the diff.
void set_reporter(reporter_base_sptr &)
Setter of the reporter to be used in this context.
size_t net_num_added_unreachable_types() const
Getter of the number of added types that are unreachable from public interfaces and that are *NOT* fi...
A comparison function for instances of base_diff.
const diff * peel_typedef_qualified_type_or_parameter_diff(const diff *dif)
If a diff node is about changes between two typedefs or qualified types, get the diff node about chan...
const string_decl_base_sptr_map & inserted_data_members() const
Getter for the data members that got inserted.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool show_offsets_sizes_in_bits() const
Get the flag that indicates if diff reports using this context should show sizes and offsets in bits...
The abstraction of an array type.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
bool has_parent_allowed_by_specific_negated_suppression() const
Test if the current diff node has a parent node which is specifically allowed by a negated suppressio...
This means the diff node (or at least one of its descendant nodes) carries a change involving two com...
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.
bool show_added_fns() const
size_t net_num_leaf_var_changes() const
Getter for the net number of leaf variable change diff nodes.
The base type of all declarations.
size_t num_leaf_var_changes_filtered_out() const
Getter for the number of leaf variable changes diff nodes that have been filtered out...
A comparison functor for instances of diff.
virtual void report(ostream &, const string &indent="") const
Report the differences between the two enums.
type_suppression_sptr is_type_suppression(suppression_sptr suppr)
Test if an instance of suppression is an instance of type_suppression.
const string_diff_sptr_map & changed_unreachable_types() const
Getter for a map of changed types that are not reachable from global functions/variables.
const string_member_function_sptr_map & deleted_member_fns() const
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of subrange_di...
function_suppression_sptr is_function_suppression(const suppression_sptr suppr)
Test if an instance of suppression is an instance of function_suppression.
vector< function_decl_diff_sptr > function_decl_diff_sptrs_type
Convenience typedef for a vector of function_decl_diff_sptr.
size_t num_changed_unreachable_types_filtered_out() const
Getter of the number of changed types that are unreachable from public interfaces and that have been ...
distinct_diff(type_or_decl_base_sptr first, type_or_decl_base_sptr second, diff_context_sptr ctxt=diff_context_sptr())
Constructor for distinct_diff.
A "Less Than" functor to compare instance of function_decl_diff.
diff_category remove_from_category(diff_category c)
Remove the current diff tree node from an a existing sef of categories. The categories include those ...
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...
size_t num_leaf_type_changes_filtered_out() const
Getter for the number of filtered out leaf type change diff nodes.
The abstraction of a change between two ABI artifacts, a.k.a an artifact change.
const pointer_diff * is_pointer_diff(const diff *diff)
Test if a diff node is about differences between two pointers.
virtual ~class_or_union_diff()
Destructor of class_or_union_diff.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of class_or_un...
const edit_script & member_fn_tmpls_changes() const
const string_diff_ptr_map & get_function_decl_diff_map() const
Getter of the map that contains function decl diffs.
const edit_script & member_fns_changes() const
Abstraction of a diff between two qualified types.
virtual enum change_kind has_local_changes() const
size_t net_num_func_removed() const
Getter for the net number of function removed.
virtual enum change_kind has_local_changes() const
shared_ptr< class_diff > class_diff_sptr
Convenience typedef for a shared pointer on a class_diff type.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of enum_diff...
const changed_var_sptrs_type & ordered_data_members_replaced_by_adms() const
Get an ordered vector of of data members that got replaced by anonymous data members.
size_t net_num_vars_changed() const
Getter for the number of variables that have a change in their sub-types, minus the number of these v...
vector< var_diff_sptr > var_diff_sptrs_type
Convenience typedef for a vector of var_diff_sptr.
const edit_script & base_changes() const
class_decl_sptr second_class_decl() const
Getter of the second class involved in the diff.
shared_ptr< typedef_diff > typedef_diff_sptr
Convenience typedef for a shared pointer on a typedef_diff type.
const string_parm_map & removed_parms() const
Getter for the map of parameters that got removed.
const function_decl_sptr first_function_decl() const
const string_diff_ptr_map & get_function_type_diff_map() const
Getter of the map that contains function type diffs.
const vector< diff * > & children_nodes() const
Getter for the children nodes of the current diff node.
const diff_sptrs_type & changed_decls() const
virtual void report(ostream &out, const string &indent="") const
Report the diff in a serialized form.
size_t net_num_changed_unreachable_types() const
Getter of the number of changed types that are unreachable from public interfaces and that have *NOT*...
The internal type for the impl idiom implementation of pointer_diff.
bool added_function_is_suppressed(const function_decl *fn) const
Test if the change reports for a give given added function has been deleted.
const string_var_ptr_map & deleted_variables() const
Getter for the variables that got deleted from the first subject of the diff.
const string_fn_parm_diff_sptr_map & subtype_changed_parms() const
Getter for the map of function parameter changes of the current diff.
virtual bool has_changes() const
Return true iff the diff node has a change.
bool has_net_subtype_changes() const
Test if the current instance of corpus_diff carries subtype changes whose reports are not suppressed ...
diff_sptr underlying_type_diff() const
Getter for the diff between the underlying types of the two qualified types.
shared_ptr< pointer_diff > pointer_diff_sptr
Convenience typedef for a shared pointer on a pointer_diff type.
virtual void report(ostream &, const string &indent="") const
Produce a basic report about the changes between two class_decl.
virtual const string & get_pretty_representation() const
Build and return a textual representation of the current instance of fn_parm_diff.
var_decl_sptr first_var() const
Getter for the first var_decl of the diff.
shared_ptr< suppression_base > suppression_sptr
Convenience typedef for a shared pointer to a suppression.
const edit_script & data_members_changes() const
void finish_diff_type()
Finish building the current instance of corpus_diff.
size_t num_func_with_virtual_offset_changes() const
Getter for the number of functions that carry virtual member offset changes.
diff_category add_to_category(diff_category c)
Adds the current diff tree node to an additional set of categories. Note that the categories include ...
bool deleted_function_is_suppressed(const function_decl *fn) const
Test if the change reports for a given deleted function have been deleted.
An abstractions of the changes between two scopes.
diff_category get_local_category() const
Getter for the local category of the current diff tree node.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
An abstraction of a diff between entities that are of a different kind (disctinct).
diff_context_sptr get_context()
Getter of the context associated with this corpus.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of pointer_dif...
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of qualified_t...
bool has_incompatible_changes() const
Test if the current instance of corpus_diff carries changes that we are sure are incompatible. By incompatible change we mean a change that "breaks" the ABI of the corpus we are looking at.
const qualified_type_diff * is_qualified_type_diff(const diff *diff)
Test if a diff node is about differences between two qualified types.
bool class_or_union_types_of_same_kind(const class_or_union *first, const class_or_union *second)
Test if two class or union types are of the same kind.
const corpus_diff * is_corpus_diff(const diff *diff)
Test if a diff node is a corpus_diff node.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
Getter the pretty representation of the subrange_diff diff node.
interned_string get_id() const
Return an ID that tries to uniquely identify the function inside a program or a library.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
bool deleted_variable_is_suppressed(const var_decl *var) const
Test if the change reports for a give given deleted variable has been deleted.
bool show_impacted_interfaces() const
Getter of the flag that indicates if the leaf reporter should display a summary of the interfaces imp...
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.
virtual void visit_begin(diff *)
This is called by the traversing code on a diff node just before visiting it. That is...
void append_child_node(diff_sptr)
Add a new child node to the vector of children nodes for the current diff node.
vector< changed_var_sptr > changed_var_sptrs_type
Convenience typedef for a vector of .gg381.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
scope_diff(scope_decl_sptr first_scope, scope_decl_sptr second_scope, diff_context_sptr ctxt=diff_context_sptr())
Constructor for scope_diff.
void mark_diff_as_visited(const diff *)
Mark a diff node as traversed by a traversing algorithm.
diff_sptr try_to_diff< class_decl >(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second, diff_context_sptr ctxt)
This is a specialization of try_to_diff() template to diff instances of class_decl.
An abstraction helper for type declarations.
A diff node in this category is a function (or function type) with at least one parameter added or re...
A functor to compare instances of elf_symbol base on their names.
This means the diff node (or at least one of its descendant nodes) carries a change that modifies the...
const qualified_type_def_sptr first_qualified_type() const
Getter for the first qualified type of the diff.
interned_string get_function_id_or_pretty_representation(function_decl *fn)
Get the ID of a function, or, if the ID can designate several different functions, get its pretty representation.
size_t num_leaf_changes_filtered_out() const
Getter of the number of leaf type change diff nodes that have been filtered out.
bool do_log() const
Test if logging was requested.
size_t count_filtered_subtype_changed_data_members(bool local_only=false) const
Count the number of /filtered/ data members with a sub-type change.
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
The base class of both types and declarations.
bool insert_diff_node(const diff *d, const type_or_decl_base_sptr &impacted_iface)
Insert a new diff node into the current instance of diff_maps.
const string_var_diff_sptr_map & changed_variables()
Getter for the non-sorted map of variables which signature didn't change but which do have some indir...
A declaration that introduces a scope.
virtual void chain_into_hierarchy()
This constructs the relation between this diff node and its detail diff nodes, in the generic view of...
bool is_negated_suppression(const suppression_base &s)
Test if a suppression specification is a negated suppression.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
bool is_reference_or_ptr_diff_to_non_basic_nor_distinct_types(const diff *diff)
Test if a diff node is a reference or pointer diff node to a change that is neither basic type change...
var_decl_sptr find_data_member_from_anonymous_data_member(const var_decl_sptr &anon_dm, const string &name)
Find a data member inside an anonymous data member.
const function_decl::parameter_sptr second_parameter() const
Getter for the second subject of this diff node.
bool show_deleted_fns() const
edit_script & function_changes() const
Abstracts a reference type.
This type abstracts changes for a class_decl.
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...
const array_type_def_sptr second_array() const
Getter for the second array of the diff.
size_t num_removed_var_syms_filtered_out() const
Getter for the number of removed variable symbols, not referenced by any debug info, that have been filtered out.
const function_type_diff * is_function_type_diff_with_local_changes(const diff *diff)
Test if a given diff node carries a function type change with local changes.
The abstraction of a qualified type.
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...
size_t count_filtered_changed_dm(bool local_only=false)
Get the number of data member changes carried by the current diff node that were filtered out...
const typedef_decl_sptr first_typedef_decl() const
Getter for the firt typedef_decl involved in the diff.
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...
bool show_added_symbols_unreferenced_by_debug_info() const
Getter for the flag that indicates if symbols not referenced by any debug info and that got added are...
const diff * parent_node() const
Getter for the parent node of the current diff node.
const base_diff * is_base_diff(const diff *diff)
Test if a diff node is about differences between two base class specifiers.
Abstraction of a base specifier in a class declaration.
diff_sptr get_canonical_diff_for(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second) const
Getter for the canonical diff node for the diff represented by their two subjects.
const diff_stats & apply_filters_and_suppressions_before_reporting()
Apply the different filters that are registered to be applied to the diff tree; that includes the cat...
size_t net_num_vars_added() const
Getter for the net number of added variables.
const suppr::suppressions_type & suppressions() const
Getter for the vector of suppressions that specify which diff node reports should be dropped on the f...
size_t num_removed_unreachable_types() const
Getter of the number of removed types that are unreachable from the public interface of the ABI corpu...
bool is_filtered_out_wrt_non_inherited_categories() const
Test if this diff tree node is to be filtered out for reporting purposes, but by considering only the...
void forbid_visiting_a_node_twice_per_interface(bool)
This function sets a flag os that if forbid_visiting_a_node_twice() returns true, then each time the ...
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.
const corpus_diff_sptr & get_corpus_diff() const
Get the corpus diff for the current context.
Abstraction of a diff between two typedef_decl.
const scope_decl_sptr first_scope() const
Getter for the first scope of the diff.
virtual enum change_kind has_local_changes() const
diff_node_visitor()
Default constructor of the diff_node_visitor type.
bool deleted_unrefed_fn_sym_is_suppressed(const elf_symbol *) const
Test if the change reports for a given deleted function symbol (that is not referenced by any debug i...
const var_diff * is_var_diff(const diff *diff)
Test if a diff node is about differences between variables.
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Report the changes carried by the current class_or_union_diff node in a textual format.
diff_category get_default_harmful_categories_bitmap()
Getter of a bitmap made of the set of change categories that are considered harmful.
size_t num_leaf_var_changes() const
Getter for the number of leaf variable change diff nodes.
This means that a diff node in the sub-tree carries an addition of enumerator to an enum type...
bool is_mostly_distinct_diff(const diff *d)
Test if a diff node carries a distinct type change or a pointer/reference/typedef to distinct type ch...
virtual const string & get_pretty_representation() const
const diff * peel_typedef_diff(const diff *dif)
If a diff node is about changes between two typedef types, get the diff node about changes between th...
This means the diff node (or at least one of its descendant nodes) carries access related changes...
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.
shared_ptr< reference_diff > reference_diff_sptr
Convenience typedef for a shared pointer on a reference_diff type.
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
The variable was deleted from the second subject of the diff.
const type_decl_sptr first_type_decl() const
Getter for the first subject of the type_decl_diff.
diff * diff_has_been_visited(const diff *) const
Test if a diff node has been traversed.
virtual void report(ostream &, const string &indent="") const
Generates a report for the current instance of base_diff.
class_decl::base_spec_sptr second_base() const
Getter for the second base spec of the diff object.
A diff node in this category carries a change from void pointer to non-void pointer.
diff * get_current_topmost_iface_diff() const
Getter of the diff current topmost interface which is impacted by the current diff node being visited...
virtual enum change_kind has_local_changes() const
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
class_or_union_sptr first_class_or_union() const
A diff node in this category has a parent node that is in the HAS_ALLOWED_CHANGE_CATEGORY category...
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
void maybe_apply_filters(diff_sptr diff)
Apply the diff filters to a given diff sub-tree.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
The abstraction of a diff between two arrays.
const string_enumerator_map & deleted_enumerators() const
diff_maps()
Default constructor of the diff_maps type.
size_t num_removed_vars_filtered_out() const
Getter for the number removed variables that have been filtered out.
const string_diff_ptr_map & get_distinct_diff_map() const
Getter of the map that contains distinct diffs.
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
size_t num_added_var_syms_filtered_out() const
Getter for the number of added variable symbols, not referenced by any debug info, that have been filtered out.
virtual bool has_changes() const
Abstraction of the declaration of a method.
bool has_decl_only_def_change(const decl_base_sptr &first, const decl_base_sptr &second)
Test if two decl_base_sptr are different just by the fact that one is decl-only and the other one is ...
size_t net_num_added_func_syms() const
Getter of the net number of added function symbols that are not referenced by any debug info...
This says that the traversing code should not mark visited nodes as having been traversed. This is useful, for instance, for visitors which have debugging purposes.
void categorize_redundant_changed_sub_nodes()
Walk the changed functions and variables diff nodes to categorize redundant nodes.
size_t net_num_func_added() const
Getter for the net number of added functions.
shared_ptr< distinct_diff > distinct_diff_sptr
Convenience typedef for a shared pointer to distinct_types_diff.
ostream & operator<<(ostream &o, diff_category c)
Serialize an instance of diff_category to an output stream.
const fn_parm_diff * is_fn_parm_diff(const diff *diff)
Test if a diff node is about differences between two function parameters.
class_decl::base_spec_sptr first_base() const
Getter for the first base spec of the diff object.
virtual bool traverse(diff_node_visitor &v)
Traverse the diff sub-tree under the current instance corpus_diff.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
bool added_unreachable_type_is_suppressed(const type_base *t) const
Test if an added type that is unreachable from public interface has been suppressed by a suppression ...
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
const type_decl_diff * is_diff_of_basic_type(const diff *d)
Test if a diff node represents a diff between two basic types.
virtual enum change_kind has_local_changes() const
Check if the current diff node carries a local change.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Abstracts a class declaration.
Abstraction of a diff between two function_decl.
A diff node in this category is a function parameter type which top cv-qualifiers change...
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
virtual void report(ostream &out, const string &indent="") const
Report the diff in a serialized form.
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...
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
bool is_at_global_scope(const decl_base &decl)
Tests whether a given declaration is at global scope.
void propagate_categories(diff *diff_tree)
Visit all the nodes of a given sub-tree. For each node that has a particular category set...
This means that a diff node in the sub-tree carries an incompatible change to a vtable.
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...
function_type_diff(const function_type_sptr first, const function_type_sptr second, diff_context_sptr ctxt)
Consutrctor of the function_type type.
bool currently_reporting() const
Tests if we are currently in the middle of emitting a report for this diff.
corpus_diff(corpus_sptr first, corpus_sptr second, diff_context_sptr ctxt=diff_context_sptr())
Constructor for corpus_diff.
size_t count_filtered_subtype_changed_dm(bool local_only=false)
Get the number of data member sub-type changes carried by the current diff node that were filtered ou...
const string_diff_ptr_map & get_enum_diff_map() const
Getter of the map that contains enum type diffs.
void switch_categories_on(diff_category c)
Setter for the bitmap that represents the set of categories that the user wants to see reported...
diff_category get_allowed_category() const
Getter for the bitmap that represents the set of categories that the user wants to see reported...
void apply_suppressions(diff *diff_tree)
Walk a given diff-sub tree and appply the suppressions carried by the context. If the suppression app...
size_t count_filtered_changed_mem_fns(const diff_context_sptr &)
Get the number of member functions changes carried by the current diff node that were filtered out...
const enum_type_decl_sptr first_enum() const
const string_diff_ptr_map & get_reference_diff_map() const
Getter of the map that contains reference type diffs.
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
shared_ptr< subrange_diff > subrange_diff_sptr
A convenience typedef for a shared pointer to subrange_diff type.
const class_diff * is_class_diff(const diff *diff)
Test if a diff node is a class_diff node.
const edit_script & member_types_changes() const
shared_ptr< type_suppression > type_suppression_sptr
Convenience typedef for a shared pointer to type_suppression.
shared_ptr< scope_diff > scope_diff_sptr
Convenience typedef for a shared pointer on a scope_diff.
base_diff(class_decl::base_spec_sptr first, class_decl::base_spec_sptr second, class_diff_sptr underlying, diff_context_sptr ctxt=diff_context_sptr())
bool show_unreachable_types()
Getter for the flag that indicates if changes on types unreachable from global functions and variable...
Abstraction of a diff between two enums.
virtual void report(ostream &out, const string &indent="") const
Ouputs a report of the differences between of the two type_decl involved in the type_decl_diff.
The default, initial, reporter of the libabigail comparison engine.
virtual enum change_kind has_local_changes() const
Abstracts a variable declaration.
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 set_category(diff_category c)
Set the category of the current diff node. This category includes the categories inherited from the c...
virtual void report(ostream &, const string &indent="") const
Serialize a report of the changes encapsulated in the current instance of function_decl_diff over to ...
void sort_string_parm_map(const string_parm_map &map, vector< function_decl::parameter_sptr > &sorted)
Sort a map of string -> function parameters.
edit_script & variable_changes() const
A functor to compare instances of var_decl base on their qualified names.
void switch_categories_off(diff_category c)
Setter for the bitmap that represents the set of categories that the user wants to see reported...
bool is_diff_of_global_decls(const diff *)
Tests if a given diff node is to represent the changes between two gobal decls.
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Abstraction of a function parameter.
bool added_variable_is_suppressed(const var_decl *var) const
Test if the change reports for a given added variable have been suppressed.
The base class of diff between decls.
The base class of diff between types.
A reporter that only reports leaf changes.
Abstraction of a diff between two basic type declarations.
const function_decl_sptr second_function_decl() const
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.
void initialize_canonical_diff(const diff_sptr diff)
Set the canonical diff node property of a given diff node appropriately.
void allocate_priv_data()
Allocate the memory for the priv_ pimpl data member of the class_or_union_diff class.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
bool soname_changed() const
Test if the soname of the underlying corpus has changed.
size_t net_num_removed_func_syms() const
Getter of the net number of removed function symbols that are not referenced by any debug info...
diff_sptr try_to_diff(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second, diff_context_sptr ctxt)
bool is_suppressed() const
Test if the current diff node has been suppressed by a user-provided suppression specification.
interned_string get_id() const
Return an ID that tries to uniquely identify the variable inside a program or a library.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
decl_base_sptr subtype_changed_dm(decl_base_sptr) const
Test if the current diff node carries a data member change for a data member which name is the same a...
bool has_net_changes() const
Test if the current instance of corpus_diff carries changes whose reports are not suppressed by any s...
const type_or_decl_base_sptr first() const
Getter for the first subject of the diff.
visiting_kind get_visiting_kind() const
Getter for the visiting policy of the traversing code while invoking this visitor.
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.
This is the base class of class_diff and union_diff.
const string_decl_base_sptr_map & deleted_data_members() const
Getter for the data members that got deleted.
The internal type for the impl idiom implementation of subrange_diff.
bool has_changes() const
Return true iff the current corpus_diff node carries a change.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
size_t num_var_syms_removed() const
Getter for the number of variable symbols (not referenced by any debug info) that got removed...
The abstraction of the diff between two subrange types.
const string_diff_ptr_map & get_type_decl_diff_map() const
Getter of the map that contains basic type diffs.
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...
A functor to compare instances of class_decl::base_spec.
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...
An abstraction of a diff between between two abi corpus.
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...
virtual bool traverse(diff_node_visitor &v)
The default traverse function.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of base_diff...
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of reference_d...
function_decl_diff(const function_decl_sptr first, const function_decl_sptr second, diff_context_sptr ctxt)
Constructor for function_decl_diff.
const var_decl_sptr get_next_data_member(const class_or_union *klass, const var_decl_sptr &data_member)
In the context of a given class or union, this function returns the data member that is located after...
void set_canonical_diff(diff *)
Setter for the canonical diff of the current instance of diff.
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
vector< changed_enumerator > changed_enumerators_type
Convenience typedef for a vector of changed enumerators.
void ensure_lookup_tables_populated()
If the lookup tables are not yet built, walk the differences and fill the lookup tables.
Abstracts a declaration for an enum type.
class_or_union_sptr second_class_or_union() const
bool is_traversing() const
Tell if a given node is being traversed or not.
size_t num_added_unreachable_types_filtered_out() const
Getter of the number of added types that are unreachable from public interfaces and that are filtered...
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
translation_unit_diff(translation_unit_sptr first, translation_unit_sptr second, diff_context_sptr ctxt=diff_context_sptr())
Constructor for translation_unit_diff.
const type_or_decl_base_sptr second() const
Getter for the second subject of the diff.
bool show_stats_only() const
Test if the comparison module should only show the diff stats.
diff_category
An enum for the different categories that a diff tree node falls into, regarding the kind of changes ...
ostream * default_output_stream()
Getter for the default output stream used by code of the comparison engine. By default the default ou...
Toplevel namespace for libabigail.
The variable was added to the second second subject of the diff.
bool do_log() const
Test if logging was requested.
virtual bool has_changes() const
Test if the current diff node carries a change.
bool show_leaf_changes_only() const
Get the flag that indicates if the diff using this context should show only leaf changes or not...
size_t num_changed_vars_filtered_out() const
Getter for the number of variables that have a change in one of their sub-types, and that have been f...
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.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
virtual void visit_end(corpus_diff *)
This is called by the traversing code on a corpus_diff node just after visiting it. That is after visiting it and its children nodes.
bool added_unrefed_var_sym_is_suppressed(const elf_symbol *) const
Test if the change reports for a given added variable symbol (that is not referenced by any debug inf...
const diff * peel_typedef_or_qualified_type_diff(const diff *dif)
If a diff node is about changes between two typedefs or qualified types, get the diff node about chan...
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.
#define SKIP_MEM_FN_IF_VIRTUALITY_DISALLOWED
Skip the processing of the current member function if its virtual-ness is disallowed by the user...
visiting_kind operator&(visiting_kind l, visiting_kind r)
The overloaded and operator for visiting_kind.
const string_base_sptr_map & inserted_bases() const
Getter for the inserted base classes of the diff.
corpus_sptr first_corpus() const
size_t count_filtered_deleted_mem_fns(const diff_context_sptr &)
Get the number of member functions deletions carried by the current diff node that were filtered out...
virtual const string & get_pretty_representation() const
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
virtual const string & get_pretty_representation() const
bool has_harmful_name_change(const decl_base_sptr &f, const decl_base_sptr &s)
Test if two decls represents a harmful name change.
virtual const string & get_pretty_representation() const
const string_diff_ptr_map & get_typedef_diff_map() const
Getter of the map that contains typedef type diffs.
bool reported_once() const
Tests if a report has already been emitted for the current diff.
virtual bool has_changes() const
Test if the current subrange_diff node carries any change.
void set_current_topmost_iface_diff(diff *)
Setter of the diff current topmost interface which is impacted by the current diff node being visited...
const diff * peel_pointer_or_qualified_type_diff(const diff *dif)
If a diff node is about changes between two pointer, reference or qualified types, get the diff node about changes between the underlying types.
bool is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr, const enum_type_decl &enom)
Test if a given enumerator is found present in an enum.
const string_function_ptr_map & added_functions()
Getter for the added functions of the diff.
type_base_sptr get_leaf_type(qualified_type_def_sptr t)
Return the first underlying type that is not a qualified type.
decl_diff_base(decl_base_sptr first_subject, decl_base_sptr second_subject, diff_context_sptr ctxt)
Constructor of decl_diff_base.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
const string_function_ptr_map & deleted_functions() const
Getter for the deleted functions of the diff.
friend corpus_diff_sptr compute_diff(const corpus_sptr f, const corpus_sptr s, diff_context_sptr ctxt)
Compute the diff between two instances of corpus.
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.
virtual bool has_changes() const
Test if the current diff node carries changes.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
void set_corpus_diff(const corpus_diff_sptr &)
Set the corpus diff relevant to this context.
bool show_redundant_changes() const
A getter for the flag that says if we should report about functions or variables diff nodes that have...
const string_enumerator_map & inserted_enumerators() const
virtual void report(ostream &out, const string &indent="") const
Emit a report about the current diff instance.
bool perform_change_categorization() const
Test if it's requested to perform diff node categorization.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
const diff_sptrs_type & changed_types() const
size_t num_leaf_changes() const
Getter of the number of leaf type change diff nodes.
The type of the private data of corpus_diff::diff_stats.
size_t net_num_vars_removed() const
Getter for the net number of removed variables.
size_t num_leaf_type_changes() const
Getter for the number of leaf type change diff nodes.
const edit_script & member_changes() const
Accessor of the edit script of the members of a scope.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
diff_category remove_from_local_category(diff_category c)
Remove the current diff tree node from the categories resulting from the local changes.
const string_elf_symbol_map & added_unrefed_function_symbols() const
Getter for function symbols not referenced by any debug info and that got added.
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.
var_decl_sptr second_var() const
Getter for the second var_decl of the diff.
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.
virtual enum change_kind has_local_changes() const
const function_decl::parameter_sptr first_parameter() const
Getter for the first subject of this diff node.
size_t num_added_unreachable_types() const
Getter of the number of added types that are unreachable from the public interface of the ABI corpus...
Abstraction for a function declaration.
virtual const string & get_pretty_representation() const
This means that a diff node in the sub-tree carries a harmless union change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of class_diff...
size_t num_added_func_filtered_out() const
Getter for the number of added function that have been filtered out.
void forget_visited_diffs()
Unmark all the diff nodes that were marked as being traversed.
const string_type_base_sptr_map & added_unreachable_types() const
Getter for a map of added types that are not reachable from global functions/variables.
virtual enum change_kind has_local_changes() const
size_t num_removed_func_syms_filtered_out() const
Getter for the number of removed function symbols, not referenced by debug info, that have been filte...
virtual const string & get_pretty_representation() const
Get a pretty representation of the current diff node.
This means that a diff node in the sub-tree carries a harmless declaration name change. This is set only for name changes for data members and typedefs.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of function_ty...
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...
const array_type_def::subrange_sptr first_subrange() const
Getter of the first subrange of the current instance subrange_diff.
This means that a diff node in the sub-tree carries a harmless data member change. An example of harmless data member change is an anonymous data member that replaces a given data member without locally changing the layout.
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.
void apply_supprs_to_added_removed_fns_vars_unreachable_types()
Apply suppression specifications for this corpus diff to the set of added/removed functions/variables...
diff_sptr leaf_underlying_type_diff() const
Getter for the diff between the most underlying non-qualified types of two qualified types...
diff_sptr compute_diff(const decl_base_sptr first, const decl_base_sptr second, diff_context_sptr ctxt)
Compute the difference between two decls. The decls can represent either type declarations, or non-type declaration.
virtual enum change_kind has_local_changes() const
size_t num_func_removed() const
Getter for the number of functions removed.
diff_category get_category() const
Getter for the category of the current diff tree node.
void clear_redundancy_categorization()
Walk the changed functions and variables diff nodes and clear the redundancy categorization they migh...
void end_traversing()
Flag a given diff node as not being traversed anymore.
class_decl_sptr first_class_decl() const
The context of the diff. This type holds various bits of information that is going to be used through...
size_t net_num_removed_var_syms() const
Getter of the net number of removed variable symbols that are not referenced by any debug info...
const diff_sptr underlying_type_diff() const
Getter of the diff node of the underlying types of the current subrange_diff diff node...
A diff node in this category is redundant. That means it's present as a child of a other nodes in the...
The abstraction of a diff between two references.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
shared_ptr< function_decl_diff > function_decl_diff_sptr
Convenience typedef for a shared pointer to a function_decl type.
This means that a diff node in the sub-tree carries a type that was declaration-only and that is now ...
Functor to sort instances of var_diff_sptr.
size_t num_vars_changed() const
Getter for the number of variables that have a change in one of their sub-types.
virtual ~union_diff()
Destructor of the union_diff node.
void emit_diff_stats(const diff_stats &stats, ostream &out, const string &indent)
Emit the summary of the functions & variables that got removed/changed/added.
diff * get_canonical_diff() const
Getter for the canonical diff of the current instance of diff.
bool has_descendant_allowed_by_specific_negated_suppression() const
Test if the current diff node has a descendant node which is specifically allowed by a negated suppre...
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...
friend var_diff_sptr compute_diff(const var_decl_sptr first, const var_decl_sptr second, diff_context_sptr ctxt)
Compute the diff between two instances of var_decl.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
virtual const string & get_pretty_representation() const
Build and return a copy of a pretty representation of the current instance of function_type_diff.
size_t net_num_leaf_changes() const
Getter of the net number of leaf change diff nodes.
const string_diff_ptr_map & get_var_decl_diff_map() const
Getter of the map that contains var decl diffs.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
const string_function_decl_diff_sptr_map & changed_functions()
Getter for the functions which signature didn't change, but which do have some indirect changes in th...
shared_ptr< type_decl_diff > type_decl_diff_sptr
Convenience typedef for a shared pointer on a type_decl_diff type.
void keep_diff_alive(diff_sptr &)
Add a diff node to the set of diff nodes that are kept alive for the life time of the current instanc...
bool is_filtered_out() const
Test if this diff tree node is to be filtered out for reporting purposes.
void add_suppressions(const suppr::suppressions_type &supprs)
Add new suppression specifications that specify which diff node reports should be dropped on the floo...
virtual enum change_kind has_local_changes() const =0
Pure interface to know if the current instance of carries a local change. A local change is a change...
virtual bool has_changes() const
Return true iff the current diff node carries a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the corpus_diff type.
const vector< function_decl::parameter_sptr > & sorted_added_parms() const
Getter for the sorted vector of added parameters .
bool show_added_vars() const
The abstraction of a diff between two pointers.
Abstraction of an elf symbol.
virtual void report(ostream &, const string &indent="") const
Report the changes carried by the current union_diff node in a textual format.
const string_elf_symbol_map & deleted_unrefed_function_symbols() const
Getter for function symbols not referenced by any debug info and that got deleted.
virtual void report(ostream &out, const string &indent="") const
Report the changes of one scope against another.
const var_diff_sptrs_type & changed_variables_sorted()
Getter for the sorted vector of variables which signature didn't change but which do have some indire...
virtual bool has_changes() const
Return true iff the current diff node carries a change.
size_t count_filtered_inserted_mem_fns(const diff_context_sptr &)
Get the number of member functions insertions carried by the current diff node that were filtered out...
size_t count_filtered_bases()
Count the number of bases classes whose changes got filtered out.
virtual const string & get_pretty_representation() const
The function was deleted from the second subject of the diff.
void forbid_visiting_a_node_twice(bool f)
This sets a flag that, if it's true, then during the traversing of a diff nodes tree each node is vis...
void apply_filter(filter_base &filter, corpus_diff_sptr d)
Walk the diff sub-trees of a a corpus_diff and apply a filter to the nodes visted. The filter categorizes each node, assigning it into one or several categories.
vector< method_decl_sptr > member_functions
Convenience typedef.
size_t net_num_added_var_syms() const
Getter of the net number of added variable symbols that are not referenced by any debug info...
const typedef_diff * is_typedef_diff(const diff *diff)
Test if a diff node is a typedef_diff node.
const function_decl_diff * is_function_decl_diff(const diff *diff)
Test if a diff node is about differences between functions.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
const diff * peel_fn_parm_diff(const diff *dif)
If a diff node is about changes between two function parameters get the diff node about changes betwe...
diff_category get_default_harmless_categories_bitmap()
Getter of a bitmap made of the set of change categories that are considered harmless.
friend scope_diff_sptr compute_diff(const scope_decl_sptr first, const scope_decl_sptr second, scope_diff_sptr d, diff_context_sptr ctxt)
Compute the diff between two scopes.
void mark_leaf_diff_nodes()
Walks the diff nodes associated to the current corpus diff and mark those that carry local changes...
void set_local_category(diff_category c)
Set the local category of the current diff node.
virtual bool visit(diff *, bool)
Default visitor implementation.
shared_ptr< translation_unit_diff > translation_unit_diff_sptr
Convenience typedef for a shared pointer on a translation_unit_diff type.
size_t num_vars_removed() const
Getter for the number of variables removed.
A diff node in this category is for a variable which type holds a cv-qualifier change.
void add_suppression(const suppr::suppression_sptr suppr)
Add a new suppression specification that specifies which diff node reports should be dropped on the f...
void clear_lookup_tables()
Clear the lookup tables useful for reporting an enum_diff.
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
virtual bool traverse(diff_node_visitor &v)
The generic traversing code that walks a given diff sub-tree.
virtual const string & get_pretty_representation() const
pointer_diff(pointer_type_def_sptr first, pointer_type_def_sptr second, diff_sptr underlying_type_diff, diff_context_sptr ctxt=diff_context_sptr())
Constructor for a pointer_diff.
size_t count_filtered_changed_data_members(bool local_only=false) const
Count the number of /filtered/ data members that got replaced by another data member.
visiting_kind operator|(visiting_kind l, visiting_kind r)
The overloaded or operator for visiting_kind.
diff_sptr underlying_type_diff() const
virtual bool has_changes() const
Return true iff the current diff node carries a change.
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.
void count_leaf_changes(size_t &num_changes, size_t &num_filtered)
Count the number of leaf changes as well as the number of the changes that have been filtered out...
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
const pointer_type_def_sptr second_pointer() const
Getter for the second subject of a pointer diff.
diff_category get_class_of_equiv_category() const
Getter of the category of the class of equivalence of the current diff tree node. ...
bool do_log() const
Test if logging was requested.
class_or_union_diff(class_or_union_sptr first_scope, class_or_union_sptr second_scope, diff_context_sptr ctxt=diff_context_sptr())
Constructor for the class_or_union_diff class.
const string_elf_symbol_map & added_unrefed_variable_symbols() const
Getter for variable symbols not referenced by any debug info and that got added.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
virtual enum change_kind has_local_changes() const
virtual void chain_into_hierarchy()
Populate the vector of children nodes of the diff base type sub-object of this instance of fn_parm_di...
virtual bool has_changes() const
Return true iff the current diff node carries a change.
size_t num_leaf_func_changes() const
Getter for the number of leaf function change diff nodes.
bool has_local_changes_to_be_reported() const
Test if this diff tree node should be reported when considering the categories that were *NOT* inheri...
virtual void visit_end(diff *)
This is called by the traversing code on a diff node just after visiting it. That is after visiting i...
virtual void report(ostream &, const string &indent="") const
Reports the difference between the two subjects of the diff in a serialized form. ...
void apply_filters(corpus_diff_sptr diff_tree)
Apply the diff tree filters that have been associated to the context of the a given corpus_diff tree...
const diff * peel_qualified_diff(const diff *dif)
If a diff node is about changes between two qualified types, get the diff node about changes between ...
size_t num_func_added() const
Getter for the number of functions added.
change_kind
The kind of change the current function suppression should apply to.
An abstraction of a diff between two translation units.
A diff node in this category has a function parameter type with a cv-qualifiers change.
vector< suppression_sptr > suppressions_type
Convenience typedef for a vector of suppression_sptr.
virtual void report(ostream &, const string &indent="") const
Build and emit a textual report about the current function_type_diff instance.
bool show_architecture_change() const
Getter for the property that says if the comparison module should show the architecture changes in it...
variable_suppression_sptr is_variable_suppression(const suppression_sptr s)
Test if an instance of suppression is an instance of variable_suppression.
visiting_kind
An enum for the different ways to visit a diff tree node.
A diff node in this category has a descendant node that is in the HAS_ALLOWED_CHANGE_CATEGORY categor...
A functor to compare two enumerators based on their value. This implements the "less than" operator...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of array_diff...
const string_diff_sptr_map & changed_unreachable_types() const
Get the map of diff nodes representing changed unreachable types.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of var_diff...
const edit_script & member_class_tmpls_changes() const
A comparison functor to compare two instances of fn_parm_diff based on their indexes.
virtual const string & get_pretty_representation() const
void begin_traversing()
Flag a given diff node as being traversed.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of function_de...
const decl_diff_base * is_decl_diff(const diff *diff)
Test if a diff node is about differences between declarations.
size_t num_changed_func_filtered_out() const
Getter for the number of functions that have a change in one of their sub-types, and that have been f...
type_base_sptr strip_typedef(const type_base_sptr type)
Recursively returns the the underlying type of a typedef. The return type should not be a typedef of ...
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of scope_diff...
const string_member_function_sptr_map & inserted_member_fns() const
diff_sptr underlying_type_diff() const
Getter for the diff between the pointed-to types of the pointers of this diff.
const string_parm_map & added_parms() const
Getter for the map of parameters that got added.
const vector< diff * > & children_nodes() const
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
const decl_base_sptr inserted_member_at(unsigned i)
Accessor that eases the manipulation of the edit script associated to this instance. It returns the scope member (of the second scope of this diff instance) that is reported as being inserted from a given index.
const array_diff * is_array_diff(const diff *diff)
Test if a diff node is a array_diff node.
bool has_basic_type_change_only(const diff *d)
Test if a diff node is a decl diff that only carries a basic type change on its type diff sub-node...
bool lookup_tables_empty() const
Tests if the lookup tables are empty.
diff_sptr type_diff() const
Getter for the diff representing the changes on the type of the function parameter involved in the cu...
size_t num_removed_unreachable_types_filtered_out() const
Getter of the number of removed types that are not reachable from public interfaces and that have bee...
A comparison functor to compare two instances of var_diff that represent changed data members based o...
change_kind
The kind of change the current variable suppression should apply to.
size_t net_num_func_changed() const
Getter for the number of functions that have a change in their sub-types, minus the number of these f...
const filtering::filters & diff_filters() const
Getter for the diff tree nodes filters to apply to diff sub-trees.
The abstraction of a pointer type.
bool lookup_tables_empty(void) const
Tests if the lookup tables are empty.
bool added_unrefed_fn_sym_is_suppressed(const elf_symbol *) const
Test if the change reports for a given added function symbol (that is not referenced by any debug inf...
const string_diff_ptr_map & get_array_diff_map() const
Getter of the map that contains array type diffs.
This type contains maps. Each map associates a type name to a diff of that type. Not all kinds of dif...
virtual bool visit(distinct_diff *, bool)
Default visitor implementation.
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...
size_t num_added_func_syms_filtered_out() const
Getter for the number of added function symbols, not referenced by any debug info, that have been filtered out.
const diff_sptr & element_type_diff() const
Getter for the diff between the two types of array elements.
const string & get_pretty_representation() const
virtual enum change_kind has_local_changes() const
Test if the current subrange_diff node carries any local change.
friend class_diff_sptr compute_diff(const class_decl_sptr first, const class_decl_sptr second, diff_context_sptr ctxt)
Compute the set of changes between two instances of class_decl.
const type_decl_sptr second_type_decl() const
Getter for the second subject of the type_decl_diff.
The function was added to the second subject of the diff.
bool show_symbols_unreferenced_by_debug_info() const
Getter for the flag that indicates if symbols not referenced by any debug info are to be compared and...
size_t num_var_syms_added() const
Getter for the number of variable symbols (not referenced by any debug info) that got added...
const array_type_def::subrange_sptr second_subrange() const
Getter of the second subrange of the current instance subrange_diff.
const vector< class_decl::base_spec_sptr > & moved_bases() const
Getter for the vector of bases that "moved". That is, the vector of base types which position changed...
const string_diff_ptr_map & get_subrange_diff_map() const
Getter of the map that contains subrange type diffs.
const string_diff_ptr_map & get_union_diff_map() const
Getter of the map that contains union type diffs.
const enum_diff * is_enum_diff(const diff *diff)
Test if a diff node is a enum_diff node.
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
The base class for the node visitors. These are the types used to visit each node traversed by the di...
bool dump_diff_tree() const
Test if the comparison engine should dump the diff tree for the changed functions and variables it ha...
A filter that walks the diff nodes tree and tags relevant diff nodes into categories considered to re...
const function_type_sptr second_function_type() const
Getter for the second subject of the diff.
void append_child_node(diff_sptr)
Append a new child node to the vector of children nodes for the current instance of corpus_diff node...
A basic type declaration that introduces no scope.
void sort_changed_data_members(changed_var_sptrs_type &input)
Sort (in place) a vector of changed data members.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
shared_ptr< base_diff > base_diff_sptr
Convenience typedef for a shared pointer to a base_diff type.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of ...
void sort_changed_enumerators(const string_changed_enumerator_map &enumerators_map, changed_enumerators_type &sorted)
Sort a map of changed enumerators.
const subrange_diff * is_subrange_diff(const diff *diff)
Test if a diff node is a subrange_diff node.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
const decl_base_sptr deleted_member_at(unsigned index) const
Accessor that eases the manipulation of the edit script associated to this instance. It returns the scope member that is reported (in the edit script) as deleted at a given index.
const string_changed_enumerator_map & changed_enumerators() const
shared_ptr< array_diff > array_diff_sptr
Convenience typedef for a shared pointer on a array_diff type.
size_t num_func_syms_added() const
Getter for the number of function symbols (not referenced by any debug info) that got added...
ostream * error_output_stream() const
Getter for the errror output stream used by code of the comparison engine. By default the error outpu...
size_t num_vars_added() const
Getter for the number of variables added.
virtual enum change_kind has_local_changes() const
bool show_soname_change() const
Getter for the property that says if the comparison module should show the soname changes in its repo...
An equality functor to deeply compare pointers.
A comparison functor to compare two data members based on their offset.
bool deleted_unrefed_var_sym_is_suppressed(const elf_symbol *) const
Test if the change reports for a given deleted variable symbol (that is not referenced by any debug i...
static bool entities_are_of_distinct_kinds(type_or_decl_base_sptr first, type_or_decl_base_sptr second)
Test if the two arguments are of different kind, or that are both NULL.
shared_ptr< fn_parm_diff > fn_parm_diff_sptr
Convenience typedef for a shared pointer to a fn_parm_diff type.
unordered_map< string, method_decl_sptr > string_member_function_sptr_map
Convenience typedef for a hash map of strings and member functions.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
const class_or_union_diff * is_anonymous_class_or_union_diff(const diff *d)
Test if a diff node is a class_or_union_diff between two anonymous classes or unions.
const string_decl_base_sptr_map & data_members_replaced_by_adms() const
Get the map of data members that got replaced by anonymous data members.
bool is_diff_of_variadic_parameter(const diff *d)
Test if a diff node represents the difference between a variadic parameter and something else...
union_decl_sptr second_union_decl() const
const var_decl * lookup_data_member(const type_base *type, const char *dm_name)
Look for a data member of a given class, struct or union type and return it.
void count_leaf_type_changes(size_t &num_type_changes, size_t &num_type_changes_filtered)
Count the number of leaf *type* changes as well as the number of the leaf type changes that have been...
bool show_relative_offset_changes(void)
Get the flag saying if offset changes should be reported in a relative way. That is, if the report should say how of many bits a class/struct data member did move.
The type of private data of class_or_union_diff.
void set_underlying_class_diff(class_diff_sptr d)
Setter for the diff object for the diff of the underlyng base classes.
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer...
const translation_unit_sptr first_translation_unit() const
Getter for the first translation unit of this diff.
bool to_be_reported() const
Test if this diff tree node should be reported.
void clear_lookup_tables(void)
Clear the lookup tables useful for reporting.
virtual const string & get_pretty_representation() const
void or_visiting_kind(visiting_kind v)
Setter for the visiting policy of the traversing code while invoking this visitor. This one makes a logical or between the current policy and the bitmap given in argument and assigns the current policy to the result.
const function_type_sptr first_function_type() const
Getter for the first subject of the diff.
virtual enum change_kind has_local_changes() const
Test if the current diff node carries local changes.
This means that a given IR artifact has a local type change.
Abstracts a diff between two instances of var_decl.
const pointer_type_def_sptr first_pointer() const
Getter for the first subject of a pointer diff.
diff_sptr type_diff() const
Getter for the diff of the types of the instances of var_decl.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
corpus_sptr second_corpus() const
corpus_sptr get_second_corpus() const
Getter for the second corpus of the corpus diff of the current context.
const typedef_decl_sptr second_typedef_decl() const
Getter for the second typedef_decl involved in the diff.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
const vector< function_decl::parameter_sptr > & sorted_deleted_parms() const
Getter for the sorted vector of deleted parameters.
void maybe_dump_diff_tree()
If the user asked to dump the diff tree node (for changed variables and functions) on the error outpu...
const class_or_union_diff * is_class_or_union_diff(const diff *d)
Test if a diff node is a class_or_union_diff node.
const var_diff_sptrs_type & sorted_subtype_changed_data_members() const
Getter of the sorted vector of data members with a (sub-)type change.
corpus_sptr get_first_corpus() const
Getter for the first corpus of the corpus diff of the current context.
type_or_decl_base_sptr member_type_has_changed(decl_base_sptr) const
Test if the current diff node carries a member type change for a member type which name is the same a...
A comparison functor to compare pointer to instances of type_or_decl_base.
bool get_is_anonymous() const
Test if the current declaration is anonymous.
This means that a diff node in the sub-tree carries an addition or removal of a non-virtual member fu...
bool is_child_node_of_base_diff(const diff *diff)
Test if a diff node is a child node of a base diff node.
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...
reference_type_def_sptr second_reference() const
Getter for the second reference of the diff.
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.
The private data and functions of the abigail::ir::comparison types.
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.
The abstraction of the version of an ELF symbol.
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...
const reference_diff * is_reference_diff(const diff *diff)
Test if a diff node is about differences between two references.
size_t net_num_removed_unreachable_types() const
Getter of the number of removed types that are not reachable from public interfaces and that have *NO...
This means that a diff node in the sub-tree carries an a symbol alias change that is harmless...
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
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.
const qualified_type_def_sptr second_qualified_type() const
Getter for the second qualified type of the diff.
bool show_hex_values() const
Get the flag that indicates if the diff reports using this context should show sizes and offsets in a...
const scope_decl_sptr second_scope() const
Getter for the second scope of the diff.
const diff * peel_reference_diff(const diff *dif)
If a diff node is about changes between two reference types, get the diff node about changes between ...
A functor to compare two changed enumerators, based on their initial value.
const diff * get_typedef_diff_underlying_type_diff(const diff *diff)
Return the leaf underlying diff node of a typedef_diff node.
size_t num_func_changed() const
Getter for the number of functions that have a change in one of their sub-types.
union_diff(union_decl_sptr first_union, union_decl_sptr second_union, diff_context_sptr ctxt=diff_context_sptr())
Constructor for the union_diff type.
const type_diff_base * is_type_diff(const diff *diff)
Test if a diff node is about differences between types.
size_t num_leaf_func_changes_filtered_out() const
Getter for the number of leaf function change diff nodes that were filtered out.
shared_ptr< corpus_diff > corpus_diff_sptr
A convenience typedef for a shared pointer to corpus_diff.
size_t get_deleted_non_static_data_members_number() const
Get the number of non static data members that were deleted.
size_t net_num_leaf_type_changes() const
Getter for the net number of leaf type change diff nodes.
const diff_context_sptr context() const
Getter of the diff context of this diff.
const string_elf_symbol_map & deleted_unrefed_variable_symbols() const
Getter for variable symbols not referenced by any debug info and that got deleted.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
subrange_diff(const array_type_def::subrange_sptr &first, const array_type_def::subrange_sptr &second, const diff_sptr &underlying_type_diff, const diff_context_sptr ctxt=diff_context_sptr())
Constructor of the subrange_diff diff node type.
void do_dump_diff_tree(const diff_sptr) const
Emit a textual representation of a diff tree to the error output stream of the current context...
shared_ptr< variable_suppression > variable_suppression_sptr
A convenience typedef for a shared pointer to variable_suppression.
const suppr::suppressions_type & direct_suppressions() const
Getter of the direct suppression specification (those that are not negated) comprised in the general ...
virtual enum change_kind has_local_changes() const
const class_or_union_diff * is_diff_of_class_or_union_type(const diff *d)
Test if a diff node represents a diff between two class or union types.
This means that a given IR artifact has a local non-type change. That is a change that is carried by ...
const suppr::suppressions_type & negated_suppressions() const
Getter of the negated suppression specifications that are comprised in the general vector of suppress...
bool visiting_a_node_twice_is_forbidden_per_interface() const
Return a flag that, if true, then during the traversing of a diff nodes tree each node is visited at ...
bool show_changed_vars() const
reference_type_def_sptr first_reference() const
Getter for the first reference of the diff.
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...
const diff_sptr compatible_child_diff() const
Getter for the child diff of this distinct_diff instance.
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
virtual void report(ostream &, const string &indent="") const
Report about the changes carried by this node.
"Less than" functor to compare instances of function_decl.
void add_to_local_and_inherited_categories(diff_category c)
Adds the current diff tree node to the categories resulting from the local and inherited changes of t...
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.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
Functor that compares two function parameters for the purpose of sorting them.
bool is_private_type_suppr_spec(const type_suppression &s)
Test if a type suppression specification represents a private type suppression automatically generate...
const function_type_diff * is_function_type_diff(const diff *diff)
Test if a diff node is a function_type_diff node.
const function_decl_diff_sptrs_type & changed_member_fns() const
Getter for the virtual members functions that have had a change in a sub-type, without having a chang...
string get_pretty_representation(const type_or_decl_base *tod, bool internal)
Build and return a copy of the pretty representation of an ABI artifact that could be either a type o...
void compute_diff(RandomAccessOutputIterator a_base, RandomAccessOutputIterator a_begin, RandomAccessOutputIterator a_end, RandomAccessOutputIterator b_base, RandomAccessOutputIterator b_begin, RandomAccessOutputIterator b_end, vector< point > &lcs, edit_script &ses, int &ses_len)
Compute the longest common subsequence of two (sub-regions of) sequences as well as the shortest edit...
virtual enum change_kind has_local_changes() const
virtual bool has_changes() const =0
Pure interface to get the length of the changes encapsulated by this diff. A length of zero means tha...
This says that the traversing code should avoid visiting the children nodes of the current node being...
decl_base_sptr member_class_tmpl_has_changed(decl_base_sptr) const
Test if the current diff node carries a member class template change for a member class template whic...
shared_ptr< function_suppression > function_suppression_sptr
Convenience typedef for a shared pointer to function_suppression.
friend void apply_suppressions(const corpus_diff *diff_tree)
Walk a corpus_diff tree and appply the suppressions carried by the context. If the suppression applie...
virtual const string & get_pretty_representation() const
virtual enum change_kind has_local_changes() const
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...
A diff node in this category carries a change in the size of the array type of a global variable...
const translation_unit_sptr second_translation_unit() const
Getter for the second translation unit of this diff.
const vector< diff_sptr > & changed_unreachable_types_sorted() const
Getter of a sorted vector of changed types that are not reachable from global functions/variables.
size_t get_inserted_non_static_data_members_number() const
Get the number of non static data members that were inserted.
const string_base_sptr_map & deleted_bases() const
Getter for the deleted base classes of the diff.
type_or_decl_base_sptr second_subject() const
Getter of the second subject of the diff.
const var_diff_sptrs_type & sorted_changed_data_members() const
Getter of the sorted vector of data members that got replaced by another data member.
size_t num_added_vars_filtered_out() const
Getter for the number of added variables that have been filtered out.
bool deleted_unreachable_type_is_suppressed(const type_base *t) const
Test if a deleted type that is unreachable from public interface has been suppressed by a suppression...
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...
const diff_sptr & underlying_type_diff() const
Getter for the diff between the two referred-to types.
bool is_allowed_by_specific_negated_suppression() const
Test if this diff node is allowed (prevented from being suppressed) by at least one negated suppressi...
const function_decl_diff_sptrs_type & changed_functions_sorted()
Getter for a sorted vector of functions which signature didn't change, but which do have some indirec...
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
bool has_basic_or_class_type_name_change(const diff *d)
Test if a diff node carries a basic or class type name change.
virtual void report(ostream &out, const string &indent="") const
Report the diff in a serialized form.
union_decl_sptr first_union_decl() const
void categorize_redundancy(diff *diff_tree)
Walk a given diff sub-tree to categorize each of the nodes with respect to the REDUNDANT_CATEGORY.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of typedef_dif...
void apply_filters_and_compute_diff_stats(corpus_diff::diff_stats &)
Compute the diff stats.
size_t num_changed_unreachable_types() const
Getter of the number of changed types that are unreachable from the public interface of the ABI corpu...
The abstraction of a typedef declaration.
std::vector< filter_base_sptr > filters
Convenience typedef for a vector of filter_base_sptr.
const diff_sptr underlying_type_diff() const
Getter for the diff between the two underlying types of the typedefs.
const vector< type_base_sptr > & added_unreachable_types_sorted() const
Getter of a sorted vector of added types that are not reachable from global functions/variables.
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
void set_visiting_kind(visiting_kind v)
Setter for the visiting policy of the traversing code while invoking this visitor.
artifact_sptr_set_type * lookup_impacted_interfaces(const diff *d) const
Lookup the interfaces that are impacted by a given leaf diff node.
vector< base_spec_sptr > base_specs
Convenience typedef.
void count_unreachable_types(size_t &num_added, size_t &num_removed, size_t &num_changed, size_t &num_filtered_added, size_t &num_filtered_removed, size_t &num_filtered_changed)
Count the number of types not reachable from the interface (i.e, not reachable from global functions ...
This is a document class that aims to capture statistics about the changes carried by a corpus_diff t...
virtual bool has_changes() const
Return true iff the current diff node carries a change.
bool visiting_a_node_twice_is_forbidden() const
Return a flag that, if true, then during the traversing of a diff nodes tree each node is visited at ...
const union_diff * is_union_diff(const diff *diff)
Test if a diff node is a union_diff node.
virtual const string & get_pretty_representation() const
void print_diff_tree(diff *diff_tree, ostream &out)
Emit a textual representation of a diff sub-tree to an output stream.
diff_maps & get_leaf_diffs()
Get the set of maps that contain leaf nodes. A leaf node being a node with a local change...
The internal type for the impl idiom implementation of var_diff.
A diff node in this category is a function return type with a cv-qualifier change.
array_diff(const array_type_def_sptr first, const array_type_def_sptr second, diff_sptr element_type_diff, diff_context_sptr ctxt=diff_context_sptr())
Constructor for array_diff.
const string_diff_ptr_map & get_fn_parm_diff_map() const
Getter of the map that contains function parameter diffs.
reference_diff(const reference_type_def_sptr first, const reference_type_def_sptr second, diff_sptr underlying, diff_context_sptr ctxt=diff_context_sptr())
Constructor for reference_diff.
shared_ptr< diff > diff_sptr
Convenience typedef for a shared_ptr for the diff class.
shared_ptr< reporter_base > reporter_base_sptr
A convenience typedef for a shared pointer to a reporter_base.
enum_diff(const enum_type_decl_sptr, const enum_type_decl_sptr, const diff_sptr, diff_context_sptr ctxt=diff_context_sptr())
Constructor for enum_diff.
friend function_type_diff_sptr compute_diff(const function_type_sptr first, const function_type_sptr second, diff_context_sptr ctxt)
Compute the diff between two instances of function_type.
const vector< type_base_sptr > & deleted_unreachable_types_sorted() const
Getter of a sorted vector of deleted types that are not reachable from global functions/variables.
const distinct_diff * is_distinct_diff(const diff *diff)
Test if a diff node is about differences between two diff nodes of different kinds.
distinct_diff_sptr compute_diff_for_distinct_kinds(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second, diff_context_sptr ctxt)
Try to diff entities that are of distinct kinds.
const diff * peel_pointer_diff(const diff *dif)
If a diff node is about changes between two pointer types, get the diff node about changes between th...
reporter_base_sptr get_reporter() const
Getter of the reporter to be used in this context.
size_t net_num_leaf_func_changes() const
Getter for the net number of leaf function change diff nodes.
bool show_changed_fns() const
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...
class_decl::base_spec_sptr base_has_changed(class_decl::base_spec_sptr) const
Test whether a given base class has changed. A base class has changed if it's in both in deleted *and...
var_diff(var_decl_sptr first, var_decl_sptr second, diff_sptr type_diff, diff_context_sptr ctxt=diff_context_sptr())
Constructor for var_diff.
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.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
virtual void report(ostream &, const string &indent="") const
Emit a textual report about the current fn_parm_diff instance.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
bool is_diff_of_variadic_parameter_type(const diff *d)
Test if a diff node represents the difference between a variadic parameter type and something else...
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
visiting_kind operator~(visiting_kind l)
The overloaded 'bit inversion' operator for visiting_kind.
virtual const string & get_pretty_representation() const
bool architecture_changed() const
Test if the architecture of the underlying corpus has changed.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
bool is_decl_only_class_with_size_change(const class_or_union &first, const class_or_union &second)
Test if two classes that are decl-only (have the decl-only flag and carry no data members) but are di...
Abstraction of a diff between two function types.
virtual enum change_kind has_local_changes() const
class_diff(class_decl_sptr first_scope, class_decl_sptr second_scope, diff_context_sptr ctxt=diff_context_sptr())
Constructor of class_diff.
const class_diff_sptr get_underlying_class_diff() const
Getter for the diff object for the diff of the underlying base classes.
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
shared_ptr< filter_base > filter_base_sptr
Convenience typedef for a shared pointer to filter_base.
const array_type_def_sptr first_array() const
Getter for the first array of the diff.
virtual const string & get_pretty_representation() const
const base_diff_sptrs_type & changed_bases()
Getter for the changed base classes of the diff.
const diff_sptr return_type_diff() const
Getter for the diff of the return types of the two function types of the current diff.
void ensure_lookup_tables_populated(void) const
If the lookup tables are not yet built, walk the differences and fill them.
A comparison functor for instances of function_decl_diff that represent changes between two virtual m...
const string_type_base_sptr_map & deleted_unreachable_types() const
Getter for a map of deleted types that are not reachable from global functions/variables.
const diff_context_sptr context() const
Getter of the context of the current diff.
Abstraction of a function type.
virtual void finish_diff_type()
Finish the insertion of a diff tree node into the diff graph.
const enum_type_decl_sptr second_enum() const
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...
size_t num_removed_func_filtered_out() const
Getter for the number of removed functions that have been filtered out.
const class_or_union_diff::priv_ptr & get_priv() const
Getter of the private data of the class_or_union_diff type.
void add_diff_filter(filtering::filter_base_sptr)
Setter for the diff filters to apply to a given diff sub-tree.
const vector< diff_sptr > & changed_unreachable_types_sorted() const
Get the sorted vector of diff nodes representing changed unreachable types.
size_t num_func_syms_removed() const
Getter for the number of function symbols (not referenced by any debug info) that got removed...
const unsigned_var_diff_sptr_map & changed_data_members() const
Getter of the map of data members that got replaced by another data member. The key of the map is the...
diff_category add_to_local_category(diff_category c)
Adds the current diff tree node to the categories resulting from the local changes of the current dif...
This means that a diff node in the sub-tree carries an addition or removal of a static data member...