19#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);
181get_symbol(
const decl_base_sptr& d)
184 return fn->get_symbol();
186 return var->get_symbol();
205 string fr = f->get_qualified_name(), sr = s->get_qualified_name();
210 if (!f->get_linkage_name().empty()
211 && !s->get_linkage_name().empty())
213 fr = f->get_linkage_name();
214 sr = s->get_linkage_name();
219 if (get_symbol(f) && get_symbol(s))
221 fr = get_symbol(f)->get_id_string();
222 sr = get_symbol(s)->get_id_string();
227 fr = f->get_pretty_representation(
true,
true);
228 sr = s->get_pretty_representation(
true,
true);
245 if (!first || !second)
259 vector<const function_decl*>& sorted)
261 sorted.reserve(map.size());
262 for (string_function_ptr_map::const_iterator i = map.begin();
265 sorted.push_back(i->second);
268 std::sort(sorted.begin(), sorted.end(), comp);
282 sorted.reserve(map.size());
283 for (string_member_function_sptr_map::const_iterator i = map.begin();
286 sorted.push_back(i->second);
289 std::sort(sorted.begin(), sorted.end(), comp);
305 sorted.reserve(map.size());
306 for (string_function_decl_diff_sptr_map::const_iterator i = map.begin();
309 sorted.push_back(i->second);
311 std::sort(sorted.begin(), sorted.end(), comp);
324 std::sort(fn_diffs.begin(), fn_diffs.end(), comp);
337 sorted.reserve(map.size());
338 for (string_var_diff_sptr_map::const_iterator i = map.begin();
341 sorted.push_back(i->second);
344 std::sort(sorted.begin(), sorted.end(), comp);
357 std::sort(var_diffs.begin(), var_diffs.end(), comp);
371 vector<elf_symbol_sptr>& sorted)
373 for (string_elf_symbol_map::const_iterator i = map.begin();
376 sorted.push_back(i->second);
379 std::sort(sorted.begin(), sorted.end(), comp);
392 vector<var_decl_sptr>& sorted)
394 for (string_var_ptr_map::const_iterator i = map.begin();
397 sorted.push_back(i->second);
400 std::sort(sorted.begin(), sorted.end(), comp);
413 sorted.reserve(map.size());
414 for (string_var_diff_sptr_map::const_iterator i = map.begin();
417 sorted.push_back(i->second);
419 std::sort(sorted.begin(), sorted.end(), comp);
432 sorted.reserve(map.size());
433 for (unsigned_var_diff_sptr_map::const_iterator i = map.begin();
436 sorted.push_back(i->second);
438 std::sort(sorted.begin(), sorted.end(), comp);
454 sorted.reserve(map.size());
455 for (string_function_decl_diff_sptr_map::const_iterator i = map.begin();
458 sorted.push_back(i->second);
461 sort(sorted.begin(), sorted.end(), comp);
475 sorted.reserve(map.size());
476 for (string_diff_sptr_map::const_iterator i = map.begin();
479 sorted.push_back(i->second);
482 sort(sorted.begin(), sorted.end(), comp);
496 sorted.reserve(map.size());
497 for (string_diff_ptr_map::const_iterator i = map.begin();
500 sorted.push_back(i->second);
503 sort(sorted.begin(), sorted.end(), comp);
517 for (string_base_diff_sptr_map::const_iterator i = map.begin();
520 sorted.push_back(i->second);
522 sort(sorted.begin(), sorted.end(), comp);
531 for (string_base_sptr_map::const_iterator i = m.begin();
534 sorted.push_back(i->second);
537 std::sort(sorted.begin(), sorted.end(), comp);
549 vector<fn_parm_diff_sptr>& sorted)
551 sorted.reserve(map.size());
552 for (unsigned_fn_parm_diff_sptr_map::const_iterator i = map.begin();
555 sorted.push_back(i->second);
558 std::sort(sorted.begin(), sorted.end(), comp);
570 vector<fn_parm_diff_sptr>& sorted)
572 sorted.reserve(map.size());
573 for (string_fn_parm_diff_sptr_map::const_iterator i = map.begin();
576 sorted.push_back(i->second);
579 std::sort(sorted.begin(), sorted.end(), comp);
590 vector<function_decl::parameter_sptr>& sorted)
592 for (string_parm_map::const_iterator i = map.begin();
595 sorted.push_back(i->second);
598 std::sort(sorted.begin(), sorted.end(), comp);
610 vector<type_or_decl_base_sptr>& sorted)
613 for (artifact_sptr_set_type::const_iterator it = set.begin();
616 sorted.push_back(*it);
619 std::sort(sorted.begin(), sorted.end(), comp);
634 vector<type_base_sptr>& sorted)
636 for (string_type_base_sptr_map::const_iterator i = map.begin();
639 sorted.push_back(i->second);
642 std::sort(sorted.begin(), sorted.end(), comp);
654 return type_base_sptr();
656 type_base_sptr ut = t->get_underlying_type();
657 qualified_type_def_sptr qut = dynamic_pointer_cast<qualified_type_def>(ut);
685 if (decl_base_sptr decl =
is_decl(first))
702 |
static_cast<unsigned>(r));}
709 &
static_cast<unsigned>(r));
715{
return static_cast<visiting_kind>(~static_cast<unsigned>(l));}
788 if (dif->first_class_or_union()->get_is_anonymous())
824 if (dif->first_subrange()->get_is_anonymous())
861 if (d->has_local_changes())
1035diff_context::diff_context()
1055diff_context::~diff_context() =
default;
1062{
return priv_->do_log_;}
1069{priv_->do_log_ = f;}
1076{priv_->corpus_diff_ = d;}
1083{
return priv_->corpus_diff_;}
1092 if (priv_->corpus_diff_)
1093 return priv_->corpus_diff_->first_corpus();
1094 return corpus_sptr();
1105 if (priv_->corpus_diff_)
1106 return priv_->corpus_diff_->second_corpus();
1107 return corpus_sptr();
1116 if (!priv_->reporter_)
1124 return priv_->reporter_;
1132{priv_->reporter_ = r;}
1146 types_or_decls_diff_map_type::const_iterator i =
1147 priv_->types_or_decls_diff_map.find(std::make_pair(first, second));
1148 if (i != priv_->types_or_decls_diff_map.end())
1162diff_context::has_diff_for_types(
const type_base_sptr first,
1163 const type_base_sptr second)
const
1164{
return has_diff_for(first, second);}
1172diff_context::has_diff_for(
const diff* d)
const
1173{
return has_diff_for(d->first_subject(), d->second_subject()).get();}
1181diff_context::has_diff_for(
const diff_sptr d)
const
1182{
return has_diff_for(d->first_subject(), d->second_subject());}
1191{
return priv_->allowed_category_;}
1200{priv_->allowed_category_ = c;}
1213{priv_->allowed_category_ = priv_->allowed_category_ | c;}
1224{priv_->allowed_category_ = priv_->allowed_category_ & ~c;}
1240{priv_->types_or_decls_diff_map[std::make_pair(first, second)] = d;}
1246diff_context::add_diff(
const diff* d)
1259diff_context::add_diff(
const diff_sptr d)
1262 add_diff(d->first_subject(), d->second_subject(), d);
1279{
return has_diff_for(first, second);}
1291{
return has_diff_for(d);}
1307 if (!has_diff_for(first, second))
1309 add_diff(first, second, d);
1310 priv_->canonical_diffs.push_back(d);
1335 canonical = canonical_diff;
1336 set_canonical_diff_for(first, second, canonical);
1379{priv_->live_diffs_.insert(d);}
1392 size_t ptr_value =
reinterpret_cast<size_t>(canonical);
1393 pointer_map::iterator it = priv_->visited_diff_nodes_.find(ptr_value);
1394 if (it != priv_->visited_diff_nodes_.end())
1395 return reinterpret_cast<diff*
>(it->second);
1428 size_t canonical_ptr_value =
reinterpret_cast<size_t>(canonical);
1429 size_t diff_ptr_value =
reinterpret_cast<size_t>(d);
1430 priv_->visited_diff_nodes_[canonical_ptr_value] = diff_ptr_value;
1436{priv_->visited_diff_nodes_.clear();}
1446{priv_->forbid_visiting_a_node_twice_ = f;}
1456{priv_->reset_visited_diffs_for_each_interface_ = f;}
1464{
return priv_->forbid_visiting_a_node_twice_;}
1478 return (priv_->forbid_visiting_a_node_twice_
1479 && priv_->reset_visited_diffs_for_each_interface_);
1487{
return priv_->filters_;}
1495{priv_->filters_.push_back(f);}
1513 for (filtering::filters::const_iterator i =
diff_filters().begin();
1520 std::cerr <<
"applying a filter to diff '"
1531 std::cerr <<
"filter applied in:" << t <<
"\n";
1533 std::cerr <<
"propagating categories for the same diff node ... \n";
1542 std::cerr <<
"categories propagated in: " << t <<
"\n";
1563 for (filtering::filters::const_iterator i =
diff_filters().begin();
1578{
return priv_->suppressions_;}
1589 priv_->negated_suppressions_.clear();
1590 priv_->direct_suppressions_.clear();
1591 return priv_->suppressions_;
1610 if (priv_->negated_suppressions_.empty())
1613 priv_->negated_suppressions_.push_back(s);
1615 return priv_->negated_suppressions_;
1633 if (priv_->direct_suppressions_.empty())
1637 priv_->direct_suppressions_.push_back(s);
1639 return priv_->direct_suppressions_;
1650 priv_->suppressions_.push_back(suppr);
1653 priv_->negated_suppressions_.clear();
1654 priv_->direct_suppressions_.clear();
1665 priv_->suppressions_.insert(priv_->suppressions_.end(),
1666 supprs.begin(), supprs.end());
1675{
return priv_->perform_change_categorization_;}
1682{priv_->perform_change_categorization_ = f;}
1696 priv_->leaf_changes_only_ = f;
1706{
return priv_->leaf_changes_only_;}
1716{
return priv_->hex_values_;}
1726{priv_->hex_values_ = f;}
1735{
return priv_->show_offsets_sizes_in_bits_;}
1744{priv_->show_offsets_sizes_in_bits_ = f;}
1753{priv_->show_relative_offset_changes_ = f;}
1762{
return priv_->show_relative_offset_changes_;}
1770{priv_->show_stats_only_ = f;}
1778{
return priv_->show_stats_only_;}
1786{priv_->show_soname_change_ = f;}
1794{
return priv_->show_soname_change_;}
1802{priv_->show_architecture_change_ = f;}
1810{
return priv_->show_architecture_change_;}
1817{priv_->show_deleted_fns_ = f;}
1823{
return priv_->show_deleted_fns_;}
1830{priv_->show_changed_fns_ = f;}
1835{
return priv_->show_changed_fns_;}
1842{priv_->show_added_fns_ = f;}
1848{
return priv_->show_added_fns_;}
1855{priv_->show_deleted_vars_ = f;}
1861{
return priv_->show_deleted_vars_;}
1868{priv_->show_changed_vars_ = f;}
1873{
return priv_->show_changed_vars_;}
1880{priv_->show_added_vars_ = f;}
1886{
return priv_->show_added_vars_;}
1893{priv_->show_num_filtered_data_members_ = f;}
1900{
return priv_->show_num_filtered_data_members_;}
1903diff_context::show_linkage_names()
const
1904{
return priv_->show_linkage_names_;}
1907diff_context::show_linkage_names(
bool f)
1908{priv_->show_linkage_names_= f;}
1915{priv_->show_locs_= f;}
1921{
return priv_->show_locs_;}
1930{
return priv_->show_redundant_changes_;}
1940 priv_->show_redundant_changes_ = f;
1942 if (priv_->show_redundant_changes_)
1954{
return priv_->show_syms_unreferenced_by_di_;}
1962{priv_->show_syms_unreferenced_by_di_ = f;}
1971{
return priv_->show_added_syms_unreferenced_by_di_;}
1980{priv_->show_added_syms_unreferenced_by_di_ = f;}
1989{priv_->show_unreachable_types_ = f;}
1998{
return priv_->show_unreachable_types_;}
2009{
return priv_->show_impacted_interfaces_;}
2020{priv_->show_impacted_interfaces_ = f;}
2029{priv_->default_output_stream_ = o;}
2038{
return priv_->default_output_stream_;}
2046{priv_->error_output_stream_ = o;}
2054{
return priv_->error_output_stream_;}
2063{
return priv_->dump_diff_tree_;}
2072{priv_->dump_diff_tree_ = f;}
2111 : priv_(new priv(first_subject, second_subject,
2133 : priv_(new priv(first_subject, second_subject,
2172 if (priv_->canonical_diff_)
2173 priv_->canonical_diff_->priv_->traversing_ =
true;
2174 priv_->traversing_ =
true;
2191 if (priv_->canonical_diff_)
2192 return priv_->canonical_diff_->priv_->traversing_;
2193 return priv_->traversing_;
2207 if (priv_->canonical_diff_)
2208 priv_->canonical_diff_->priv_->traversing_ =
false;
2209 priv_->traversing_ =
false;
2225 if (diff::priv_->finished_)
2228 diff::priv_->finished_ =
true;
2236{
return dynamic_pointer_cast<type_or_decl_base>(priv_->first_subject_);}
2243{
return dynamic_pointer_cast<type_or_decl_base>(priv_->second_subject_);}
2250{
return priv_->children_;}
2257{
return priv_->parent_;}
2270{
return priv_->canonical_diff_;}
2278{priv_->canonical_diff_ = d;}
2291 context()->keep_diff_alive(d);
2298 priv_->children_.push_back(d.get());
2300 d->priv_->parent_ =
this;
2308{
return priv_->get_context();}
2325 if (priv_->canonical_diff_)
2326 return priv_->canonical_diff_->priv_->currently_reporting_;
2327 return priv_->currently_reporting_;
2338 if (priv_->canonical_diff_)
2339 priv_->canonical_diff_->priv_->currently_reporting_ = f;
2340 priv_->currently_reporting_ = f;
2351 return priv_->canonical_diff_->priv_->reported_once_;
2411 bool already_visited =
false;
2412 if (
context()->visiting_a_node_twice_is_forbidden()
2413 &&
context()->diff_has_been_visited(
this))
2414 already_visited =
true;
2416 bool mark_visited_nodes_as_traversed =
2419 if (!already_visited && !v.
visit(
this,
true))
2422 if (mark_visited_nodes_as_traversed)
2423 context()->mark_diff_as_visited(
this);
2429 && !already_visited)
2436 if (!(*i)->traverse(v))
2439 if (mark_visited_nodes_as_traversed)
2440 context()->mark_diff_as_visited(
this);
2448 if (!v.
visit(
this,
false))
2451 if (mark_visited_nodes_as_traversed)
2452 context()->mark_diff_as_visited(
this);
2457 if (!already_visited && mark_visited_nodes_as_traversed)
2458 context()->mark_diff_as_visited(
this);
2472 priv_->canonical_diff_->priv_->reported_once_ = f;
2473 priv_->reported_once_ = f;
2485{
return priv_->local_category_;}
2511{
return priv_->category_;}
2526 priv_->category_ = priv_->category_ | c;
2527 return priv_->category_;
2541 priv_->local_category_ = priv_->local_category_ | c;
2542 return priv_->local_category_;
2570 priv_->category_ = priv_->category_ & ~c;
2571 return priv_->category_;
2585 priv_->local_category_ = priv_->local_category_ & ~c;
2586 return priv_->local_category_;
2596{priv_->category_ = c;}
2603{priv_->local_category_ = c;}
2628 && !canonical->is_allowed_by_specific_negated_suppression()
2629 && !canonical->has_descendant_allowed_by_specific_negated_suppression()
2630 && !canonical->has_parent_allowed_by_specific_negated_suppression())
2671 return priv_->is_filtered_out(c);
2682 bool is_private =
false;
2711 bool do_suppress = !
context()->negated_suppressions().empty();
2715 for (
auto n :
context()->negated_suppressions())
2716 if (!n->suppresses_diff(
this))
2718 do_suppress =
false;
2725 for (
auto d :
context()->direct_suppressions())
2726 if (d->suppresses_diff(
this))
2730 is_private_type =
true;
2784 for (suppressions_type::const_iterator i = suppressions.begin();
2785 i != suppressions.end();
2789 && !(*i)->suppresses_diff(
this))
2829 if (priv_->pretty_representation_.empty())
2830 priv_->pretty_representation_ =
"empty_diff";
2831 return priv_->pretty_representation_;
2858type_diff_base::type_diff_base(type_base_sptr first_subject,
2859 type_base_sptr second_subject,
2861 :
diff(first_subject, second_subject, ctxt),
2865type_diff_base::~type_diff_base()
2881 decl_base_sptr second_subject,
2883 :
diff(first_subject, second_subject, ctxt),
2887decl_diff_base::~decl_diff_base()
2898 if (diff::priv_->pretty_representation_.empty())
2900 std::ostringstream o;
2901 o <<
"distinct_diff[";
2912 diff::priv_->pretty_representation_ = o.str();
2914 return diff::priv_->pretty_representation_;
2947 :
diff(first, second, ctxt),
2981 if (!priv_->compatible_child_diff)
2989 priv_->compatible_child_diff =
2995 return priv_->compatible_child_diff;
3020 return typeid(f) !=
typeid(s);
3038 return NO_CHANGE_KIND;
3049 context()->get_reporter()->report(*
this, out, indent);
3072 ctxt->initialize_canonical_diff(result);
3097template<
typename DiffType>
3103 if (shared_ptr<DiffType> f =
3104 dynamic_pointer_cast<DiffType>(first))
3106 shared_ptr<DiffType> s =
3107 dynamic_pointer_cast<DiffType>(second);
3133 dynamic_pointer_cast<class_decl>(first))
3139 if (f->get_is_declaration_only())
3146 if (s->get_is_declaration_only())
3201 ((d = try_to_diff<type_decl>(f, s, ctxt))
3202 ||(d = try_to_diff<enum_type_decl>(f, s, ctxt))
3203 ||(d = try_to_diff<union_decl>(f, s,ctxt))
3205 ||(d = try_to_diff<pointer_type_def>(f, s, ctxt))
3206 ||(d = try_to_diff<reference_type_def>(f, s, ctxt))
3207 ||(d = try_to_diff<ptr_to_mbr_type>(f, s, ctxt))
3208 ||(d = try_to_diff<array_type_def::subrange_type>(f, s, ctxt))
3209 ||(d = try_to_diff<array_type_def>(f, s, ctxt))
3210 ||(d = try_to_diff<qualified_type_def>(f, s, ctxt))
3211 ||(d = try_to_diff<typedef_decl>(f, s, ctxt))
3212 ||(d = try_to_diff<function_type>(f, s, ctxt))
3213 ||(d = try_to_diff_distinct_kinds(f, s, ctxt)));
3223 |
static_cast<unsigned>(c2));}
3242 ^
static_cast<unsigned>(c2));}
3247 &
static_cast<unsigned>(c2));}
3251{
return static_cast<diff_category>(~static_cast<unsigned>(c));}
3290 | abigail::comparison::REFERENCE_LVALUENESS_CHANGE_CATEGORY
3332 bool emitted_a_category =
false;
3336 o <<
"NO_CHANGE_CATEGORY";
3337 emitted_a_category =
true;
3342 if (emitted_a_category)
3344 o <<
"ACCESS_CHANGE_CATEGORY";
3345 emitted_a_category |=
true;
3350 if (emitted_a_category)
3352 o <<
"COMPATIBLE_TYPE_CHANGE_CATEGORY";
3353 emitted_a_category |=
true;
3358 if (emitted_a_category)
3360 o <<
"HARMLESS_DECL_NAME_CHANGE_CATEGORY";
3361 emitted_a_category |=
true;
3366 if (emitted_a_category)
3368 o <<
"NON_VIRT_MEM_FUN_CHANGE_CATEGORY";
3369 emitted_a_category |=
true;
3374 if (emitted_a_category)
3376 o <<
"STATIC_DATA_MEMBER_CHANGE_CATEGORY";
3377 emitted_a_category |=
true;
3382 if (emitted_a_category)
3384 o <<
"HARMLESS_ENUM_CHANGE_CATEGORY";
3385 emitted_a_category |=
true;
3390 if (emitted_a_category)
3392 o <<
"HARMLESS_DATA_MEMBER_CHANGE_CATEGORY";
3393 emitted_a_category |=
true;
3398 if (emitted_a_category)
3400 o <<
"HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY";
3401 emitted_a_category |=
true;
3406 if (emitted_a_category)
3408 o <<
"HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY";
3409 emitted_a_category |=
true;
3414 if (emitted_a_category)
3416 o <<
"SUPPRESSED_CATEGORY";
3417 emitted_a_category |=
true;
3422 if (emitted_a_category)
3424 o <<
"PRIVATE_TYPE_CATEGORY";
3425 emitted_a_category |=
true;
3430 if (emitted_a_category)
3432 o <<
"SIZE_OR_OFFSET_CHANGE_CATEGORY";
3433 emitted_a_category |=
true;
3438 if (emitted_a_category)
3440 o <<
"VIRTUAL_MEMBER_CHANGE_CATEGORY";
3441 emitted_a_category |=
true;
3444 if (c & REFERENCE_LVALUENESS_CHANGE_CATEGORY)
3446 if (emitted_a_category)
3448 o <<
"REFERENCE_LVALUENESS_CHANGE_CATEGORY";
3449 emitted_a_category |=
true;
3454 if (emitted_a_category)
3456 o <<
"NON_COMPATIBLE_DISTINCT_CHANGE_CATEGORY";
3457 emitted_a_category |=
true;
3462 if (emitted_a_category)
3464 o <<
"NON_COMPATIBLE_NAME_CHANGE_CATEGORY";
3465 emitted_a_category |=
true;
3470 if (emitted_a_category)
3472 o <<
"REDUNDANT_CATEGORY";
3473 emitted_a_category |=
true;
3478 if (emitted_a_category)
3480 o <<
"TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY";
3481 emitted_a_category |=
true;
3486 if (emitted_a_category)
3488 o <<
"FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY";
3489 emitted_a_category |=
true;
3494 if (emitted_a_category)
3496 o <<
"FN_PARM_TYPE_CV_CHANGE_CATEGORY";
3497 emitted_a_category |=
true;
3502 if (emitted_a_category)
3504 o <<
"FN_RETURN_TYPE_CV_CHANGE_CATEGORY";
3505 emitted_a_category |=
true;
3510 if (emitted_a_category)
3512 o <<
"FN_PARM_ADD_REMOVE_CHANGE_CATEGORY";
3513 emitted_a_category |=
true;
3518 if (emitted_a_category)
3520 o <<
"VAR_TYPE_CV_CHANGE_CATEGORY";
3521 emitted_a_category |=
true;
3526 if (emitted_a_category)
3528 o <<
"VOID_PTR_TO_PTR_CHANGE_CATEGORY";
3529 emitted_a_category |=
true;
3534 if (emitted_a_category)
3536 o <<
"BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY";
3537 emitted_a_category |=
true;
3542 if (emitted_a_category)
3544 o <<
"HAS_ALLOWED_CHANGE_CATEGORY";
3545 emitted_a_category |=
true;
3550 if (emitted_a_category)
3552 o <<
"HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY";
3553 emitted_a_category |=
true;
3558 if (emitted_a_category)
3560 o <<
"HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY";
3561 emitted_a_category |=
true;
3584compute_diff_for_decls(
const decl_base_sptr first,
3585 const decl_base_sptr second,
3591 ((d = try_to_diff<function_decl>(first, second, ctxt))
3592 || (d = try_to_diff<var_decl>(first, second, ctxt))
3593 || (d = try_to_diff_distinct_kinds(first, second, ctxt)));
3616 const decl_base_sptr second,
3619 if (!first || !second)
3624 d = compute_diff_for_types(first, second, ctxt);
3626 d = compute_diff_for_decls(first, second, ctxt);
3646 const type_base_sptr second,
3652 diff_sptr d = compute_diff_for_types(f,s, ctxt);
3667 string prefix=
"diff of ";
3687 if (diff::priv_->pretty_representation_.empty())
3689 std::ostringstream o;
3695 diff::priv_->pretty_representation_ = o.str();
3697 return diff::priv_->pretty_representation_;
3740 if (
diff_sptr result = priv_->type_diff_.lock())
3747 context()->keep_diff_alive(result);
3748 priv_->type_diff_ = result;
3769 return ir::NO_CHANGE_KIND;
3781 context()->get_reporter()->report(*
this, out, indent);
3802 ctxt->initialize_canonical_diff(d);
3832 priv_(new
priv(underlying))
3840{
return dynamic_pointer_cast<pointer_type_def>(
first_subject());}
3847{
return dynamic_pointer_cast<pointer_type_def>(
second_subject());}
3854 if (diff::priv_->pretty_representation_.empty())
3856 std::ostringstream o;
3857 o <<
"pointer_diff["
3862 diff::priv_->pretty_representation_ = o.str();
3864 return diff::priv_->pretty_representation_;
3883 return ir::NO_CHANGE_KIND;
3892{
return priv_->underlying_type_diff_;}
3901{priv_->underlying_type_diff_ = d;}
3912 context()->get_reporter()->report(*
this, out, indent);
3932 diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
3933 second->get_pointed_to_type(),
3936 ctxt->initialize_canonical_diff(result);
3961 priv_(new
priv(underlying_type_diff))
3989{
return priv_->underlying_type_diff_;}
3998 if (diff::priv_->pretty_representation_.empty())
4000 std::ostringstream o;
4001 o <<
"subrange_diff["
4006 diff::priv_->pretty_representation_ = o.str();
4008 return diff::priv_->pretty_representation_;
4030 return ir::NO_CHANGE_KIND;
4040{
context()->get_reporter()->report(*
this, out, indent);}
4068 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
4069 second->get_underlying_type(),
4073 ctxt->initialize_canonical_diff(result);
4108 vector<subrange_diff_sptr>& subrange_diffs,
4111 priv_(new
priv(element_type_diff, subrange_diffs))
4119{
return dynamic_pointer_cast<array_type_def>(
first_subject());}
4133{
return priv_->element_type_diff_;}
4138const vector<subrange_diff_sptr>&
4140{
return priv_->subrange_diffs_;}
4161{priv_->element_type_diff_ = d;}
4168{priv_->subrange_diffs_ = d;}
4175 if (diff::priv_->pretty_representation_.empty())
4177 std::ostringstream o;
4183 diff::priv_->pretty_representation_ = o.str();
4185 return diff::priv_->pretty_representation_;
4202 if (f->get_name() != s->get_name())
4204 if (f->get_size_in_bits() != s->get_size_in_bits())
4206 if (f->get_alignment_in_bits() != s->get_alignment_in_bits())
4229 return ir::NO_CHANGE_KIND;
4240 context()->get_reporter()->report(*
this, out, indent);
4258 diff_sptr element_diff = compute_diff_for_types(first->get_element_type(),
4259 second->get_element_type(),
4261 vector<subrange_diff_sptr> subrange_diffs;
4262 if (first->get_subranges().size() == first->get_subranges().size())
4264 for (
unsigned i = 0; i < first->get_subranges().size(); ++i)
4268 second->get_subranges()[i],
4277 ctxt->initialize_canonical_diff(result);
4305 priv_(new
priv(underlying))
4313{
return dynamic_pointer_cast<reference_type_def>(
first_subject());}
4320{
return dynamic_pointer_cast<reference_type_def>(
second_subject());}
4328{
return priv_->underlying_type_diff_;}
4336 priv_->underlying_type_diff_ = d;
4337 return priv_->underlying_type_diff_;
4345 if (diff::priv_->pretty_representation_.empty())
4347 std::ostringstream o;
4348 o <<
"reference_diff["
4353 diff::priv_->pretty_representation_ = o.str();
4355 return diff::priv_->pretty_representation_;
4376 return ir::NO_CHANGE_KIND;
4387 context()->get_reporter()->report(*
this, out, indent);
4405 diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
4406 second->get_pointed_to_type(),
4409 ctxt->initialize_canonical_diff(result);
4436 priv_(new
priv(member_type_diff, containing_type_diff))
4446{
return dynamic_pointer_cast<ptr_to_mbr_type>(
first_subject());}
4464{
return priv_->member_type_diff_;}
4473{
return priv_->containing_type_diff_;}
4493 return ir::NO_CHANGE_KIND;
4503 if (diff::priv_->pretty_representation_.empty())
4505 std::ostringstream o;
4506 o <<
"ptr_to_mbr_diff["
4511 diff::priv_->pretty_representation_ = o.str();
4513 return diff::priv_->pretty_representation_;
4519 context()->get_reporter()->report(*
this, out, indent);
4556 is_type(second->get_member_type()),
4561 is_type(second->get_containing_type()),
4566 containing_type_diff,
4568 ctxt->initialize_canonical_diff(result);
4593 qualified_type_def_sptr second,
4597 priv_(new
priv(under))
4603const qualified_type_def_sptr
4605{
return dynamic_pointer_cast<qualified_type_def>(
first_subject());}
4610const qualified_type_def_sptr
4612{
return dynamic_pointer_cast<qualified_type_def>(
second_subject());}
4621{
return priv_->underlying_type_diff;}
4631 if (!priv_->leaf_underlying_type_diff)
4632 priv_->leaf_underlying_type_diff
4637 return priv_->leaf_underlying_type_diff;
4647{priv_->underlying_type_diff = d;}
4654 if (diff::priv_->pretty_representation_.empty())
4656 std::ostringstream o;
4657 o <<
"qualified_type_diff["
4662 diff::priv_->pretty_representation_ = o.str();
4664 return diff::priv_->pretty_representation_;
4683 return ir::NO_CHANGE_KIND;
4694 context()->get_reporter()->report(*
this, out, indent);
4707qualified_type_diff_sptr
4709 const qualified_type_def_sptr second,
4712 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
4713 second->get_underlying_type(),
4717 ctxt->initialize_canonical_diff(result);
4730enum_diff::clear_lookup_tables()
4732 priv_->deleted_enumerators_.clear();
4733 priv_->inserted_enumerators_.clear();
4734 priv_->changed_enumerators_.clear();
4741enum_diff::lookup_tables_empty()
const
4743 return (priv_->deleted_enumerators_.empty()
4744 && priv_->inserted_enumerators_.empty()
4745 && priv_->changed_enumerators_.empty());
4751enum_diff::ensure_lookup_tables_populated()
4753 if (!lookup_tables_empty())
4757 edit_script e = priv_->enumerators_changes_;
4759 for (vector<deletion>::const_iterator it = e.deletions().begin();
4760 it != e.deletions().end();
4763 unsigned i = it->index();
4764 const enum_type_decl::enumerator& n =
4766 const string& name = n.get_name();
4767 ABG_ASSERT(priv_->deleted_enumerators_.find(n.get_name())
4768 == priv_->deleted_enumerators_.end());
4769 priv_->deleted_enumerators_[name] = n;
4772 for (vector<insertion>::const_iterator it = e.insertions().begin();
4773 it != e.insertions().end();
4776 for (vector<unsigned>::const_iterator iit =
4777 it->inserted_indexes().begin();
4778 iit != it->inserted_indexes().end();
4782 const enum_type_decl::enumerator& n =
4784 const string& name = n.get_name();
4785 ABG_ASSERT(priv_->inserted_enumerators_.find(n.get_name())
4786 == priv_->inserted_enumerators_.end());
4787 string_enumerator_map::const_iterator j =
4788 priv_->deleted_enumerators_.find(name);
4789 if (j == priv_->deleted_enumerators_.end())
4790 priv_->inserted_enumerators_[name] = n;
4794 priv_->changed_enumerators_[j->first] =
4795 std::make_pair(j->second, n);
4796 priv_->deleted_enumerators_.erase(j);
4809 for (
auto& entry : priv_->inserted_enumerators_)
4811 enum_type_decl::enumerator& final_enumerator = entry.second;
4812 enum_type_decl::enumerator initial_enumerator;
4813 if (
first_enum()->find_enumerator_by_value(entry.second.get_value(),
4814 initial_enumerator))
4816 enum_type_decl::enumerator foo;
4818 find_enumerator_by_name(initial_enumerator.get_name(),
4821 priv_->changed_enumerators_[initial_enumerator.get_name()] =
4822 std::make_pair(initial_enumerator, final_enumerator);
4823 enums_to_erase.push_back(final_enumerator);
4828 for (
auto& enomerator : enums_to_erase)
4829 priv_->inserted_enumerators_.erase(enomerator.
get_name());
4838 enums_to_erase.clear();
4839 for (
auto& entry : priv_->deleted_enumerators_)
4841 enum_type_decl::enumerator& initial_enumerator = entry.second;
4842 enum_type_decl::enumerator final_enumerator;
4843 if (
second_enum()->find_enumerator_by_value(entry.second.get_value(),
4846 enum_type_decl::enumerator foo;
4848 find_enumerator_by_name(final_enumerator.get_name(),
4851 priv_->changed_enumerators_[initial_enumerator.get_name()] =
4852 std::make_pair(initial_enumerator, final_enumerator);
4853 enums_to_erase.push_back(initial_enumerator);
4858 for (
auto& enomerator : enums_to_erase)
4859 priv_->deleted_enumerators_.erase(enomerator.
get_name());
4887 priv_(new
priv(underlying_type_diff))
4893{
return dynamic_pointer_cast<enum_type_decl>(
first_subject());}
4903{
return priv_->underlying_type_diff_;}
4908{
return priv_->deleted_enumerators_;}
4913{
return priv_->inserted_enumerators_;}
4918{
return priv_->changed_enumerators_;}
4925 if (diff::priv_->pretty_representation_.empty())
4927 std::ostringstream o;
4933 diff::priv_->pretty_representation_ = o.str();
4935 return diff::priv_->pretty_representation_;
4954 return ir::NO_CHANGE_KIND;
4965 context()->get_reporter()->report(*
this, out, indent);
4987 diff_sptr ud = compute_diff_for_types(first->get_underlying_type(),
4988 second->get_underlying_type(),
4990 enum_diff_sptr d(
new enum_diff(first, second, ud, ctxt));
4991 if (first != second)
4994 first->get_enumerators().end(),
4995 second->get_enumerators().begin(),
4996 second->get_enumerators().end(),
4997 d->priv_->enumerators_changes_);
4998 d->ensure_lookup_tables_populated();
5000 ctxt->initialize_canonical_diff(d);
5022 string qname = d->get_qualified_name();
5023 string_diff_sptr_map::const_iterator it =
5024 changed_member_types_.find(qname);
5026 return ((it == changed_member_types_.end())
5028 : it->second->second_subject());
5045 string qname = d->get_qualified_name();
5046 string_var_diff_sptr_map::const_iterator it =
5047 subtype_changed_dm_.find(qname);
5049 if (it == subtype_changed_dm_.end())
5050 return decl_base_sptr();
5051 return it->second->second_var();
5069 string qname = d->get_qualified_name();
5070 string_diff_sptr_map::const_iterator it =
5071 changed_member_class_tmpls_.find(qname);
5073 return ((it == changed_member_class_tmpls_.end())
5075 : dynamic_pointer_cast<decl_base>(it->second->second_subject()));
5086 for (string_decl_base_sptr_map::const_iterator i =
5087 deleted_data_members_.begin();
5088 i != deleted_data_members_.end();
5105 for (string_decl_base_sptr_map::const_iterator i =
5106 inserted_data_members_.begin();
5107 i != inserted_data_members_.end();
5127 size_t num_filtered= 0;
5128 for (var_diff_sptrs_type::const_iterator i =
5129 sorted_subtype_changed_dm_.begin();
5130 i != sorted_subtype_changed_dm_.end();
5135 if ((*i)->has_local_changes() && (*i)->is_filtered_out())
5140 if ((*i)->is_filtered_out())
5144 return num_filtered;
5158 size_t num_filtered= 0;
5160 for (unsigned_var_diff_sptr_map::const_iterator i = changed_dm_.begin();
5161 i != changed_dm_.end();
5176 return num_filtered;
5185#define SKIP_MEM_FN_IF_VIRTUALITY_DISALLOWED \
5187 if (get_member_function_is_virtual(f) \
5188 || get_member_function_is_virtual(s)) \
5190 if (!(allowed_category | VIRTUAL_MEMBER_CHANGE_CATEGORY)) \
5195 if (!(allowed_category | NON_VIRT_MEM_FUN_CHANGE_CATEGORY)) \
5210 diff_category allowed_category = ctxt->get_allowed_category();
5212 for (function_decl_diff_sptrs_type::const_iterator i =
5213 sorted_changed_member_functions_.begin();
5214 i != sorted_changed_member_functions_.end();
5217 method_decl_sptr f =
5218 dynamic_pointer_cast<method_decl>
5219 ((*i)->first_function_decl());
5222 method_decl_sptr s =
5223 dynamic_pointer_cast<method_decl>
5224 ((*i)->second_function_decl());
5230 ctxt->maybe_apply_filters(
diff);
5249 diff_category allowed_category = ctxt->get_allowed_category();
5251 for (string_member_function_sptr_map::const_iterator i =
5252 inserted_member_functions_.begin();
5253 i != inserted_member_functions_.end();
5256 method_decl_sptr f = i->second,
5262 ctxt->maybe_apply_filters(
diff);
5282 diff_category allowed_category = ctxt->get_allowed_category();
5284 for (string_member_function_sptr_map::const_iterator i =
5285 deleted_member_functions_.begin();
5286 i != deleted_member_functions_.end();
5289 method_decl_sptr f = i->second,
5295 ctxt->maybe_apply_filters(
diff);
5312 priv_->deleted_member_types_.clear();
5313 priv_->inserted_member_types_.clear();
5314 priv_->changed_member_types_.clear();
5315 priv_->deleted_data_members_.clear();
5316 priv_->inserted_data_members_.clear();
5317 priv_->subtype_changed_dm_.clear();
5318 priv_->deleted_member_functions_.clear();
5319 priv_->inserted_member_functions_.clear();
5320 priv_->changed_member_functions_.clear();
5321 priv_->deleted_member_class_tmpls_.clear();
5322 priv_->inserted_member_class_tmpls_.clear();
5323 priv_->changed_member_class_tmpls_.clear();
5332 return (priv_->deleted_member_types_.empty()
5333 && priv_->inserted_member_types_.empty()
5334 && priv_->changed_member_types_.empty()
5335 && priv_->deleted_data_members_.empty()
5336 && priv_->inserted_data_members_.empty()
5337 && priv_->subtype_changed_dm_.empty()
5338 && priv_->inserted_member_functions_.empty()
5339 && priv_->deleted_member_functions_.empty()
5340 && priv_->changed_member_functions_.empty()
5341 && priv_->deleted_member_class_tmpls_.empty()
5342 && priv_->inserted_member_class_tmpls_.empty()
5343 && priv_->changed_member_class_tmpls_.empty());
5354 for (vector<deletion>::const_iterator it = e.deletions().begin();
5355 it != e.deletions().end();
5358 unsigned i = it->index();
5362 if (record_type && record_type->get_is_declaration_only())
5364 string name = d->get_name();
5365 priv_->deleted_member_types_[name] = d;
5368 for (vector<insertion>::const_iterator it = e.insertions().begin();
5369 it != e.insertions().end();
5372 for (vector<unsigned>::const_iterator iit =
5373 it->inserted_indexes().begin();
5374 iit != it->inserted_indexes().end();
5381 if (record_type && record_type->get_is_declaration_only())
5383 string name = d->get_name();
5384 string_decl_base_sptr_map::const_iterator j =
5385 priv_->deleted_member_types_.find(name);
5386 if (j != priv_->deleted_member_types_.end())
5388 if (*j->second != *d)
5389 priv_->changed_member_types_[name] =
5392 priv_->deleted_member_types_.erase(j);
5395 priv_->inserted_member_types_[name] = d;
5403 for (vector<deletion>::const_iterator it = e.deletions().begin();
5404 it != e.deletions().end();
5407 unsigned i = it->index();
5410 string name = data_member->get_anon_dm_reliable_name();
5411 priv_->deleted_data_members_[name] = data_member;
5414 for (vector<insertion>::const_iterator it = e.insertions().begin();
5415 it != e.insertions().end();
5418 for (vector<unsigned>::const_iterator iit =
5419 it->inserted_indexes().begin();
5420 iit != it->inserted_indexes().end();
5427 string name = added_dm->get_anon_dm_reliable_name();
5428 ABG_ASSERT(priv_->inserted_data_members_.find(name)
5429 == priv_->inserted_data_members_.end());
5431 bool ignore_added_anonymous_data_member =
false;
5469 bool added_anon_dm_changes_dm =
false;
5472 vector<var_decl_sptr> dms_replaced_by_anon_dm;
5481 for (string_decl_base_sptr_map::const_iterator it =
5482 priv_->deleted_data_members_.begin();
5483 it != priv_->deleted_data_members_.end();
5492 string deleted_dm_name = it->second->get_name();
5508 size_t replaced_dm_offset =
5510 replacing_dm_offset =
5513 if (replaced_dm_offset != replacing_dm_offset)
5521 added_anon_dm_changes_dm =
true;
5525 if (replaced_dm->get_type()->get_size_in_bits()
5526 == replaced_dm->get_type()->get_size_in_bits())
5527 dms_replaced_by_anon_dm.push_back(replaced_dm);
5530 added_anon_dm_changes_dm =
true;
5539 if (!added_anon_dm_changes_dm
5540 && !dms_replaced_by_anon_dm.empty())
5543 type_base_sptr added_dm_type = added_dm->get_type();
5559 ignore_added_anonymous_data_member =
true;
5560 for (vector<var_decl_sptr>::const_iterator i =
5561 dms_replaced_by_anon_dm.begin();
5562 i != dms_replaced_by_anon_dm.end();
5565 string n = (*i)->get_name();
5566 priv_->dms_replaced_by_adms_[n] =
5568 priv_->deleted_data_members_.erase(n);
5574 if (!ignore_added_anonymous_data_member)
5587 string_decl_base_sptr_map::const_iterator j =
5588 priv_->deleted_data_members_.find(name);
5589 if (j != priv_->deleted_data_members_.end())
5591 if (*j->second != *d)
5594 priv_->subtype_changed_dm_[name]=
5597 priv_->deleted_data_members_.erase(j);
5600 priv_->inserted_data_members_[name] = d;
5608 for (string_decl_base_sptr_map::const_iterator i =
5609 priv_->deleted_data_members_.begin();
5610 i != priv_->deleted_data_members_.end();
5614 priv_->deleted_dm_by_offset_[offset] = i->second;
5617 for (string_decl_base_sptr_map::const_iterator i =
5618 priv_->inserted_data_members_.begin();
5619 i != priv_->inserted_data_members_.end();
5623 priv_->inserted_dm_by_offset_[offset] = i->second;
5626 for (unsigned_decl_base_sptr_map::const_iterator i =
5627 priv_->inserted_dm_by_offset_.begin();
5628 i != priv_->inserted_dm_by_offset_.end();
5631 unsigned_decl_base_sptr_map::const_iterator j =
5632 priv_->deleted_dm_by_offset_.find(i->first);
5633 if (j != priv_->deleted_dm_by_offset_.end())
5637 priv_->changed_dm_[i->first] =
5642 for (unsigned_var_diff_sptr_map::const_iterator i =
5643 priv_->changed_dm_.begin();
5644 i != priv_->changed_dm_.end();
5647 priv_->deleted_dm_by_offset_.erase(i->first);
5648 priv_->inserted_dm_by_offset_.erase(i->first);
5649 priv_->deleted_data_members_.erase
5650 (i->second->first_var()->get_anon_dm_reliable_name());
5651 priv_->inserted_data_members_.erase
5652 (i->second->second_var()->get_anon_dm_reliable_name());
5660 non_anonymous_dms_in_second_class);
5661 vector<string> deleted_data_members_to_delete;
5663 for (
auto& entry : priv_->deleted_data_members_)
5680 bool anonymous_dm_members_present =
true;
5684 for (
auto& e : non_anonymous_data_members)
5686 if (non_anonymous_dms_in_second_class.find(e.first)
5687 == non_anonymous_dms_in_second_class.end())
5692 anonymous_dm_members_present =
false;
5694 if (anonymous_dm_members_present)
5699 deleted_data_members_to_delete.push_back(data_member->get_anon_dm_reliable_name());
5705 for (
string& name_of_dm_to_delete: deleted_data_members_to_delete)
5706 priv_->deleted_data_members_.erase(name_of_dm_to_delete);
5709 priv_->sorted_subtype_changed_dm_);
5711 priv_->sorted_changed_dm_);
5714 edit_script& e = priv_->member_class_tmpls_changes_;
5716 for (vector<deletion>::const_iterator it = e.deletions().begin();
5717 it != e.deletions().end();
5720 unsigned i = it->index();
5724 string name = d->get_name();
5725 ABG_ASSERT(priv_->deleted_member_class_tmpls_.find(name)
5726 == priv_->deleted_member_class_tmpls_.end());
5727 priv_->deleted_member_class_tmpls_[name] = d;
5730 for (vector<insertion>::const_iterator it = e.insertions().begin();
5731 it != e.insertions().end();
5734 for (vector<unsigned>::const_iterator iit =
5735 it->inserted_indexes().begin();
5736 iit != it->inserted_indexes().end();
5743 string name = d->get_name();
5744 ABG_ASSERT(priv_->inserted_member_class_tmpls_.find(name)
5745 == priv_->inserted_member_class_tmpls_.end());
5746 string_decl_base_sptr_map::const_iterator j =
5747 priv_->deleted_member_class_tmpls_.find(name);
5748 if (j != priv_->deleted_member_class_tmpls_.end())
5750 if (*j->second != *d)
5751 priv_->changed_member_types_[name]=
5753 priv_->deleted_member_class_tmpls_.erase(j);
5756 priv_->inserted_member_class_tmpls_[name] = d;
5761 priv_->sorted_changed_member_types_);
5770 priv_.reset(
new priv);
5781 class_or_union_sptr second_scope,
5799const class_or_union_diff::priv_ptr&
5812 return canonical->priv_;
5834{
return get_priv()->member_types_changes_;}
5840{
return get_priv()->member_types_changes_;}
5846{
return get_priv()->data_members_changes_;}
5852{
return get_priv()->data_members_changes_;}
5859{
return get_priv()->inserted_data_members_;}
5866{
return get_priv()->deleted_data_members_;}
5872{
return get_priv()->member_fns_changes_;}
5881{
return get_priv()->sorted_changed_member_functions_;}
5887{
return get_priv()->member_fns_changes_;}
5892{
return get_priv()->deleted_member_functions_;}
5897{
return get_priv()->inserted_member_functions_;}
5915{
return get_priv()->sorted_changed_dm_;}
5923{
return get_priv()->count_filtered_changed_dm(local);}
5930{
return get_priv()->sorted_subtype_changed_dm_;}
5937{
return get_priv()->count_filtered_subtype_changed_dm(local);}
5949{
return get_priv()->dms_replaced_by_adms_;}
5961 if (priv_->dms_replaced_by_adms_ordered_.empty())
5963 for (string_decl_base_sptr_map::const_iterator it =
5964 priv_->dms_replaced_by_adms_.begin();
5965 it != priv_->dms_replaced_by_adms_.end();
5972 priv_->dms_replaced_by_adms_ordered_.push_back(changed_dm);
5977 return priv_->dms_replaced_by_adms_ordered_;
5984{
return get_priv()->member_fn_tmpls_changes_;}
5990{
return get_priv()->member_fn_tmpls_changes_;}
5996{
return get_priv()->member_class_tmpls_changes_;}
6002{
return get_priv()->member_class_tmpls_changes_;}
6018 return ir::NO_CHANGE_KIND;
6031 context()->get_reporter()->report(*
this, out, indent);
6043 for (var_diff_sptrs_type::const_iterator i =
6044 get_priv()->sorted_subtype_changed_dm_.begin();
6045 i !=
get_priv()->sorted_subtype_changed_dm_.end();
6050 for (var_diff_sptrs_type::const_iterator i =
6051 get_priv()->sorted_changed_dm_.begin();
6052 i !=
get_priv()->sorted_changed_dm_.end();
6058 for (function_decl_diff_sptrs_type::const_iterator i =
6059 get_priv()->sorted_changed_member_functions_.begin();
6060 i !=
get_priv()->sorted_changed_member_functions_.end();
6075class_diff::clear_lookup_tables(
void)
6077 priv_->deleted_bases_.clear();
6078 priv_->inserted_bases_.clear();
6079 priv_->changed_bases_.clear();
6086class_diff::lookup_tables_empty(
void)
const
6088 return (priv_->deleted_bases_.empty()
6089 && priv_->inserted_bases_.empty()
6090 && priv_->changed_bases_.empty());
6100static string_member_function_sptr_map::const_iterator
6103 for (string_member_function_sptr_map::const_iterator i = map.begin();
6128 const vector<method_decl_sptr>& s_virt_methods)
const
6132 if (!lookup_tables_empty())
6136 edit_script& e = get_priv()->base_changes_;
6138 for (vector<deletion>::const_iterator it = e.deletions().begin();
6139 it != e.deletions().end();
6142 unsigned i = it->index();
6145 string name = b->get_base_class()->get_qualified_name();
6146 ABG_ASSERT(get_priv()->deleted_bases_.find(name)
6147 == get_priv()->deleted_bases_.end());
6148 get_priv()->deleted_bases_[name] = b;
6151 for (vector<insertion>::const_iterator it = e.insertions().begin();
6152 it != e.insertions().end();
6155 for (vector<unsigned>::const_iterator iit =
6156 it->inserted_indexes().begin();
6157 iit != it->inserted_indexes().end();
6163 string name = b->get_base_class()->get_qualified_name();
6164 ABG_ASSERT(get_priv()->inserted_bases_.find(name)
6165 == get_priv()->inserted_bases_.end());
6166 string_base_sptr_map::const_iterator j =
6167 get_priv()->deleted_bases_.find(name);
6168 if (j != get_priv()->deleted_bases_.end())
6171 get_priv()->changed_bases_[name] =
6177 get_priv()->moved_bases_.push_back(b);
6178 get_priv()->deleted_bases_.erase(j);
6181 get_priv()->inserted_bases_[name] = b;
6191 class_or_union_diff::priv_->deleted_data_members_;
6193 vector<var_decl_sptr> deleted_data_members_present_in_bases;
6201 var_decl_sptr member = klass->find_data_member(deleted_member->get_name());
6203 deleted_data_members_present_in_bases.push_back(member);
6210 for (
var_decl_sptr m : deleted_data_members_present_in_bases)
6212 string name = m->get_name();
6216 if (*deleted_member != *m)
6220 class_or_union_diff::priv_->subtype_changed_dm_[name]= dif;
6227 get_priv()->sorted_deleted_bases_);
6229 get_priv()->sorted_inserted_bases_);
6231 get_priv()->sorted_changed_bases_);
6236 edit_script& e = p->member_fns_changes_;
6238 for (vector<deletion>::const_iterator it = e.deletions().begin();
6239 it != e.deletions().end();
6242 unsigned i = it->index();
6243 method_decl_sptr mem_fn = f_virt_methods[i];
6244 string name = mem_fn->get_symbol()
6245 ? mem_fn->get_symbol()->get_name()
6246 : mem_fn->get_linkage_name();
6248 name = mem_fn->get_pretty_representation();
6250 if (p->deleted_member_functions_.find(name)
6251 != p->deleted_member_functions_.end())
6253 p->deleted_member_functions_[name] = mem_fn;
6256 for (vector<insertion>::const_iterator it = e.insertions().begin();
6257 it != e.insertions().end();
6260 for (vector<unsigned>::const_iterator iit =
6261 it->inserted_indexes().begin();
6262 iit != it->inserted_indexes().end();
6267 method_decl_sptr mem_fn = s_virt_methods[i];
6268 string name = mem_fn->get_symbol()
6269 ? mem_fn->get_symbol()->get_name()
6270 : mem_fn->get_linkage_name();
6272 name = mem_fn->get_pretty_representation();
6274 if (p->inserted_member_functions_.find(name)
6275 != p->inserted_member_functions_.end())
6277 string_member_function_sptr_map::const_iterator j =
6278 p->deleted_member_functions_.find(name);
6280 if (j != p->deleted_member_functions_.end())
6282 if (*j->second != *mem_fn)
6283 p->changed_member_functions_[name] =
6284 compute_diff(static_pointer_cast<function_decl>(j->second),
6285 static_pointer_cast<function_decl>(mem_fn),
6287 p->deleted_member_functions_.erase(j);
6290 p->inserted_member_functions_[name] = mem_fn;
6337 vector<string> to_delete;
6338 corpus_sptr f =
context()->get_first_corpus(),
6339 s =
context()->get_second_corpus();
6341 for (string_member_function_sptr_map::const_iterator i =
6360 find_virtual_dtor_in_map(p->inserted_member_functions_);
6361 if (it != p->inserted_member_functions_.end())
6369 (!i->second->get_linkage_name().empty())
6370 ? i->second->get_linkage_name()
6371 : i->second->get_pretty_representation();
6372 to_delete.push_back(name);
6373 p->inserted_member_functions_.erase(it);
6380 if (!i->second->get_symbol()
6381 || s->lookup_function_symbol(*i->second->get_symbol()))
6382 to_delete.push_back(i->first);
6386 for (vector<string>::const_iterator i = to_delete.begin();
6387 i != to_delete.end();
6389 p->deleted_member_functions_.erase(*i);
6394 for (string_member_function_sptr_map::const_iterator i =
6403 if (!i->second->get_symbol()
6404 || f->lookup_function_symbol(*i->second->get_symbol()))
6405 to_delete.push_back(i->first);
6408 for (vector<string>::const_iterator i = to_delete.begin();
6409 i != to_delete.end();
6411 p->inserted_member_functions_.erase(*i);
6414 p->sorted_deleted_member_functions_);
6417 p->sorted_inserted_member_functions_);
6420 (p->changed_member_functions_,
6421 p->sorted_changed_member_functions_);
6428class_diff::allocate_priv_data()
6432 priv_.reset(
new priv);
6445 string qname = d->get_base_class()->get_qualified_name();
6446 string_base_diff_sptr_map::const_iterator it =
6447 changed_bases_.find(qname);
6449 return (it == changed_bases_.end())
6451 : it->second->second_base();
6462 size_t num_filtered = 0;
6463 for (base_diff_sptrs_type::const_iterator i = sorted_changed_bases_.begin();
6464 i != sorted_changed_bases_.end();
6471 return num_filtered;
6485 for (base_diff_sptrs_type::const_iterator i =
6486 get_priv()->sorted_changed_bases_.begin();
6487 i != get_priv()->sorted_changed_bases_.end();
6512class_diff::~class_diff()
6526const class_diff::priv_ptr&
6527class_diff::get_priv()
const
6539 return canonical->priv_;
6547 if (diff::priv_->pretty_representation_.empty())
6549 std::ostringstream o;
6555 diff::priv_->pretty_representation_ = o.str();
6557 return diff::priv_->pretty_representation_;
6576 return ir::NO_CHANGE_KIND;
6580shared_ptr<class_decl>
6587shared_ptr<class_decl>
6594{
return get_priv()->base_changes_;}
6602{
return get_priv()->deleted_bases_;}
6610{
return get_priv()->inserted_bases_;}
6617{
return get_priv()->sorted_changed_bases_;}
6625const vector<class_decl::base_spec_sptr>&
6627{
return get_priv()->moved_bases_;}
6632{
return get_priv()->base_changes_;}
6643 context()->get_reporter()->report(*
this, out, indent);
6668 ctxt->initialize_canonical_diff(changes);
6671 if (!ctxt->get_canonical_diff_for(first, second))
6675 diff_sptr canonical_diff = ctxt->get_canonical_diff_for(changes);
6677 ctxt->set_canonical_diff_for(first, second, canonical_diff);
6693 if (
is_class_diff(changes->get_canonical_diff()) == changes.get())
6696 changes->allocate_priv_data();
6708 f->get_base_specifiers().end(),
6709 s->get_base_specifiers().begin(),
6710 s->get_base_specifiers().end(),
6711 changes->base_changes());
6717 f->get_member_types().end(),
6718 s->get_member_types().begin(),
6719 s->get_member_types().end(),
6720 changes->member_types_changes());
6725 f->get_non_static_data_members().end(),
6726 s->get_non_static_data_members().begin(),
6727 s->get_non_static_data_members().end(),
6728 changes->data_members_changes());
6750 vector<method_decl_sptr> first_virt_mems;
6751 vector<method_decl_sptr> second_virt_mems;
6752 first_virt_mems.reserve(f->get_virtual_mem_fns().size());
6753 second_virt_mems.reserve(s->get_virtual_mem_fns().size());
6755 for (
auto virt_method : f->get_virtual_mem_fns())
6759 first_virt_mems.push_back(virt_method);
6762 for (
auto virt_method : s->get_virtual_mem_fns())
6766 second_virt_mems.push_back(virt_method);
6769 compute_diff(first_virt_mems.begin(), first_virt_mems.end(),
6770 second_virt_mems.begin(), second_virt_mems.end(),
6771 changes->member_fns_changes());
6774 compute_diff(f->get_member_function_templates().begin(),
6775 f->get_member_function_templates().end(),
6776 s->get_member_function_templates().begin(),
6777 s->get_member_function_templates().end(),
6778 changes->member_fn_tmpls_changes());
6783 f->get_member_class_templates().end(),
6784 s->get_member_class_templates().begin(),
6785 s->get_member_class_templates().end(),
6786 changes->member_class_tmpls_changes());
6789 changes->ensure_lookup_tables_populated(first_virt_mems, second_virt_mems);
6819 :
diff(first, second, ctxt),
6820 priv_(new
priv(underlying))
6828{
return dynamic_pointer_cast<class_decl::base_spec>(
first_subject());}
6835{
return dynamic_pointer_cast<class_decl::base_spec>(
second_subject());}
6844{
return priv_->underlying_class_diff_;}
6853{priv_->underlying_class_diff_ = d;}
6860 if (diff::priv_->pretty_representation_.empty())
6862 std::ostringstream o;
6868 diff::priv_->pretty_representation_ = o.str();
6870 return diff::priv_->pretty_representation_;
6889 return ir::NO_CHANGE_KIND;
6900 context()->get_reporter()->report(*
this, out, indent);
6922 second->get_base_class(),
6926 ctxt->initialize_canonical_diff(changes);
6941union_diff::clear_lookup_tables(
void)
6948union_diff::lookup_tables_empty(
void)
const
6954union_diff::ensure_lookup_tables_populated(
void)
const
6960union_diff::allocate_priv_data()
6973 union_decl_sptr second_union,
6996 if (diff::priv_->pretty_representation_.empty())
6998 std::ostringstream o;
7004 diff::priv_->pretty_representation_ = o.str();
7006 return diff::priv_->pretty_representation_;
7018 context()->get_reporter()->report(*
this, out, indent);
7033 const union_decl_sptr second,
7036 union_diff_sptr changes(
new union_diff(first, second, ctxt));
7038 ctxt->initialize_canonical_diff(changes);
7054 if (
is_union_diff(changes->get_canonical_diff()) == changes.get())
7057 changes->allocate_priv_data();
7068 compute_diff(first->get_non_static_data_members().begin(),
7069 first->get_non_static_data_members().end(),
7070 second->get_non_static_data_members().begin(),
7071 second->get_non_static_data_members().end(),
7072 changes->data_members_changes());
7077 first->get_mem_fns().end(),
7078 second->get_mem_fns().begin(),
7079 second->get_mem_fns().end(),
7080 changes->member_fns_changes());
7083 compute_diff(first->get_member_function_templates().begin(),
7084 first->get_member_function_templates().end(),
7085 second->get_member_function_templates().begin(),
7086 second->get_member_function_templates().end(),
7087 changes->member_fn_tmpls_changes());
7090 changes->ensure_lookup_tables_populated();
7104scope_diff::clear_lookup_tables()
7106 priv_->deleted_types_.clear();
7107 priv_->deleted_decls_.clear();
7108 priv_->inserted_types_.clear();
7109 priv_->inserted_decls_.clear();
7110 priv_->changed_types_.clear();
7111 priv_->changed_decls_.clear();
7112 priv_->removed_types_.clear();
7113 priv_->removed_decls_.clear();
7114 priv_->added_types_.clear();
7115 priv_->added_decls_.clear();
7125scope_diff::lookup_tables_empty()
const
7127 return (priv_->deleted_types_.empty()
7128 && priv_->deleted_decls_.empty()
7129 && priv_->inserted_types_.empty()
7130 && priv_->inserted_decls_.empty()
7131 && priv_->changed_types_.empty()
7132 && priv_->changed_decls_.empty()
7133 && priv_->removed_types_.empty()
7134 && priv_->removed_decls_.empty()
7135 && priv_->added_types_.empty()
7136 && priv_->added_decls_.empty());
7142scope_diff::ensure_lookup_tables_populated()
7144 if (!lookup_tables_empty())
7147 edit_script& e = priv_->member_changes_;
7150 for (
const auto& deletion : e.deletions())
7152 unsigned i = deletion.index();
7154 string qname = decl->get_qualified_name();
7158 if (klass_decl && klass_decl->get_is_declaration_only())
7169 == priv_->deleted_types_.end());
7170 priv_->deleted_types_[qname] = decl;
7175 == priv_->deleted_decls_.end());
7176 priv_->deleted_decls_[qname] = decl;
7182 for (vector<insertion>::const_iterator it = e.insertions().begin();
7183 it != e.insertions().end();
7186 for (vector<unsigned>::const_iterator i = it->inserted_indexes().begin();
7187 i != it->inserted_indexes().end();
7191 string qname = decl->get_qualified_name();
7195 dynamic_pointer_cast<class_decl>(decl);
7196 if (klass_decl && klass_decl->get_is_declaration_only())
7206 ABG_ASSERT(priv_->inserted_types_.find(qname)
7207 == priv_->inserted_types_.end());
7208 string_decl_base_sptr_map::const_iterator j =
7209 priv_->deleted_types_.find(qname);
7210 if (j != priv_->deleted_types_.end())
7212 if (*j->second != *decl)
7213 priv_->changed_types_[qname] =
7215 priv_->deleted_types_.erase(j);
7218 priv_->inserted_types_[qname] = decl;
7222 ABG_ASSERT(priv_->inserted_decls_.find(qname)
7223 == priv_->inserted_decls_.end());
7224 string_decl_base_sptr_map::const_iterator j =
7225 priv_->deleted_decls_.find(qname);
7226 if (j != priv_->deleted_decls_.end())
7228 if (*j->second != *decl)
7229 priv_->changed_decls_[qname] =
7231 priv_->deleted_decls_.erase(j);
7234 priv_->inserted_decls_[qname] = decl;
7240 priv_->sorted_changed_decls_);
7242 priv_->sorted_changed_types_);
7245 for (string_decl_base_sptr_map::const_iterator i =
7246 priv_->deleted_types_.begin();
7247 i != priv_->deleted_types_.end();
7250 string_decl_base_sptr_map::const_iterator r =
7251 priv_->inserted_types_.find(i->first);
7252 if (r == priv_->inserted_types_.end())
7253 priv_->removed_types_[i->first] = i->second;
7255 for (string_decl_base_sptr_map::const_iterator i =
7256 priv_->deleted_decls_.begin();
7257 i != priv_->deleted_decls_.end();
7260 string_decl_base_sptr_map::const_iterator r =
7261 priv_->inserted_decls_.find(i->first);
7262 if (r == priv_->inserted_decls_.end())
7263 priv_->removed_decls_[i->first] = i->second;
7267 for (string_decl_base_sptr_map::const_iterator i =
7268 priv_->inserted_types_.begin();
7269 i != priv_->inserted_types_.end();
7272 string_decl_base_sptr_map::const_iterator r =
7273 priv_->deleted_types_.find(i->first);
7274 if (r == priv_->deleted_types_.end())
7275 priv_->added_types_[i->first] = i->second;
7277 for (string_decl_base_sptr_map::const_iterator i =
7278 priv_->inserted_decls_.begin();
7279 i != priv_->inserted_decls_.end();
7282 string_decl_base_sptr_map::const_iterator r =
7283 priv_->deleted_decls_.find(i->first);
7284 if (r == priv_->deleted_decls_.end())
7285 priv_->added_decls_[i->first] = i->second;
7297 for (diff_sptrs_type::const_iterator i =
changed_types().begin();
7303 for (diff_sptrs_type::const_iterator i =
changed_decls().begin();
7323 :
diff(first_scope, second_scope, ctxt),
7361{
return priv_->member_changes_;}
7383{
return priv_->member_changes_;}
7398 return scope->get_member_decls()[i];
7429 return scope->get_member_decls()[i];
7450{
return priv_->sorted_changed_types_;}
7456{
return priv_->sorted_changed_decls_;}
7459scope_diff::removed_types()
const
7460{
return priv_->removed_types_;}
7463scope_diff::removed_decls()
const
7464{
return priv_->removed_decls_;}
7467scope_diff::added_types()
const
7468{
return priv_->added_types_;}
7471scope_diff::added_decls()
const
7472{
return priv_->added_decls_;}
7479 if (diff::priv_->pretty_representation_.empty())
7481 std::ostringstream o;
7487 diff::priv_->pretty_representation_ = o.str();
7489 return diff::priv_->pretty_representation_;
7511 return ir::NO_CHANGE_KIND;
7522 context()->get_reporter()->report(*
this, out, indent);
7548 ABG_ASSERT(d->first_scope() == first && d->second_scope() == second);
7551 first->get_member_decls().end(),
7552 second->get_member_decls().begin(),
7553 second->get_member_decls().end(),
7554 d->member_changes());
7556 d->ensure_lookup_tables_populated();
7582 ctxt->initialize_canonical_diff(d);
7606 ABG_ASSERT(first->get_index() == second->get_index());
7619{
return dynamic_pointer_cast<function_decl::parameter>(
first_subject());}
7627{
return dynamic_pointer_cast<function_decl::parameter>(
second_subject());}
7637{
return priv_->type_diff;}
7647 if (diff::priv_->pretty_representation_.empty())
7649 std::ostringstream o;
7650 o <<
"function_parameter_diff["
7655 diff::priv_->pretty_representation_ = o.str();
7657 return diff::priv_->pretty_representation_;
7678 return ir::NO_CHANGE_KIND;
7689 context()->get_reporter()->report(*
this, out, indent);
7723 if (!first || !second)
7727 ctxt->initialize_canonical_diff(result);
7736function_type_diff::ensure_lookup_tables_populated()
7738 priv_->return_type_diff_ =
7745 for (vector<deletion>::const_iterator i =
7746 priv_->parm_changes_.deletions().begin();
7747 i != priv_->parm_changes_.deletions().end();
7752 parm_name = parm->get_name_id();
7756 priv_->deleted_parms_[parm_name] = parm;
7757 priv_->deleted_parms_by_id_[parm->get_index()] = parm;
7760 for (vector<insertion>::const_iterator i =
7761 priv_->parm_changes_.insertions().begin();
7762 i != priv_->parm_changes_.insertions().end();
7765 for (vector<unsigned>::const_iterator j =
7766 i->inserted_indexes().begin();
7767 j != i->inserted_indexes().end();
7771 parm_name = parm->get_name_id();
7776 string_parm_map::const_iterator k =
7777 priv_->deleted_parms_.find(parm_name);
7778 if (k != priv_->deleted_parms_.end())
7780 if (*k->second != *parm)
7781 priv_->subtype_changed_parms_[parm_name] =
7783 priv_->deleted_parms_.erase(parm_name);
7786 priv_->added_parms_[parm_name] = parm;
7789 unsigned_parm_map::const_iterator k =
7790 priv_->deleted_parms_by_id_.find(parm->get_index());
7791 if (k != priv_->deleted_parms_by_id_.end())
7793 if (*k->second != *parm
7794 && (k->second->get_name_id() != parm_name))
7795 priv_->changed_parms_by_id_[parm->get_index()] =
7797 priv_->added_parms_.erase(parm_name);
7798 priv_->deleted_parms_.erase(k->second->get_name_id());
7799 priv_->deleted_parms_by_id_.erase(parm->get_index());
7802 priv_->added_parms_by_id_[parm->get_index()] = parm;
7808 priv_->sorted_subtype_changed_parms_);
7810 priv_->sorted_changed_parms_by_id_);
7812 priv_->sorted_deleted_parms_);
7815 priv_->sorted_added_parms_);
7825function_type_diff::deleted_parameter_at(
int i)
const
7831const vector<function_decl::parameter_sptr>&
7833{
return priv_->sorted_deleted_parms_;}
7838const vector<function_decl::parameter_sptr>&
7840{
return priv_->sorted_added_parms_;}
7849function_type_diff::inserted_parameter_at(
int i)
const
7877{
return dynamic_pointer_cast<function_type>(
first_subject());}
7893{
return priv_->return_type_diff_;}
7900{
return priv_->subtype_changed_parms_;}
7907{
return priv_->deleted_parms_;}
7914{
return priv_->added_parms_;}
7924 if (diff::priv_->pretty_representation_.empty())
7926 std::ostringstream o;
7927 o <<
"function_type_diff["
7932 diff::priv_->pretty_representation_ = o.str();
7934 return diff::priv_->pretty_representation_;
7958 return ir::NO_CHANGE_KIND;
7970 context()->get_reporter()->report(*
this, out, indent);
7984 for (vector<fn_parm_diff_sptr>::const_iterator i =
7985 priv_->sorted_subtype_changed_parms_.begin();
7986 i != priv_->sorted_subtype_changed_parms_.end();
7991 for (vector<fn_parm_diff_sptr>::const_iterator i =
7992 priv_->sorted_changed_parms_by_id_.begin();
7993 i != priv_->sorted_changed_parms_by_id_.end();
8016 if (!first || !second)
8025 first->get_parameters().end(),
8026 second->get_first_parm(),
8027 second->get_parameters().end(),
8028 result->priv_->parm_changes_);
8030 result->ensure_lookup_tables_populated();
8032 ctxt->initialize_canonical_diff(result);
8042function_decl_diff::ensure_lookup_tables_populated()
8079{
return dynamic_pointer_cast<function_decl>(
first_subject());}
8087function_decl_diff::type_diff()
const
8088{
return priv_->type_diff_;}
8095 if (diff::priv_->pretty_representation_.empty())
8097 std::ostringstream o;
8098 o <<
"function_diff["
8103 diff::priv_->pretty_representation_ = o.str();
8105 return diff::priv_->pretty_representation_;
8124 return ir::NO_CHANGE_KIND;
8136 context()->get_reporter()->report(*
this, out, indent);
8156 if (!first || !second)
8168 result->priv_->type_diff_ = type_diff;
8170 result->ensure_lookup_tables_populated();
8172 ctxt->initialize_canonical_diff(result);
8216 if (diff::priv_->pretty_representation_.empty())
8218 std::ostringstream o;
8219 o <<
"type_decl_diff["
8224 diff::priv_->pretty_representation_ = o.str();
8226 return diff::priv_->pretty_representation_;
8244 return ir::NO_CHANGE_KIND;
8255 context()->get_reporter()->report(*
this, out, indent);
8293 ctxt->initialize_canonical_diff(result);
8330 priv_(new
priv(underlying))
8338{
return dynamic_pointer_cast<typedef_decl>(
first_subject());}
8354{
return priv_->underlying_type_diff_;}
8363{priv_->underlying_type_diff_ = d;}
8370 if (diff::priv_->pretty_representation_.empty())
8372 std::ostringstream o;
8373 o <<
"typedef_diff["
8378 diff::priv_->pretty_representation_ = o.str();
8380 return diff::priv_->pretty_representation_;
8402 return ir::NO_CHANGE_KIND;
8414 context()->get_reporter()->report(*
this, out, indent);
8434 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
8435 second->get_underlying_type(),
8439 ctxt->initialize_canonical_diff(result);
8491 priv_(new
priv(first, second))
8500{
return priv_->first_;}
8507{
return priv_->second_;}
8521{
return ir::NO_CHANGE_KIND;}
8560 compute_diff(static_pointer_cast<scope_decl>(first->get_global_scope()),
8561 static_pointer_cast<scope_decl>(second->get_global_scope()),
8565 ctxt->initialize_canonical_diff(tu_diff);
8575struct diff_maps::priv
8598diff_maps::~diff_maps() =
default;
8605{
return priv_->type_decl_diff_map_;}
8612{
return priv_->type_decl_diff_map_;}
8619{
return priv_->enum_diff_map_;}
8626{
return priv_->enum_diff_map_;}
8633{
return priv_->class_diff_map_;}
8640{
return priv_->class_diff_map_;}
8647{
return priv_->union_diff_map_;}
8654{
return priv_->union_diff_map_;}
8661{
return priv_->typedef_diff_map_;}
8668{
return priv_->typedef_diff_map_;}
8675{
return priv_->subrange_diff_map_;}
8682{
return priv_->subrange_diff_map_;}
8689{
return priv_->array_diff_map_;}
8696{
return priv_->array_diff_map_;}
8703{
return priv_->reference_diff_map_;}
8710{{
return priv_->reference_diff_map_;}}
8717{
return priv_->fn_parm_diff_map_;}
8724{
return priv_->fn_parm_diff_map_;}
8731{
return priv_->function_type_diff_map_;}
8738{
return priv_->function_type_diff_map_;}
8745{
return priv_->function_decl_diff_map_;}
8752{
return priv_->function_decl_diff_map_;}
8759{
return priv_->var_decl_diff_map_;}
8766{
return priv_->var_decl_diff_map_;}
8773{
return priv_->distinct_diff_map_;}
8780{
return priv_->distinct_diff_map_;}
8838 diff_artifact_set_map_type::iterator i =
8839 priv_->impacted_artifacts_map_.find(dif);
8841 if (i == priv_->impacted_artifacts_map_.end())
8844 set.insert(impacted_iface);
8845 priv_->impacted_artifacts_map_[dif] = set;
8848 i->second.insert(impacted_iface);
8862 diff_artifact_set_map_type::iterator i =
8863 priv_->impacted_artifacts_map_.find(d);
8865 if (i == priv_->impacted_artifacts_map_.end())
8881 : priv_(new
priv(ctxt))
8889{
return priv_->num_func_removed;}
8896{priv_->num_func_removed = n;}
8906 if (priv_->ctxt() && !priv_->ctxt()->show_deleted_fns())
8907 return num_func_removed();
8908 return priv_->num_removed_func_filtered_out;
8917{priv_->num_removed_func_filtered_out = t;}
8928 ABG_ASSERT(num_func_removed() >= num_removed_func_filtered_out());
8929 return num_func_removed() - num_removed_func_filtered_out();
8937{
return priv_->num_func_added;}
8944{priv_->num_func_added = n;}
8952 if (priv_->ctxt() && !priv_->ctxt()->show_added_fns())
8953 return num_func_added();
8954 return priv_->num_added_func_filtered_out;
8963{priv_->num_added_func_filtered_out = n;}
8975 ABG_ASSERT(num_func_added() >= num_added_func_filtered_out());
8976 return num_func_added() - num_added_func_filtered_out();
8986{
return priv_->num_func_changed;}
8995{priv_->num_func_changed = n;}
9004{
return priv_->num_changed_func_filtered_out;}
9013{priv_->num_changed_func_filtered_out = n;}
9021{
return priv_->num_func_with_virt_offset_changes;}
9030{priv_->num_func_with_virt_offset_changes = n;}
9040{
return priv_->num_func_with_local_harmful_changes;}
9050{priv_->num_func_with_local_harmful_changes = n;}
9060{
return priv_->num_var_with_local_harmful_changes;}
9070{priv_->num_var_with_local_harmful_changes = n;}
9077{
return priv_->num_func_with_incompatible_changes;}
9084{priv_->num_func_with_incompatible_changes = n;}
9091{
return priv_->num_var_with_incompatible_changes;}
9098{priv_->num_var_with_incompatible_changes = n;}
9109{
return num_func_changed() - num_changed_func_filtered_out();}
9118{
return net_num_func_changed() - num_func_with_incompatible_changes();}
9125{
return priv_->num_vars_removed;}
9132{priv_->num_vars_removed = n;}
9141 if (priv_->ctxt() && !priv_->ctxt()->show_deleted_vars())
9142 return num_vars_removed();
9143 return priv_->num_removed_vars_filtered_out;
9152{priv_->num_removed_vars_filtered_out = n;}
9164 ABG_ASSERT(num_vars_removed() >= num_removed_vars_filtered_out());
9165 return num_vars_removed() - num_removed_vars_filtered_out();
9173{
return priv_->num_vars_added;}
9180{priv_->num_vars_added = n;}
9189 if (priv_->ctxt() && !priv_->ctxt()->show_added_vars())
9190 return num_vars_added();
9191 return priv_->num_added_vars_filtered_out;
9200{priv_->num_added_vars_filtered_out = n;}
9212 ABG_ASSERT(num_vars_added() >= num_added_vars_filtered_out());
9213 return num_vars_added() - num_added_vars_filtered_out();
9223{
return priv_->num_vars_changed;}
9232{priv_->num_vars_changed = n;}
9241{
return priv_->num_changed_vars_filtered_out;}
9250{priv_->num_changed_vars_filtered_out = n;}
9261{
return num_vars_changed() - num_changed_vars_filtered_out();}
9270{
return net_num_vars_changed() - num_var_with_incompatible_changes();}
9279{
return priv_->num_func_syms_removed;}
9288{priv_->num_func_syms_removed = n;}
9299 && !priv_->ctxt()->show_symbols_unreferenced_by_debug_info())
9300 return num_func_syms_removed();
9301 return priv_->num_removed_func_syms_filtered_out;
9311{priv_->num_removed_func_syms_filtered_out = n;}
9326 ABG_ASSERT(num_func_syms_removed() >= num_removed_func_syms_filtered_out());
9327 return num_func_syms_removed() - num_removed_func_syms_filtered_out();
9337{
return priv_->num_func_syms_added;}
9346{priv_->num_func_syms_added = n;}
9357 && !(priv_->ctxt()->show_added_symbols_unreferenced_by_debug_info()
9358 && priv_->ctxt()->show_symbols_unreferenced_by_debug_info()))
9359 return num_func_syms_added();
9360 return priv_->num_added_func_syms_filtered_out;
9370{priv_->num_added_func_syms_filtered_out = n;}
9385 ABG_ASSERT(num_func_syms_added() >= num_added_func_syms_filtered_out());
9386 return num_func_syms_added()- num_added_func_syms_filtered_out();
9396{
return priv_->num_var_syms_removed;}
9405{priv_->num_var_syms_removed = n;}
9416 && !priv_->ctxt()->show_symbols_unreferenced_by_debug_info())
9417 return num_var_syms_removed();
9418 return priv_->num_removed_var_syms_filtered_out;
9428{priv_->num_removed_var_syms_filtered_out = n;}
9443 ABG_ASSERT(num_var_syms_removed() >= num_removed_var_syms_filtered_out());
9444 return num_var_syms_removed() - num_removed_var_syms_filtered_out();
9454{
return priv_->num_var_syms_added;}
9463{priv_->num_var_syms_added = n;}
9474 && !(priv_->ctxt()->show_added_symbols_unreferenced_by_debug_info()
9475 && priv_->ctxt()->show_symbols_unreferenced_by_debug_info()))
9476 return num_var_syms_added();
9477 return priv_->num_added_var_syms_filtered_out;
9487{priv_->num_added_var_syms_filtered_out = n;}
9502 ABG_ASSERT(num_var_syms_added() >= num_added_var_syms_filtered_out());
9503 return num_var_syms_added() - num_added_var_syms_filtered_out();
9511{
return priv_->num_leaf_changes;}
9518{priv_->num_leaf_changes = n;}
9526{
return priv_->num_leaf_changes_filtered_out;}
9535{priv_->num_leaf_changes_filtered_out = n;}
9548 ABG_ASSERT(num_leaf_changes() >= num_leaf_changes_filtered_out());
9549 return num_leaf_changes() - num_leaf_changes_filtered_out();
9557{
return priv_->num_leaf_type_changes;}
9564{priv_->num_leaf_type_changes = n;}
9571{
return priv_->num_leaf_type_changes_filtered_out;}
9577{priv_->num_leaf_type_changes_filtered_out = n;}
9587{
return num_leaf_type_changes() - num_leaf_type_changes_filtered_out();}
9594{
return priv_->num_leaf_func_changes;}
9601{priv_->num_leaf_func_changes = n;}
9610{
return priv_->num_leaf_func_with_incompatible_changes;}
9619{priv_->num_leaf_func_with_incompatible_changes = n;}
9628{
return priv_->num_leaf_func_changes_filtered_out;}
9637{priv_->num_leaf_func_changes_filtered_out = n;}
9648{
return num_leaf_func_changes() - num_leaf_func_changes_filtered_out();}
9658 return (net_num_leaf_func_changes()
9659 - num_leaf_func_with_incompatible_changes());
9667{
return priv_->num_leaf_var_changes;}
9674{priv_->num_leaf_var_changes = n;}
9683{
return priv_->num_leaf_var_with_incompatible_changes;}
9692{priv_->num_leaf_var_with_incompatible_changes = n;}
9704{
return priv_->num_added_unreachable_types;}
9717{priv_->num_added_unreachable_types = n;}
9728{
return priv_->num_added_unreachable_types_filtered_out;}
9739{priv_->num_added_unreachable_types_filtered_out = n;}
9753 num_added_unreachable_types_filtered_out());
9755 return (num_added_unreachable_types()
9757 num_added_unreachable_types_filtered_out());
9770{
return priv_->num_removed_unreachable_types;}
9782{priv_->num_removed_unreachable_types = n;}
9793{
return priv_->num_removed_unreachable_types_filtered_out;}
9804{priv_->num_removed_unreachable_types_filtered_out = n;}
9818 num_removed_unreachable_types_filtered_out());
9820 return (num_removed_unreachable_types()
9822 num_removed_unreachable_types_filtered_out());
9835{
return priv_->num_changed_unreachable_types;}
9847{priv_->num_changed_unreachable_types = n;}
9858{
return priv_->num_changed_unreachable_types_filtered_out;}
9869{priv_->num_changed_unreachable_types_filtered_out = n;}
9883 num_changed_unreachable_types_filtered_out());
9885 return (num_changed_unreachable_types()
9887 num_changed_unreachable_types_filtered_out());
9897{
return priv_->num_leaf_var_changes_filtered_out;}
9906{priv_->num_leaf_var_changes_filtered_out = n;}
9917{
return num_leaf_var_changes() - num_leaf_var_changes_filtered_out();}
9926{
return net_num_leaf_var_changes() - num_leaf_var_with_incompatible_changes();}
9934{
return ctxt_.lock();}
9942 return (deleted_fns_.empty()
9943 && added_fns_.empty()
9944 && changed_fns_map_.empty()
9945 && deleted_vars_.empty()
9946 && added_vars_.empty()
9947 && changed_vars_map_.empty());
9954 deleted_fns_.clear();
9956 changed_fns_map_.clear();
9957 deleted_vars_.clear();
9958 added_vars_.clear();
9959 changed_vars_map_.clear();
9975 auto it = deleted_fns_.find(
id);
9976 if (it == deleted_fns_.end())
9978 it->second.insert(fn);
9993 auto it = added_fns_.find(
id);
9994 if (it == added_fns_.end())
9996 it->second.insert(fn);
10004 if (!lookup_tables_empty())
10015 unordered_map<string, const function_decl*> first_fns_map;
10016 first_fns_map.reserve(first_->get_functions().size());
10017 for (
const auto* fn : first_->get_functions())
10021 first_fns_map[n] = fn;
10024 for (
const auto* fn : second_->get_functions())
10029 const unordered_set<const function_decl*>* found =
nullptr;
10040 bool fn_has_changed =
true;
10041 if ((found = first_->lookup_functions(n)))
10043 for (
auto first_fn : *found)
10045 if (*first_fn == *fn)
10047 fn_has_changed =
false;
10053 fn_has_changed =
false;
10055 if (fn_has_changed)
10066 vector<const function_decl*> sorted_fns;
10067 sorted_fns.reserve(found->size());
10068 for (
auto f : *found)
10069 sorted_fns.push_back(f);
10071 std::sort(sorted_fns.begin(), sorted_fns.end(), comp);
10082 changed_fns_map_[n] = d;
10083 first_fns_map.erase(n);
10088 first_fns_map.erase(n);
10090 add_function_to_added_functions(fn);
10095 for (
const auto& entry : first_fns_map)
10096 add_function_to_deleted_functions(entry.second);
10104 vector<interned_string> to_delete;
10105 for (
auto& entry : deleted_fns_)
10113 bool do_delete = entry.second.empty();
10114 for (
auto fn : entry.second)
10116 if (!fn->get_symbol()
10138 to_delete.push_back(entry.first);
10141 for (
auto i = to_delete.begin(); i != to_delete.end(); ++i)
10142 deleted_fns_.erase(*i);
10146 for (
auto& entry : added_fns_)
10148 bool do_delete = entry.second.empty();
10149 for (
auto f : entry.second)
10151 if (!f->get_symbol()
10159 if (first_->lookup_function_symbol(*f->get_symbol()))
10167 to_delete.push_back(entry.first);
10170 if (!entry.second.empty())
10173 if (!f->
get_symbol()->get_version().is_empty()
10174 && f->
get_symbol()->get_version().is_default())
10181 const string& sym_name = f->
get_symbol()->get_name();
10183 if (first_->lookup_function_symbol(sym_name,
10189 to_delete.push_back(entry.first);
10197 for (
auto& s : to_delete)
10198 added_fns_.erase(s);
10205 unordered_map<string, var_decl_sptr> first_vars_map;
10206 first_vars_map.reserve(first_->get_variables().size());
10207 for (
const auto& var : first_->get_variables())
10209 string n = var->get_id();
10213 if (first_vars_map.find(n) == first_vars_map.end())
10214 first_vars_map[n] = var;
10220 for (
const auto& var : second_->get_variables())
10222 string n = var->get_id();
10224 auto j = first_vars_map.find(n);
10225 if (j != first_vars_map.end())
10228 if (*j->second != *var)
10234 first_vars_map.erase(j);
10236 else if (added_vars_.find(n) == added_vars_.end())
10237 added_vars_[n] = var;
10243 for (
const auto& entry : first_vars_map)
10244 deleted_vars_[entry.first] = entry.second;
10247 sorted_changed_vars_);
10253 vector<string> to_delete;
10254 for (string_var_ptr_map::const_iterator i = deleted_vars_.begin();
10255 i != deleted_vars_.end();
10257 if (second_->lookup_variable_symbol(*i->second->get_symbol()))
10258 to_delete.push_back(i->first);
10260 for (vector<string>::const_iterator i = to_delete.begin();
10261 i != to_delete.end();
10263 deleted_vars_.erase(*i);
10268 for (string_var_ptr_map::const_iterator i = added_vars_.begin();
10269 i != added_vars_.end();
10271 if (first_->lookup_variable_symbol(*i->second->get_symbol()))
10272 to_delete.push_back(i->first);
10273 else if (! i->second->get_symbol()->get_version().is_empty()
10274 && i->second->get_symbol()->get_version().is_default())
10282 if (first_->lookup_variable_symbol(i->second->get_symbol()->get_name(),
10284 to_delete.push_back(i->first);
10287 for (vector<string>::const_iterator i = to_delete.begin();
10288 i != to_delete.end();
10290 added_vars_.erase(*i);
10297 unordered_map<string, type_base*> first_non_reachable_types;
10298 for (
auto type : first_->get_sorted_types_not_reachable_from_public_interfaces())
10303 if (d->get_is_declaration_only())
10312 type->get_cached_pretty_representation(
false);
10313 first_non_reachable_types[repr] = type;
10316 for (
auto type : second_->get_sorted_types_not_reachable_from_public_interfaces())
10321 if (d->get_is_declaration_only())
10329 type->get_cached_pretty_representation(
false);
10330 auto it = first_non_reachable_types.find(repr);
10331 if (it == first_non_reachable_types.end())
10333 if (!lookup_type(repr, *first_))
10336 added_unreachable_types_[repr] = t;
10344 if (*first != *second)
10348 changed_unreachable_types_[repr]= d;
10350 first_non_reachable_types.erase(it);
10356 for (
auto e : first_non_reachable_types)
10360 type->get_cached_pretty_representation(
false);
10362 if (!lookup_type(repr, *second_))
10363 deleted_unreachable_types_[repr] = type;
10375 std::set<type_base_sptr> deleted_anon_types;
10376 std::set<type_base_sptr> added_anon_types;
10378 for (
auto entry : deleted_unreachable_types_)
10384 deleted_anon_types.insert(entry.second);
10388 for (
auto entry : added_unreachable_types_)
10393 added_anon_types.insert(entry.second);
10398 class_or_union_sptr deleted_class;
10403 for (
auto deleted: deleted_anon_types)
10412 for (
auto enr : deleted_enum->get_enumerators())
10414 bool this_enum_got_changed =
false;
10415 for (
auto t : added_anon_types)
10432 changed_unreachable_types_[repr]= d;
10433 this_enum_got_changed =
true;
10440 removed_anon_types_to_erase[r1] = deleted_enum;
10441 added_anon_types_to_erase[r2] = added_enum;
10445 if (this_enum_got_changed)
10449 else if (deleted_class)
10454 for (
auto dm : deleted_class->get_data_members())
10456 bool this_class_got_changed =
false;
10457 for (
auto klass : added_anon_types)
10459 if (class_or_union_sptr added_class =
10478 changed_unreachable_types_[repr]= d;
10479 this_class_got_changed =
true;
10486 removed_anon_types_to_erase[r1] = deleted_class;
10487 added_anon_types_to_erase[r2] = added_class;
10491 if (this_class_got_changed)
10500 for (
auto entry : added_anon_types_to_erase)
10501 added_unreachable_types_.erase(entry.first);
10503 for (
auto entry : removed_anon_types_to_erase)
10504 deleted_unreachable_types_.erase(entry.first);
10536 bool built_some_diffs =
false;
10540 vector<const function_decl*> deleted_fns_to_delete;
10541 vector<const function_decl*> added_fns_to_delete;
10542 for (
auto& deleted_fn : deleted_fns)
10544 for (
auto& added_fn : added_fns)
10548 if (f_fn_id == s_fn_id)
10550 deleted_fns_to_delete.push_back(deleted_fn);
10551 added_fns_to_delete.push_back(added_fn);
10557 changed_fns_map_[f_fn_id] = d;
10558 built_some_diffs =
true;
10569 for (
auto& f : deleted_fns_to_delete)
10570 deleted_fns.erase(f);
10571 for (
auto& f : added_fns_to_delete)
10572 added_fns.erase(f);
10574 return built_some_diffs;
10601 return fn_suppr->suppresses_function(fn, k, ctxt);
10628 return var_suppr->suppresses_variable(var, k, ctxt);
10640 for (suppressions_type::const_iterator i = suppressions.begin();
10641 i != suppressions.end();
10648 for (
auto& entry : added_fns_)
10649 if (function_is_suppressed(*entry.second.begin(), fn_suppr,
10652 suppressed_added_fns_[entry.first] = *entry.second.begin();
10655 for (
auto& entry : deleted_fns_)
10656 if (function_is_suppressed(*entry.second.begin(), fn_suppr,
10659 suppressed_deleted_fns_[entry.first] = *entry.second.begin();
10662 for (string_elf_symbol_map::const_iterator e =
10663 added_unrefed_fn_syms_.begin();
10664 e != added_unrefed_fn_syms_.end();
10666 if (fn_suppr->suppresses_function_symbol(e->second,
10669 suppressed_added_unrefed_fn_syms_[e->first] = e->second;
10672 for (string_elf_symbol_map::const_iterator e =
10673 deleted_unrefed_fn_syms_.begin();
10674 e != deleted_unrefed_fn_syms_.end();
10676 if (fn_suppr->suppresses_function_symbol(e->second,
10679 suppressed_deleted_unrefed_fn_syms_[e->first] = e->second;
10687 for (
auto& entry : added_fns_)
10696 if (type_suppr->suppresses_type(c, ctxt))
10697 suppressed_added_fns_[entry.first] = f;
10701 for (
auto& entry : deleted_fns_)
10710 if (type_suppr->suppresses_type(c, ctxt))
10711 suppressed_deleted_fns_[entry.first] = f;
10717 for (string_type_base_sptr_map::const_iterator e =
10718 deleted_unreachable_types_.begin();
10719 e != deleted_unreachable_types_.end();
10721 if (type_suppr->suppresses_type(e->second, ctxt))
10722 suppressed_deleted_unreachable_types_[e->first] = e->second;
10726 for (string_type_base_sptr_map::const_iterator e =
10727 added_unreachable_types_.begin();
10728 e != added_unreachable_types_.end();
10730 if (type_suppr->suppresses_type(e->second, ctxt))
10731 suppressed_added_unreachable_types_[e->first] = e->second;
10738 for (string_var_ptr_map::const_iterator e = added_vars_.begin();
10739 e != added_vars_.end();
10741 if (variable_is_suppressed(e->second, var_suppr,
10744 suppressed_added_vars_[e->first] = e->second;
10747 for (string_var_ptr_map::const_iterator e = deleted_vars_.begin();
10748 e != deleted_vars_.end();
10750 if (variable_is_suppressed(e->second, var_suppr,
10753 suppressed_deleted_vars_[e->first] = e->second;
10756 for (string_elf_symbol_map::const_iterator e =
10757 added_unrefed_var_syms_.begin();
10758 e != added_unrefed_var_syms_.end();
10760 if (var_suppr->suppresses_variable_symbol(e->second,
10763 suppressed_added_unrefed_var_syms_[e->first] = e->second;
10766 for (string_elf_symbol_map::const_iterator e =
10767 deleted_unrefed_var_syms_.begin();
10768 e != deleted_unrefed_var_syms_.end();
10770 if (var_suppr->suppresses_variable_symbol(e->second,
10773 suppressed_deleted_unrefed_var_syms_[e->first] = e->second;
10792 string_function_ptr_map::const_iterator i =
10793 suppressed_deleted_fns_.find(n);
10795 return (i != suppressed_deleted_fns_.end());
10812 string_type_base_sptr_map::const_iterator i =
10813 suppressed_added_unreachable_types_.find(repr);
10814 if (i == suppressed_added_unreachable_types_.end())
10834 string_type_base_sptr_map::const_iterator i =
10835 suppressed_deleted_unreachable_types_.find(repr);
10836 if (i == suppressed_deleted_unreachable_types_.end())
10856 string_function_ptr_map::const_iterator i =
10857 suppressed_added_fns_.find(n);
10859 return (i != suppressed_added_fns_.end());
10875 string n = var->get_id();
10876 string_var_ptr_map::const_iterator i =
10877 suppressed_deleted_vars_.find(n);
10879 return (i != suppressed_deleted_vars_.end());
10895 string n = var->get_id();
10896 string_var_ptr_map::const_iterator i =
10897 suppressed_added_vars_.find(n);
10899 return (i != suppressed_added_vars_.end());
10915 string_elf_symbol_map::const_iterator i =
10916 suppressed_deleted_unrefed_fn_syms_.find(s->
get_id_string());
10918 return (i != suppressed_deleted_unrefed_fn_syms_.end());
10934 string_elf_symbol_map::const_iterator i =
10935 suppressed_added_unrefed_fn_syms_.find(s->
get_id_string());
10937 return (i != suppressed_added_unrefed_fn_syms_.end());
10953 string_elf_symbol_map::const_iterator i =
10954 suppressed_deleted_unrefed_var_syms_.find(s->
get_id_string());
10956 return (i != suppressed_deleted_unrefed_var_syms_.end());
10972 string_elf_symbol_map::const_iterator i =
10973 suppressed_added_unrefed_var_syms_.find(s->
get_id_string());
10975 return (i != suppressed_added_unrefed_var_syms_.end());
10978#ifdef do_count_diff_map_changes
10979#undef do_count_diff_map_changes
10981#define do_count_diff_map_changes(diff_map, n_changes, n_filtered) \
10983 string_diff_ptr_map::const_iterator i; \
10984 for (i = diff_map.begin(); \
10985 i != diff_map.end(); \
10988 if (const var_diff* d = is_var_diff(i->second)) \
10989 if (is_data_member(d->first_var())) \
10992 if (i->second->has_local_changes()) \
10994 if (!i->second->get_canonical_diff()->to_be_reported()) \
11010 count_leaf_type_changes(num_changes, num_filtered);
11013 do_count_diff_map_changes(leaf_diffs_.get_function_decl_diff_map(),
11014 num_changes, num_filtered);
11015 do_count_diff_map_changes(leaf_diffs_.get_var_decl_diff_map(),
11016 num_changes, num_filtered);
11029 size_t &num_filtered)
11031 do_count_diff_map_changes(leaf_diffs_.get_type_decl_diff_map(),
11032 num_changes, num_filtered);
11033 do_count_diff_map_changes(leaf_diffs_.get_enum_diff_map(),
11034 num_changes, num_filtered);
11035 do_count_diff_map_changes(leaf_diffs_.get_class_diff_map(),
11036 num_changes, num_filtered);
11037 do_count_diff_map_changes(leaf_diffs_.get_union_diff_map(),
11038 num_changes, num_filtered);
11039 do_count_diff_map_changes(leaf_diffs_.get_typedef_diff_map(),
11040 num_changes, num_filtered);
11041 do_count_diff_map_changes(leaf_diffs_.get_subrange_diff_map(),
11042 num_changes, num_filtered);
11043 do_count_diff_map_changes(leaf_diffs_.get_array_diff_map(),
11044 num_changes, num_filtered);
11045 do_count_diff_map_changes(leaf_diffs_.get_distinct_diff_map(),
11046 num_changes, num_filtered);
11047 do_count_diff_map_changes(leaf_diffs_.get_fn_parm_diff_map(),
11048 num_changes, num_filtered);
11076 size_t &num_deleted,
11077 size_t &num_changed,
11078 size_t &num_filtered_added,
11079 size_t &num_filtered_deleted,
11080 size_t &num_filtered_changed)
11082 num_added = added_unreachable_types_.size();
11083 num_deleted = deleted_unreachable_types_.size();
11084 num_changed = changed_unreachable_types_.size();
11085 num_filtered_added = suppressed_added_unreachable_types_.size();
11086 num_filtered_deleted = suppressed_deleted_unreachable_types_.size();
11088 std::map<string, type_base*> counted_changed_non_reachable_types;
11094 t =
is_type(d->first_subject());
11095 repr = t->get_pretty_representation();
11096 if (counted_changed_non_reachable_types.find(repr)
11097 != counted_changed_non_reachable_types.end())
11100 if (d->is_filtered_out())
11102 ++num_filtered_changed;
11103 counted_changed_non_reachable_types[repr] = t.get();
11114{
return changed_unreachable_types_;}
11125const vector<diff_sptr>&
11128if (changed_unreachable_types_sorted_.empty())
11129 if (!changed_unreachable_types_.empty())
11131 changed_unreachable_types_sorted_);
11133 return changed_unreachable_types_sorted_;
11144 if (ctxt->perform_change_categorization())
11146 if (get_context()->
do_log())
11148 std::cerr <<
"in corpus_diff::priv::maybe_perform_change_categorization:"
11149 <<
"applying filters to "
11150 << changed_fns_.size()
11151 <<
" changed fns ...\n";
11158 for (function_decl_diff_sptrs_type::const_iterator i =
11159 changed_fns_.begin();
11160 i != changed_fns_.end();
11164 ctxt->maybe_apply_filters(
diff);
11167 if (get_context()->do_log())
11170 std::cerr <<
"in corpus_diff::priv::perform_change_categorization():"
11171 <<
"filters to changed fn applied in:" << t <<
"\n";
11173 std::cerr <<
"in corpus_diff::priv::perform_change_categorization:"
11174 <<
"applying filters to "
11175 << sorted_changed_vars_.size()
11176 <<
" changed vars ...\n";
11182 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
11183 i != sorted_changed_vars_.end();
11187 ctxt->maybe_apply_filters(
diff);
11190 if (get_context()->do_log())
11193 std::cerr <<
"in corpus_diff::priv::perform_change_categorization:"
11194 <<
"filters to changed vars applied in:" << t <<
"\n";
11198 std::cerr <<
"in corpus_diff::priv::perform_change_categorization:"
11199 <<
"applying filters to "
11201 <<
" unreachable types ...\n";
11208 ctxt->maybe_apply_filters(
diff);
11210 if (get_context()->do_log())
11214 std::cerr <<
"in corpus_diff::priv::perform_change_categorization:"
11215 <<
"applied filters to " << n <<
" unreachable types in "
11229 if (ctxt->perform_change_categorization())
11231 if (get_context()->
do_log())
11233 std::cerr <<
"in corpus_diff::priv::perform_redundant_node_categorization:"
11234 <<
"filters to unreachable types applied in:" << t <<
"\n";
11236 std::cerr <<
"in corpus_diff::priv::perform_redundant_node_categorization:"
11237 <<
"categorizing redundant changed sub nodes ...\n";
11241 categorize_redundant_changed_sub_nodes();
11243 if (get_context()->
do_log())
11246 std::cerr <<
"in corpus_diff::priv::perform_redundant_node_categorization:"
11247 <<
"redundant changed sub nodes categorized in:" << t <<
"\n";
11249 std::cerr <<
"in corpus_diff::priv::perform_redundant_node_categorization:"
11250 <<
"count changed fns ...\n";
11275 maybe_perform_change_categorization();
11276 maybe_perform_redundant_node_categorization();
11278 get_context()->perform_change_categorization(
false);
11297 for (function_decl_diff_sptrs_type::const_iterator i =
11298 changed_fns_.begin();
11299 i != changed_fns_.end();
11302 bool incompatible_change =
false;
11303 if ((*i)->is_filtered_out())
11308 if ((*i)->has_local_changes())
11314 if (!(*i)->is_categorized_as_suppressed())
11328 incompatible_change =
true;
11338 incompatible_change =
true;
11342 if ((*i)->has_local_changes())
11346 if (incompatible_change)
11348 incompatible_changed_fns_.push_back(*i);
11352 if ((*i)->has_local_changes())
11357 if ((*i)->is_filtered_out())
11365 if ((*i)->has_local_changes())
11373 if (get_context()->do_log())
11375 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
11376 <<
"changed fn counted in:" << t <<
"\n";
11378 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
11379 <<
"count changed vars ...\n";
11386 for (var_diff_sptrs_type ::const_iterator i = sorted_changed_vars_.begin();
11387 i != sorted_changed_vars_.end();
11390 bool incompatible_change =
false;
11391 if ((*i)->is_filtered_out())
11396 if ((*i)->has_local_changes())
11401 if (!(*i)->is_categorized_as_suppressed())
11405 incompatible_change =
true;
11406 incompatible_changed_vars_.push_back(*i);
11412 if ((*i)->is_filtered_out())
11417 if ((*i)->has_local_changes())
11424 if ((*i)->has_local_changes())
11429 if (incompatible_change)
11435 if (get_context()->do_log())
11438 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
11439 <<
"changed vars counted in:" << t <<
"\n";
11441 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
11442 <<
"count leaf changed types ...\n";
11457 size_t num_type_changes = 0, num_type_filtered = 0;
11458 count_leaf_type_changes(num_type_changes, num_type_filtered);
11464 if (get_context()->
do_log())
11467 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
11468 <<
"changed leaf types counted in:" << t <<
"\n";
11470 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
11471 <<
"count leaf changed artefacts ...\n";
11477 size_t num_changes = 0, num_filtered = 0;
11478 count_leaf_changes(num_changes, num_filtered);
11484 if (get_context()->
do_log())
11487 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
11488 <<
"changed leaf artefacts counted in:" << t <<
"\n";
11490 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
11491 <<
"count unreachable types ...\n";
11497 size_t num_added_unreachable_types = 0,
11498 num_changed_unreachable_types = 0,
11499 num_deleted_unreachable_types = 0,
11500 num_added_unreachable_types_filtered = 0,
11501 num_changed_unreachable_types_filtered = 0,
11502 num_deleted_unreachable_types_filtered = 0;
11504 count_unreachable_types(num_added_unreachable_types,
11505 num_deleted_unreachable_types,
11506 num_changed_unreachable_types,
11507 num_added_unreachable_types_filtered,
11508 num_deleted_unreachable_types_filtered,
11509 num_changed_unreachable_types_filtered);
11511 if (get_context()->
do_log())
11514 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
11515 <<
"unreachable types counted in:" << t <<
"\n";
11522 (num_added_unreachable_types_filtered);
11524 (num_deleted_unreachable_types_filtered);
11526 (num_changed_unreachable_types_filtered);
11542 const string& indent)
11545 size_t net_num_leaf_changes =
11558 if (!sonames_equal_)
11559 out << indent <<
"ELF SONAME changed\n";
11561 if (!architectures_equal_)
11562 out << indent <<
"ELF architecture changed\n";
11566 if (ctxt->show_leaf_changes_only())
11568 out <<
"Leaf changes summary: ";
11569 out << net_num_leaf_changes <<
" artifact";
11570 if (net_num_leaf_changes > 1)
11575 out <<
" (" << num_filtered <<
" filtered out)";
11578 out << indent <<
"Changed leaf types summary: "
11582 <<
" filtered out)";
11583 out <<
" leaf type";
11586 out <<
" changed\n";
11589 out << indent <<
"Removed/Changed/Added functions summary: ";
11594 <<
" filtered out)";
11601 <<
" filtered out)";
11608 out <<
"functions";
11614 out << indent <<
"Removed/Changed/Added variables summary: ";
11618 <<
" filtered out)";
11625 <<
" filtered out)";
11632 out <<
"variables";
11635 <<
" filtered out)";
11644 out << indent <<
"Functions changes summary: ";
11649 <<
" filtered out)";
11660 if (total_nb_function_changes <= 1)
11661 out <<
" function";
11663 out <<
" functions";
11670 out << indent <<
"Variables changes summary: ";
11674 <<
" filtered out)";
11685 <<
" filtered out)";
11686 if (total_nb_variable_changes <= 1)
11687 out <<
" variable";
11689 out <<
" variables";
11695 if (ctxt->show_unreachable_types())
11697 size_t total_nb_unreachable_type_changes =
11703 out << indent <<
"Unreachable types summary: "
11708 <<
" filtered out)";
11715 <<
" filtered out)";
11722 <<
" filtered out)";
11723 if (total_nb_unreachable_type_changes <= 1)
11730 if (ctxt->show_symbols_unreferenced_by_debug_info()
11738 if (!ctxt->show_added_symbols_unreferenced_by_debug_info()
11748 <<
"Function symbols changes summary: "
11752 <<
" filtered out)";
11757 <<
" filtered out)";
11758 out <<
" function symbol";
11761 out <<
" not referenced by debug info\n";
11766 if (!ctxt->show_added_symbols_unreferenced_by_debug_info()
11776 <<
"Variable symbols changes summary: "
11780 <<
" filtered out)";
11785 <<
" filtered out)";
11786 out <<
" variable symbol";
11789 out <<
" not referenced by debug info\n";
11802 ctxt->forget_visited_diffs();
11803 for (function_decl_diff_sptrs_type::const_iterator i =
11804 changed_fns_.begin();
11805 i!= changed_fns_.end();
11812 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
11813 i!= sorted_changed_vars_.end();
11820 for (diff_sptrs_type::const_iterator i =
11837 for (function_decl_diff_sptrs_type::const_iterator i = changed_fns_.begin();
11838 i!= changed_fns_.end();
11845 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
11846 i!= sorted_changed_vars_.end();
11864 if (!ctxt->dump_diff_tree()
11865 || ctxt->error_output_stream() == 0)
11868 if (!changed_fns_.empty())
11870 *ctxt->error_output_stream() <<
"changed functions diff tree: \n\n";
11871 for (function_decl_diff_sptrs_type::const_iterator i =
11872 changed_fns_.begin();
11873 i != changed_fns_.end();
11881 if (!sorted_changed_vars_.empty())
11883 *ctxt->error_output_stream() <<
"\nchanged variables diff tree: \n\n";
11884 for (var_diff_sptrs_type::const_iterator i =
11885 sorted_changed_vars_.begin();
11886 i != sorted_changed_vars_.end();
11896 *ctxt->error_output_stream() <<
"\nchanged unreachable "
11897 "types diff tree: \n\n";
11898 for (vector<diff_sptr>::const_iterator i =
11916 for (function_decl_diff_sptrs_type::const_iterator i =
11935 corpus_sptr second,
11937 : priv_(new
priv(first, second, ctxt))
11940corpus_diff::~corpus_diff() =
default;
11946 if (priv_->finished_)
11949 priv_->finished_ =
true;
11969{
return priv_->first_;}
11974{
return priv_->second_;}
11977const vector<diff*>&
11979{
return priv_->children_;}
11997 bool inserted =
false;
11998 for (vector<diff*>::iterator i = priv_->children_.begin();
11999 i != priv_->children_.end();
12004 context()->keep_diff_alive(d);
12005 priv_->children_.insert(i, d.get());
12014 context()->keep_diff_alive(d);
12018 priv_->children_.push_back(d.get());
12027{
return !priv_->sonames_equal_;}
12034{
return !priv_->architectures_equal_;}
12041{
return priv_->deleted_fns_;}
12048{
return priv_->added_fns_;}
12060{
return priv_->changed_fns_map_;}
12069{
return priv_->changed_fns_;}
12078{
return priv_->incompatible_changed_fns_;}
12087{
return priv_->incompatible_changed_fns_;}
12095{
return priv_->deleted_vars_;}
12102{
return priv_->added_vars_;}
12110{
return priv_->changed_vars_map_;}
12118{
return priv_->sorted_changed_vars_;}
12127{
return priv_->incompatible_changed_vars_;}
12136{
return priv_->incompatible_changed_vars_;}
12145{
return priv_->deleted_unrefed_fn_syms_;}
12154{
return priv_->added_unrefed_fn_syms_;}
12163{
return priv_->deleted_unrefed_var_syms_;}
12172{
return priv_->added_unrefed_var_syms_;}
12181{
return priv_->deleted_unreachable_types_;}
12189const vector<type_base_sptr>&
12192 if (priv_->deleted_unreachable_types_sorted_.empty())
12193 if (!priv_->deleted_unreachable_types_.empty())
12195 priv_->deleted_unreachable_types_sorted_);
12197 return priv_->deleted_unreachable_types_sorted_;
12207{
return priv_->added_unreachable_types_;}
12215const vector<type_base_sptr>&
12218 if (priv_->added_unreachable_types_sorted_.empty())
12219 if (!priv_->added_unreachable_types_.empty())
12221 priv_->added_unreachable_types_sorted_);
12223 return priv_->added_unreachable_types_sorted_;
12233{
return priv_->changed_unreachable_types_;}
12241const vector<diff_sptr>&
12243{
return priv_->changed_unreachable_types_sorted();}
12250{
return priv_->get_context();}
12257 if (priv_->pretty_representation_.empty())
12259 std::ostringstream o;
12260 o <<
"corpus_diff["
12265 priv_->pretty_representation_ = o.str();
12267 return priv_->pretty_representation_;
12280 || !(priv_->deleted_fns_.empty()
12281 && (priv_->added_fns_.empty()
12282 || !ctxt->show_added_fns())
12283 && priv_->changed_fns_map_.empty()
12284 && priv_->deleted_vars_.empty()
12285 && (priv_->added_vars_.empty()
12286 || !ctxt->show_added_vars())
12287 && priv_->changed_vars_map_.empty()
12288 && (priv_->added_unrefed_fn_syms_.empty()
12289 || !ctxt->show_added_symbols_unreferenced_by_debug_info())
12290 && (priv_->deleted_unrefed_fn_syms_.empty()
12291 || !ctxt->show_symbols_unreferenced_by_debug_info())
12292 && (priv_->added_unrefed_var_syms_.empty()
12293 || !ctxt->show_added_symbols_unreferenced_by_debug_info())
12294 && (priv_->deleted_unrefed_var_syms_.empty()
12295 || !ctxt->show_symbols_unreferenced_by_debug_info())
12296 && (priv_->deleted_unreachable_types_.empty()
12297 || !ctxt->show_unreachable_types())
12298 && (priv_->added_unreachable_types_.empty()
12299 || !ctxt->show_unreachable_types())
12300 && (priv_->changed_unreachable_types_.empty()
12301 || !ctxt->show_unreachable_types())));
12347 && ctxt->show_symbols_unreferenced_by_debug_info())
12349 && ctxt->show_symbols_unreferenced_by_debug_info())
12351 && ctxt->show_unreachable_types()));
12359 && ctxt->show_unreachable_types())
12365 for (
auto &entry : priv_->changed_unreachable_types())
12409{
return context()->get_reporter()->diff_has_net_changes(
this);}
12435 if (priv_->diff_stats_)
12436 return *priv_->diff_stats_;
12444 std::cerr <<
"Marking leaf nodes ...\n";
12453 std::cerr <<
"leaf nodes marked in:" << t <<
"\n";
12454 std::cerr <<
"Applying filters and computing diff stats ...\n";
12458 priv_->apply_filters_and_compute_diff_stats(
this, *priv_->diff_stats_);
12463 std::cerr <<
"Filters applied and diff stats computed in: " << t <<
"\n";
12466 return *priv_->diff_stats_;
12488 visit_begin(
diff *d)
12535 const corpus_diff *corpus_diff_node = ctxt->get_corpus_diff().get();
12545 get_leaf_diffs().insert_diff_node(d, iface);
12563 if (!
context()->show_leaf_changes_only())
12566 leaf_diff_node_marker_visitor v;
12567 context()->forget_visited_diffs();
12568 bool s =
context()->visiting_a_node_twice_is_forbidden();
12569 context()->forbid_visiting_a_node_twice(
true);
12570 if (
context()->show_impacted_interfaces())
12571 context()->forbid_visiting_a_node_twice_per_interface(
true);
12573 context()->forbid_visiting_a_node_twice(s);
12574 context()->forbid_visiting_a_node_twice_per_interface(
false);
12584{
return priv_->leaf_diffs_;}
12593{
return priv_->leaf_diffs_;}
12604 context()->get_reporter()->report(*
this, out, indent);
12619 if (!v.
visit(
this,
true))
12625 for (function_decl_diff_sptrs_type::const_iterator i =
12633 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
12634 ctxt->forget_visited_diffs();
12647 for (var_diff_sptrs_type::const_iterator i =
12655 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
12656 ctxt->forget_visited_diffs();
12673 for (vector<diff_sptr>::const_iterator i =
12681 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
12682 ctxt->forget_visited_diffs();
12719template<
typename lookup_fn>
12721compute_unreferenced_symbol_set_diff(
const corpus_sptr& first,
12722 const corpus_sptr& second,
12727 lookup_fn lookup_in_corpus)
12730 unordered_map<string, elf_symbol_sptr> first_map, second_map;
12731 first_map.reserve(first_syms.size());
12732 second_map.reserve(second_syms.size());
12734 for (
const auto& sym : first_syms)
12735 first_map[sym->get_id_string()] = sym;
12737 for (
const auto& sym : second_syms)
12738 second_map[sym->get_id_string()] = sym;
12741 for (
const auto& entry : first_map)
12743 if (second_map.find(entry.first) == second_map.end())
12745 if (!lookup_in_corpus(second, *entry.second))
12746 deleted_syms[entry.first] = entry.second;
12751 for (
const auto& entry : second_map)
12753 if (first_map.find(entry.first) != first_map.end())
12756 if (!lookup_in_corpus(first, *entry.second))
12758 bool do_add =
true;
12759 if (!entry.second->get_version().is_empty()
12760 && entry.second->get_version().is_default())
12766 elf_symbol::version empty_version;
12767 if (lookup_in_corpus(first, entry.second->get_name(),
12772 added_syms[entry.first] = entry.second;
12791 const corpus_sptr s,
12801 ctxt->set_corpus_diff(r);
12803 if(ctxt->show_soname_change())
12804 r->priv_->sonames_equal_ = f->get_soname() == s->get_soname();
12806 r->priv_->sonames_equal_ =
true;
12808 r->priv_->architectures_equal_ =
12809 f->get_architecture_name() == s->get_architecture_name();
12820 compute_unreferenced_symbol_set_diff
12822 f->get_unreferenced_function_symbols(),
12823 s->get_unreferenced_function_symbols(),
12824 r->priv_->deleted_unrefed_fn_syms_,
12825 r->priv_->added_unrefed_fn_syms_,
12826 [](
const auto& c,
auto&&... args)
12827 {return c->lookup_function_symbol(std::forward<decltype(args)>(args)...);});
12832 compute_unreferenced_symbol_set_diff
12834 f->get_unreferenced_variable_symbols(),
12835 s->get_unreferenced_variable_symbols(),
12836 r->priv_->deleted_unrefed_var_syms_,
12837 r->priv_->added_unrefed_var_syms_,
12838 [](
const auto& c,
auto&&... args)
12839 {return c->lookup_variable_symbol(std::forward<decltype(args)>(args)...);});
12841 r->priv_->compare_fns_vars_and_ensure_lookup_tables_populated();
12862 const corpus_group_sptr& s,
12866 corpus_sptr c1 = f;
12867 corpus_sptr c2 = s;
12879struct diff_node_visitor::priv
12881 diff* topmost_interface_diff;
12885 : topmost_interface_diff(),
12890 : topmost_interface_diff(),
12900diff_node_visitor::~diff_node_visitor() =
default;
12906 : priv_(new priv(k))
12916{
return priv_->kind;}
12936{priv_->kind = priv_->kind | v;}
12944{priv_->topmost_interface_diff = d;}
12952{
return priv_->topmost_interface_diff;}
13179 bool already_visited = d->
context()->diff_has_been_visited(d);
13187 bool update_canonical = !already_visited && canonical;
13189 for (
auto node : d->children_nodes())
13206 ? node->get_canonical_diff()
13227 if (!already_visited && canonical)
13228 if (update_canonical)
13229 canonical->add_to_category(c);
13257 c &= (~NON_COMPATIBLE_NAME_CHANGE_CATEGORY
13258 & ~NON_COMPATIBLE_DISTINCT_CHANGE_CATEGORY);
13271 c &= (~NON_COMPATIBLE_NAME_CHANGE_CATEGORY
13272 & ~NON_COMPATIBLE_DISTINCT_CHANGE_CATEGORY);
13280 c &= ~NON_COMPATIBLE_NAME_CHANGE_CATEGORY;
13295 category_propagation_visitor v;
13296 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13297 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
13298 diff_tree->
context()->forget_visited_diffs();
13300 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13322 category_propagation_visitor v;
13323 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13324 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13326 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13350 visit_begin(
diff* d)
13352 bool is_private_type =
false;
13363 if (canonical_diff != d)
13419 bool has_non_suppressed_child =
false;
13420 bool has_non_empty_child =
false;
13421 bool has_suppressed_child =
false;
13422 bool has_non_private_child =
false;
13423 bool has_private_child =
false;
13424 bool has_descendant_with_allowed_change =
false;
13457 && (!d->has_local_changes()
13482 for (vector<diff*>::const_iterator i = d->children_nodes().begin();
13483 i != d->children_nodes().end();
13487 if (child->has_changes())
13489 has_non_empty_child =
true;
13493 has_suppressed_child =
true;
13494 else if (child->get_class_of_equiv_category()
13500 has_non_suppressed_child =
true;
13502 if (child->get_class_of_equiv_category()
13504 has_private_child =
true;
13512 has_non_private_child =
true;
13516 if (has_non_empty_child
13517 && has_suppressed_child
13518 && !has_non_suppressed_child)
13524 if (canonical_diff != d)
13540 if (has_non_empty_child
13541 && has_private_child
13542 && !has_non_private_child)
13548 if (canonical_diff != d)
13558 && has_private_child
13559 && has_non_empty_child)
13565 if (canonical_diff != d)
13582 if (fn_type_diff->is_suppressed())
13588 if (canonical_diff != d)
13597 for (
auto child_node : d->children_nodes())
13603 has_descendant_with_allowed_change =
true;
13605 if (has_descendant_with_allowed_change)
13608 d->add_to_category(c);
13609 d->get_canonical_diff()->add_to_category(c);
13627 suppression_categorization_visitor v;
13629 bool s =
get_context()->visiting_a_node_twice_is_forbidden();
13630 get_context()->forbid_visiting_a_node_twice(
true);
13649 if (diff_tree && !diff_tree->
context()->suppressions().empty())
13653 suppression_categorization_visitor v;
13654 diff_tree->
context()->forget_visited_diffs();
13655 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13656 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
13658 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13681 if (diff_tree && !diff_tree->
context()->suppressions().empty())
13686 suppression_categorization_visitor v;
13687 diff_tree->
context()->forget_visited_diffs();
13688 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13689 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
13691 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13697 apply_supprs_to_added_removed_fns_vars_unreachable_types();
13727 do_indent(
unsigned level)
13729 for (
unsigned i = 0; i < level; ++i)
13733 diff_node_printer(ostream& out)
13734 : diff_node_visitor(DO_NOT_MARK_VISITED_NODES_AS_VISITED),
13752 visit_begin(corpus_diff*)
13758 visit_end(corpus_diff*)
13764 visit(diff* d,
bool pre)
13773 out_ << d->get_pretty_representation();
13777 do_indent(level_ + 1);
13778 out_ <<
"category: "<< d->get_category() <<
"\n";
13779 do_indent(level_ + 1);
13780 out_ <<
"local category: "<< d->get_local_category() <<
"\n";
13781 do_indent(level_ + 1);
13782 out_ <<
"@: " << std::hex << d << std::dec <<
"\n";
13783 do_indent(level_ + 1);
13784 out_ <<
"@-canonical: " << std::hex
13785 << d->get_canonical_diff()
13786 << std::dec <<
"\n";
13794 visit(corpus_diff* d,
bool pre)
13803 for (
unsigned i = 0; i < level_; ++i)
13805 out_ << d->get_pretty_representation();
13824 diff_node_printer p(out);
13825 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13826 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13828 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13842 diff_node_printer p(out);
13843 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13844 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13846 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13881 std::cout << c << std::endl;
13894 bool skip_children_nodes_;
13896 redundancy_marking_visitor()
13897 : skip_children_nodes_()
13901 visit_begin(diff* d)
13903 if (d->to_be_reported())
13909 if ((d->context()->diff_has_been_visited(d)
13910 || d->get_canonical_diff()->is_traversing())
13911 && d->has_changes())
13926 bool redundant_with_sibling_node =
false;
13931 if (p &&
dynamic_cast<const fn_parm_diff*
>(p))
13935 for (vector<diff*>::const_iterator s =
13936 p->children_nodes().begin();
13937 s != p->children_nodes().end();
13945 if (fn_parm_diff* f =
dynamic_cast<fn_parm_diff*
>(*s))
13946 sib = f->type_diff().get();
13949 if (sib->get_canonical_diff() == d->get_canonical_diff()
13952 && (is_base_diff(sib) || is_distinct_diff(sib)))
13954 redundant_with_sibling_node =
true;
13958 if (!redundant_with_sibling_node
13965 && !filtering::is_mostly_distinct_diff(d)
13979 && (!d->get_canonical_diff()->is_filtered_out()
13980 || (d->get_canonical_diff()->get_category()
13987 && d->context()->diff_has_been_visited(d) != d
14007 set_visiting_kind(get_visiting_kind()
14008 | SKIP_CHILDREN_VISITING_KIND);
14009 skip_children_nodes_ =
true;
14016 set_visiting_kind(get_visiting_kind() | SKIP_CHILDREN_VISITING_KIND);
14017 skip_children_nodes_ =
true;
14022 visit_begin(corpus_diff*)
14029 if (skip_children_nodes_)
14035 set_visiting_kind(get_visiting_kind() & (~SKIP_CHILDREN_VISITING_KIND));
14036 skip_children_nodes_ =
false;
14044 if (!(d->get_category() & REDUNDANT_CATEGORY)
14073 && (!(d->has_local_changes()
14074 & LOCAL_NON_TYPE_CHANGE_KIND)))
14084 && (!(d->has_local_changes()
14085 & LOCAL_NON_TYPE_CHANGE_KIND)))
14091 && (!(d->has_local_changes()
14092 & LOCAL_NON_TYPE_CHANGE_KIND)))
14095 bool has_non_redundant_child =
false;
14096 bool has_non_empty_child =
false;
14098 for (vector<diff*>::const_iterator i =
14099 d->children_nodes().begin();
14100 i != d->children_nodes().end();
14103 if ((*i)->has_changes())
14114 has_non_empty_child =
true;
14121 if ((*i)->to_be_reported()
14123 has_non_redundant_child =
true;
14125 if (has_non_redundant_child)
14132 if (has_non_empty_child
14133 && !has_non_redundant_child)
14134 d->add_to_category(REDUNDANT_CATEGORY);
14140 visit_end(corpus_diff*)
14149 visit(corpus_diff*,
bool)
14157struct redundancy_clearing_visitor :
public diff_node_visitor
14160 visit(corpus_diff*,
bool)
14164 visit(diff* d,
bool)
14168 c &= ~REDUNDANT_CATEGORY;
14169 d->set_category(c);
14181 if (diff_tree->
context()->show_redundant_changes())
14183 redundancy_marking_visitor v;
14184 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
14185 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
14187 diff_tree->
context()->forbid_visiting_a_node_twice(s);
14205 redundancy_marking_visitor v;
14206 diff_tree->
context()->forget_visited_diffs();
14207 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
14208 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
14210 diff_tree->
context()->forbid_visiting_a_node_twice(s);
14230 redundancy_clearing_visitor v;
14231 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
14232 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
14234 diff_tree->
context()->forbid_visiting_a_node_twice(s);
14235 diff_tree->
context()->forget_visited_diffs();
14253 redundancy_clearing_visitor v;
14254 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
14255 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
14257 diff_tree->
context()->forbid_visiting_a_node_twice(s);
14258 diff_tree->
context()->forget_visited_diffs();
14284 if (!ctxt->perform_change_categorization())
14292 ctxt->maybe_apply_filters(diff_tree);
14307 c->apply_filters_and_suppressions_before_reporting();
14324 if (t && t->get_environment().is_variadic_parameter_type(t))
14328 if (t && t->get_environment().is_variadic_parameter_type(t))
14393 if (allow_indirect_type)
14594has_local_type_change_only(
const diff *d)
14622 return (has_local_type_change_only(v)
14625 return (has_local_type_change_only(p)
14629 return (has_local_type_change_only(f)
The private data and functions of the abigail::ir::comparison types.
#define SKIP_MEM_FN_IF_VIRTUALITY_DISALLOWED
Skip the processing of the current member function if its virtual-ness is disallowed by the user.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
This contains the private implementation of the suppression engine of libabigail.
The abstraction of a diff between two arrays.
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 diff base type sub-object of this instance of array_diff.
const diff_sptr & element_type_diff() const
Getter for the diff between the two types of array elements.
array_diff(const array_type_def_sptr first, const array_type_def_sptr second, diff_sptr element_type_diff, vector< subrange_diff_sptr > &subrange_diffs, diff_context_sptr ctxt=diff_context_sptr())
Constructor for array_diff.
bool any_subrange_diff_to_be_reported() const
Test if any subrange diff is to be reported.
const array_type_def_sptr second_array() const
Getter for the second array of the diff.
const array_type_def_sptr first_array() const
Getter for the first array of the diff.
virtual enum change_kind has_local_changes() const
const vector< subrange_diff_sptr > & subrange_diffs() const
Getter for the diffs between the array subranges.
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
An abstraction of a diff between two instances of class_decl::base_spec.
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 diff base type sub-object of this instance of base_diff.
void set_underlying_class_diff(class_diff_sptr d)
Setter for the diff object for the diff of the underlyng base classes.
class_decl::base_spec_sptr second_base() const
Getter for the second base spec of the diff object.
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())
const class_diff_sptr get_underlying_class_diff() const
Getter for the diff object for the diff of the underlying base classes.
class_decl::base_spec_sptr first_base() const
Getter for the first base spec of the diff object.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Generates a report for the current instance of base_diff.
This type abstracts changes for a class_decl.
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 diff base type sub-object of this instance of class_diff.
class_decl_sptr first_class_decl() const
const base_diff_sptrs_type & changed_bases()
Getter for the changed base classes of the 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_base_sptr_map & inserted_bases() const
Getter for the inserted base classes of the diff.
const string_base_sptr_map & deleted_bases() const
Getter for the deleted base classes of the diff.
virtual enum change_kind has_local_changes() const
const edit_script & base_changes() const
virtual const string & get_pretty_representation() const
class_diff(class_decl_sptr first_scope, class_decl_sptr second_scope, diff_context_sptr ctxt=diff_context_sptr())
Constructor of class_diff.
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.
class_decl_sptr second_class_decl() const
Getter of the second class involved in the diff.
virtual void report(ostream &, const string &indent="") const
Produce a basic report about the changes between two class_decl.
This is the base class of class_diff and union_diff.
virtual bool has_changes() const
Test if the current diff node carries a change.
const edit_script & member_fn_tmpls_changes() const
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 class_or_union_diff::priv_ptr & get_priv() const
Getter of the private data of the class_or_union_diff type.
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_class_tmpls_changes() const
void allocate_priv_data()
Allocate the memory for the priv_ pimpl data member of the class_or_union_diff class.
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 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...
const edit_script & member_types_changes() const
const string_member_function_sptr_map & deleted_member_fns() const
class_or_union_sptr first_class_or_union() const
const var_diff_sptrs_type & sorted_subtype_changed_data_members() const
Getter of the sorted vector of data members with a (sub-)type change.
bool lookup_tables_empty(void) const
Tests if the lookup tables are empty.
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.
void clear_lookup_tables(void)
Clear the lookup tables useful for reporting.
const string_decl_base_sptr_map & deleted_data_members() const
Getter for the data members that got deleted.
virtual ~class_or_union_diff()
Destructor of class_or_union_diff.
const string_decl_base_sptr_map & inserted_data_members() const
Getter for the data members that got inserted.
void ensure_lookup_tables_populated(void) const
If the lookup tables are not yet built, walk the differences and fill them.
const string_member_function_sptr_map & inserted_member_fns() const
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...
const edit_script & data_members_changes() const
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.
virtual enum change_kind has_local_changes() const
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.
const edit_script & member_fns_changes() const
class_or_union_sptr second_class_or_union() const
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.
virtual void report(ostream &, const string &indent="") const
Report the changes carried by the current class_or_union_diff node in a textual format.
This is a document class that aims to capture statistics about the changes carried by a corpus_diff t...
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 ...
size_t num_func_removed() const
Getter for the number of functions removed.
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...
size_t num_vars_changed() const
Getter for the number of variables that have a change in one of their sub-types.
size_t num_var_with_incompatible_changes() const
Getter for the number of variables with incompatible changes.
size_t net_num_leaf_func_non_incompatible_changes() const
Getter for the net number of leaf function diff nodes that carry changes that are NOT incompatible.
size_t net_num_leaf_var_changes() const
Getter for the net number of leaf variable change diff nodes.
size_t num_vars_added() const
Getter for the number of variables added.
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...
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...
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...
size_t net_num_non_incompatible_var_changed() const
Getter of the net number of variables with changes that are not incompatible.
size_t num_removed_vars_filtered_out() const
Getter for the number removed variables that have been filtered out.
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...
size_t net_num_vars_removed() const
Getter for the net number of removed variables.
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...
size_t num_removed_var_syms_filtered_out() const
Getter for the number of removed variable symbols, not referenced by any debug info,...
size_t num_leaf_func_with_incompatible_changes() const
Getter for the number of leaf function diff nodes that carry incompatible changes.
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.
size_t num_added_var_syms_filtered_out() const
Getter for the number of added variable symbols, not referenced by any debug info,...
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.
size_t num_func_with_local_harmful_changes() const
Getter for the number of functions with local harmful changes.
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.
size_t num_var_syms_added() const
Getter for the number of variable symbols (not referenced by any debug info) that got added.
size_t num_leaf_var_changes() const
Getter for the number of leaf variable change diff nodes.
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.
size_t num_func_with_incompatible_changes() const
Getter for the number of functions with incompatible changes.
size_t net_num_non_incompatible_func_changed() const
Getter of the net number of functions with changes that are not incompatible.
size_t net_num_func_removed() const
Getter for the net number of function removed.
size_t net_num_func_added() const
Getter for the net number of added functions.
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...
size_t net_num_leaf_changes() const
Getter of the net number of leaf change diff nodes.
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...
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...
size_t num_added_func_filtered_out() const
Getter for the number of added function that have been filtered out.
size_t num_func_syms_added() const
Getter for the number of function symbols (not referenced by any debug info) that got added.
size_t net_num_leaf_type_changes() const
Getter for the net number of leaf type change diff nodes.
size_t num_func_added() const
Getter for the number of functions added.
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.
size_t num_leaf_type_changes() const
Getter for the number of leaf type change diff nodes.
size_t num_leaf_var_changes_filtered_out() const
Getter for the number of leaf variable changes diff nodes that have been filtered out.
size_t num_added_vars_filtered_out() const
Getter for the number of added variables that have been filtered out.
size_t num_func_with_virtual_offset_changes() const
Getter for the number of functions that carry virtual member offset changes.
size_t net_num_leaf_var_non_incompatible_changes() const
Getter for the net number of leaf variable diff nodes that carry changes that are NOT incompatible.
size_t num_func_changed() const
Getter for the number of functions that have a change in one of their sub-types.
size_t num_removed_func_filtered_out() const
Getter for the number of removed functions that have been filtered out.
size_t net_num_vars_added() const
Getter for the net number of added variables.
size_t num_leaf_changes() const
Getter of the number of leaf type change diff nodes.
size_t num_leaf_func_changes_filtered_out() const
Getter for the number of leaf function change diff nodes that were filtered out.
size_t num_added_func_syms_filtered_out() const
Getter for the number of added function symbols, not referenced by any debug info,...
size_t num_leaf_type_changes_filtered_out() const
Getter for the number of filtered out leaf type change diff nodes.
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...
size_t net_num_leaf_func_changes() const
Getter for the net number of leaf function change diff nodes.
size_t num_leaf_func_changes() const
Getter for the number of leaf function change diff nodes.
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*...
size_t num_func_syms_removed() const
Getter for the number of function symbols (not referenced by any debug info) that got removed.
size_t num_leaf_var_with_incompatible_changes() const
Getter for the number of leaf variable diff nodes that carry incompatible changes.
size_t num_leaf_changes_filtered_out() const
Getter of the number of leaf type change diff nodes that have been filtered out.
size_t num_vars_removed() const
Getter for the number of variables removed.
size_t num_var_syms_removed() const
Getter for the number of variable symbols (not referenced by any debug info) that got removed.
size_t num_var_with_local_harmful_changes() const
Getter for the number of variables with local harmful changes.
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...
An abstraction of a diff between between two abi corpus.
bool has_incompatible_changes() const
Test if the current instance of corpus_diff carries changes that we are sure are incompatible....
bool has_changes() const
Return true iff the current corpus_diff node carries a change.
void finish_diff_type()
Finish building the current instance of corpus_diff.
virtual void chain_into_hierarchy()
Populate the vector of children node of the corpus_diff type.
const string_var_ptr_map & deleted_variables() const
Getter for the variables that got deleted from the first subject of the 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.
const istring_functions_set_map_type & added_functions()
Getter for the added functions of the diff.
bool soname_changed() const
Test if the soname of the underlying corpus has changed.
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.
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 vector< diff * > & children_nodes() const
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 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...
const string_elf_symbol_map & deleted_unrefed_function_symbols() const
Getter for function symbols not referenced by any debug info and that got deleted.
const string_elf_symbol_map & deleted_unrefed_variable_symbols() const
Getter for variable symbols not referenced by any debug info and that got deleted.
const string_function_decl_diff_sptr_map & changed_functions() const
Getter for the functions which signature didn't change, but which do have some indirect changes in th...
const var_diff_sptrs_type & incompatible_changed_variables() const
Getter of the set of diff nodes representing incompatibly changed global variables.
corpus_diff(corpus_sptr first, corpus_sptr second, diff_context_sptr ctxt=diff_context_sptr())
Constructor for corpus_diff.
corpus_sptr second_corpus() const
bool do_log() const
Test if logging was requested.
const string_elf_symbol_map & added_unrefed_function_symbols() const
Getter for function symbols not referenced by any debug info and that got added.
bool has_net_subtype_changes() const
Test if the current instance of corpus_diff carries subtype changes whose reports are not suppressed ...
const string_var_ptr_map & added_variables() const
Getter for the added variables of the diff.
diff_maps & get_leaf_diffs()
Get the set of maps that contain leaf nodes. A leaf node being a node with a local change.
const diff_context_sptr context() const
Getter of the diff context of this diff.
bool has_net_changes() const
Test if the current instance of corpus_diff carries changes whose reports are not suppressed by any s...
virtual bool traverse(diff_node_visitor &v)
Traverse the diff sub-tree under the current instance corpus_diff.
const diff_stats & apply_filters_and_suppressions_before_reporting()
Mark leaf nodes and apply the different filters that are registered to be applied to the diff tree; t...
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...
void mark_leaf_diff_nodes()
Walks the diff nodes associated to the current corpus diff and mark those that carry local changes....
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.
corpus_sptr first_corpus() const
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 function_decl_diff_sptrs_type & incompatible_changed_functions() const
Getter of the set of diff nodes representing incompatibly changed functions.
virtual void report(ostream &out, const string &indent="") const
Report the diff in a serialized form.
const string_elf_symbol_map & added_unrefed_variable_symbols() const
Getter for variable symbols not referenced by any debug info and that got added.
const istring_functions_set_omap_type & deleted_functions() const
Getter for the deleted functions of the diff.
const string & get_pretty_representation() const
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.
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...
const function_decl_diff_sptrs_type & changed_functions_sorted() const
Getter for a sorted vector of functions which signature didn't change, but which do have some indirec...
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.
bool architecture_changed() const
Test if the architecture of the underlying corpus has changed.
The base class of diff between decls.
decl_diff_base(decl_base_sptr first_subject, decl_base_sptr second_subject, diff_context_sptr ctxt)
Constructor of decl_diff_base.
The default, initial, reporter of the libabigail comparison engine.
The context of the diff. This type holds various bits of information that is going to be used through...
bool show_deleted_vars() const
void add_suppressions(const suppr::suppressions_type &supprs)
Add new suppression specifications that specify which diff node reports should be dropped on the floo...
diff_category get_allowed_category() const
Getter for the bitmap that represents the set of categories that the user wants to see reported.
void forget_visited_diffs()
Unmark all the diff nodes that were marked as being traversed.
corpus_sptr get_first_corpus() const
Getter for the first corpus of the corpus diff of the current context.
bool show_architecture_change() const
Getter for the property that says if the comparison module should show the architecture changes in it...
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,...
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...
bool show_changed_fns() const
void initialize_canonical_diff(const diff_sptr diff)
Set the canonical diff node property of a given diff node appropriately.
bool show_redundant_changes() const
A getter for the flag that says if we should report about functions or variables diff nodes that have...
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 ...
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...
diff * diff_has_been_visited(const diff *) const
Test if a diff node has been traversed.
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 ...
void set_corpus_diff(const corpus_diff_sptr &)
Set the corpus diff relevant to this context.
bool show_leaf_changes_only() const
Get the flag that indicates if the diff using this context should show only leaf changes or not.
bool perform_change_categorization() const
Test if it's requested to perform diff node categorization.
bool show_impacted_interfaces() const
Getter of the flag that indicates if the leaf reporter should display a summary of the interfaces imp...
bool show_soname_change() const
Getter for the property that says if the comparison module should show the soname changes in its repo...
reporter_base_sptr get_reporter() const
Getter of the reporter to be used in this context.
void add_diff_filter(filtering::filter_base_sptr)
Setter for the diff filters to apply to a given diff sub-tree.
bool do_log() const
Test if logging was requested.
const suppr::suppressions_type & direct_suppressions() const
Getter of the direct suppression specification (those that are not negated) comprised in the general ...
void maybe_apply_filters(diff_sptr diff)
Apply the diff filters to a given diff sub-tree.
bool show_added_fns() const
const suppr::suppressions_type & suppressions() const
Getter for the vector of suppressions that specify which diff node reports should be dropped on the f...
bool show_relative_offset_changes(void)
Get the flag saying if offset changes should be reported in a relative way. That is,...
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 ...
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,...
const suppr::suppressions_type & negated_suppressions() const
Getter of the negated suppression specifications that are comprised in the general vector of suppress...
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...
bool show_hex_values() const
Get the flag that indicates if the diff reports using this context should show sizes and offsets in a...
bool show_deleted_fns() const
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 show_stats_only() const
Test if the comparison module should only show the diff stats.
bool show_added_vars() const
const filtering::filters & diff_filters() const
Getter for the diff tree nodes filters to apply to diff sub-trees.
bool show_unreachable_types()
Getter for the flag that indicates if changes on types unreachable from global functions and variable...
const corpus_diff_sptr & get_corpus_diff() const
Get the corpus diff for the current context.
void mark_diff_as_visited(const diff *)
Mark a diff node as traversed by a traversing algorithm.
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.
bool show_changed_vars() const
void switch_categories_on(diff_category c)
Setter for the bitmap that represents the set of categories that the user wants to see reported.
ostream * default_output_stream()
Getter for the default output stream used by code of the comparison engine. By default the default ou...
bool dump_diff_tree() const
Test if the comparison engine should dump the diff tree for the changed functions and variables it ha...
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...
bool show_num_filtered_data_members() const
Get whether to show the number of filtered data members.
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...
corpus_sptr get_second_corpus() const
Getter for the second corpus of the corpus diff of the current context.
void set_allowed_category(diff_category c)
Setter for the bitmap that represents the set of categories that the user wants to see reported.
void set_reporter(reporter_base_sptr &)
Setter of the reporter to be used in this context.
ostream * error_output_stream() const
Getter for the errror output stream used by code of the comparison engine. By default the error outpu...
This type contains maps. Each map associates a type name to a diff of that type. Not all kinds of dif...
const string_diff_ptr_map & get_function_decl_diff_map() const
Getter of the map that contains function decl diffs.
const string_diff_ptr_map & get_var_decl_diff_map() const
Getter of the map that contains var decl diffs.
const string_diff_ptr_map & get_enum_diff_map() const
Getter of the map that contains enum type diffs.
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.
diff_maps()
Default constructor of the diff_maps type.
const string_diff_ptr_map & get_union_diff_map() const
Getter of the map that contains union type diffs.
artifact_sptr_set_type * lookup_impacted_interfaces(const diff *d) const
Lookup the interfaces that are impacted by a given leaf diff node.
const string_diff_ptr_map & get_function_type_diff_map() const
Getter of the map that contains function type diffs.
const string_diff_ptr_map & get_typedef_diff_map() const
Getter of the map that contains typedef type diffs.
const string_diff_ptr_map & get_distinct_diff_map() const
Getter of the map that contains distinct diffs.
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_reference_diff_map() const
Getter of the map that contains reference type diffs.
const string_diff_ptr_map & get_array_diff_map() const
Getter of the map that contains array type diffs.
const string_diff_ptr_map & get_type_decl_diff_map() const
Getter of the map that contains basic type diffs.
const string_diff_ptr_map & get_fn_parm_diff_map() const
Getter of the map that contains function parameter diffs.
const string_diff_ptr_map & get_class_diff_map() const
Getter of the map that contains class type diffs.
The base class for the node visitors. These are the types used to visit each node traversed by the di...
void or_visiting_kind(visiting_kind v)
Setter for the visiting policy of the traversing code while invoking this visitor....
virtual bool visit(diff *, bool)
Default visitor implementation.
virtual void visit_end(corpus_diff *)
This is called by the traversing code on a corpus_diff node just after visiting it....
void set_current_topmost_iface_diff(diff *)
Setter of the diff current topmost interface which is impacted by the current diff node being visited...
virtual void visit_begin(diff *)
This is called by the traversing code on a diff node just before visiting it. That is,...
visiting_kind get_visiting_kind() const
Getter for the visiting policy of the traversing code while invoking this visitor.
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...
diff_node_visitor()
Default constructor of the diff_node_visitor type.
void set_visiting_kind(visiting_kind v)
Setter for the visiting policy of the traversing code while invoking this visitor.
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 bool traverse(diff_node_visitor &v)
The default traverse function.
The abstraction of a change between two ABI artifacts, a.k.a an artifact change.
void begin_traversing()
Flag a given diff node as being traversed.
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 finish_diff_type()
Finish the insertion of a diff tree node into the diff graph.
virtual void chain_into_hierarchy()
This constructs the relation between this diff node and its detail diff nodes, in the generic view of...
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 ...
type_or_decl_base_sptr second_subject() const
Getter of the second subject of the diff.
bool is_traversing() const
Tell if a given node is being traversed or not.
type_or_decl_base_sptr first_subject() const
Getter of the first subject of the diff.
bool is_suppressed() const
Test if the current diff node has been suppressed by a user-provided suppression specification.
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...
diff * get_canonical_diff() const
Getter for the canonical diff of the current instance of diff.
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...
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...
const vector< diff * > & children_nodes() const
Getter for the children nodes of the current diff node.
diff_category get_category() const
Getter for the category of the current diff tree node.
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...
diff_category remove_from_local_category(diff_category c)
Remove the current diff tree node from the categories resulting from the local changes.
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...
bool do_log() const
Test if logging was requested.
diff_category get_local_category() const
Getter for the local category of the current diff tree node.
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 is_categorized_as_suppressed() const
Test if the current diff node has been suppressed by a suppression specification or it has been categ...
const diff_context_sptr context() const
Getter of the context of the current diff.
virtual enum change_kind has_local_changes() const =0
Pure interface to know if the current instance of @diff carries a local change. A local change is a c...
virtual bool traverse(diff_node_visitor &v)
The generic traversing code that walks a given diff sub-tree.
bool currently_reporting() const
Tests if we are currently in the middle of emitting a report for this diff.
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...
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...
bool to_be_reported() const
Test if this diff tree node should be reported.
const diff * parent_node() const
Getter for the parent node of the current diff node.
diff_category get_class_of_equiv_category() const
Getter of the category of the class of equivalence of the current diff tree node.
void set_canonical_diff(diff *)
Setter for the canonical diff of the current instance of diff.
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...
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...
void set_local_category(diff_category c)
Set the local category of the current diff node.
virtual const string & get_pretty_representation() const
Get a pretty representation of the current diff node.
void append_child_node(diff_sptr)
Add a new child node to the vector of children nodes for the current diff node.
bool is_filtered_out() const
Test if this diff tree node is to be filtered out for reporting purposes.
void end_traversing()
Flag a given diff node as not being traversed anymore.
bool reported_once() const
Tests if a report has already been emitted for the current diff.
An abstraction of a diff between entities that are of a different kind (disctinct).
virtual bool has_changes() const
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of @distinct_d...
const diff_sptr compatible_child_diff() const
Getter for the child diff of this distinct_diff instance.
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.
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.
virtual void report(ostream &out, const string &indent="") const
Emit a report about the current diff instance.
const type_or_decl_base_sptr first() const
Getter for the first subject of the diff.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
const type_or_decl_base_sptr second() const
Getter for the second subject of the diff.
Abstraction of a diff between two enums.
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 diff base type sub-object of this instance of enum_diff.
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.
diff_sptr underlying_type_diff() const
const string_changed_enumerator_map & changed_enumerators() const
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
const enum_type_decl_sptr first_enum() const
const string_enumerator_map & deleted_enumerators() const
const enum_type_decl_sptr second_enum() const
const string_enumerator_map & inserted_enumerators() const
virtual void report(ostream &, const string &indent="") const
Report the differences between the two enums.
A filter that walks the diff nodes tree and tags relevant diff nodes into categories considered to re...
Abstraction of a diff between two function parameters.
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 nodes of the diff base type sub-object of this instance of fn_parm_di...
const function_decl::parameter_sptr first_parameter() const
Getter for the first subject of this diff node.
virtual enum change_kind has_local_changes() const
Check if the current diff node carries a local change.
virtual const string & get_pretty_representation() const
Build and return a textual representation of the current instance of fn_parm_diff.
const function_decl::parameter_sptr second_parameter() const
Getter for the second subject of this diff node.
diff_sptr type_diff() const
Getter for the diff representing the changes on the type of the function parameter involved in the cu...
virtual void report(ostream &, const string &indent="") const
Emit a textual report about the current fn_parm_diff instance.
Abstraction of a diff between two function_decl.
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 diff base type sub-object of this instance of function_de...
const function_decl_sptr second_function_decl() const
function_decl_diff(const function_decl_sptr first, const function_decl_sptr second, diff_context_sptr ctxt)
Constructor for function_decl_diff.
virtual enum change_kind has_local_changes() const
const function_decl_sptr first_function_decl() const
virtual const string & get_pretty_representation() const
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 ...
Abstraction of a diff between two function types.
virtual bool has_changes() const
Test if the current diff node carries changes.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of function_ty...
const string_fn_parm_diff_sptr_map & subtype_changed_parms() const
Getter for the map of function parameter changes of the current 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.
const string_parm_map & removed_parms() const
Getter for the map of parameters that got removed.
const string_parm_map & added_parms() const
Getter for the map of parameters that got added.
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< function_decl::parameter_sptr > & sorted_added_parms() const
Getter for the sorted vector of added parameters .
const function_type_sptr first_function_type() const
Getter for the first subject of the diff.
const function_type_sptr second_function_type() const
Getter for the second subject of the diff.
function_type_diff(const function_type_sptr first, const function_type_sptr second, diff_context_sptr ctxt)
Consutrctor of the function_type type.
virtual enum change_kind has_local_changes() const
Test if the current diff node carries local changes.
virtual const string & get_pretty_representation() const
Build and return a copy of a pretty representation of the current instance of function_type_diff.
const vector< function_decl::parameter_sptr > & sorted_deleted_parms() const
Getter for the sorted vector of deleted parameters.
virtual void report(ostream &, const string &indent="") const
Build and emit a textual report about the current function_type_diff instance.
A reporter that only reports leaf changes.
The abstraction of a diff between two pointers.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
const pointer_type_def_sptr first_pointer() const
Getter for the first subject of a pointer diff.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of pointer_dif...
const pointer_type_def_sptr second_pointer() const
Getter for the second subject of a pointer diff.
diff_sptr underlying_type_diff() const
Getter for the diff between the pointed-to types of the pointers of this diff.
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.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
The abstraction of a diff between two ptr_to_mbr_type.
virtual bool has_changes() const
Test whether the current diff node carries any change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of ptr_to_mbr_...
virtual ~ptr_to_mbr_diff()
Destructor of ptr_to_mbr_diff.
ptr_to_mbr_type_sptr first_ptr_to_mbr_type() const
Getter of the first pointer-to-member subject of the current diff node.
const diff_sptr containing_type_diff() const
Getter of the diff node carrying changes to the containing type of first subject of the current diff ...
const diff_sptr member_type_diff() const
Getter of the diff node carrying changes to the member type of first subject of the current diff node...
ptr_to_mbr_type_sptr second_ptr_to_mbr_type() const
Getter of the second pointer-to-member subject of the current diff node.
virtual enum change_kind has_local_changes() const
Test whether the current diff node carries any local change.
virtual const string & get_pretty_representation() const
Get the pretty representation of the current ptr_to_mbr_diff node.
virtual void report(ostream &, const string &indent="") const
Pure interface to report the diff in a serialized form that is legible for the user.
Abstraction of a diff between two qualified types.
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 diff base type sub-object of this instance of qualified_t...
diff_sptr leaf_underlying_type_diff() const
Getter for the diff between the most underlying non-qualified types of two qualified types.
diff_sptr underlying_type_diff() const
Getter for the diff between the underlying types of the two qualified 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.
const qualified_type_def_sptr second_qualified_type() const
Getter for the second qualified type of the diff.
virtual enum change_kind has_local_changes() const
const qualified_type_def_sptr first_qualified_type() const
Getter for the first qualified type of the diff.
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
The abstraction of a diff between two references.
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 diff base type sub-object of this instance of reference_d...
reference_type_def_sptr first_reference() const
Getter for the first reference of the diff.
reference_type_def_sptr second_reference() const
Getter for the second reference of the diff.
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.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
const diff_sptr & underlying_type_diff() const
Getter for the diff between the two referred-to types.
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
An abstractions of the changes between two scopes.
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 diff base type sub-object of this instance of scope_diff.
const diff_sptrs_type & changed_types() const
const scope_decl_sptr second_scope() const
Getter for the second scope of the diff.
const scope_decl_sptr first_scope() const
Getter for the first scope of the diff.
const decl_base_sptr deleted_member_at(unsigned index) const
Accessor that eases the manipulation of the edit script associated to this instance....
const diff_sptrs_type & changed_decls() const
scope_diff(scope_decl_sptr first_scope, scope_decl_sptr second_scope, diff_context_sptr ctxt=diff_context_sptr())
Constructor for scope_diff.
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.
const decl_base_sptr inserted_member_at(unsigned i)
Accessor that eases the manipulation of the edit script associated to this instance....
virtual void report(ostream &out, const string &indent="") const
Report the changes of one scope against another.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
const edit_script & member_changes() const
Accessor of the edit script of the members of a scope.
The abstraction of the diff between two subrange types.
virtual bool has_changes() const
Test if the current subrange_diff node carries any change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of subrange_di...
const array_type_def::subrange_sptr second_subrange() const
Getter of the second subrange of the current instance subrange_diff.
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.
const array_type_def::subrange_sptr first_subrange() const
Getter of the first subrange of the current instance subrange_diff.
const diff_sptr underlying_type_diff() const
Getter of the diff node of the underlying types of the current subrange_diff diff node.
virtual enum change_kind has_local_changes() const
Test if the current subrange_diff node carries any local change.
virtual const string & get_pretty_representation() const
Getter the pretty representation of the subrange_diff diff node.
virtual void report(ostream &, const string &indent="") const
Report about the changes carried by this node.
An abstraction of a diff between two translation units.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
const translation_unit_sptr second_translation_unit() const
Getter for the second translation unit of this diff.
translation_unit_diff(translation_unit_sptr first, translation_unit_sptr second, diff_context_sptr ctxt=diff_context_sptr())
Constructor for translation_unit_diff.
virtual void report(ostream &out, const string &indent="") const
Report the diff in a serialized form.
virtual enum change_kind has_local_changes() const
const translation_unit_sptr first_translation_unit() const
Getter for the first translation unit of this diff.
Abstraction of a diff between two basic type declarations.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
const type_decl_sptr first_type_decl() const
Getter for the first subject of the type_decl_diff.
const type_decl_sptr second_type_decl() const
Getter for the second subject of the type_decl_diff.
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.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
The base class of diff between types.
Abstraction of a diff between two typedef_decl.
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 diff base type sub-object of this instance of typedef_dif...
const typedef_decl_sptr second_typedef_decl() const
Getter for the second typedef_decl involved in the diff.
const typedef_decl_sptr first_typedef_decl() const
Getter for the firt typedef_decl involved in the diff.
const diff_sptr underlying_type_diff() const
Getter for the diff between the two underlying types of the typedefs.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Reports the difference between the two subjects of the diff in a serialized form.
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.
union_decl_sptr first_union_decl() const
union_decl_sptr second_union_decl() const
virtual ~union_diff()
Destructor of the union_diff node.
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Report the changes carried by the current union_diff node in a textual format.
Abstracts a diff between two instances of var_decl.
virtual bool has_changes() const
Return true iff the diff node has a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of var_diff.
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.
var_decl_sptr first_var() const
Getter for the first var_decl of the diff.
virtual void report(ostream &out, const string &indent="") const
Report the diff in a serialized form.
virtual enum change_kind has_local_changes() const
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.
virtual const string & get_pretty_representation() const
diff_sptr type_diff() const
Getter for the diff of the types of the instances of var_decl.
var_decl_sptr second_var() const
Getter for the second var_decl of the diff.
The abstraction of an edit script for transforming a sequence A into a sequence B.
The abstraction of an interned string.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
vector< base_spec_sptr > base_specs
Convenience typedef.
vector< method_decl_sptr > member_functions
Convenience typedef.
bool get_is_anonymous() const
Test if the current declaration is anonymous.
The abstraction of the version of an ELF symbol.
Abstraction of an elf symbol.
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Abstraction for a function declaration.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
const elf_symbol_sptr get_symbol() const
Gets the the underlying ELF symbol for the current variable, that was set using function_decl::set_sy...
An abstraction helper for type declarations.
The base class of both types and declarations.
change_kind
The kind of change the current function suppression should apply to.
@ ADDED_FUNCTION_CHANGE_KIND
The function was added to the second subject of the diff.
@ DELETED_FUNCTION_CHANGE_KIND
The function was deleted from the second subject of the diff.
change_kind
The kind of change the current variable suppression should apply to.
@ ADDED_VARIABLE_CHANGE_KIND
The variable was added to the second second subject of the diff.
@ DELETED_VARIABLE_CHANGE_KIND
The variable was deleted from the second subject of the diff.
bool has_void_ptr_to_ptr_change(const diff *dif)
Test if a diff node carries a void* to pointer type change.
diff_category has_fn_return_or_parm_harmful_change(const diff *d)
Test if a diff node is a function diff node that carries either a return or a parameter type change t...
diff_category has_var_harmful_local_change(const diff *d)
Test if a diff node carries a harmful local change to a variable.
std::vector< filter_base_sptr > filters
Convenience typedef for a vector of filter_base_sptr.
bool has_fn_with_virtual_offset_change(const diff *d)
Test if a diff node carries a change to the offset of a virtual function.
bool has_harmless_enum_to_int_change(const diff *diff)
Test if a diff node carries a harmless change of an enum into an integer (or vice-versa).
bool is_harmful_name_change(const decl_base_sptr &f, const decl_base_sptr &s, const diff_context_sptr &ctxt)
Test if two decls represent a harmful name change.
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...
shared_ptr< filter_base > filter_base_sptr
Convenience typedef for a shared pointer to filter_base.
bool has_benign_array_of_unknown_size_change(const diff *dif)
Test if a diff node carries a benign change to the size of a variable of type array.
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 ...
bool has_basic_or_class_type_name_change(const diff *d)
Test if a diff node carries a basic or class type name change.
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....
bool is_harmful_category(diff_category c)
Test if an instance of diff_category (a category bit-field) is harmful or not.
shared_ptr< diff > diff_sptr
Convenience typedef for a shared_ptr for the diff class.
visiting_kind operator~(visiting_kind l)
The overloaded 'bit inversion' operator for visiting_kind.
const decl_diff_base * is_decl_diff(const diff *diff)
Test if a diff node is about differences between declarations.
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 ...
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,...
void categorize_redundancy(diff *diff_tree)
Walk a given diff sub-tree to categorize each of the nodes with respect to the REDUNDANT_CATEGORY.
vector< diff * > diff_ptrs_type
Convenience typedef for a vector of diff*.
shared_ptr< decl_diff_base > decl_diff_base_sptr
Convenience typedef for a shared_ptr of decl_diff_base.
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...
diff_category
An enum for the different categories that a diff tree node falls into, regarding the kind of changes ...
@ ACCESS_CHANGE_CATEGORY
This means the diff node (or at least one of its descendant nodes) carries access related changes,...
@ HARMLESS_DATA_MEMBER_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless data member change....
@ SUPPRESSED_CATEGORY
This means that a diff node was marked as suppressed by a user-provided suppression specification.
@ VIRTUAL_MEMBER_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an incompatible change to a vtable.
@ REDUNDANT_CATEGORY
A diff node in this category is redundant. That means it's present as a child of a other nodes in the...
@ SIZE_OR_OFFSET_CHANGE_CATEGORY
This means the diff node (or at least one of its descendant nodes) carries a change that modifies the...
@ NON_VIRT_MEM_FUN_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an addition or removal of a non-virtual member fu...
@ HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY
A diff node in this category has a descendant node that is in the HAS_ALLOWED_CHANGE_CATEGORY categor...
@ HARMLESS_ENUM_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an addition of enumerator to an enum type.
@ FN_PARM_ADD_REMOVE_CHANGE_CATEGORY
A diff node in this category is a function (or function type) with at least one parameter added or re...
@ VOID_PTR_TO_PTR_CHANGE_CATEGORY
A diff node in this category carries a change from void pointer to non-void pointer.
@ NON_COMPATIBLE_DISTINCT_CHANGE_CATEGORY
A change between two non-compatible types of different kinds.
@ PRIVATE_TYPE_CATEGORY
This means that a diff node was warked as being for a private type. That is, the diff node is meant t...
@ NON_COMPATIBLE_NAME_CHANGE_CATEGORY
A non-compatible name change between two types.
@ COMPATIBLE_TYPE_CHANGE_CATEGORY
This means the diff node (or at least one of its descendant nodes) carries a change involving two com...
@ TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a type that was declaration-only and that is now ...
@ STATIC_DATA_MEMBER_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an addition or removal of a static data member.
@ HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless union or class change.
@ HARMLESS_DECL_NAME_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless declaration name change....
@ NO_CHANGE_CATEGORY
This means the diff node does not carry any (meaningful) change, or that it carries changes that have...
@ HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY
A diff node in this category has a parent node that is in the HAS_ALLOWED_CHANGE_CATEGORY category....
@ BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY
A diff node in this category carries a change in the size of the array type of a global variable,...
@ VAR_TYPE_CV_CHANGE_CATEGORY
A diff node in this category is for a variable which type holds a cv-qualifier change.
@ HAS_ALLOWED_CHANGE_CATEGORY
A diff node in this category carries a change that must be reported, even if the diff node is also in...
@ FN_PARM_TYPE_CV_CHANGE_CATEGORY
A diff node in this category has a function parameter type with a cv-qualifiers change.
@ FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY
A diff node in this category is a function parameter type which top cv-qualifiers change.
@ FN_RETURN_TYPE_CV_CHANGE_CATEGORY
A diff node in this category is a function return type with a cv-qualifier change.
@ HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an a symbol alias change that is harmless.
shared_ptr< reporter_base > reporter_base_sptr
A convenience typedef for a shared pointer to a reporter_base.
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.
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...
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.
const subrange_diff * is_anonymous_subrange_diff(const diff *d)
Test if a diff node is a subrange_diff between two anonymous subranges.
const pointer_diff * is_pointer_diff(const diff *diff)
Test if a diff node is about differences between two pointers.
vector< var_diff_sptr > var_diff_sptrs_type
Convenience typedef for a vector of var_diff_sptr.
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.
void sort_string_function_ptr_map(const string_function_ptr_map &map, vector< const function_decl * > &sorted)
Sort an instance of string_function_ptr_map map and stuff a resulting sorted vector of pointers to fu...
diff_sptr try_to_diff(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second, diff_context_sptr ctxt)
</distinct_diff>
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.
void propagate_categories(diff *diff_tree)
Visit all the nodes of a given sub-tree. For each node that has a particular category set,...
const subrange_diff * is_subrange_diff(const diff *diff)
Test if a diff node is a subrange_diff node.
unordered_map< unsigned, fn_parm_diff_sptr > unsigned_fn_parm_diff_sptr_map
Convenience typedef for a map which key is an integer and which value is a changed parameter.
void sort_string_base_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.
diff_category get_default_harmless_categories_bitmap()
Getter of a bitmap made of the set of change categories that are considered harmless.
vector< diff_sptr > diff_sptrs_type
Convenience typedef for a vector of diff_sptr.
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.
void sort_changed_data_members(changed_var_sptrs_type &input)
Sort (in place) a vector of changed data members.
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.
void print_category(diff_category c)
Print a given category out to stdout for debuging purposes.
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.
shared_ptr< type_decl_diff > type_decl_diff_sptr
Convenience typedef for a shared pointer on a type_decl_diff type.
bool is_diff_of_variadic_parameter(const diff *d)
Test if a diff node represents the difference between a variadic parameter and something else.
shared_ptr< diff_context > diff_context_sptr
Convenience typedef for a shared pointer of diff_context.
bool is_diff_of_global_decls(const diff *)
Tests if a given diff node is to represent the changes between two gobal decls.
shared_ptr< subrange_diff > subrange_diff_sptr
A convenience typedef for a shared pointer to subrange_diff type.
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.
diff_category get_default_harmful_categories_bitmap()
Getter of a bitmap made of the set of change categories that are considered harmful.
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...
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.
shared_ptr< var_diff > var_diff_sptr
Convenience typedef for a shared pointer to a var_diff type.
unordered_map< string, method_decl_sptr > string_member_function_sptr_map
Convenience typedef for a hash map of strings and member functions.
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...
shared_ptr< reference_diff > reference_diff_sptr
Convenience typedef for a shared pointer on a reference_diff type.
vector< base_diff_sptr > base_diff_sptrs_type
Convenience typedef for a vector of base_diff_sptr.
shared_ptr< function_decl_diff > function_decl_diff_sptr
Convenience typedef for a shared pointer to a function_decl type.
shared_ptr< ptr_to_mbr_diff > ptr_to_mbr_diff_sptr
Typedef of a shared_ptr to ptr_to_mbr_diff.
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.
const function_decl_diff * is_function_decl_diff(const diff *diff)
Test if a diff node is about differences between functions.
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...
shared_ptr< fn_parm_diff > fn_parm_diff_sptr
Convenience typedef for a shared pointer to a fn_parm_diff type.
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 clear_redundancy_categorization(diff *diff_tree)
Walk a given diff sub-tree to clear the REDUNDANT_CATEGORY out of the category of the nodes.
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...
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.
bool is_less_than(const decl_diff_base &first, const decl_diff_base &second)
Compare two decl diff nodes (decl_diff_base) for the purpose of sorting.
bool is_child_node_of_base_diff(const diff *diff)
Test if a diff node is a child node of a base diff node.
visiting_kind
An enum for the different ways to visit a diff tree node.
@ SKIP_CHILDREN_VISITING_KIND
This says that the traversing code should avoid visiting the children nodes of the current node being...
@ DO_NOT_MARK_VISITED_NODES_AS_VISITED
This says that the traversing code should not mark visited nodes as having been traversed....
visiting_kind operator&(visiting_kind l, visiting_kind r)
The overloaded and operator for visiting_kind.
void sort_function_decl_diffs(function_decl_diff_sptrs_type &fn_diffs)
Sort a vector of function_decl_diff_sptr.
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...
const function_type_diff * is_function_type_diff(const diff *diff)
Test if a diff node is a function_type_diff node.
const distinct_diff * is_distinct_diff(const diff *diff)
Test if a diff node is about differences between two diff nodes of different kinds.
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...
visiting_kind operator|(visiting_kind l, visiting_kind r)
The overloaded or operator for visiting_kind.
const array_diff * is_array_diff(const diff *diff)
Test if a diff node is a array_diff node.
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 ...
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...
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
unordered_map< string, var_decl_sptr > string_var_ptr_map
Convenience typedef for a map which key is a string and which value is a point to var_decl.
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.
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.
shared_ptr< base_diff > base_diff_sptr
Convenience typedef for a shared pointer to a base_diff type.
shared_ptr< scope_diff > scope_diff_sptr
Convenience typedef for a shared pointer on a scope_diff.
shared_ptr< class_diff > class_diff_sptr
Convenience typedef for a shared pointer on a class_diff type.
const base_diff * is_base_diff(const diff *diff)
Test if a diff node is about differences between two base class specifiers.
const fn_parm_diff * is_fn_parm_diff(const diff *diff)
Test if a diff node is about differences between two function parameters.
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...
const union_diff * is_union_diff(const diff *diff)
Test if a diff node is a union_diff node.
vector< changed_var_sptr > changed_var_sptrs_type
Convenience typedef for a vector of @changed_var_sptr.gg381.
shared_ptr< pointer_diff > pointer_diff_sptr
Convenience typedef for a shared pointer on a pointer_diff type.
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...
void sort_string_var_ptr_map(const string_var_ptr_map &map, vector< var_decl_sptr > &sorted)
Sort a map of string -> pointer to var_decl.
void sort_string_parm_map(const string_parm_map &map, vector< function_decl::parameter_sptr > &sorted)
Sort a map of string -> function parameters.
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.
const enum_diff * is_enum_diff(const diff *diff)
Test if a diff node is a enum_diff node.
unordered_map< string, base_diff_sptr > string_base_diff_sptr_map
Convenience typedef for a map of string and base_diff_sptr.
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.
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 corpus_diff * is_corpus_diff(const diff *diff)
Test if a diff node is a corpus_diff node.
const diff * get_typedef_diff_underlying_type_diff(const diff *diff)
Return the leaf underlying diff node of a typedef_diff node.
const typedef_diff * is_typedef_diff(const diff *diff)
Test if a diff node is a typedef_diff node.
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...
type_base_sptr get_leaf_type(qualified_type_def_sptr t)
Return the first underlying type that is not a qualified type.
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...
shared_ptr< array_diff > array_diff_sptr
Convenience typedef for a shared pointer on a array_diff type.
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...
const class_diff * is_class_diff(const diff *diff)
Test if a diff node is a class_diff node.
const type_decl_diff * is_diff_of_basic_type(const diff *d)
Test if a diff node represents a diff between two basic types.
unordered_map< string, diff_sptr > string_diff_sptr_map
Convenience typedef for a map which value is a diff_sptr. The key of the map is the qualified name of...
unordered_map< 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...
const qualified_type_diff * is_qualified_type_diff(const diff *diff)
Test if a diff node is about differences between 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,...
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...
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...
void sort_changed_enumerators(const string_changed_enumerator_map &enumerators_map, changed_enumerators_type &sorted)
Sort a map of changed enumerators.
void print_diff_tree(diff *diff_tree, ostream &out)
Emit a textual representation of a diff sub-tree to an output stream.
vector< changed_enumerator > changed_enumerators_type
Convenience typedef for a vector of changed enumerators.
vector< function_decl_diff_sptr > function_decl_diff_sptrs_type
Convenience typedef for a vector of function_decl_diff_sptr.
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.
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....
shared_ptr< function_type_diff > function_type_diff_sptr
A convenience typedef for a shared pointer to function_type_type_diff.
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.
const var_diff * is_var_diff(const diff *diff)
Test if a diff node is about differences between variables.
const type_diff_base * is_type_diff(const diff *diff)
Test if a diff node is about differences between types.
void sort_var_diffs(var_diff_sptrs_type &var_diffs)
Sort a vector of var_diff_sptr.
unordered_map< string, elf_symbol_sptr > string_elf_symbol_map
Convenience typedef for a map whose key is a string and whose value is an elf_symbol_sptr.
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...
const reference_diff * is_reference_diff(const diff *diff)
Test if a diff node is about differences between two references.
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.
shared_ptr< distinct_diff > distinct_diff_sptr
Convenience typedef for a shared pointer to distinct_types_diff.
shared_ptr< corpus_diff > corpus_diff_sptr
A convenience typedef for a shared pointer to corpus_diff.
std::pair< var_decl_sptr, var_decl_sptr > changed_var_sptr
Convenience typedef for a pair of var_decl_sptr representing a var_decl change. The first member of t...
void apply_filters_and_categorize_diff_node_tree(diff_sptr &diff_tree)
Apply the diff tree filters that have been associated with the context of the a given diff,...
shared_ptr< typedef_diff > typedef_diff_sptr
Convenience typedef for a shared pointer on a typedef_diff type.
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...
void sort_enumerators(const string_enumerator_map &enumerators_map, enum_type_decl::enumerators &sorted)
Sort a map of enumerators by their value.
unordered_map< string, const 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.
ostream & operator<<(ostream &o, diff_category c)
Serialize an instance of diff_category to an output stream.
shared_ptr< translation_unit_diff > translation_unit_diff_sptr
Convenience typedef for a shared pointer on a translation_unit_diff type.
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...
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
bool equals(const decl_base &l, const decl_base &r, change_kind *k, bool qualified_name, bool linkage_name)
Compares two instances of decl_base.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
const global_scope_sptr get_global_scope(decl_base_sptr decl)
Return the global scope as seen by a given declaration.
interned_string get_function_symbol_id(const function_decl *fn)
Get the ID of the symbol of a function or the linkage name of the function if it has no symbol.
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.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
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.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
@ LOCAL_TYPE_CHANGE_KIND
This means that a given IR artifact has a local type change.
@ ALL_LOCAL_CHANGES_MASK
Testing (anding) against this mask means that a given IR artifact has local differences,...
@ LOCAL_NON_TYPE_CHANGE_KIND
This means that a given IR artifact has a local non-type change. That is a change that is carried by ...
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
bool collect_non_anonymous_data_members(const class_or_union *cou, string_decl_base_sptr_map &dms)
Collect all the non-anonymous data members of a class or union type.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
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...
std::vector< elf_symbol_sptr > elf_symbols
Convenience typedef for a vector of elf_symbol.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
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...
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
string get_name(const type_or_decl_base *tod, bool qualified)
Build and return a copy of the name of an ABI artifact that is either a type or a decl.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
std::map< interned_string, functions_set_type > istring_functions_set_omap_type
An ordered map that associates an interned string with a set of hashed function decls.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
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.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
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< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
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.
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
class_or_union * anonymous_data_member_to_class_or_union(const var_decl *d)
Get the class_or_union type of a given anonymous data member.
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...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
unordered_map< interned_string, functions_set_type, hash_interned_string > istring_functions_set_map_type
A map that associates an interned string with a set of hashed function decls.
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.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
bool types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
Test if two types are equal modulo a typedef or CV qualifiers.
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
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.
unordered_set< const function_decl *, c11d_decl_hasher< function_decl >, c11d_decl_eq< function_decl > > functions_set_type
A set of hashed function decls. The hash value is the canonical type of the function....
type_base * peel_qualified_or_typedef_type(const type_base *type)
Return the leaf underlying type of a qualified or typedef type.
bool is_at_global_scope(const decl_base &decl)
Tests whether a given declaration is at global scope.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
shared_ptr< variable_suppression > variable_suppression_sptr
A convenience typedef for a shared pointer to variable_suppression.
vector< suppression_sptr > suppressions_type
Convenience typedef for a vector of suppression_sptr.
shared_ptr< function_suppression > function_suppression_sptr
Convenience typedef for a shared pointer to function_suppression.
variable_suppression_sptr is_variable_suppression(const suppression_sptr s)
Test if an instance of suppression is an instance of variable_suppression.
bool is_opaque_type_suppr_spec(const type_suppression &s)
Test if a type suppression specification represents a private type suppression automatically generate...
shared_ptr< type_suppression > type_suppression_sptr
Convenience typedef for a shared pointer to type_suppression.
function_suppression_sptr is_function_suppression(const suppression_sptr suppr)
Test if an instance of suppression is an instance of function_suppression.
type_suppression_sptr is_type_suppression(suppression_sptr suppr)
Test if an instance of suppression is an instance of type_suppression.
shared_ptr< suppression_base > suppression_sptr
Convenience typedef for a shared pointer to a suppression.
bool is_negated_suppression(const suppression_base &s)
Test if a suppression specification is a negated suppression.
Toplevel namespace for libabigail.
A comparison function for instances of base_diff.
A functor to compare instances of class_decl::base_spec.
A functor to compare two changed enumerators, based on their initial value.
size_t count_filtered_bases()
Count the number of bases classes whose changes got filtered out.
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...
The type of private data of class_or_union_diff.
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.
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...
size_t get_deleted_non_static_data_members_number() const
Get the number of non static data members that were deleted.
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.
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...
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...
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...
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_deleted_mem_fns(const diff_context_sptr &)
Get the number of member functions deletions carried by the current diff node that were filtered out.
size_t get_inserted_non_static_data_members_number() const
Get the number of non static data members that were inserted.
The type of the private data of corpus_diff::diff_stats.
bool try_build_diffs_from_deleted_and_added_fns(functions_set_type &deleted_fns, functions_set_type &added_fns)
This is a sub-routine of ensure_lookup_tables_populated.
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 vector< diff_sptr > & changed_unreachable_types_sorted() const
Get the sorted vector of diff nodes representing changed unreachable types.
diff_context_sptr get_context()
Getter of the context associated with this corpus.
void categorize_redundant_changed_sub_nodes()
Walk the changed functions and variables diff nodes to categorize redundant nodes.
const string_diff_sptr_map & changed_unreachable_types() const
Get the map of diff nodes representing changed unreachable types.
void add_function_to_deleted_functions(const function_decl *fn)
Add a function_decl* to the 'deleted_fns_' map in the current instance of corpus_diff::priv.
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...
void add_function_to_added_functions(const function_decl *fn)
Add a function_decl* to the 'added_fns_' map in the current instance of corpus_diff::priv.
void maybe_perform_change_categorization()
Apply the diff change categorization filters to the current ABI corpus. As a result,...
bool lookup_tables_empty() const
Tests if the lookup tables are empty.
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...
void maybe_perform_redundant_node_categorization()
If diff_context::perform_change_categorization() is true, then perform the redundancy categorization ...
void apply_suppressions(corpus_diff *d)
Apply suppression specifications to a sub-tree of corpus_diff*.
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...
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...
void compare_fns_vars_and_ensure_lookup_tables_populated()
If the lookup tables are not yet built, walk the differences and fill the lookup tables.
void maybe_dump_diff_tree()
If the user asked to dump the diff tree node (for changed variables and functions) on the error outpu...
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 ...
bool deleted_variable_is_suppressed(const var_decl_sptr &var) const
Test if the change reports for a give given deleted variable has been deleted.
void clear_redundancy_categorization()
Walk the changed functions and variables diff nodes and clear the redundancy categorization they migh...
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.
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 added_variable_is_suppressed(const var_decl_sptr &var) const
Test if the change reports for a given added variable have been suppressed.
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...
bool deleted_function_is_suppressed(const function_decl *fn) const
Test if the change reports for a given deleted function have been deleted.
void apply_filters_and_compute_diff_stats(corpus_diff *, corpus_diff::diff_stats &)
Compute the diff stats.
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...
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.
bool added_function_is_suppressed(const function_decl *fn) const
Test if the change reports for a give given added function has been deleted.
void clear_lookup_tables()
Clear the lookup tables useful for reporting an enum_diff.
A comparison functor to compare two data members based on their offset.
A comparison functor to compare two instances of var_diff that represent changed data members based o...
A comparison functor for instances of diff.
A functor to compare two instances of diff_sptr.
The private data structure for distinct_diff.
A functor to compare instances of elf_symbol base on their names.
A functor to compare two enumerators based on their value. This implements the "less than" operator.
A comparison functor to compare two instances of fn_parm_diff based on their indexes.
"Less than" functor to compare instances of function_decl.
A "Less Than" functor to compare instance of function_decl_diff.
Functor that compares two function parameters for the purpose of sorting them.
The internal type for the impl idiom implementation of pointer_diff.
The private data of the ptr_to_mbr_diff type.
The internal type for the impl idiom implementation of subrange_diff.
A functor to compare instances of var_decl base on their qualified names.
The internal type for the impl idiom implementation of var_diff.
Functor to sort instances of var_diff_sptr.
A comparison functor for instances of function_decl_diff that represent changes between two virtual m...
A functor to sort decls somewhat topologically. That is, types are sorted in a way that makes the one...
A comparison functor to compare pointer to instances of type_or_decl_base.
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.