20 #include "abg-reporter-priv.h"
115 for (string_enumerator_map::const_iterator i = enumerators_map.begin();
116 i != enumerators_map.end();
118 sorted.push_back(i->second);
120 std::sort(sorted.begin(), sorted.end(), comp);
132 for (string_changed_enumerator_map::const_iterator i =
133 enumerators_map.begin();
134 i != enumerators_map.end();
136 sorted.push_back(i->second);
139 std::sort(sorted.begin(), sorted.end(), comp);
149 vector<decl_base_sptr>& sorted)
151 sorted.reserve(data_members.size());
152 for (string_decl_base_sptr_map::const_iterator i = data_members.begin();
153 i != data_members.end();
155 sorted.push_back(i->second);
158 std::sort(sorted.begin(), sorted.end(), comp);
168 std::sort(to_sort.begin(), to_sort.end(), comp);
184 string fr = f->get_qualified_name(), sr = s->get_qualified_name();
189 if (!f->get_linkage_name().empty()
190 && !s->get_linkage_name().empty())
192 fr = f->get_linkage_name();
193 sr = s->get_linkage_name();
198 if (f->get_symbol() && s->get_symbol())
200 fr = f->get_symbol()->get_id_string();
201 sr = s->get_symbol()->get_id_string();
206 fr = f->get_pretty_representation(
true,
true);
207 sr = s->get_pretty_representation(
true,
true);
220 vector<const function_decl*>& sorted)
222 sorted.reserve(map.size());
223 for (string_function_ptr_map::const_iterator i = map.begin();
226 sorted.push_back(i->second);
229 std::sort(sorted.begin(), sorted.end(), comp);
243 sorted.reserve(map.size());
244 for (string_member_function_sptr_map::const_iterator i = map.begin();
247 sorted.push_back(i->second);
250 std::sort(sorted.begin(), sorted.end(), comp);
266 sorted.reserve(map.size());
267 for (string_function_decl_diff_sptr_map::const_iterator i = map.begin();
270 sorted.push_back(i->second);
272 std::sort(sorted.begin(), sorted.end(), comp);
285 sorted.reserve(map.size());
286 for (string_var_diff_sptr_map::const_iterator i = map.begin();
289 sorted.push_back(i->second);
292 std::sort(sorted.begin(), sorted.end(), comp);
306 vector<elf_symbol_sptr>& sorted)
308 for (string_elf_symbol_map::const_iterator i = map.begin();
311 sorted.push_back(i->second);
314 std::sort(sorted.begin(), sorted.end(), comp);
327 vector<const var_decl*>& sorted)
329 for (string_var_ptr_map::const_iterator i = map.begin();
332 sorted.push_back(i->second);
335 std::sort(sorted.begin(), sorted.end(), comp);
348 sorted.reserve(map.size());
349 for (string_var_diff_sptr_map::const_iterator i = map.begin();
352 sorted.push_back(i->second);
354 std::sort(sorted.begin(), sorted.end(), comp);
367 sorted.reserve(map.size());
368 for (unsigned_var_diff_sptr_map::const_iterator i = map.begin();
371 sorted.push_back(i->second);
373 std::sort(sorted.begin(), sorted.end(), comp);
389 sorted.reserve(map.size());
390 for (string_function_decl_diff_sptr_map::const_iterator i = map.begin();
393 sorted.push_back(i->second);
396 sort(sorted.begin(), sorted.end(), comp);
410 sorted.reserve(map.size());
411 for (string_diff_sptr_map::const_iterator i = map.begin();
414 sorted.push_back(i->second);
417 sort(sorted.begin(), sorted.end(), comp);
431 sorted.reserve(map.size());
432 for (string_diff_ptr_map::const_iterator i = map.begin();
435 sorted.push_back(i->second);
438 sort(sorted.begin(), sorted.end(), comp);
452 for (string_base_diff_sptr_map::const_iterator i = map.begin();
455 sorted.push_back(i->second);
457 sort(sorted.begin(), sorted.end(), comp);
466 for (string_base_sptr_map::const_iterator i = m.begin();
469 sorted.push_back(i->second);
472 std::sort(sorted.begin(), sorted.end(), comp);
484 vector<fn_parm_diff_sptr>& sorted)
486 sorted.reserve(map.size());
487 for (unsigned_fn_parm_diff_sptr_map::const_iterator i = map.begin();
490 sorted.push_back(i->second);
493 std::sort(sorted.begin(), sorted.end(), comp);
505 vector<fn_parm_diff_sptr>& sorted)
507 sorted.reserve(map.size());
508 for (string_fn_parm_diff_sptr_map::const_iterator i = map.begin();
511 sorted.push_back(i->second);
514 std::sort(sorted.begin(), sorted.end(), comp);
525 vector<function_decl::parameter_sptr>& sorted)
527 for (string_parm_map::const_iterator i = map.begin();
530 sorted.push_back(i->second);
533 std::sort(sorted.begin(), sorted.end(), comp);
545 vector<type_or_decl_base_sptr>& sorted)
548 for (artifact_sptr_set_type::const_iterator it = set.begin();
551 sorted.push_back(*it);
554 std::sort(sorted.begin(), sorted.end(), comp);
569 vector<type_base_sptr>& sorted)
571 for (string_type_base_sptr_map::const_iterator i = map.begin();
574 sorted.push_back(i->second);
577 std::sort(sorted.begin(), sorted.end(), comp);
589 return type_base_sptr();
591 type_base_sptr ut = t->get_underlying_type();
620 if (decl_base_sptr decl =
is_decl(first))
637 | static_cast<unsigned>(r));}
644 & static_cast<unsigned>(r));
650 {
return static_cast<visiting_kind>(~static_cast<
unsigned>(l));}
680 {
return dynamic_cast<const class_diff*
>(diff);}
690 {
return dynamic_cast<const enum_diff*
>(diff);}
700 {
return dynamic_cast<const union_diff*
>(diff);}
724 if (dif->first_class_or_union()->get_is_anonymous())
757 {
return dynamic_cast<const array_diff*
>(diff);}
780 if (d->has_local_changes())
904 {
return dynamic_cast<const base_diff*
>(diff);}
954 diff_context::diff_context()
970 diff_context::~diff_context() =
default;
977 {
return priv_->do_log_;}
984 {priv_->do_log_ = f;}
991 {priv_->corpus_diff_ = d;}
998 {
return priv_->corpus_diff_;}
1007 if (priv_->corpus_diff_)
1008 return priv_->corpus_diff_->first_corpus();
1009 return corpus_sptr();
1020 if (priv_->corpus_diff_)
1021 return priv_->corpus_diff_->second_corpus();
1022 return corpus_sptr();
1031 if (!priv_->reporter_)
1039 return priv_->reporter_;
1047 {priv_->reporter_ = r;}
1061 types_or_decls_diff_map_type::const_iterator i =
1062 priv_->types_or_decls_diff_map.find(std::make_pair(first, second));
1063 if (i != priv_->types_or_decls_diff_map.end())
1077 diff_context::has_diff_for_types(
const type_base_sptr first,
1078 const type_base_sptr second)
const
1079 {
return has_diff_for(first, second);}
1087 diff_context::has_diff_for(
const diff* d)
const
1088 {
return has_diff_for(d->first_subject(), d->second_subject()).
get();}
1096 diff_context::has_diff_for(
const diff_sptr d)
const
1097 {
return has_diff_for(d->first_subject(), d->second_subject());}
1106 {
return priv_->allowed_category_;}
1115 {priv_->allowed_category_ = c;}
1128 {priv_->allowed_category_ = priv_->allowed_category_ | c;}
1139 {priv_->allowed_category_ = priv_->allowed_category_ & ~c;}
1155 {priv_->types_or_decls_diff_map[std::make_pair(first, second)] = d;}
1161 diff_context::add_diff(
const diff* d)
1174 diff_context::add_diff(
const diff_sptr d)
1177 add_diff(d->first_subject(), d->second_subject(), d);
1194 {
return has_diff_for(first, second);}
1206 {
return has_diff_for(d);}
1222 if (!has_diff_for(first, second))
1224 add_diff(first, second, d);
1225 priv_->canonical_diffs.push_back(d);
1250 canonical = canonical_diff;
1251 set_canonical_diff_for(first, second, canonical);
1274 if (diff->get_canonical_diff() == 0)
1277 set_or_get_canonical_diff_for(diff->first_subject(),
1278 diff->second_subject(),
1280 diff->set_canonical_diff(canonical.get());
1294 {priv_->live_diffs_.insert(d);}
1307 size_t ptr_value =
reinterpret_cast<size_t>(canonical);
1308 pointer_map::iterator it = priv_->visited_diff_nodes_.find(ptr_value);
1309 if (it != priv_->visited_diff_nodes_.end())
1310 return reinterpret_cast<diff*>(it->second);
1343 size_t canonical_ptr_value =
reinterpret_cast<size_t>(canonical);
1344 size_t diff_ptr_value =
reinterpret_cast<size_t>(d);
1345 priv_->visited_diff_nodes_[canonical_ptr_value] = diff_ptr_value;
1351 {priv_->visited_diff_nodes_.clear();}
1361 {priv_->forbid_visiting_a_node_twice_ = f;}
1371 {priv_->reset_visited_diffs_for_each_interface_ = f;}
1379 {
return priv_->forbid_visiting_a_node_twice_;}
1393 return (priv_->forbid_visiting_a_node_twice_
1394 && priv_->reset_visited_diffs_for_each_interface_);
1402 {
return priv_->filters_;}
1410 {priv_->filters_.push_back(f);}
1425 if (!diff->has_changes())
1428 for (filtering::filters::const_iterator i =
diff_filters().begin();
1435 std::cerr <<
"applying a filter to diff '"
1436 << diff->get_pretty_representation()
1446 std::cerr <<
"filter applied!:" << t <<
"\n";
1448 std::cerr <<
"propagating categories for the same diff node ... \n";
1457 std::cerr <<
"category propagated!: " << t <<
"\n";
1475 if (!diff || !diff->has_changes())
1478 for (filtering::filters::const_iterator i =
diff_filters().begin();
1493 {
return priv_->suppressions_;}
1504 priv_->negated_suppressions_.clear();
1505 priv_->direct_suppressions_.clear();
1506 return priv_->suppressions_;
1525 if (priv_->negated_suppressions_.empty())
1528 priv_->negated_suppressions_.push_back(s);
1530 return priv_->negated_suppressions_;
1548 if (priv_->direct_suppressions_.empty())
1552 priv_->direct_suppressions_.push_back(s);
1554 return priv_->direct_suppressions_;
1565 priv_->suppressions_.push_back(suppr);
1568 priv_->negated_suppressions_.clear();
1569 priv_->direct_suppressions_.clear();
1580 priv_->suppressions_.insert(priv_->suppressions_.end(),
1581 supprs.begin(), supprs.end());
1590 {
return priv_->perform_change_categorization_;}
1597 {priv_->perform_change_categorization_ = f;}
1611 priv_->leaf_changes_only_ = f;
1621 {
return priv_->leaf_changes_only_;}
1631 {
return priv_->hex_values_;}
1641 {priv_->hex_values_ = f;}
1650 {
return priv_->show_offsets_sizes_in_bits_;}
1659 {priv_->show_offsets_sizes_in_bits_ = f;}
1668 {priv_->show_relative_offset_changes_ = f;}
1677 {
return priv_->show_relative_offset_changes_;}
1685 {priv_->show_stats_only_ = f;}
1693 {
return priv_->show_stats_only_;}
1701 {priv_->show_soname_change_ = f;}
1709 {
return priv_->show_soname_change_;}
1717 {priv_->show_architecture_change_ = f;}
1725 {
return priv_->show_architecture_change_;}
1732 {priv_->show_deleted_fns_ = f;}
1738 {
return priv_->show_deleted_fns_;}
1745 {priv_->show_changed_fns_ = f;}
1750 {
return priv_->show_changed_fns_;}
1757 {priv_->show_added_fns_ = f;}
1763 {
return priv_->show_added_fns_;}
1770 {priv_->show_deleted_vars_ = f;}
1776 {
return priv_->show_deleted_vars_;}
1783 {priv_->show_changed_vars_ = f;}
1788 {
return priv_->show_changed_vars_;}
1795 {priv_->show_added_vars_ = f;}
1801 {
return priv_->show_added_vars_;}
1804 diff_context::show_linkage_names()
const
1805 {
return priv_->show_linkage_names_;}
1808 diff_context::show_linkage_names(
bool f)
1809 {priv_->show_linkage_names_= f;}
1816 {priv_->show_locs_= f;}
1822 {
return priv_->show_locs_;}
1831 {
return priv_->show_redundant_changes_;}
1840 {priv_->show_redundant_changes_ = f;}
1848 {
return priv_->show_syms_unreferenced_by_di_;}
1856 {priv_->show_syms_unreferenced_by_di_ = f;}
1865 {
return priv_->show_added_syms_unreferenced_by_di_;}
1874 {priv_->show_added_syms_unreferenced_by_di_ = f;}
1883 {priv_->show_unreachable_types_ = f;}
1892 {
return priv_->show_unreachable_types_;}
1903 {
return priv_->show_impacted_interfaces_;}
1914 {priv_->show_impacted_interfaces_ = f;}
1923 {priv_->default_output_stream_ = o;}
1932 {
return priv_->default_output_stream_;}
1940 {priv_->error_output_stream_ = o;}
1948 {
return priv_->error_output_stream_;}
1957 {
return priv_->dump_diff_tree_;}
1966 {priv_->dump_diff_tree_ = f;}
2005 : priv_(new priv(first_subject, second_subject,
2027 : priv_(new priv(first_subject, second_subject,
2066 if (priv_->canonical_diff_)
2067 priv_->canonical_diff_->priv_->traversing_ =
true;
2068 priv_->traversing_ =
true;
2085 if (priv_->canonical_diff_)
2086 return priv_->canonical_diff_->priv_->traversing_;
2087 return priv_->traversing_;
2101 if (priv_->canonical_diff_)
2102 priv_->canonical_diff_->priv_->traversing_ =
false;
2103 priv_->traversing_ =
false;
2119 if (diff::priv_->finished_)
2122 diff::priv_->finished_ =
true;
2142 const vector<diff*>&
2144 {
return priv_->children_;}
2151 {
return priv_->parent_;}
2164 {
return priv_->canonical_diff_;}
2172 {priv_->canonical_diff_ = d;}
2185 context()->keep_diff_alive(d);
2192 priv_->children_.push_back(d.get());
2194 d->priv_->parent_ =
this;
2202 {
return priv_->get_context();}
2219 if (priv_->canonical_diff_)
2220 return priv_->canonical_diff_->priv_->currently_reporting_;
2221 return priv_->currently_reporting_;
2232 if (priv_->canonical_diff_)
2233 priv_->canonical_diff_->priv_->currently_reporting_ = f;
2234 priv_->currently_reporting_ = f;
2245 return priv_->canonical_diff_->priv_->reported_once_;
2305 bool already_visited =
false;
2306 if (
context()->visiting_a_node_twice_is_forbidden()
2307 &&
context()->diff_has_been_visited(
this))
2308 already_visited =
true;
2310 bool mark_visited_nodes_as_traversed =
2313 if (!already_visited && !v.
visit(
this,
true))
2316 if (mark_visited_nodes_as_traversed)
2317 context()->mark_diff_as_visited(
this);
2323 && !already_visited)
2330 if (!(*i)->traverse(v))
2333 if (mark_visited_nodes_as_traversed)
2334 context()->mark_diff_as_visited(
this);
2342 if (!v.
visit(
this,
false))
2345 if (mark_visited_nodes_as_traversed)
2346 context()->mark_diff_as_visited(
this);
2351 if (!already_visited && mark_visited_nodes_as_traversed)
2352 context()->mark_diff_as_visited(
this);
2366 priv_->canonical_diff_->priv_->reported_once_ = f;
2367 priv_->reported_once_ = f;
2379 {
return priv_->local_category_;}
2405 {
return priv_->category_;}
2420 priv_->category_ = priv_->category_ | c;
2421 return priv_->category_;
2435 priv_->local_category_ = priv_->local_category_ | c;
2436 return priv_->local_category_;
2464 priv_->category_ = priv_->category_ & ~c;
2465 return priv_->category_;
2479 priv_->local_category_ = priv_->local_category_ & ~c;
2480 return priv_->local_category_;
2490 {priv_->category_ = c;}
2497 {priv_->local_category_ = c;}
2522 && !canonical->is_allowed_by_specific_negated_suppression()
2523 && !canonical->has_descendant_allowed_by_specific_negated_suppression()
2524 && !canonical->has_parent_allowed_by_specific_negated_suppression())
2565 return priv_->is_filtered_out(c);
2576 bool is_private =
false;
2605 bool do_suppress = !
context()->negated_suppressions().empty();
2609 for (
auto n :
context()->negated_suppressions())
2610 if (!n->suppresses_diff(
this))
2612 do_suppress =
false;
2619 for (
auto d :
context()->direct_suppressions())
2620 if (d->suppresses_diff(
this))
2624 is_private_type =
true;
2664 for (suppressions_type::const_iterator i = suppressions.begin();
2665 i != suppressions.end();
2669 && !(*i)->suppresses_diff(
this))
2709 if (priv_->pretty_representation_.empty())
2710 priv_->pretty_representation_ =
"empty_diff";
2711 return priv_->pretty_representation_;
2738 type_diff_base::type_diff_base(type_base_sptr first_subject,
2739 type_base_sptr second_subject,
2741 :
diff(first_subject, second_subject, ctxt),
2745 type_diff_base::~type_diff_base()
2761 decl_base_sptr second_subject,
2763 :
diff(first_subject, second_subject, ctxt),
2767 decl_diff_base::~decl_diff_base()
2778 if (diff::priv_->pretty_representation_.empty())
2780 std::ostringstream o;
2781 o <<
"distinct_diff[";
2792 diff::priv_->pretty_representation_ = o.str();
2794 return diff::priv_->pretty_representation_;
2827 :
diff(first, second, ctxt),
2861 if (!priv_->compatible_child_diff)
2873 return priv_->compatible_child_diff;
2888 if (!!first != !!second)
2890 if (!first && !second)
2894 if (first == second)
2898 return typeid(f) !=
typeid(s);
2916 return NO_CHANGE_KIND;
2927 context()->get_reporter()->report(*
this, out, indent);
2950 ctxt->initialize_canonical_diff(result);
2975 template<
typename DiffType>
2981 if (shared_ptr<DiffType> f =
2982 dynamic_pointer_cast<DiffType>(first))
2984 shared_ptr<DiffType> s =
2985 dynamic_pointer_cast<DiffType>(second);
3011 dynamic_pointer_cast<class_decl>(first))
3017 if (f->get_is_declaration_only())
3024 if (s->get_is_declaration_only())
3079 ((d = try_to_diff<type_decl>(f, s, ctxt))
3080 ||(d = try_to_diff<enum_type_decl>(f, s, ctxt))
3081 ||(d = try_to_diff<union_decl>(f, s,ctxt))
3083 ||(d = try_to_diff<pointer_type_def>(f, s, ctxt))
3084 ||(d = try_to_diff<reference_type_def>(f, s, ctxt))
3085 ||(d = try_to_diff<ptr_to_mbr_type>(f, s, ctxt))
3086 ||(d = try_to_diff<array_type_def::subrange_type>(f, s, ctxt))
3087 ||(d = try_to_diff<array_type_def>(f, s, ctxt))
3088 ||(d = try_to_diff<qualified_type_def>(f, s, ctxt))
3089 ||(d = try_to_diff<typedef_decl>(f, s, ctxt))
3090 ||(d = try_to_diff<function_type>(f, s, ctxt))
3091 ||(d = try_to_diff_distinct_kinds(f, s, ctxt)));
3100 {
return static_cast<diff_category>(
static_cast<unsigned>(c1)
3101 | static_cast<unsigned>(c2));}
3119 {
return static_cast<diff_category>(
static_cast<unsigned>(c1)
3120 ^ static_cast<unsigned>(c2));}
3124 {
return static_cast<diff_category>(
static_cast<unsigned>(c1)
3125 & static_cast<unsigned>(c2));}
3129 {
return static_cast<diff_category>(~static_cast<
unsigned>(c));}
3181 bool emitted_a_category =
false;
3185 o <<
"NO_CHANGE_CATEGORY";
3186 emitted_a_category =
true;
3191 if (emitted_a_category)
3193 o <<
"ACCESS_CHANGE_CATEGORY";
3194 emitted_a_category |=
true;
3199 if (emitted_a_category)
3201 o <<
"COMPATIBLE_TYPE_CHANGE_CATEGORY";
3202 emitted_a_category |=
true;
3207 if (emitted_a_category)
3209 o <<
"HARMLESS_DECL_NAME_CHANGE_CATEGORY";
3210 emitted_a_category |=
true;
3215 if (emitted_a_category)
3217 o <<
"NON_VIRT_MEM_FUN_CHANGE_CATEGORY";
3218 emitted_a_category |=
true;
3223 if (emitted_a_category)
3225 o <<
"STATIC_DATA_MEMBER_CHANGE_CATEGORY";
3226 emitted_a_category |=
true;
3231 if (emitted_a_category)
3233 o <<
"HARMLESS_ENUM_CHANGE_CATEGORY";
3234 emitted_a_category |=
true;
3239 if (emitted_a_category)
3241 o <<
"HARMLESS_DATA_MEMBER_CHANGE_CATEGORY";
3242 emitted_a_category |=
true;
3247 if (emitted_a_category)
3249 o <<
"HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY";
3250 emitted_a_category |=
true;
3255 if (emitted_a_category)
3257 o <<
"HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY";
3258 emitted_a_category |=
true;
3263 if (emitted_a_category)
3265 o <<
"SUPPRESSED_CATEGORY";
3266 emitted_a_category |=
true;
3271 if (emitted_a_category)
3273 o <<
"PRIVATE_TYPE_CATEGORY";
3274 emitted_a_category |=
true;
3279 if (emitted_a_category)
3281 o <<
"SIZE_OR_OFFSET_CHANGE_CATEGORY";
3282 emitted_a_category |=
true;
3287 if (emitted_a_category)
3289 o <<
"VIRTUAL_MEMBER_CHANGE_CATEGORY";
3290 emitted_a_category |=
true;
3295 if (emitted_a_category)
3297 o <<
"REDUNDANT_CATEGORY";
3298 emitted_a_category |=
true;
3303 if (emitted_a_category)
3305 o <<
"TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY";
3306 emitted_a_category |=
true;
3311 if (emitted_a_category)
3313 o <<
"FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY";
3314 emitted_a_category |=
true;
3319 if (emitted_a_category)
3321 o <<
"FN_PARM_TYPE_CV_CHANGE_CATEGORY";
3322 emitted_a_category |=
true;
3327 if (emitted_a_category)
3329 o <<
"FN_RETURN_TYPE_CV_CHANGE_CATEGORY";
3330 emitted_a_category |=
true;
3335 if (emitted_a_category)
3337 o <<
"FN_PARM_ADD_REMOVE_CHANGE_CATEGORY";
3338 emitted_a_category |=
true;
3343 if (emitted_a_category)
3345 o <<
"VAR_TYPE_CV_CHANGE_CATEGORY";
3346 emitted_a_category |=
true;
3351 if (emitted_a_category)
3353 o <<
"VOID_PTR_TO_PTR_CHANGE_CATEGORY";
3354 emitted_a_category |=
true;
3359 if (emitted_a_category)
3361 o <<
"BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY";
3362 emitted_a_category |=
true;
3367 if (emitted_a_category)
3369 o <<
"HAS_ALLOWED_CHANGE_CATEGORY";
3370 emitted_a_category |=
true;
3375 if (emitted_a_category)
3377 o <<
"HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY";
3378 emitted_a_category |=
true;
3383 if (emitted_a_category)
3385 o <<
"HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY";
3386 emitted_a_category |=
true;
3409 compute_diff_for_decls(
const decl_base_sptr first,
3410 const decl_base_sptr second,
3416 ((d = try_to_diff<function_decl>(first, second, ctxt))
3417 || (d = try_to_diff<var_decl>(first, second, ctxt))
3418 || (d = try_to_diff_distinct_kinds(first, second, ctxt)));
3441 const decl_base_sptr second,
3444 if (!first || !second)
3449 d = compute_diff_for_types(first, second, ctxt);
3451 d = compute_diff_for_decls(first, second, ctxt);
3471 const type_base_sptr second,
3477 diff_sptr d = compute_diff_for_types(f,s, ctxt);
3492 string prefix=
"diff of ";
3512 if (diff::priv_->pretty_representation_.empty())
3514 std::ostringstream o;
3520 diff::priv_->pretty_representation_ = o.str();
3522 return diff::priv_->pretty_representation_;
3565 if (
diff_sptr result = priv_->type_diff_.lock())
3572 context()->keep_diff_alive(result);
3573 priv_->type_diff_ = result;
3594 return ir::NO_CHANGE_KIND;
3606 context()->get_reporter()->report(*
this, out, indent);
3627 ctxt->initialize_canonical_diff(d);
3657 priv_(new
priv(underlying))
3679 if (diff::priv_->pretty_representation_.empty())
3681 std::ostringstream o;
3682 o <<
"pointer_diff["
3687 diff::priv_->pretty_representation_ = o.str();
3689 return diff::priv_->pretty_representation_;
3708 return ir::NO_CHANGE_KIND;
3717 {
return priv_->underlying_type_diff_;}
3726 {priv_->underlying_type_diff_ = d;}
3737 context()->get_reporter()->report(*
this, out, indent);
3757 diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
3758 second->get_pointed_to_type(),
3761 ctxt->initialize_canonical_diff(result);
3786 priv_(
new priv(underlying_type_diff))
3814 {
return priv_->underlying_type_diff_;}
3823 if (diff::priv_->pretty_representation_.empty())
3825 std::ostringstream o;
3826 o <<
"subrange_diff["
3831 diff::priv_->pretty_representation_ = o.str();
3833 return diff::priv_->pretty_representation_;
3855 return ir::NO_CHANGE_KIND;
3865 {
context()->get_reporter()->report(*
this, out, indent);}
3893 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
3894 second->get_underlying_type(),
3898 ctxt->initialize_canonical_diff(result);
3931 priv_(new
priv(element_type_diff))
3953 {
return priv_->element_type_diff_;}
3960 {priv_->element_type_diff_ = d;}
3967 if (diff::priv_->pretty_representation_.empty())
3969 std::ostringstream o;
3975 diff::priv_->pretty_representation_ = o.str();
3977 return diff::priv_->pretty_representation_;
3994 if (f->get_name() != s->get_name())
3996 if (f->get_size_in_bits() != s->get_size_in_bits())
3998 if (f->get_alignment_in_bits() != s->get_alignment_in_bits())
4018 return ir::NO_CHANGE_KIND;
4029 context()->get_reporter()->report(*
this, out, indent);
4047 diff_sptr d = compute_diff_for_types(first->get_element_type(),
4048 second->get_element_type(),
4051 ctxt->initialize_canonical_diff(result);
4079 priv_(new
priv(underlying))
4102 {
return priv_->underlying_type_diff_;}
4110 priv_->underlying_type_diff_ = d;
4111 return priv_->underlying_type_diff_;
4119 if (diff::priv_->pretty_representation_.empty())
4121 std::ostringstream o;
4122 o <<
"reference_diff["
4127 diff::priv_->pretty_representation_ = o.str();
4129 return diff::priv_->pretty_representation_;
4150 return ir::NO_CHANGE_KIND;
4161 context()->get_reporter()->report(*
this, out, indent);
4179 diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
4180 second->get_pointed_to_type(),
4183 ctxt->initialize_canonical_diff(result);
4210 priv_(new
priv(member_type_diff, containing_type_diff))
4238 {
return priv_->member_type_diff_;}
4247 {
return priv_->containing_type_diff_;}
4267 return ir::NO_CHANGE_KIND;
4277 if (diff::priv_->pretty_representation_.empty())
4279 std::ostringstream o;
4280 o <<
"ptr_to_mbr_diff["
4285 diff::priv_->pretty_representation_ = o.str();
4287 return diff::priv_->pretty_representation_;
4293 context()->get_reporter()->report(*
this, out, indent);
4330 is_type(second->get_member_type()),
4335 is_type(second->get_containing_type()),
4340 containing_type_diff,
4342 ctxt->initialize_canonical_diff(result);
4367 qualified_type_def_sptr second,
4371 priv_(new
priv(under))
4377 const qualified_type_def_sptr
4384 const qualified_type_def_sptr
4395 {
return priv_->underlying_type_diff;}
4405 if (!priv_->leaf_underlying_type_diff)
4406 priv_->leaf_underlying_type_diff
4411 return priv_->leaf_underlying_type_diff;
4421 {priv_->underlying_type_diff = d;}
4428 if (diff::priv_->pretty_representation_.empty())
4430 std::ostringstream o;
4431 o <<
"qualified_type_diff["
4436 diff::priv_->pretty_representation_ = o.str();
4438 return diff::priv_->pretty_representation_;
4457 return ir::NO_CHANGE_KIND;
4468 context()->get_reporter()->report(*
this, out, indent);
4481 qualified_type_diff_sptr
4483 const qualified_type_def_sptr second,
4486 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
4487 second->get_underlying_type(),
4491 ctxt->initialize_canonical_diff(result);
4504 enum_diff::clear_lookup_tables()
4506 priv_->deleted_enumerators_.clear();
4507 priv_->inserted_enumerators_.clear();
4508 priv_->changed_enumerators_.clear();
4515 enum_diff::lookup_tables_empty()
const
4517 return (priv_->deleted_enumerators_.empty()
4518 && priv_->inserted_enumerators_.empty()
4519 && priv_->changed_enumerators_.empty());
4525 enum_diff::ensure_lookup_tables_populated()
4527 if (!lookup_tables_empty())
4531 edit_script e = priv_->enumerators_changes_;
4533 for (vector<deletion>::const_iterator it = e.deletions().begin();
4534 it != e.deletions().end();
4537 unsigned i = it->index();
4538 const enum_type_decl::enumerator& n =
4540 const string& name = n.get_name();
4541 ABG_ASSERT(priv_->deleted_enumerators_.find(n.get_name())
4542 == priv_->deleted_enumerators_.end());
4543 priv_->deleted_enumerators_[name] = n;
4546 for (vector<insertion>::const_iterator it = e.insertions().begin();
4547 it != e.insertions().end();
4550 for (vector<unsigned>::const_iterator iit =
4551 it->inserted_indexes().begin();
4552 iit != it->inserted_indexes().end();
4556 const enum_type_decl::enumerator& n =
4558 const string& name = n.get_name();
4559 ABG_ASSERT(priv_->inserted_enumerators_.find(n.get_name())
4560 == priv_->inserted_enumerators_.end());
4561 string_enumerator_map::const_iterator j =
4562 priv_->deleted_enumerators_.find(name);
4563 if (j == priv_->deleted_enumerators_.end())
4564 priv_->inserted_enumerators_[name] = n;
4568 priv_->changed_enumerators_[j->first] =
4569 std::make_pair(j->second, n);
4570 priv_->deleted_enumerators_.erase(j);
4601 priv_(new
priv(underlying_type_diff))
4617 {
return priv_->underlying_type_diff_;}
4622 {
return priv_->deleted_enumerators_;}
4627 {
return priv_->inserted_enumerators_;}
4632 {
return priv_->changed_enumerators_;}
4639 if (diff::priv_->pretty_representation_.empty())
4641 std::ostringstream o;
4647 diff::priv_->pretty_representation_ = o.str();
4649 return diff::priv_->pretty_representation_;
4668 return ir::NO_CHANGE_KIND;
4679 context()->get_reporter()->report(*
this, out, indent);
4701 diff_sptr ud = compute_diff_for_types(first->get_underlying_type(),
4702 second->get_underlying_type(),
4704 enum_diff_sptr d(
new enum_diff(first, second, ud, ctxt));
4705 if (first != second)
4708 first->get_enumerators().end(),
4709 second->get_enumerators().begin(),
4710 second->get_enumerators().end(),
4711 d->priv_->enumerators_changes_);
4712 d->ensure_lookup_tables_populated();
4714 ctxt->initialize_canonical_diff(d);
4736 string qname = d->get_qualified_name();
4737 string_diff_sptr_map::const_iterator it =
4738 changed_member_types_.find(qname);
4740 return ((it == changed_member_types_.end())
4742 : it->second->second_subject());
4759 string qname = d->get_qualified_name();
4760 string_var_diff_sptr_map::const_iterator it =
4761 subtype_changed_dm_.find(qname);
4763 if (it == subtype_changed_dm_.end())
4764 return decl_base_sptr();
4765 return it->second->second_var();
4783 string qname = d->get_qualified_name();
4784 string_diff_sptr_map::const_iterator it =
4785 changed_member_class_tmpls_.find(qname);
4787 return ((it == changed_member_class_tmpls_.end())
4789 : dynamic_pointer_cast<
decl_base>(it->second->second_subject()));
4800 for (string_decl_base_sptr_map::const_iterator i =
4801 deleted_data_members_.begin();
4802 i != deleted_data_members_.end();
4819 for (string_decl_base_sptr_map::const_iterator i =
4820 inserted_data_members_.begin();
4821 i != inserted_data_members_.end();
4841 size_t num_filtered= 0;
4842 for (var_diff_sptrs_type::const_iterator i =
4843 sorted_subtype_changed_dm_.begin();
4844 i != sorted_subtype_changed_dm_.end();
4849 if ((*i)->has_changes()
4850 && !(*i)->has_local_changes_to_be_reported())
4855 if ((*i)->is_filtered_out())
4859 return num_filtered;
4873 size_t num_filtered= 0;
4875 for (unsigned_var_diff_sptr_map::const_iterator i = changed_dm_.begin();
4876 i != changed_dm_.end();
4882 if ((diff->has_changes() && !diff->has_local_changes_to_be_reported())
4883 || diff->is_filtered_out())
4888 if (diff->is_filtered_out())
4892 return num_filtered;
4901 #define SKIP_MEM_FN_IF_VIRTUALITY_DISALLOWED \
4903 if (get_member_function_is_virtual(f) \
4904 || get_member_function_is_virtual(s)) \
4906 if (!(allowed_category | VIRTUAL_MEMBER_CHANGE_CATEGORY)) \
4911 if (!(allowed_category | NON_VIRT_MEM_FUN_CHANGE_CATEGORY)) \
4926 diff_category allowed_category = ctxt->get_allowed_category();
4928 for (function_decl_diff_sptrs_type::const_iterator i =
4929 sorted_changed_member_functions_.begin();
4930 i != sorted_changed_member_functions_.end();
4933 method_decl_sptr f =
4935 ((*i)->first_function_decl());
4938 method_decl_sptr s =
4940 ((*i)->second_function_decl());
4946 ctxt->maybe_apply_filters(diff);
4948 if (diff->is_filtered_out())
4965 diff_category allowed_category = ctxt->get_allowed_category();
4967 for (string_member_function_sptr_map::const_iterator i =
4968 inserted_member_functions_.begin();
4969 i != inserted_member_functions_.end();
4972 method_decl_sptr f = i->second,
4978 ctxt->maybe_apply_filters(diff);
4981 && diff->is_filtered_out())
4998 diff_category allowed_category = ctxt->get_allowed_category();
5000 for (string_member_function_sptr_map::const_iterator i =
5001 deleted_member_functions_.begin();
5002 i != deleted_member_functions_.end();
5005 method_decl_sptr f = i->second,
5011 ctxt->maybe_apply_filters(diff);
5014 && diff->is_filtered_out())
5028 priv_->deleted_member_types_.clear();
5029 priv_->inserted_member_types_.clear();
5030 priv_->changed_member_types_.clear();
5031 priv_->deleted_data_members_.clear();
5032 priv_->inserted_data_members_.clear();
5033 priv_->subtype_changed_dm_.clear();
5034 priv_->deleted_member_functions_.clear();
5035 priv_->inserted_member_functions_.clear();
5036 priv_->changed_member_functions_.clear();
5037 priv_->deleted_member_class_tmpls_.clear();
5038 priv_->inserted_member_class_tmpls_.clear();
5039 priv_->changed_member_class_tmpls_.clear();
5048 return (priv_->deleted_member_types_.empty()
5049 && priv_->inserted_member_types_.empty()
5050 && priv_->changed_member_types_.empty()
5051 && priv_->deleted_data_members_.empty()
5052 && priv_->inserted_data_members_.empty()
5053 && priv_->subtype_changed_dm_.empty()
5054 && priv_->inserted_member_functions_.empty()
5055 && priv_->deleted_member_functions_.empty()
5056 && priv_->changed_member_functions_.empty()
5057 && priv_->deleted_member_class_tmpls_.empty()
5058 && priv_->inserted_member_class_tmpls_.empty()
5059 && priv_->changed_member_class_tmpls_.empty());
5068 edit_script& e = priv_->member_types_changes_;
5070 for (vector<deletion>::const_iterator it = e.deletions().begin();
5071 it != e.deletions().end();
5074 unsigned i = it->index();
5078 if (record_type && record_type->get_is_declaration_only())
5080 string name = d->get_name();
5081 priv_->deleted_member_types_[name] = d;
5084 for (vector<insertion>::const_iterator it = e.insertions().begin();
5085 it != e.insertions().end();
5088 for (vector<unsigned>::const_iterator iit =
5089 it->inserted_indexes().begin();
5090 iit != it->inserted_indexes().end();
5097 if (record_type && record_type->get_is_declaration_only())
5099 string name = d->get_name();
5100 string_decl_base_sptr_map::const_iterator j =
5101 priv_->deleted_member_types_.find(name);
5102 if (j != priv_->deleted_member_types_.end())
5104 if (*j->second != *d)
5105 priv_->changed_member_types_[name] =
5108 priv_->deleted_member_types_.erase(j);
5111 priv_->inserted_member_types_[name] = d;
5117 edit_script& e = priv_->data_members_changes_;
5119 for (vector<deletion>::const_iterator it = e.deletions().begin();
5120 it != e.deletions().end();
5123 unsigned i = it->index();
5126 string name = data_member->get_anon_dm_reliable_name();
5128 ABG_ASSERT(priv_->deleted_data_members_.find(name)
5129 == priv_->deleted_data_members_.end());
5130 priv_->deleted_data_members_[name] = data_member;
5133 for (vector<insertion>::const_iterator it = e.insertions().begin();
5134 it != e.insertions().end();
5137 for (vector<unsigned>::const_iterator iit =
5138 it->inserted_indexes().begin();
5139 iit != it->inserted_indexes().end();
5146 string name = added_dm->get_anon_dm_reliable_name();
5147 ABG_ASSERT(priv_->inserted_data_members_.find(name)
5148 == priv_->inserted_data_members_.end());
5150 bool ignore_added_anonymous_data_member =
false;
5188 bool added_anon_dm_changes_dm =
false;
5191 vector<var_decl_sptr> dms_replaced_by_anon_dm;
5200 for (string_decl_base_sptr_map::const_iterator it =
5201 priv_->deleted_data_members_.begin();
5202 it != priv_->deleted_data_members_.end();
5211 string deleted_dm_name = it->second->get_name();
5227 size_t replaced_dm_offset =
5229 replacing_dm_offset =
5232 if (replaced_dm_offset != replacing_dm_offset)
5240 added_anon_dm_changes_dm =
true;
5244 if (replaced_dm->get_type()->get_size_in_bits()
5245 == replaced_dm->get_type()->get_size_in_bits())
5246 dms_replaced_by_anon_dm.push_back(replaced_dm);
5249 added_anon_dm_changes_dm =
true;
5258 if (!added_anon_dm_changes_dm
5259 && !dms_replaced_by_anon_dm.empty())
5262 type_base_sptr added_dm_type = added_dm->get_type();
5278 ignore_added_anonymous_data_member =
true;
5279 for (vector<var_decl_sptr>::const_iterator i =
5280 dms_replaced_by_anon_dm.begin();
5281 i != dms_replaced_by_anon_dm.end();
5284 string n = (*i)->get_name();
5285 priv_->dms_replaced_by_adms_[n] =
5287 priv_->deleted_data_members_.erase(n);
5293 if (!ignore_added_anonymous_data_member)
5306 string_decl_base_sptr_map::const_iterator j =
5307 priv_->deleted_data_members_.find(name);
5308 if (j != priv_->deleted_data_members_.end())
5310 if (*j->second != *d)
5313 priv_->subtype_changed_dm_[name]=
5316 priv_->deleted_data_members_.erase(j);
5319 priv_->inserted_data_members_[name] = d;
5327 for (string_decl_base_sptr_map::const_iterator i =
5328 priv_->deleted_data_members_.begin();
5329 i != priv_->deleted_data_members_.end();
5333 priv_->deleted_dm_by_offset_[offset] = i->second;
5336 for (string_decl_base_sptr_map::const_iterator i =
5337 priv_->inserted_data_members_.begin();
5338 i != priv_->inserted_data_members_.end();
5342 priv_->inserted_dm_by_offset_[offset] = i->second;
5345 for (unsigned_decl_base_sptr_map::const_iterator i =
5346 priv_->inserted_dm_by_offset_.begin();
5347 i != priv_->inserted_dm_by_offset_.end();
5350 unsigned_decl_base_sptr_map::const_iterator j =
5351 priv_->deleted_dm_by_offset_.find(i->first);
5352 if (j != priv_->deleted_dm_by_offset_.end())
5356 priv_->changed_dm_[i->first] =
5361 for (unsigned_var_diff_sptr_map::const_iterator i =
5362 priv_->changed_dm_.begin();
5363 i != priv_->changed_dm_.end();
5366 priv_->deleted_dm_by_offset_.erase(i->first);
5367 priv_->inserted_dm_by_offset_.erase(i->first);
5368 priv_->deleted_data_members_.erase
5369 (i->second->first_var()->get_anon_dm_reliable_name());
5370 priv_->inserted_data_members_.erase
5371 (i->second->second_var()->get_anon_dm_reliable_name());
5379 non_anonymous_dms_in_second_class);
5380 vector<string> deleted_data_members_to_delete;
5382 for (
auto& entry : priv_->deleted_data_members_)
5399 bool anonymous_dm_members_present =
true;
5403 for (
auto& e : non_anonymous_data_members)
5405 if (non_anonymous_dms_in_second_class.find(e.first)
5406 == non_anonymous_dms_in_second_class.end())
5411 anonymous_dm_members_present =
false;
5413 if (anonymous_dm_members_present)
5418 deleted_data_members_to_delete.push_back(data_member->get_anon_dm_reliable_name());
5424 for (
string& name_of_dm_to_delete: deleted_data_members_to_delete)
5425 priv_->deleted_data_members_.erase(name_of_dm_to_delete);
5428 priv_->sorted_subtype_changed_dm_);
5430 priv_->sorted_changed_dm_);
5433 edit_script& e = priv_->member_class_tmpls_changes_;
5435 for (vector<deletion>::const_iterator it = e.deletions().begin();
5436 it != e.deletions().end();
5439 unsigned i = it->index();
5443 string name = d->get_name();
5444 ABG_ASSERT(priv_->deleted_member_class_tmpls_.find(name)
5445 == priv_->deleted_member_class_tmpls_.end());
5446 priv_->deleted_member_class_tmpls_[name] = d;
5449 for (vector<insertion>::const_iterator it = e.insertions().begin();
5450 it != e.insertions().end();
5453 for (vector<unsigned>::const_iterator iit =
5454 it->inserted_indexes().begin();
5455 iit != it->inserted_indexes().end();
5462 string name = d->get_name();
5463 ABG_ASSERT(priv_->inserted_member_class_tmpls_.find(name)
5464 == priv_->inserted_member_class_tmpls_.end());
5465 string_decl_base_sptr_map::const_iterator j =
5466 priv_->deleted_member_class_tmpls_.find(name);
5467 if (j != priv_->deleted_member_class_tmpls_.end())
5469 if (*j->second != *d)
5470 priv_->changed_member_types_[name]=
5472 priv_->deleted_member_class_tmpls_.erase(j);
5475 priv_->inserted_member_class_tmpls_[name] = d;
5480 priv_->sorted_changed_member_types_);
5489 priv_.reset(
new priv);
5500 class_or_union_sptr second_scope,
5518 const class_or_union_diff::priv_ptr&
5531 return canonical->priv_;
5553 {
return get_priv()->member_types_changes_;}
5559 {
return get_priv()->member_types_changes_;}
5565 {
return get_priv()->data_members_changes_;}
5571 {
return get_priv()->data_members_changes_;}
5578 {
return get_priv()->inserted_data_members_;}
5585 {
return get_priv()->deleted_data_members_;}
5591 {
return get_priv()->member_fns_changes_;}
5600 {
return get_priv()->sorted_changed_member_functions_;}
5606 {
return get_priv()->member_fns_changes_;}
5611 {
return get_priv()->deleted_member_functions_;}
5616 {
return get_priv()->inserted_member_functions_;}
5634 {
return get_priv()->sorted_changed_dm_;}
5642 {
return get_priv()->count_filtered_changed_dm(local);}
5649 {
return get_priv()->sorted_subtype_changed_dm_;}
5656 {
return get_priv()->count_filtered_subtype_changed_dm(local);}
5668 {
return get_priv()->dms_replaced_by_adms_;}
5680 if (priv_->dms_replaced_by_adms_ordered_.empty())
5682 for (string_decl_base_sptr_map::const_iterator it =
5683 priv_->dms_replaced_by_adms_.begin();
5684 it != priv_->dms_replaced_by_adms_.end();
5691 priv_->dms_replaced_by_adms_ordered_.push_back(changed_dm);
5696 return priv_->dms_replaced_by_adms_ordered_;
5703 {
return get_priv()->member_fn_tmpls_changes_;}
5709 {
return get_priv()->member_fn_tmpls_changes_;}
5715 {
return get_priv()->member_class_tmpls_changes_;}
5721 {
return get_priv()->member_class_tmpls_changes_;}
5737 return ir::NO_CHANGE_KIND;
5750 context()->get_reporter()->report(*
this, out, indent);
5762 for (var_diff_sptrs_type::const_iterator i =
5763 get_priv()->sorted_subtype_changed_dm_.begin();
5764 i !=
get_priv()->sorted_subtype_changed_dm_.end();
5769 for (var_diff_sptrs_type::const_iterator i =
5770 get_priv()->sorted_changed_dm_.begin();
5771 i !=
get_priv()->sorted_changed_dm_.end();
5777 for (diff_sptrs_type::const_iterator i =
5778 get_priv()->sorted_changed_member_types_.begin();
5779 i !=
get_priv()->sorted_changed_member_types_.end();
5785 for (function_decl_diff_sptrs_type::const_iterator i =
5786 get_priv()->sorted_changed_member_functions_.begin();
5787 i !=
get_priv()->sorted_changed_member_functions_.end();
5802 class_diff::clear_lookup_tables(
void)
5804 priv_->deleted_bases_.clear();
5805 priv_->inserted_bases_.clear();
5806 priv_->changed_bases_.clear();
5813 class_diff::lookup_tables_empty(
void)
const
5815 return (priv_->deleted_bases_.empty()
5816 && priv_->inserted_bases_.empty()
5817 && priv_->changed_bases_.empty());
5827 static string_member_function_sptr_map::const_iterator
5830 for (string_member_function_sptr_map::const_iterator i = map.begin();
5844 class_diff::ensure_lookup_tables_populated(
void)
const
5848 if (!lookup_tables_empty())
5852 edit_script& e = get_priv()->base_changes_;
5854 for (vector<deletion>::const_iterator it = e.deletions().begin();
5855 it != e.deletions().end();
5858 unsigned i = it->index();
5861 string name = b->get_base_class()->get_qualified_name();
5862 ABG_ASSERT(get_priv()->deleted_bases_.find(name)
5863 == get_priv()->deleted_bases_.end());
5864 get_priv()->deleted_bases_[name] = b;
5867 for (vector<insertion>::const_iterator it = e.insertions().begin();
5868 it != e.insertions().end();
5871 for (vector<unsigned>::const_iterator iit =
5872 it->inserted_indexes().begin();
5873 iit != it->inserted_indexes().end();
5879 string name = b->get_base_class()->get_qualified_name();
5880 ABG_ASSERT(get_priv()->inserted_bases_.find(name)
5881 == get_priv()->inserted_bases_.end());
5882 string_base_sptr_map::const_iterator j =
5883 get_priv()->deleted_bases_.find(name);
5884 if (j != get_priv()->deleted_bases_.end())
5887 get_priv()->changed_bases_[name] =
5893 get_priv()->moved_bases_.push_back(b);
5894 get_priv()->deleted_bases_.erase(j);
5897 get_priv()->inserted_bases_[name] = b;
5907 class_or_union_diff::priv_->deleted_data_members_;
5909 vector<var_decl_sptr> deleted_data_members_present_in_bases;
5910 for (
auto entry : deleted_data_members)
5917 var_decl_sptr member = klass->find_data_member(deleted_member->get_name());
5919 deleted_data_members_present_in_bases.push_back(member);
5926 for (
var_decl_sptr m : deleted_data_members_present_in_bases)
5928 string name = m->get_name();
5929 auto it = deleted_data_members.find(name);
5930 ABG_ASSERT(it != deleted_data_members.end());
5932 if (*deleted_member != *m)
5936 class_or_union_diff::priv_->subtype_changed_dm_[name]= dif;
5938 deleted_data_members.erase(name);
5943 get_priv()->sorted_deleted_bases_);
5945 get_priv()->sorted_inserted_bases_);
5947 get_priv()->sorted_changed_bases_);
5952 edit_script& e = p->member_fns_changes_;
5954 for (vector<deletion>::const_iterator it = e.deletions().begin();
5955 it != e.deletions().end();
5958 unsigned i = it->index();
5959 method_decl_sptr mem_fn =
5961 string name = mem_fn->get_linkage_name();
5963 name = mem_fn->get_pretty_representation();
5965 if (p->deleted_member_functions_.find(name)
5966 != p->deleted_member_functions_.end())
5968 p->deleted_member_functions_[name] = mem_fn;
5971 for (vector<insertion>::const_iterator it = e.insertions().begin();
5972 it != e.insertions().end();
5975 for (vector<unsigned>::const_iterator iit =
5976 it->inserted_indexes().begin();
5977 iit != it->inserted_indexes().end();
5982 method_decl_sptr mem_fn =
5984 string name = mem_fn->get_linkage_name();
5986 name = mem_fn->get_pretty_representation();
5988 if (p->inserted_member_functions_.find(name)
5989 != p->inserted_member_functions_.end())
5991 string_member_function_sptr_map::const_iterator j =
5992 p->deleted_member_functions_.find(name);
5994 if (j != p->deleted_member_functions_.end())
5996 if (*j->second != *mem_fn)
5997 p->changed_member_functions_[name] =
5998 compute_diff(static_pointer_cast<function_decl>(j->second),
5999 static_pointer_cast<function_decl>(mem_fn),
6001 p->deleted_member_functions_.erase(j);
6004 p->inserted_member_functions_[name] = mem_fn;
6051 vector<string> to_delete;
6052 corpus_sptr f =
context()->get_first_corpus(),
6053 s =
context()->get_second_corpus();
6055 for (string_member_function_sptr_map::const_iterator i =
6074 find_virtual_dtor_in_map(p->inserted_member_functions_);
6075 if (it != p->inserted_member_functions_.end())
6083 (!i->second->get_linkage_name().empty())
6084 ? i->second->get_linkage_name()
6085 : i->second->get_pretty_representation();
6086 to_delete.push_back(name);
6087 p->inserted_member_functions_.erase(it);
6094 if (!i->second->get_symbol()
6095 || s->lookup_function_symbol(*i->second->get_symbol()))
6096 to_delete.push_back(i->first);
6100 for (vector<string>::const_iterator i = to_delete.begin();
6101 i != to_delete.end();
6103 p->deleted_member_functions_.erase(*i);
6108 for (string_member_function_sptr_map::const_iterator i =
6117 if (!i->second->get_symbol()
6118 || f->lookup_function_symbol(*i->second->get_symbol()))
6119 to_delete.push_back(i->first);
6122 for (vector<string>::const_iterator i = to_delete.begin();
6123 i != to_delete.end();
6125 p->inserted_member_functions_.erase(*i);
6128 p->sorted_deleted_member_functions_);
6131 p->sorted_inserted_member_functions_);
6134 (p->changed_member_functions_,
6135 p->sorted_changed_member_functions_);
6142 class_diff::allocate_priv_data()
6146 priv_.reset(
new priv);
6159 string qname = d->get_base_class()->get_qualified_name();
6160 string_base_diff_sptr_map::const_iterator it =
6161 changed_bases_.find(qname);
6163 return (it == changed_bases_.end())
6165 : it->second->second_base();
6176 size_t num_filtered = 0;
6177 for (base_diff_sptrs_type::const_iterator i = sorted_changed_bases_.begin();
6178 i != sorted_changed_bases_.end();
6182 if (diff && diff->is_filtered_out())
6185 return num_filtered;
6199 for (base_diff_sptrs_type::const_iterator i =
6200 get_priv()->sorted_changed_bases_.begin();
6201 i != get_priv()->sorted_changed_bases_.end();
6226 class_diff::~class_diff()
6240 const class_diff::priv_ptr&
6241 class_diff::get_priv()
const
6253 return canonical->priv_;
6261 if (diff::priv_->pretty_representation_.empty())
6263 std::ostringstream o;
6269 diff::priv_->pretty_representation_ = o.str();
6271 return diff::priv_->pretty_representation_;
6290 return ir::NO_CHANGE_KIND;
6294 shared_ptr<class_decl>
6301 shared_ptr<class_decl>
6308 {
return get_priv()->base_changes_;}
6316 {
return get_priv()->deleted_bases_;}
6324 {
return get_priv()->inserted_bases_;}
6331 {
return get_priv()->sorted_changed_bases_;}
6339 const vector<class_decl::base_spec_sptr>&
6341 {
return get_priv()->moved_bases_;}
6346 {
return get_priv()->base_changes_;}
6357 context()->get_reporter()->report(*
this, out, indent);
6382 ctxt->initialize_canonical_diff(changes);
6385 if (!ctxt->get_canonical_diff_for(first, second))
6389 diff_sptr canonical_diff = ctxt->get_canonical_diff_for(changes);
6391 ctxt->set_canonical_diff_for(first, second, canonical_diff);
6407 if (
is_class_diff(changes->get_canonical_diff()) == changes.get())
6410 changes->allocate_priv_data();
6422 f->get_base_specifiers().end(),
6423 s->get_base_specifiers().begin(),
6424 s->get_base_specifiers().end(),
6425 changes->base_changes());
6431 f->get_member_types().end(),
6432 s->get_member_types().begin(),
6433 s->get_member_types().end(),
6434 changes->member_types_changes());
6439 f->get_non_static_data_members().end(),
6440 s->get_non_static_data_members().begin(),
6441 s->get_non_static_data_members().end(),
6442 changes->data_members_changes());
6446 f->get_virtual_mem_fns().end(),
6447 s->get_virtual_mem_fns().begin(),
6448 s->get_virtual_mem_fns().end(),
6449 changes->member_fns_changes());
6452 compute_diff(f->get_member_function_templates().begin(),
6453 f->get_member_function_templates().end(),
6454 s->get_member_function_templates().begin(),
6455 s->get_member_function_templates().end(),
6456 changes->member_fn_tmpls_changes());
6461 f->get_member_class_templates().end(),
6462 s->get_member_class_templates().begin(),
6463 s->get_member_class_templates().end(),
6464 changes->member_class_tmpls_changes());
6467 changes->ensure_lookup_tables_populated();
6497 :
diff(first, second, ctxt),
6498 priv_(new
priv(underlying))
6522 {
return priv_->underlying_class_diff_;}
6531 {priv_->underlying_class_diff_ = d;}
6538 if (diff::priv_->pretty_representation_.empty())
6540 std::ostringstream o;
6546 diff::priv_->pretty_representation_ = o.str();
6548 return diff::priv_->pretty_representation_;
6567 return ir::NO_CHANGE_KIND;
6578 context()->get_reporter()->report(*
this, out, indent);
6600 second->get_base_class(),
6604 ctxt->initialize_canonical_diff(changes);
6619 union_diff::clear_lookup_tables(
void)
6626 union_diff::lookup_tables_empty(
void)
const
6632 union_diff::ensure_lookup_tables_populated(
void)
const
6638 union_diff::allocate_priv_data()
6651 union_decl_sptr second_union,
6674 if (diff::priv_->pretty_representation_.empty())
6676 std::ostringstream o;
6682 diff::priv_->pretty_representation_ = o.str();
6684 return diff::priv_->pretty_representation_;
6696 context()->get_reporter()->report(*
this, out, indent);
6711 const union_decl_sptr second,
6714 union_diff_sptr changes(
new union_diff(first, second, ctxt));
6716 ctxt->initialize_canonical_diff(changes);
6732 if (
is_union_diff(changes->get_canonical_diff()) == changes.get())
6735 changes->allocate_priv_data();
6746 compute_diff(first->get_non_static_data_members().begin(),
6747 first->get_non_static_data_members().end(),
6748 second->get_non_static_data_members().begin(),
6749 second->get_non_static_data_members().end(),
6750 changes->data_members_changes());
6755 first->get_mem_fns().end(),
6756 second->get_mem_fns().begin(),
6757 second->get_mem_fns().end(),
6758 changes->member_fns_changes());
6761 compute_diff(first->get_member_function_templates().begin(),
6762 first->get_member_function_templates().end(),
6763 second->get_member_function_templates().begin(),
6764 second->get_member_function_templates().end(),
6765 changes->member_fn_tmpls_changes());
6768 changes->ensure_lookup_tables_populated();
6782 scope_diff::clear_lookup_tables()
6784 priv_->deleted_types_.clear();
6785 priv_->deleted_decls_.clear();
6786 priv_->inserted_types_.clear();
6787 priv_->inserted_decls_.clear();
6788 priv_->changed_types_.clear();
6789 priv_->changed_decls_.clear();
6790 priv_->removed_types_.clear();
6791 priv_->removed_decls_.clear();
6792 priv_->added_types_.clear();
6793 priv_->added_decls_.clear();
6803 scope_diff::lookup_tables_empty()
const
6805 return (priv_->deleted_types_.empty()
6806 && priv_->deleted_decls_.empty()
6807 && priv_->inserted_types_.empty()
6808 && priv_->inserted_decls_.empty()
6809 && priv_->changed_types_.empty()
6810 && priv_->changed_decls_.empty()
6811 && priv_->removed_types_.empty()
6812 && priv_->removed_decls_.empty()
6813 && priv_->added_types_.empty()
6814 && priv_->added_decls_.empty());
6820 scope_diff::ensure_lookup_tables_populated()
6822 if (!lookup_tables_empty())
6825 edit_script& e = priv_->member_changes_;
6828 for (
const auto& deletion : e.deletions())
6830 unsigned i = deletion.index();
6832 string qname = decl->get_qualified_name();
6836 if (klass_decl && klass_decl->get_is_declaration_only())
6847 == priv_->deleted_types_.end());
6848 priv_->deleted_types_[qname] = decl;
6853 == priv_->deleted_decls_.end());
6854 priv_->deleted_decls_[qname] = decl;
6860 for (vector<insertion>::const_iterator it = e.insertions().begin();
6861 it != e.insertions().end();
6864 for (vector<unsigned>::const_iterator i = it->inserted_indexes().begin();
6865 i != it->inserted_indexes().end();
6869 string qname = decl->get_qualified_name();
6873 dynamic_pointer_cast<class_decl>(decl);
6874 if (klass_decl && klass_decl->get_is_declaration_only())
6884 ABG_ASSERT(priv_->inserted_types_.find(qname)
6885 == priv_->inserted_types_.end());
6886 string_decl_base_sptr_map::const_iterator j =
6887 priv_->deleted_types_.find(qname);
6888 if (j != priv_->deleted_types_.end())
6890 if (*j->second != *decl)
6891 priv_->changed_types_[qname] =
6893 priv_->deleted_types_.erase(j);
6896 priv_->inserted_types_[qname] = decl;
6900 ABG_ASSERT(priv_->inserted_decls_.find(qname)
6901 == priv_->inserted_decls_.end());
6902 string_decl_base_sptr_map::const_iterator j =
6903 priv_->deleted_decls_.find(qname);
6904 if (j != priv_->deleted_decls_.end())
6906 if (*j->second != *decl)
6907 priv_->changed_decls_[qname] =
6909 priv_->deleted_decls_.erase(j);
6912 priv_->inserted_decls_[qname] = decl;
6918 priv_->sorted_changed_decls_);
6920 priv_->sorted_changed_types_);
6923 for (string_decl_base_sptr_map::const_iterator i =
6924 priv_->deleted_types_.begin();
6925 i != priv_->deleted_types_.end();
6928 string_decl_base_sptr_map::const_iterator r =
6929 priv_->inserted_types_.find(i->first);
6930 if (r == priv_->inserted_types_.end())
6931 priv_->removed_types_[i->first] = i->second;
6933 for (string_decl_base_sptr_map::const_iterator i =
6934 priv_->deleted_decls_.begin();
6935 i != priv_->deleted_decls_.end();
6938 string_decl_base_sptr_map::const_iterator r =
6939 priv_->inserted_decls_.find(i->first);
6940 if (r == priv_->inserted_decls_.end())
6941 priv_->removed_decls_[i->first] = i->second;
6945 for (string_decl_base_sptr_map::const_iterator i =
6946 priv_->inserted_types_.begin();
6947 i != priv_->inserted_types_.end();
6950 string_decl_base_sptr_map::const_iterator r =
6951 priv_->deleted_types_.find(i->first);
6952 if (r == priv_->deleted_types_.end())
6953 priv_->added_types_[i->first] = i->second;
6955 for (string_decl_base_sptr_map::const_iterator i =
6956 priv_->inserted_decls_.begin();
6957 i != priv_->inserted_decls_.end();
6960 string_decl_base_sptr_map::const_iterator r =
6961 priv_->deleted_decls_.find(i->first);
6962 if (r == priv_->deleted_decls_.end())
6963 priv_->added_decls_[i->first] = i->second;
6975 for (diff_sptrs_type::const_iterator i =
changed_types().begin();
6981 for (diff_sptrs_type::const_iterator i =
changed_decls().begin();
7001 :
diff(first_scope, second_scope, ctxt),
7039 {
return priv_->member_changes_;}
7061 {
return priv_->member_changes_;}
7072 const decl_base_sptr
7089 const decl_base_sptr
7103 const decl_base_sptr
7120 const decl_base_sptr
7128 {
return priv_->sorted_changed_types_;}
7134 {
return priv_->sorted_changed_decls_;}
7137 scope_diff::removed_types()
const
7138 {
return priv_->removed_types_;}
7141 scope_diff::removed_decls()
const
7142 {
return priv_->removed_decls_;}
7145 scope_diff::added_types()
const
7146 {
return priv_->added_types_;}
7149 scope_diff::added_decls()
const
7150 {
return priv_->added_decls_;}
7157 if (diff::priv_->pretty_representation_.empty())
7159 std::ostringstream o;
7165 diff::priv_->pretty_representation_ = o.str();
7167 return diff::priv_->pretty_representation_;
7189 return ir::NO_CHANGE_KIND;
7200 context()->get_reporter()->report(*
this, out, indent);
7226 ABG_ASSERT(d->first_scope() == first && d->second_scope() == second);
7229 first->get_member_decls().end(),
7230 second->get_member_decls().begin(),
7231 second->get_member_decls().end(),
7232 d->member_changes());
7234 d->ensure_lookup_tables_populated();
7260 ctxt->initialize_canonical_diff(d);
7284 ABG_ASSERT(first->get_index() == second->get_index());
7315 {
return priv_->type_diff;}
7325 if (diff::priv_->pretty_representation_.empty())
7327 std::ostringstream o;
7328 o <<
"function_parameter_diff["
7333 diff::priv_->pretty_representation_ = o.str();
7335 return diff::priv_->pretty_representation_;
7356 return ir::NO_CHANGE_KIND;
7367 context()->get_reporter()->report(*
this, out, indent);
7401 if (!first || !second)
7405 ctxt->initialize_canonical_diff(result);
7414 function_type_diff::ensure_lookup_tables_populated()
7416 priv_->return_type_diff_ =
7423 for (vector<deletion>::const_iterator i =
7424 priv_->parm_changes_.deletions().begin();
7425 i != priv_->parm_changes_.deletions().end();
7430 parm_name = parm->get_name_id();
7434 priv_->deleted_parms_[parm_name] = parm;
7435 priv_->deleted_parms_by_id_[parm->get_index()] = parm;
7438 for (vector<insertion>::const_iterator i =
7439 priv_->parm_changes_.insertions().begin();
7440 i != priv_->parm_changes_.insertions().end();
7443 for (vector<unsigned>::const_iterator j =
7444 i->inserted_indexes().begin();
7445 j != i->inserted_indexes().end();
7449 parm_name = parm->get_name_id();
7454 string_parm_map::const_iterator k =
7455 priv_->deleted_parms_.find(parm_name);
7456 if (k != priv_->deleted_parms_.end())
7458 if (*k->second != *parm)
7459 priv_->subtype_changed_parms_[parm_name] =
7461 priv_->deleted_parms_.erase(parm_name);
7464 priv_->added_parms_[parm_name] = parm;
7467 unsigned_parm_map::const_iterator k =
7468 priv_->deleted_parms_by_id_.find(parm->get_index());
7469 if (k != priv_->deleted_parms_by_id_.end())
7471 if (*k->second != *parm
7472 && (k->second->get_name_id() != parm_name))
7473 priv_->changed_parms_by_id_[parm->get_index()] =
7475 priv_->added_parms_.erase(parm_name);
7476 priv_->deleted_parms_.erase(k->second->get_name_id());
7477 priv_->deleted_parms_by_id_.erase(parm->get_index());
7480 priv_->added_parms_by_id_[parm->get_index()] = parm;
7486 priv_->sorted_subtype_changed_parms_);
7488 priv_->sorted_changed_parms_by_id_);
7490 priv_->sorted_deleted_parms_);
7493 priv_->sorted_added_parms_);
7503 function_type_diff::deleted_parameter_at(
int i)
const
7509 const vector<function_decl::parameter_sptr>&
7511 {
return priv_->sorted_deleted_parms_;}
7516 const vector<function_decl::parameter_sptr>&
7518 {
return priv_->sorted_added_parms_;}
7527 function_type_diff::inserted_parameter_at(
int i)
const
7571 {
return priv_->return_type_diff_;}
7578 {
return priv_->subtype_changed_parms_;}
7585 {
return priv_->deleted_parms_;}
7592 {
return priv_->added_parms_;}
7602 if (diff::priv_->pretty_representation_.empty())
7604 std::ostringstream o;
7605 o <<
"function_type_diff["
7610 diff::priv_->pretty_representation_ = o.str();
7612 return diff::priv_->pretty_representation_;
7636 return ir::NO_CHANGE_KIND;
7648 context()->get_reporter()->report(*
this, out, indent);
7662 for (vector<fn_parm_diff_sptr>::const_iterator i =
7663 priv_->sorted_subtype_changed_parms_.begin();
7664 i != priv_->sorted_subtype_changed_parms_.end();
7669 for (vector<fn_parm_diff_sptr>::const_iterator i =
7670 priv_->sorted_changed_parms_by_id_.begin();
7671 i != priv_->sorted_changed_parms_by_id_.end();
7694 if (!first || !second)
7703 first->get_parameters().end(),
7704 second->get_first_parm(),
7705 second->get_parameters().end(),
7706 result->priv_->parm_changes_);
7708 result->ensure_lookup_tables_populated();
7710 ctxt->initialize_canonical_diff(result);
7720 function_decl_diff::ensure_lookup_tables_populated()
7765 function_decl_diff::type_diff()
const
7766 {
return priv_->type_diff_;}
7773 if (diff::priv_->pretty_representation_.empty())
7775 std::ostringstream o;
7776 o <<
"function_diff["
7781 diff::priv_->pretty_representation_ = o.str();
7783 return diff::priv_->pretty_representation_;
7802 return ir::NO_CHANGE_KIND;
7814 context()->get_reporter()->report(*
this, out, indent);
7834 if (!first || !second)
7846 result->priv_->type_diff_ = type_diff;
7848 result->ensure_lookup_tables_populated();
7850 ctxt->initialize_canonical_diff(result);
7894 if (diff::priv_->pretty_representation_.empty())
7896 std::ostringstream o;
7897 o <<
"type_decl_diff["
7902 diff::priv_->pretty_representation_ = o.str();
7904 return diff::priv_->pretty_representation_;
7922 return ir::NO_CHANGE_KIND;
7933 context()->get_reporter()->report(*
this, out, indent);
7971 ctxt->initialize_canonical_diff(result);
8008 priv_(new
priv(underlying))
8032 {
return priv_->underlying_type_diff_;}
8041 {priv_->underlying_type_diff_ = d;}
8048 if (diff::priv_->pretty_representation_.empty())
8050 std::ostringstream o;
8051 o <<
"typedef_diff["
8056 diff::priv_->pretty_representation_ = o.str();
8058 return diff::priv_->pretty_representation_;
8080 return ir::NO_CHANGE_KIND;
8092 context()->get_reporter()->report(*
this, out, indent);
8112 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
8113 second->get_underlying_type(),
8117 ctxt->initialize_canonical_diff(result);
8169 priv_(new
priv(first, second))
8178 {
return priv_->first_;}
8185 {
return priv_->second_;}
8199 {
return ir::NO_CHANGE_KIND;}
8238 compute_diff(static_pointer_cast<scope_decl>(first->get_global_scope()),
8239 static_pointer_cast<scope_decl>(second->get_global_scope()),
8243 ctxt->initialize_canonical_diff(tu_diff);
8253 struct diff_maps::priv
8276 diff_maps::~diff_maps() =
default;
8283 {
return priv_->type_decl_diff_map_;}
8290 {
return priv_->type_decl_diff_map_;}
8297 {
return priv_->enum_diff_map_;}
8304 {
return priv_->enum_diff_map_;}
8311 {
return priv_->class_diff_map_;}
8318 {
return priv_->class_diff_map_;}
8325 {
return priv_->union_diff_map_;}
8332 {
return priv_->union_diff_map_;}
8339 {
return priv_->typedef_diff_map_;}
8346 {
return priv_->typedef_diff_map_;}
8353 {
return priv_->subrange_diff_map_;}
8360 {
return priv_->subrange_diff_map_;}
8367 {
return priv_->array_diff_map_;}
8374 {
return priv_->array_diff_map_;}
8381 {
return priv_->reference_diff_map_;}
8388 {{
return priv_->reference_diff_map_;}}
8395 {
return priv_->fn_parm_diff_map_;}
8402 {
return priv_->fn_parm_diff_map_;}
8409 {
return priv_->function_type_diff_map_;}
8416 {
return priv_->function_type_diff_map_;}
8423 {
return priv_->function_decl_diff_map_;}
8430 {
return priv_->function_decl_diff_map_;}
8437 {
return priv_->var_decl_diff_map_;}
8444 {
return priv_->var_decl_diff_map_;}
8451 {
return priv_->distinct_diff_map_;}
8458 {
return priv_->distinct_diff_map_;}
8516 diff_artifact_set_map_type::iterator i =
8517 priv_->impacted_artifacts_map_.find(dif);
8519 if (i == priv_->impacted_artifacts_map_.end())
8522 set.insert(impacted_iface);
8523 priv_->impacted_artifacts_map_[dif] = set;
8526 i->second.insert(impacted_iface);
8540 diff_artifact_set_map_type::iterator i =
8541 priv_->impacted_artifacts_map_.find(d);
8543 if (i == priv_->impacted_artifacts_map_.end())
8559 : priv_(new
priv(ctxt))
8567 {
return priv_->num_func_removed;}
8574 {priv_->num_func_removed = n;}
8584 if (priv_->ctxt() && !priv_->ctxt()->show_deleted_fns())
8585 return num_func_removed();
8586 return priv_->num_removed_func_filtered_out;
8595 {priv_->num_removed_func_filtered_out = t;}
8606 ABG_ASSERT(num_func_removed() >= num_removed_func_filtered_out());
8607 return num_func_removed() - num_removed_func_filtered_out();
8615 {
return priv_->num_func_added;}
8622 {priv_->num_func_added = n;}
8630 if (priv_->ctxt() && !priv_->ctxt()->show_added_fns())
8631 return num_func_added();
8632 return priv_->num_added_func_filtered_out;
8641 {priv_->num_added_func_filtered_out = n;}
8653 ABG_ASSERT(num_func_added() >= num_added_func_filtered_out());
8654 return num_func_added() - num_added_func_filtered_out();
8664 {
return priv_->num_func_changed;}
8673 {priv_->num_func_changed = n;}
8682 {
return priv_->num_changed_func_filtered_out;}
8691 {priv_->num_changed_func_filtered_out = n;}
8699 {
return priv_->num_func_with_virt_offset_changes;}
8708 {priv_->num_func_with_virt_offset_changes = n;}
8719 {
return num_func_changed() - num_changed_func_filtered_out();}
8726 {
return priv_->num_vars_removed;}
8733 {priv_->num_vars_removed = n;}
8742 if (priv_->ctxt() && !priv_->ctxt()->show_deleted_vars())
8743 return num_vars_removed();
8744 return priv_->num_removed_vars_filtered_out;
8753 {priv_->num_removed_vars_filtered_out = n;}
8765 ABG_ASSERT(num_vars_removed() >= num_removed_vars_filtered_out());
8766 return num_vars_removed() - num_removed_vars_filtered_out();
8774 {
return priv_->num_vars_added;}
8781 {priv_->num_vars_added = n;}
8790 if (priv_->ctxt() && !priv_->ctxt()->show_added_vars())
8791 return num_vars_added();
8792 return priv_->num_added_vars_filtered_out;
8801 {priv_->num_added_vars_filtered_out = n;}
8813 ABG_ASSERT(num_vars_added() >= num_added_vars_filtered_out());
8814 return num_vars_added() - num_added_vars_filtered_out();
8824 {
return priv_->num_vars_changed;}
8833 {priv_->num_vars_changed = n;}
8842 {
return priv_->num_changed_vars_filtered_out;}
8851 {priv_->num_changed_vars_filtered_out = n;}
8862 {
return num_vars_changed() - num_changed_vars_filtered_out();}
8871 {
return priv_->num_func_syms_removed;}
8880 {priv_->num_func_syms_removed = n;}
8891 && !priv_->ctxt()->show_symbols_unreferenced_by_debug_info())
8892 return num_func_syms_removed();
8893 return priv_->num_removed_func_syms_filtered_out;
8903 {priv_->num_removed_func_syms_filtered_out = n;}
8918 ABG_ASSERT(num_func_syms_removed() >= num_removed_func_syms_filtered_out());
8919 return num_func_syms_removed() - num_removed_func_syms_filtered_out();
8929 {
return priv_->num_func_syms_added;}
8938 {priv_->num_func_syms_added = n;}
8949 && !(priv_->ctxt()->show_added_symbols_unreferenced_by_debug_info()
8950 && priv_->ctxt()->show_symbols_unreferenced_by_debug_info()))
8951 return num_func_syms_added();
8952 return priv_->num_added_func_syms_filtered_out;
8962 {priv_->num_added_func_syms_filtered_out = n;}
8977 ABG_ASSERT(num_func_syms_added() >= num_added_func_syms_filtered_out());
8978 return num_func_syms_added()- num_added_func_syms_filtered_out();
8988 {
return priv_->num_var_syms_removed;}
8997 {priv_->num_var_syms_removed = n;}
9008 && !priv_->ctxt()->show_symbols_unreferenced_by_debug_info())
9009 return num_var_syms_removed();
9010 return priv_->num_removed_var_syms_filtered_out;
9020 {priv_->num_removed_var_syms_filtered_out = n;}
9035 ABG_ASSERT(num_var_syms_removed() >= num_removed_var_syms_filtered_out());
9036 return num_var_syms_removed() - num_removed_var_syms_filtered_out();
9046 {
return priv_->num_var_syms_added;}
9055 {priv_->num_var_syms_added = n;}
9066 && !(priv_->ctxt()->show_added_symbols_unreferenced_by_debug_info()
9067 && priv_->ctxt()->show_symbols_unreferenced_by_debug_info()))
9068 return num_var_syms_added();
9069 return priv_->num_added_var_syms_filtered_out;
9079 {priv_->num_added_var_syms_filtered_out = n;}
9094 ABG_ASSERT(num_var_syms_added() >= num_added_var_syms_filtered_out());
9095 return num_var_syms_added() - num_added_var_syms_filtered_out();
9103 {
return priv_->num_leaf_changes;}
9110 {priv_->num_leaf_changes = n;}
9118 {
return priv_->num_leaf_changes_filtered_out;}
9127 {priv_->num_leaf_changes_filtered_out = n;}
9140 ABG_ASSERT(num_leaf_changes() >= num_leaf_changes_filtered_out());
9141 return num_leaf_changes() - num_leaf_changes_filtered_out();
9149 {
return priv_->num_leaf_type_changes;}
9156 {priv_->num_leaf_type_changes = n;}
9163 {
return priv_->num_leaf_type_changes_filtered_out;}
9169 {priv_->num_leaf_type_changes_filtered_out = n;}
9179 {
return num_leaf_type_changes() - num_leaf_type_changes_filtered_out();}
9186 {
return priv_->num_leaf_func_changes;}
9193 {priv_->num_leaf_func_changes = n;}
9202 {
return priv_->num_leaf_func_changes_filtered_out;}
9211 {priv_->num_leaf_func_changes_filtered_out = n;}
9222 {
return num_leaf_func_changes() - num_leaf_func_changes_filtered_out();}
9229 {
return priv_->num_leaf_var_changes;}
9236 {priv_->num_leaf_var_changes = n;}
9248 {
return priv_->num_added_unreachable_types;}
9261 {priv_->num_added_unreachable_types = n;}
9272 {
return priv_->num_added_unreachable_types_filtered_out;}
9283 {priv_->num_added_unreachable_types_filtered_out = n;}
9297 num_added_unreachable_types_filtered_out());
9299 return (num_added_unreachable_types()
9301 num_added_unreachable_types_filtered_out());
9314 {
return priv_->num_removed_unreachable_types;}
9326 {priv_->num_removed_unreachable_types = n;}
9337 {
return priv_->num_removed_unreachable_types_filtered_out;}
9348 {priv_->num_removed_unreachable_types_filtered_out = n;}
9362 num_removed_unreachable_types_filtered_out());
9364 return (num_removed_unreachable_types()
9366 num_removed_unreachable_types_filtered_out());
9379 {
return priv_->num_changed_unreachable_types;}
9391 {priv_->num_changed_unreachable_types = n;}
9402 {
return priv_->num_changed_unreachable_types_filtered_out;}
9413 {priv_->num_changed_unreachable_types_filtered_out = n;}
9427 num_changed_unreachable_types_filtered_out());
9429 return (num_changed_unreachable_types()
9431 num_changed_unreachable_types_filtered_out());
9441 {
return priv_->num_leaf_var_changes_filtered_out;}
9450 {priv_->num_leaf_var_changes_filtered_out = n;}
9461 {
return num_leaf_var_changes() - num_leaf_var_changes_filtered_out();}
9471 {
return ctxt_.lock();}
9479 return (deleted_fns_.empty()
9480 && added_fns_.empty()
9481 && changed_fns_map_.empty()
9482 && deleted_vars_.empty()
9483 && added_vars_.empty()
9484 && changed_vars_map_.empty());
9491 deleted_fns_.clear();
9493 changed_fns_map_.clear();
9494 deleted_vars_.clear();
9495 added_vars_.clear();
9496 changed_vars_map_.clear();
9504 if (!lookup_tables_empty())
9510 edit_script& e = fns_edit_script_;
9512 for (vector<deletion>::const_iterator it = e.deletions().begin();
9513 it != e.deletions().end();
9516 unsigned i = it->index();
9517 ABG_ASSERT(i < first_->get_functions().size());
9519 const function_decl* deleted_fn = first_->get_functions()[i];
9526 deleted_fns_[n] = deleted_fn;
9529 for (vector<insertion>::const_iterator it = e.insertions().begin();
9530 it != e.insertions().end();
9533 for (vector<unsigned>::const_iterator iit =
9534 it->inserted_indexes().begin();
9535 iit != it->inserted_indexes().end();
9539 const function_decl* added_fn = second_->get_functions()[i];
9546 string_function_ptr_map::const_iterator j =
9547 deleted_fns_.find(n);
9548 if (j != deleted_fns_.end())
9555 if (*j->second != *added_fn)
9556 changed_fns_map_[j->first] = d;
9557 deleted_fns_.erase(j);
9560 added_fns_[n] = added_fn;
9569 vector<string> to_delete;
9570 for (string_function_ptr_map::const_iterator i = deleted_fns_.begin();
9571 i != deleted_fns_.end();
9573 if (second_->lookup_function_symbol(*i->second->get_symbol()))
9574 to_delete.push_back(i->first);
9576 for (vector<string>::const_iterator i = to_delete.begin();
9577 i != to_delete.end();
9579 deleted_fns_.erase(*i);
9584 for (string_function_ptr_map::const_iterator i = added_fns_.begin();
9585 i != added_fns_.end();
9588 if (first_->lookup_function_symbol(*i->second->get_symbol()))
9589 to_delete.push_back(i->first);
9590 else if (! i->second->get_symbol()->get_version().is_empty()
9591 && i->second->get_symbol()->get_version().is_default())
9599 if (first_->lookup_function_symbol(i->second->get_symbol()->get_name(),
9601 to_delete.push_back(i->first);
9605 for (vector<string>::const_iterator i = to_delete.begin();
9606 i != to_delete.end();
9608 added_fns_.erase(*i);
9612 edit_script& e = vars_edit_script_;
9614 for (vector<deletion>::const_iterator it = e.deletions().begin();
9615 it != e.deletions().end();
9618 unsigned i = it->index();
9619 ABG_ASSERT(i < first_->get_variables().size());
9621 const var_decl* deleted_var = first_->get_variables()[i];
9622 string n = deleted_var->
get_id();
9624 ABG_ASSERT(deleted_vars_.find(n) == deleted_vars_.end());
9625 deleted_vars_[n] = deleted_var;
9628 for (vector<insertion>::const_iterator it = e.insertions().begin();
9629 it != e.insertions().end();
9632 for (vector<unsigned>::const_iterator iit =
9633 it->inserted_indexes().begin();
9634 iit != it->inserted_indexes().end();
9638 const var_decl* added_var = second_->get_variables()[i];
9639 string n = added_var->
get_id();
9642 string_var_ptr_map::const_iterator k = added_vars_.find(n);
9643 if ( k != added_vars_.end())
9650 string_var_ptr_map::const_iterator j =
9651 deleted_vars_.find(n);
9652 if (j != deleted_vars_.end())
9654 if (*j->second != *added_var)
9662 deleted_vars_.erase(j);
9665 added_vars_[n] = added_var;
9669 sorted_changed_vars_);
9675 vector<string> to_delete;
9676 for (string_var_ptr_map::const_iterator i = deleted_vars_.begin();
9677 i != deleted_vars_.end();
9679 if (second_->lookup_variable_symbol(*i->second->get_symbol()))
9680 to_delete.push_back(i->first);
9682 for (vector<string>::const_iterator i = to_delete.begin();
9683 i != to_delete.end();
9685 deleted_vars_.erase(*i);
9690 for (string_var_ptr_map::const_iterator i = added_vars_.begin();
9691 i != added_vars_.end();
9693 if (first_->lookup_variable_symbol(*i->second->get_symbol()))
9694 to_delete.push_back(i->first);
9695 else if (! i->second->get_symbol()->get_version().is_empty()
9696 && i->second->get_symbol()->get_version().is_default())
9704 if (first_->lookup_variable_symbol(i->second->get_symbol()->get_name(),
9706 to_delete.push_back(i->first);
9709 for (vector<string>::const_iterator i = to_delete.begin();
9710 i != to_delete.end();
9712 added_vars_.erase(*i);
9719 edit_script& e = unrefed_fn_syms_edit_script_;
9720 for (vector<deletion>::const_iterator it = e.deletions().begin();
9721 it != e.deletions().end();
9724 unsigned i = it->index();
9725 ABG_ASSERT(i < first_->get_unreferenced_function_symbols().size());
9727 first_->get_unreferenced_function_symbols()[i];
9728 if (!second_->lookup_function_symbol(*deleted_sym))
9729 deleted_unrefed_fn_syms_[deleted_sym->get_id_string()] = deleted_sym;
9732 for (vector<insertion>::const_iterator it = e.insertions().begin();
9733 it != e.insertions().end();
9736 for (vector<unsigned>::const_iterator iit =
9737 it->inserted_indexes().begin();
9738 iit != it->inserted_indexes().end();
9742 ABG_ASSERT(i < second_->get_unreferenced_function_symbols().size());
9744 second_->get_unreferenced_function_symbols()[i];
9745 if ((deleted_unrefed_fn_syms_.find(added_sym->get_id_string())
9746 == deleted_unrefed_fn_syms_.end()))
9748 if (!first_->lookup_function_symbol(*added_sym))
9751 if (! added_sym->get_version().is_empty()
9752 && added_sym->get_version().is_default())
9760 if (first_->lookup_function_symbol(added_sym->get_name(),
9766 added_unrefed_fn_syms_[added_sym->get_id_string()] =
9771 deleted_unrefed_fn_syms_.erase(added_sym->get_id_string());
9780 edit_script& e = unrefed_var_syms_edit_script_;
9781 for (vector<deletion>::const_iterator it = e.deletions().begin();
9782 it != e.deletions().end();
9785 unsigned i = it->index();
9786 ABG_ASSERT(i < first_->get_unreferenced_variable_symbols().size());
9788 first_->get_unreferenced_variable_symbols()[i];
9789 if (!second_->lookup_variable_symbol(*deleted_sym))
9790 deleted_unrefed_var_syms_[deleted_sym->get_id_string()] = deleted_sym;
9793 for (vector<insertion>::const_iterator it = e.insertions().begin();
9794 it != e.insertions().end();
9797 for (vector<unsigned>::const_iterator iit =
9798 it->inserted_indexes().begin();
9799 iit != it->inserted_indexes().end();
9803 ABG_ASSERT(i < second_->get_unreferenced_variable_symbols().size());
9805 second_->get_unreferenced_variable_symbols()[i];
9806 if (deleted_unrefed_var_syms_.find(added_sym->get_id_string())
9807 == deleted_unrefed_var_syms_.end())
9809 if (!first_->lookup_variable_symbol(*added_sym))
9812 if (! added_sym->get_version().is_empty()
9813 && added_sym->get_version().is_default())
9821 if (first_->lookup_variable_symbol(added_sym->get_name(),
9827 added_unrefed_var_syms_[added_sym->get_id_string()] =
9832 deleted_unrefed_var_syms_.erase(added_sym->get_id_string());
9839 edit_script& e = unreachable_types_edit_script_;
9843 for (vector<deletion>::const_iterator it = e.deletions().begin();
9844 it != e.deletions().end();
9847 unsigned i = it->index();
9849 (first_->get_types_not_reachable_from_public_interfaces()[i]);
9856 deleted_unreachable_types_[repr] = t;
9861 for (vector<insertion>::const_iterator it = e.insertions().begin();
9862 it != e.insertions().end();
9865 for (vector<unsigned>::const_iterator iit =
9866 it->inserted_indexes().begin();
9867 iit != it->inserted_indexes().end();
9872 (second_->get_types_not_reachable_from_public_interfaces()[i]);
9891 string_type_base_sptr_map::const_iterator j =
9892 deleted_unreachable_types_.find(repr);
9893 if (j != deleted_unreachable_types_.end())
9898 decl_base_sptr old_type =
is_decl(j->second);
9899 decl_base_sptr new_type =
is_decl(t);
9900 if (old_type != new_type)
9908 changed_unreachable_types_[repr]= d;
9914 deleted_unreachable_types_.erase(j);
9919 added_unreachable_types_[repr] = t;
9932 std::set<type_base_sptr> deleted_anon_types;
9933 std::set<type_base_sptr> added_anon_types;
9935 for (
auto entry : deleted_unreachable_types_)
9941 deleted_anon_types.insert(entry.second);
9945 for (
auto entry : added_unreachable_types_)
9950 added_anon_types.insert(entry.second);
9955 class_or_union_sptr deleted_class;
9960 for (
auto deleted: deleted_anon_types)
9969 for (
auto enr : deleted_enum->get_enumerators())
9971 bool this_enum_got_changed =
false;
9972 for (
auto t : added_anon_types)
9989 changed_unreachable_types_[repr]= d;
9990 this_enum_got_changed =
true;
9997 removed_anon_types_to_erase[r1] = deleted_enum;
9998 added_anon_types_to_erase[r2] = added_enum;
10002 if (this_enum_got_changed)
10006 else if (deleted_class)
10011 for (
auto dm : deleted_class->get_data_members())
10013 bool this_class_got_changed =
false;
10014 for (
auto klass : added_anon_types)
10016 if (class_or_union_sptr added_class =
10035 changed_unreachable_types_[repr]= d;
10036 this_class_got_changed =
true;
10043 removed_anon_types_to_erase[r1] = deleted_class;
10044 added_anon_types_to_erase[r2] = added_class;
10048 if (this_class_got_changed)
10057 for (
auto entry : added_anon_types_to_erase)
10058 added_unreachable_types_.erase(entry.first);
10060 for (
auto entry : removed_anon_types_to_erase)
10061 deleted_unreachable_types_.erase(entry.first);
10090 return fn_suppr->suppresses_function(fn, k, ctxt);
10109 variable_is_suppressed(
const var_decl* var,
10117 return var_suppr->suppresses_variable(var, k, ctxt);
10129 for (suppressions_type::const_iterator i = suppressions.begin();
10130 i != suppressions.end();
10137 for (string_function_ptr_map::const_iterator e = added_fns_.begin();
10138 e != added_fns_.end();
10140 if (function_is_suppressed(e->second, fn_suppr,
10143 suppressed_added_fns_[e->first] = e->second;
10146 for (string_function_ptr_map::const_iterator e = deleted_fns_.begin();
10147 e != deleted_fns_.end();
10149 if (function_is_suppressed(e->second, fn_suppr,
10152 suppressed_deleted_fns_[e->first] = e->second;
10155 for (string_elf_symbol_map::const_iterator e =
10156 added_unrefed_fn_syms_.begin();
10157 e != added_unrefed_fn_syms_.end();
10159 if (fn_suppr->suppresses_function_symbol(e->second,
10162 suppressed_added_unrefed_fn_syms_[e->first] = e->second;
10165 for (string_elf_symbol_map::const_iterator e =
10166 deleted_unrefed_fn_syms_.begin();
10167 e != deleted_unrefed_fn_syms_.end();
10169 if (fn_suppr->suppresses_function_symbol(e->second,
10172 suppressed_deleted_unrefed_fn_syms_[e->first] = e->second;
10180 for (string_function_ptr_map::const_iterator e = added_fns_.begin();
10181 e != added_fns_.end();
10190 if (type_suppr->suppresses_type(c, ctxt))
10191 suppressed_added_fns_[e->first] = e->second;
10194 for (string_function_ptr_map::const_iterator e = deleted_fns_.begin();
10195 e != deleted_fns_.end();
10204 if (type_suppr->suppresses_type(c, ctxt))
10205 suppressed_deleted_fns_[e->first] = e->second;
10210 for (string_type_base_sptr_map::const_iterator e =
10211 deleted_unreachable_types_.begin();
10212 e != deleted_unreachable_types_.end();
10214 if (type_suppr->suppresses_type(e->second, ctxt))
10215 suppressed_deleted_unreachable_types_[e->first] = e->second;
10219 for (string_type_base_sptr_map::const_iterator e =
10220 added_unreachable_types_.begin();
10221 e != added_unreachable_types_.end();
10223 if (type_suppr->suppresses_type(e->second, ctxt))
10224 suppressed_added_unreachable_types_[e->first] = e->second;
10231 for (string_var_ptr_map::const_iterator e = added_vars_.begin();
10232 e != added_vars_.end();
10234 if (variable_is_suppressed(e->second, var_suppr,
10237 suppressed_added_vars_[e->first] = e->second;
10240 for (string_var_ptr_map::const_iterator e = deleted_vars_.begin();
10241 e != deleted_vars_.end();
10243 if (variable_is_suppressed(e->second, var_suppr,
10246 suppressed_deleted_vars_[e->first] = e->second;
10249 for (string_elf_symbol_map::const_iterator e =
10250 added_unrefed_var_syms_.begin();
10251 e != added_unrefed_var_syms_.end();
10253 if (var_suppr->suppresses_variable_symbol(e->second,
10256 suppressed_added_unrefed_var_syms_[e->first] = e->second;
10259 for (string_elf_symbol_map::const_iterator e =
10260 deleted_unrefed_var_syms_.begin();
10261 e != deleted_unrefed_var_syms_.end();
10263 if (var_suppr->suppresses_variable_symbol(e->second,
10266 suppressed_deleted_unrefed_var_syms_[e->first] = e->second;
10284 string_function_ptr_map::const_iterator i =
10285 suppressed_deleted_fns_.find(fn->
get_id());
10287 return (i != suppressed_deleted_fns_.end());
10304 string_type_base_sptr_map::const_iterator i =
10305 suppressed_added_unreachable_types_.find(repr);
10306 if (i == suppressed_added_unreachable_types_.end())
10326 string_type_base_sptr_map::const_iterator i =
10327 suppressed_deleted_unreachable_types_.find(repr);
10328 if (i == suppressed_deleted_unreachable_types_.end())
10347 string_function_ptr_map::const_iterator i =
10348 suppressed_added_fns_.find(fn->
get_id());
10350 return (i != suppressed_added_fns_.end());
10366 string_var_ptr_map::const_iterator i =
10367 suppressed_deleted_vars_.find(var->
get_id());
10369 return (i != suppressed_deleted_vars_.end());
10385 string_var_ptr_map::const_iterator i =
10386 suppressed_added_vars_.find(var->
get_id());
10388 return (i != suppressed_added_vars_.end());
10404 string_elf_symbol_map::const_iterator i =
10405 suppressed_deleted_unrefed_fn_syms_.find(s->
get_id_string());
10407 return (i != suppressed_deleted_unrefed_fn_syms_.end());
10423 string_elf_symbol_map::const_iterator i =
10424 suppressed_added_unrefed_fn_syms_.find(s->
get_id_string());
10426 return (i != suppressed_added_unrefed_fn_syms_.end());
10442 string_elf_symbol_map::const_iterator i =
10443 suppressed_deleted_unrefed_var_syms_.find(s->
get_id_string());
10445 return (i != suppressed_deleted_unrefed_var_syms_.end());
10461 string_elf_symbol_map::const_iterator i =
10462 suppressed_added_unrefed_var_syms_.find(s->
get_id_string());
10464 return (i != suppressed_added_unrefed_var_syms_.end());
10467 #ifdef do_count_diff_map_changes
10468 #undef do_count_diff_map_changes
10470 #define do_count_diff_map_changes(diff_map, n_changes, n_filtered) \
10472 string_diff_ptr_map::const_iterator i; \
10473 for (i = diff_map.begin(); \
10474 i != diff_map.end(); \
10477 if (const var_diff* d = is_var_diff(i->second)) \
10478 if (is_data_member(d->first_var())) \
10481 if (i->second->has_local_changes()) \
10483 if (!i->second->get_canonical_diff()->to_be_reported()) \
10499 count_leaf_type_changes(num_changes, num_filtered);
10502 do_count_diff_map_changes(leaf_diffs_.get_function_decl_diff_map(),
10503 num_changes, num_filtered);
10504 do_count_diff_map_changes(leaf_diffs_.get_var_decl_diff_map(),
10505 num_changes, num_filtered);
10518 size_t &num_filtered)
10520 do_count_diff_map_changes(leaf_diffs_.get_type_decl_diff_map(),
10521 num_changes, num_filtered);
10522 do_count_diff_map_changes(leaf_diffs_.get_enum_diff_map(),
10523 num_changes, num_filtered);
10524 do_count_diff_map_changes(leaf_diffs_.get_class_diff_map(),
10525 num_changes, num_filtered);
10526 do_count_diff_map_changes(leaf_diffs_.get_union_diff_map(),
10527 num_changes, num_filtered);
10528 do_count_diff_map_changes(leaf_diffs_.get_typedef_diff_map(),
10529 num_changes, num_filtered);
10530 do_count_diff_map_changes(leaf_diffs_.get_subrange_diff_map(),
10531 num_changes, num_filtered);
10532 do_count_diff_map_changes(leaf_diffs_.get_array_diff_map(),
10533 num_changes, num_filtered);
10534 do_count_diff_map_changes(leaf_diffs_.get_distinct_diff_map(),
10535 num_changes, num_filtered);
10536 do_count_diff_map_changes(leaf_diffs_.get_fn_parm_diff_map(),
10537 num_changes, num_filtered);
10565 size_t &num_deleted,
10566 size_t &num_changed,
10567 size_t &num_filtered_added,
10568 size_t &num_filtered_deleted,
10569 size_t &num_filtered_changed)
10571 num_added = added_unreachable_types_.size();
10572 num_deleted = deleted_unreachable_types_.size();
10573 num_changed = changed_unreachable_types_.size();
10574 num_filtered_added = suppressed_added_unreachable_types_.size();
10575 num_filtered_deleted = suppressed_deleted_unreachable_types_.size();
10577 for (vector<diff_sptr>::const_iterator i =
10581 if (!(*i)->to_be_reported())
10582 ++num_filtered_changed;
10591 {
return changed_unreachable_types_;}
10602 const vector<diff_sptr>&
10605 if (changed_unreachable_types_sorted_.empty())
10606 if (!changed_unreachable_types_.empty())
10608 changed_unreachable_types_sorted_);
10610 return changed_unreachable_types_sorted_;
10645 if (ctxt->perform_change_categorization())
10647 if (get_context()->do_log())
10649 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10650 <<
"applying filters to "
10651 << changed_fns_.size()
10652 <<
" changed fns ...\n";
10658 for (function_decl_diff_sptrs_type::const_iterator i =
10659 changed_fns_.begin();
10660 i != changed_fns_.end();
10664 ctxt->maybe_apply_filters(diff);
10667 if (get_context()->
do_log())
10670 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10671 <<
"filters to changed fn applied!:" << t <<
"\n";
10673 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10674 <<
"applying filters to "
10675 << sorted_changed_vars_.size()
10676 <<
" changed vars ...\n";
10682 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
10683 i != sorted_changed_vars_.end();
10687 ctxt->maybe_apply_filters(diff);
10690 if (get_context()->
do_log())
10693 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10694 <<
"filters to changed vars applied!:" << t <<
"\n";
10696 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10697 <<
"applying filters to unreachable types ...\n";
10704 ctxt->maybe_apply_filters(diff);
10707 ctxt->maybe_apply_filters(entry.second);
10709 if (get_context()->
do_log())
10712 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10713 <<
"filters to unreachable types applied!:" << t <<
"\n";
10715 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10716 <<
"categorizing redundant changed sub nodes ...\n";
10720 categorize_redundant_changed_sub_nodes();
10722 if (get_context()->
do_log())
10725 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10726 <<
"redundant changed sub nodes categorized!:" << t <<
"\n";
10728 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10729 <<
"count changed fns ...\n";
10737 for (function_decl_diff_sptrs_type::const_iterator i =
10738 changed_fns_.begin();
10739 i != changed_fns_.end();
10742 if ((*i)->is_filtered_out())
10747 if ((*i)->has_local_changes())
10758 if ((*i)->has_local_changes())
10763 if (get_context()->do_log())
10766 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10767 <<
"changed fn counted!:" << t <<
"\n";
10769 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10770 <<
"count changed vars ...\n";
10776 for (var_diff_sptrs_type ::const_iterator i = sorted_changed_vars_.begin();
10777 i != sorted_changed_vars_.end();
10780 if ((*i)->is_filtered_out())
10785 if ((*i)->has_local_changes())
10789 if ((*i)->has_local_changes())
10794 if (get_context()->do_log())
10797 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10798 <<
"changed vars counted!:" << t <<
"\n";
10800 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10801 <<
"count leaf changed types ...\n";
10816 size_t num_type_changes = 0, num_type_filtered = 0;
10817 count_leaf_type_changes(num_type_changes, num_type_filtered);
10823 if (get_context()->
do_log())
10826 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10827 <<
"changed leaf types counted!:" << t <<
"\n";
10829 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10830 <<
"count leaf changed artefacts ...\n";
10836 size_t num_changes = 0, num_filtered = 0;
10837 count_leaf_changes(num_changes, num_filtered);
10843 if (get_context()->
do_log())
10846 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10847 <<
"changed leaf artefacts counted!:" << t <<
"\n";
10849 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10850 <<
"count unreachable types ...\n";
10856 size_t num_added_unreachable_types = 0,
10857 num_changed_unreachable_types = 0,
10858 num_deleted_unreachable_types = 0,
10859 num_added_unreachable_types_filtered = 0,
10860 num_changed_unreachable_types_filtered = 0,
10861 num_deleted_unreachable_types_filtered = 0;
10863 count_unreachable_types(num_added_unreachable_types,
10864 num_deleted_unreachable_types,
10865 num_changed_unreachable_types,
10866 num_added_unreachable_types_filtered,
10867 num_deleted_unreachable_types_filtered,
10868 num_changed_unreachable_types_filtered);
10870 if (get_context()->
do_log())
10873 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10874 <<
"unreachable types counted!:" << t <<
"\n";
10881 (num_added_unreachable_types_filtered);
10883 (num_deleted_unreachable_types_filtered);
10885 (num_changed_unreachable_types_filtered);
10901 const string& indent)
10904 size_t net_num_leaf_changes =
10917 if (!sonames_equal_)
10918 out << indent <<
"ELF SONAME changed\n";
10920 if (!architectures_equal_)
10921 out << indent <<
"ELF architecture changed\n";
10925 if (ctxt->show_leaf_changes_only())
10927 out <<
"Leaf changes summary: ";
10928 out << net_num_leaf_changes <<
" artifact";
10929 if (net_num_leaf_changes > 1)
10934 out <<
" (" << num_filtered <<
" filtered out)";
10937 out << indent <<
"Changed leaf types summary: "
10941 <<
" filtered out)";
10942 out <<
" leaf type";
10945 out <<
" changed\n";
10948 out << indent <<
"Removed/Changed/Added functions summary: ";
10953 <<
" filtered out)";
10960 <<
" filtered out)";
10967 out <<
"functions";
10973 out << indent <<
"Removed/Changed/Added variables summary: ";
10977 <<
" filtered out)";
10984 <<
" filtered out)";
10991 out <<
"variables";
10994 <<
" filtered out)";
11003 out << indent <<
"Functions changes summary: ";
11008 <<
" filtered out)";
11019 if (total_nb_function_changes <= 1)
11020 out <<
" function";
11022 out <<
" functions";
11029 out << indent <<
"Variables changes summary: ";
11033 <<
" filtered out)";
11044 <<
" filtered out)";
11045 if (total_nb_variable_changes <= 1)
11046 out <<
" variable";
11048 out <<
" variables";
11054 if (ctxt->show_unreachable_types())
11056 size_t total_nb_unreachable_type_changes =
11062 out << indent <<
"Unreachable types summary: "
11067 <<
" filtered out)";
11074 <<
" filtered out)";
11081 <<
" filtered out)";
11082 if (total_nb_unreachable_type_changes <= 1)
11089 if (ctxt->show_symbols_unreferenced_by_debug_info()
11097 if (!ctxt->show_added_symbols_unreferenced_by_debug_info()
11107 <<
"Function symbols changes summary: "
11111 <<
" filtered out)";
11116 <<
" filtered out)";
11117 out <<
" function symbol";
11120 out <<
" not referenced by debug info\n";
11125 if (!ctxt->show_added_symbols_unreferenced_by_debug_info()
11135 <<
"Variable symbols changes summary: "
11139 <<
" filtered out)";
11144 <<
" filtered out)";
11145 out <<
" variable symbol";
11148 out <<
" not referenced by debug info\n";
11162 ctxt->forget_visited_diffs();
11163 for (function_decl_diff_sptrs_type::const_iterator i =
11164 changed_fns_.begin();
11165 i!= changed_fns_.end();
11172 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
11173 i!= sorted_changed_vars_.end();
11180 for (diff_sptrs_type::const_iterator i =
11196 for (function_decl_diff_sptrs_type::const_iterator i = changed_fns_.begin();
11197 i!= changed_fns_.end();
11204 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
11205 i!= sorted_changed_vars_.end();
11223 if (!ctxt->dump_diff_tree()
11224 || ctxt->error_output_stream() == 0)
11227 if (!changed_fns_.empty())
11229 *ctxt->error_output_stream() <<
"changed functions diff tree: \n\n";
11230 for (function_decl_diff_sptrs_type::const_iterator i =
11231 changed_fns_.begin();
11232 i != changed_fns_.end();
11240 if (!sorted_changed_vars_.empty())
11242 *ctxt->error_output_stream() <<
"\nchanged variables diff tree: \n\n";
11243 for (var_diff_sptrs_type::const_iterator i =
11244 sorted_changed_vars_.begin();
11245 i != sorted_changed_vars_.end();
11255 *ctxt->error_output_stream() <<
"\nchanged unreachable "
11256 "types diff tree: \n\n";
11257 for (vector<diff_sptr>::const_iterator i =
11275 for (function_decl_diff_sptrs_type::const_iterator i =
11294 corpus_sptr second,
11296 : priv_(new
priv(first, second, ctxt))
11299 corpus_diff::~corpus_diff() =
default;
11305 if (priv_->finished_)
11308 priv_->finished_ =
true;
11316 {
return context()->do_log();}
11328 {
return priv_->first_;}
11333 {
return priv_->second_;}
11336 const vector<diff*>&
11338 {
return priv_->children_;}
11356 bool inserted =
false;
11357 for (vector<diff*>::iterator i = priv_->children_.begin();
11358 i != priv_->children_.end();
11363 context()->keep_diff_alive(d);
11364 priv_->children_.insert(i, d.get());
11373 context()->keep_diff_alive(d);
11377 priv_->children_.push_back(d.get());
11385 {
return priv_->fns_edit_script_;}
11391 {
return priv_->vars_edit_script_;}
11398 {
return !priv_->sonames_equal_;}
11405 {
return !priv_->architectures_equal_;}
11412 {
return priv_->deleted_fns_;}
11419 {
return priv_->added_fns_;}
11431 {
return priv_->changed_fns_map_;}
11440 {
return priv_->changed_fns_;}
11448 {
return priv_->deleted_vars_;}
11455 {
return priv_->added_vars_;}
11463 {
return priv_->changed_vars_map_;}
11471 {
return priv_->sorted_changed_vars_;}
11480 {
return priv_->deleted_unrefed_fn_syms_;}
11489 {
return priv_->added_unrefed_fn_syms_;}
11498 {
return priv_->deleted_unrefed_var_syms_;}
11507 {
return priv_->added_unrefed_var_syms_;}
11516 {
return priv_->deleted_unreachable_types_;}
11524 const vector<type_base_sptr>&
11527 if (priv_->deleted_unreachable_types_sorted_.empty())
11528 if (!priv_->deleted_unreachable_types_.empty())
11530 priv_->deleted_unreachable_types_sorted_);
11532 return priv_->deleted_unreachable_types_sorted_;
11542 {
return priv_->added_unreachable_types_;}
11550 const vector<type_base_sptr>&
11553 if (priv_->added_unreachable_types_sorted_.empty())
11554 if (!priv_->added_unreachable_types_.empty())
11556 priv_->added_unreachable_types_sorted_);
11558 return priv_->added_unreachable_types_sorted_;
11568 {
return priv_->changed_unreachable_types_;}
11576 const vector<diff_sptr>&
11578 {
return priv_->changed_unreachable_types_sorted();}
11585 {
return priv_->get_context();}
11592 if (priv_->pretty_representation_.empty())
11594 std::ostringstream o;
11595 o <<
"corpus_diff["
11600 priv_->pretty_representation_ = o.str();
11602 return priv_->pretty_representation_;
11613 || !(priv_->deleted_fns_.empty()
11614 && priv_->added_fns_.empty()
11615 && priv_->changed_fns_map_.empty()
11616 && priv_->deleted_vars_.empty()
11617 && priv_->added_vars_.empty()
11618 && priv_->changed_vars_map_.empty()
11619 && priv_->added_unrefed_fn_syms_.empty()
11620 && priv_->deleted_unrefed_fn_syms_.empty()
11621 && priv_->added_unrefed_var_syms_.empty()
11622 && priv_->deleted_unrefed_var_syms_.empty()
11623 && priv_->deleted_unreachable_types_.empty()
11624 && priv_->added_unreachable_types_.empty()
11625 && priv_->changed_unreachable_types_.empty()));
11673 if (!has_incompatible_changes
11680 for (
auto &entry : priv_->changed_unreachable_types())
11688 has_incompatible_changes |=
true;
11724 {
return context()->get_reporter()->diff_has_net_changes(
this);}
11749 if (priv_->diff_stats_)
11750 return *priv_->diff_stats_;
11755 std::cerr <<
"Applying suppressions ...\n";
11764 std::cerr <<
"suppressions applied!:" << t <<
"\n";
11771 std::cerr <<
"Marking leaf nodes ...\n";
11780 std::cerr <<
"leaf nodes marked!:" << t <<
"\n";
11781 std::cerr <<
"Applying filters and computing diff stats ...\n";
11785 priv_->apply_filters_and_compute_diff_stats(*priv_->diff_stats_);
11790 std::cerr <<
"Filters applied and diff stats computed!: " << t <<
"\n";
11793 return *priv_->diff_stats_;
11815 visit_begin(
diff *d)
11860 const corpus_diff *corpus_diff_node = ctxt->get_corpus_diff().get();
11863 if (
diff *iface_diff = get_current_topmost_iface_diff())
11870 get_leaf_diffs().insert_diff_node(d, iface);
11888 if (!
context()->show_leaf_changes_only())
11891 leaf_diff_node_marker_visitor v;
11892 context()->forget_visited_diffs();
11893 bool s =
context()->visiting_a_node_twice_is_forbidden();
11894 context()->forbid_visiting_a_node_twice(
true);
11895 if (
context()->show_impacted_interfaces())
11896 context()->forbid_visiting_a_node_twice_per_interface(
true);
11898 context()->forbid_visiting_a_node_twice(s);
11899 context()->forbid_visiting_a_node_twice_per_interface(
false);
11909 {
return priv_->leaf_diffs_;}
11918 {
return priv_->leaf_diffs_;}
11929 context()->get_reporter()->report(*
this, out, indent);
11944 if (!v.
visit(
this,
true))
11950 for (function_decl_diff_sptrs_type::const_iterator i =
11958 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
11959 ctxt->forget_visited_diffs();
11972 for (var_diff_sptrs_type::const_iterator i =
11980 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
11981 ctxt->forget_visited_diffs();
11998 for (vector<diff_sptr>::const_iterator i =
12006 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
12007 ctxt->forget_visited_diffs();
12035 const corpus_sptr s,
12038 typedef corpus::functions::const_iterator fns_it_type;
12039 typedef corpus::variables::const_iterator vars_it_type;
12040 typedef elf_symbols::const_iterator symbols_it_type;
12042 typedef vector<type_base_wptr>::const_iterator type_base_wptr_it_type;
12051 ctxt->set_corpus_diff(r);
12053 if(ctxt->show_soname_change())
12054 r->priv_->sonames_equal_ = f->get_soname() == s->get_soname();
12056 r->priv_->sonames_equal_ =
true;
12058 r->priv_->architectures_equal_ =
12059 f->get_architecture_name() == s->get_architecture_name();
12062 diff_utils::compute_diff<fns_it_type, eq_type>(f->get_functions().begin(),
12063 f->get_functions().end(),
12064 s->get_functions().begin(),
12065 s->get_functions().end(),
12066 r->priv_->fns_edit_script_);
12069 diff_utils::compute_diff<vars_it_type, eq_type>
12070 (f->get_variables().begin(), f->get_variables().end(),
12071 s->get_variables().begin(), s->get_variables().end(),
12072 r->priv_->vars_edit_script_);
12076 diff_utils::compute_diff<symbols_it_type, eq_type>
12077 (f->get_unreferenced_function_symbols().begin(),
12078 f->get_unreferenced_function_symbols().end(),
12079 s->get_unreferenced_function_symbols().begin(),
12080 s->get_unreferenced_function_symbols().end(),
12081 r->priv_->unrefed_fn_syms_edit_script_);
12085 diff_utils::compute_diff<symbols_it_type, eq_type>
12086 (f->get_unreferenced_variable_symbols().begin(),
12087 f->get_unreferenced_variable_symbols().end(),
12088 s->get_unreferenced_variable_symbols().begin(),
12089 s->get_unreferenced_variable_symbols().end(),
12090 r->priv_->unrefed_var_syms_edit_script_);
12092 if (ctxt->show_unreachable_types())
12095 diff_utils::compute_diff<type_base_wptr_it_type, eq_type>
12096 (f->get_types_not_reachable_from_public_interfaces().begin(),
12097 f->get_types_not_reachable_from_public_interfaces().end(),
12098 s->get_types_not_reachable_from_public_interfaces().begin(),
12099 s->get_types_not_reachable_from_public_interfaces().end(),
12100 r->priv_->unreachable_types_edit_script_);
12102 r->priv_->ensure_lookup_tables_populated();
12123 const corpus_group_sptr& s,
12127 corpus_sptr c1 = f;
12128 corpus_sptr c2 = s;
12139 struct diff_node_visitor::priv
12141 diff* topmost_interface_diff;
12145 : topmost_interface_diff(),
12150 : topmost_interface_diff(),
12160 diff_node_visitor::~diff_node_visitor() =
default;
12166 : priv_(new priv(k))
12176 {
return priv_->kind;}
12196 {priv_->kind = priv_->kind | v;}
12204 {priv_->topmost_interface_diff = d;}
12212 {
return priv_->topmost_interface_diff;}
12439 bool already_visited = d->
context()->diff_has_been_visited(d);
12447 bool update_canonical = !already_visited && canonical;
12449 for (vector<diff*>::const_iterator i = d->
children_nodes().begin();
12482 if (!already_visited && canonical)
12483 if (update_canonical)
12484 canonical->add_to_category(c);
12498 category_propagation_visitor v;
12499 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12500 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
12501 diff_tree->
context()->forget_visited_diffs();
12503 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12525 category_propagation_visitor v;
12526 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12527 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
12529 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12554 visit_begin(diff* d)
12556 bool is_private_type =
false;
12567 if (canonical_diff != d)
12623 bool has_non_suppressed_child =
false;
12624 bool has_non_empty_child =
false;
12625 bool has_suppressed_child =
false;
12626 bool has_non_private_child =
false;
12627 bool has_private_child =
false;
12628 bool has_descendant_with_allowed_change =
false;
12661 && (!d->has_local_changes()
12686 for (vector<diff*>::const_iterator i = d->children_nodes().begin();
12687 i != d->children_nodes().end();
12691 if (child->has_changes())
12693 has_non_empty_child =
true;
12695 has_suppressed_child =
true;
12696 else if (child->get_class_of_equiv_category()
12702 has_non_suppressed_child =
true;
12704 if (child->get_class_of_equiv_category()
12706 has_private_child =
true;
12707 else if (child->get_class_of_equiv_category()
12713 has_non_private_child =
true;
12717 if (has_non_empty_child
12718 && has_suppressed_child
12719 && !has_non_suppressed_child)
12725 if (canonical_diff != d)
12741 if (has_non_empty_child
12742 && has_private_child
12743 && !has_non_private_child)
12749 if (canonical_diff != d)
12759 && has_private_child
12760 && has_non_empty_child)
12766 if (canonical_diff != d)
12783 if (fn_type_diff->is_suppressed())
12789 if (canonical_diff != d)
12798 for (
auto child_node : d->children_nodes())
12804 has_descendant_with_allowed_change =
true;
12806 if (has_descendant_with_allowed_change)
12809 d->add_to_category(c);
12810 d->get_canonical_diff()->add_to_category(c);
12824 if (diff_tree && !diff_tree->
context()->suppressions().empty())
12828 suppression_categorization_visitor v;
12829 diff_tree->
context()->forget_visited_diffs();
12830 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12831 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
12833 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12856 if (diff_tree && !diff_tree->
context()->suppressions().empty())
12861 suppression_categorization_visitor v;
12862 diff_tree->
context()->forget_visited_diffs();
12863 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12864 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
12865 const_cast<corpus_diff*
>(diff_tree)->traverse(v);
12866 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12872 apply_supprs_to_added_removed_fns_vars_unreachable_types();
12902 do_indent(
unsigned level)
12904 for (
unsigned i = 0; i < level; ++i)
12908 diff_node_printer(ostream& out)
12927 visit_begin(corpus_diff*)
12933 visit_end(corpus_diff*)
12939 visit(diff* d,
bool pre)
12948 out_ << d->get_pretty_representation();
12952 do_indent(level_ + 1);
12953 out_ <<
"category: "<< d->get_category() <<
"\n";
12954 do_indent(level_ + 1);
12955 out_ <<
"@: " << std::hex << d << std::dec <<
"\n";
12956 do_indent(level_ + 1);
12957 out_ <<
"@-canonical: " << std::hex
12958 << d->get_canonical_diff()
12959 << std::dec <<
"\n";
12967 visit(corpus_diff* d,
bool pre)
12976 for (
unsigned i = 0; i < level_; ++i)
12978 out_ << d->get_pretty_representation();
12997 diff_node_printer p(out);
12998 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12999 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13001 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13015 diff_node_printer p(out);
13016 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13017 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13019 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13058 bool skip_children_nodes_;
13060 redundancy_marking_visitor()
13061 : skip_children_nodes_()
13065 visit_begin(diff* d)
13067 if (d->to_be_reported())
13073 if ((d->context()->diff_has_been_visited(d)
13074 || d->get_canonical_diff()->is_traversing())
13075 && d->has_changes())
13090 bool redundant_with_sibling_node =
false;
13095 if (p && dynamic_cast<const fn_parm_diff*>(p))
13099 for (vector<diff*>::const_iterator s =
13100 p->children_nodes().begin();
13101 s != p->children_nodes().end();
13109 if (fn_parm_diff* f = dynamic_cast<fn_parm_diff*>(*s))
13110 sib = f->type_diff().get();
13113 if (sib->get_canonical_diff() == d->get_canonical_diff()
13118 redundant_with_sibling_node =
true;
13122 if (!redundant_with_sibling_node
13143 && (!d->get_canonical_diff()->is_filtered_out()
13144 || (d->get_canonical_diff()->get_category()
13151 && d->context()->diff_has_been_visited(d) != d
13173 skip_children_nodes_ =
true;
13181 skip_children_nodes_ =
true;
13186 visit_begin(corpus_diff*)
13193 if (skip_children_nodes_)
13200 skip_children_nodes_ =
false;
13208 && (!d->has_local_changes_to_be_reported()
13234 && (!(d->has_local_changes()
13245 && (!(d->has_local_changes()
13252 && (!(d->has_local_changes()
13256 bool has_non_redundant_child =
false;
13257 bool has_non_empty_child =
false;
13258 for (vector<diff*>::const_iterator i =
13259 d->children_nodes().begin();
13260 i != d->children_nodes().end();
13263 if ((*i)->has_changes())
13265 has_non_empty_child =
true;
13272 if ((*i)->to_be_reported()
13274 has_non_redundant_child =
true;
13276 if (has_non_redundant_child)
13283 if (has_non_empty_child
13284 && !has_non_redundant_child)
13291 visit_end(corpus_diff*)
13300 visit(corpus_diff*,
bool)
13308 struct redundancy_clearing_visitor :
public diff_node_visitor
13311 visit(corpus_diff*,
bool)
13315 visit(diff* d,
bool)
13320 d->set_category(c);
13332 if (diff_tree->
context()->show_redundant_changes())
13334 redundancy_marking_visitor v;
13335 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13336 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13338 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13356 redundancy_marking_visitor v;
13357 diff_tree->
context()->forget_visited_diffs();
13358 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13359 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13361 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13381 redundancy_clearing_visitor v;
13382 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13383 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13385 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13386 diff_tree->
context()->forget_visited_diffs();
13404 redundancy_clearing_visitor v;
13405 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13406 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13408 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13409 diff_tree->
context()->forget_visited_diffs();
13430 diff_tree->context()->maybe_apply_filters(diff_tree);
13448 if (t && t->get_environment().is_variadic_parameter_type(t))
13452 if (t && t->get_environment().is_variadic_parameter_type(t))
13517 if (allow_indirect_type)
13718 has_local_type_change_only(
const diff *d)
13745 else if (
const var_diff * v = dynamic_cast<const var_diff*>(d))
13746 return (has_local_type_change_only(v)
13748 else if (
const fn_parm_diff * p = dynamic_cast<const fn_parm_diff*>(d))
13749 return (has_local_type_change_only(p)
13752 dynamic_cast<const function_decl_diff*>(d))
13753 return (has_local_type_change_only(f)
bool show_deleted_vars() const
Testing (anding) against this mask means that a given IR artifact has local differences, with respect to the other artifact it was compared against. A local change is a change that is carried by the artifact itself (or its type), rather than by one off its sub-types.
qualified_type_diff(qualified_type_def_sptr first, qualified_type_def_sptr second, diff_sptr underling, diff_context_sptr ctxt=diff_context_sptr())
Constructor for qualified_type_diff.
void set_allowed_category(diff_category c)
Setter for the bitmap that represents the set of categories that the user wants to see reported...
bool is_filtered_out_without_looking_at_allowed_changes() const
Test if this diff tree node is to be filtered out for reporting purposes, but without considering the...
bool is_child_node_of_function_parm_diff(const diff *diff)
Test if a diff node is a child node of a function parameter diff node.
vector< diff * > diff_ptrs_type
Convenience typedef for a vector of diff*.
const string_diff_ptr_map & get_class_diff_map() const
Getter of the map that contains class type diffs.
std::pair< var_decl_sptr, var_decl_sptr > changed_var_sptr
Convenience typedef for a pair of var_decl_sptr representing a var_decl change. The first member of t...
const string_var_ptr_map & added_variables() const
Getter for the added variables of the diff.
void set_reporter(reporter_base_sptr &)
Setter of the reporter to be used in this context.
size_t net_num_added_unreachable_types() const
Getter of the number of added types that are unreachable from public interfaces and that are *NOT* fi...
A comparison function for instances of base_diff.
const diff * peel_typedef_qualified_type_or_parameter_diff(const diff *dif)
If a diff node is about changes between two typedefs or qualified types, get the diff node about chan...
const string_decl_base_sptr_map & inserted_data_members() const
Getter for the data members that got inserted.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool show_offsets_sizes_in_bits() const
Get the flag that indicates if diff reports using this context should show sizes and offsets in bits...
The abstraction of an array type.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
bool has_parent_allowed_by_specific_negated_suppression() const
Test if the current diff node has a parent node which is specifically allowed by a negated suppressio...
This means the diff node (or at least one of its descendant nodes) carries a change involving two com...
void sort_enumerators(const string_enumerator_map &enumerators_map, enum_type_decl::enumerators &sorted)
Sort a map of enumerators by their value.
shared_ptr< function_type_diff > function_type_diff_sptr
A convenience typedef for a shared pointer to function_type_type_diff.
bool show_added_fns() const
size_t net_num_leaf_var_changes() const
Getter for the net number of leaf variable change diff nodes.
The base type of all declarations.
size_t num_leaf_var_changes_filtered_out() const
Getter for the number of leaf variable changes diff nodes that have been filtered out...
A comparison functor for instances of diff.
virtual void report(ostream &, const string &indent="") const
Report the differences between the two enums.
type_suppression_sptr is_type_suppression(suppression_sptr suppr)
Test if an instance of suppression is an instance of type_suppression.
const string_diff_sptr_map & changed_unreachable_types() const
Getter for a map of changed types that are not reachable from global functions/variables.
const string_member_function_sptr_map & deleted_member_fns() const
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 void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of subrange_di...
function_suppression_sptr is_function_suppression(const suppression_sptr suppr)
Test if an instance of suppression is an instance of function_suppression.
vector< function_decl_diff_sptr > function_decl_diff_sptrs_type
Convenience typedef for a vector of function_decl_diff_sptr.
The private data of the ptr_to_mbr_diff type.
size_t num_changed_unreachable_types_filtered_out() const
Getter of the number of changed types that are unreachable from public interfaces and that have been ...
distinct_diff(type_or_decl_base_sptr first, type_or_decl_base_sptr second, diff_context_sptr ctxt=diff_context_sptr())
Constructor for distinct_diff.
A "Less Than" functor to compare instance of function_decl_diff.
diff_category remove_from_category(diff_category c)
Remove the current diff tree node from an a existing sef of categories. The categories include those ...
void sort_string_member_function_sptr_map(const string_member_function_sptr_map &map, class_or_union::member_functions &sorted)
Sort a map that's an instance of string_member_function_sptr_map and fill a vector of member function...
size_t num_leaf_type_changes_filtered_out() const
Getter for the number of filtered out leaf type change diff nodes.
The abstraction of a change between two ABI artifacts, a.k.a an artifact change.
const pointer_diff * is_pointer_diff(const diff *diff)
Test if a diff node is about differences between two pointers.
virtual ~class_or_union_diff()
Destructor of class_or_union_diff.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of class_or_un...
const edit_script & member_fn_tmpls_changes() const
const string_diff_ptr_map & get_function_decl_diff_map() const
Getter of the map that contains function decl diffs.
const edit_script & member_fns_changes() const
Abstraction of a diff between two qualified types.
virtual enum change_kind has_local_changes() const
size_t net_num_func_removed() const
Getter for the net number of function removed.
virtual enum change_kind has_local_changes() const
shared_ptr< class_diff > class_diff_sptr
Convenience typedef for a shared pointer on a class_diff type.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of enum_diff...
const changed_var_sptrs_type & ordered_data_members_replaced_by_adms() const
Get an ordered vector of of data members that got replaced by anonymous data members.
size_t net_num_vars_changed() const
Getter for the number of variables that have a change in their sub-types, minus the number of these v...
vector< var_diff_sptr > var_diff_sptrs_type
Convenience typedef for a vector of var_diff_sptr.
const edit_script & base_changes() const
class_decl_sptr second_class_decl() const
Getter of the second class involved in the diff.
shared_ptr< typedef_diff > typedef_diff_sptr
Convenience typedef for a shared pointer on a typedef_diff type.
const string_parm_map & removed_parms() const
Getter for the map of parameters that got removed.
const function_decl_sptr first_function_decl() const
const string_diff_ptr_map & get_function_type_diff_map() const
Getter of the map that contains function type diffs.
const vector< diff * > & children_nodes() const
Getter for the children nodes of the current diff node.
const diff_sptrs_type & changed_decls() const
virtual void report(ostream &out, const string &indent="") const
Report the diff in a serialized form.
size_t net_num_changed_unreachable_types() const
Getter of the number of changed types that are unreachable from public interfaces and that have *NOT*...
The internal type for the impl idiom implementation of pointer_diff.
bool added_function_is_suppressed(const function_decl *fn) const
Test if the change reports for a give given added function has been deleted.
const string_var_ptr_map & deleted_variables() const
Getter for the variables that got deleted from the first subject of the diff.
const string_fn_parm_diff_sptr_map & subtype_changed_parms() const
Getter for the map of function parameter changes of the current diff.
virtual bool has_changes() const
Return true iff the diff node has a change.
bool has_net_subtype_changes() const
Test if the current instance of corpus_diff carries subtype changes whose reports are not suppressed ...
diff_sptr underlying_type_diff() const
Getter for the diff between the underlying types of the two qualified types.
shared_ptr< pointer_diff > pointer_diff_sptr
Convenience typedef for a shared pointer on a pointer_diff type.
virtual void report(ostream &, const string &indent="") const
Produce a basic report about the changes between two class_decl.
virtual const string & get_pretty_representation() const
Build and return a textual representation of the current instance of fn_parm_diff.
var_decl_sptr first_var() const
Getter for the first var_decl of the diff.
shared_ptr< suppression_base > suppression_sptr
Convenience typedef for a shared pointer to a suppression.
const edit_script & data_members_changes() const
void finish_diff_type()
Finish building the current instance of corpus_diff.
size_t num_func_with_virtual_offset_changes() const
Getter for the number of functions that carry virtual member offset changes.
diff_category add_to_category(diff_category c)
Adds the current diff tree node to an additional set of categories. Note that the categories include ...
bool deleted_function_is_suppressed(const function_decl *fn) const
Test if the change reports for a given deleted function have been deleted.
An abstractions of the changes between two scopes.
diff_category get_local_category() const
Getter for the local category of the current diff tree node.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
An abstraction of a diff between entities that are of a different kind (disctinct).
diff_context_sptr get_context()
Getter of the context associated with this corpus.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of pointer_dif...
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of qualified_t...
bool has_incompatible_changes() const
Test if the current instance of corpus_diff carries changes that we are sure are incompatible. By incompatible change we mean a change that "breaks" the ABI of the corpus we are looking at.
const qualified_type_diff * is_qualified_type_diff(const diff *diff)
Test if a diff node is about differences between two qualified types.
bool class_or_union_types_of_same_kind(const class_or_union *first, const class_or_union *second)
Test if two class or union types are of the same kind.
const corpus_diff * is_corpus_diff(const diff *diff)
Test if a diff node is a corpus_diff node.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
Getter the pretty representation of the subrange_diff diff node.
interned_string get_id() const
Return an ID that tries to uniquely identify the function inside a program or a library.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
bool deleted_variable_is_suppressed(const var_decl *var) const
Test if the change reports for a give given deleted variable has been deleted.
bool show_impacted_interfaces() const
Getter of the flag that indicates if the leaf reporter should display a summary of the interfaces imp...
void sort_string_var_diff_sptr_map(const string_var_diff_sptr_map &map, var_diff_sptrs_type &sorted)
Sort of an instance of string_var_diff_sptr_map map.
virtual void visit_begin(diff *)
This is called by the traversing code on a diff node just before visiting it. That is...
void append_child_node(diff_sptr)
Add a new child node to the vector of children nodes for the current diff node.
vector< changed_var_sptr > changed_var_sptrs_type
Convenience typedef for a vector of .gg381.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
scope_diff(scope_decl_sptr first_scope, scope_decl_sptr second_scope, diff_context_sptr ctxt=diff_context_sptr())
Constructor for scope_diff.
void mark_diff_as_visited(const diff *)
Mark a diff node as traversed by a traversing algorithm.
diff_sptr try_to_diff< class_decl >(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second, diff_context_sptr ctxt)
This is a specialization of try_to_diff() template to diff instances of class_decl.
An abstraction helper for type declarations.
A diff node in this category is a function (or function type) with at least one parameter added or re...
A functor to compare instances of elf_symbol base on their names.
This means the diff node (or at least one of its descendant nodes) carries a change that modifies the...
const qualified_type_def_sptr first_qualified_type() const
Getter for the first qualified type of the diff.
size_t num_leaf_changes_filtered_out() const
Getter of the number of leaf type change diff nodes that have been filtered out.
bool do_log() const
Test if logging was requested.
size_t count_filtered_subtype_changed_data_members(bool local_only=false) const
Count the number of /filtered/ data members with a sub-type change.
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
The base class of both types and declarations.
bool insert_diff_node(const diff *d, const type_or_decl_base_sptr &impacted_iface)
Insert a new diff node into the current instance of diff_maps.
const string_var_diff_sptr_map & changed_variables()
Getter for the non-sorted map of variables which signature didn't change but which do have some indir...
A declaration that introduces a scope.
virtual void chain_into_hierarchy()
This constructs the relation between this diff node and its detail diff nodes, in the generic view of...
bool is_negated_suppression(const suppression_base &s)
Test if a suppression specification is a negated suppression.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
bool is_reference_or_ptr_diff_to_non_basic_nor_distinct_types(const diff *diff)
Test if a diff node is a reference or pointer diff node to a change that is neither basic type change...
var_decl_sptr find_data_member_from_anonymous_data_member(const var_decl_sptr &anon_dm, const string &name)
Find a data member inside an anonymous data member.
const function_decl::parameter_sptr second_parameter() const
Getter for the second subject of this diff node.
bool show_deleted_fns() const
edit_script & function_changes() const
Abstracts a reference type.
This type abstracts changes for a class_decl.
void clear_redundancy_categorization(diff *diff_tree)
Walk a given diff sub-tree to clear the REDUNDANT_CATEGORY out of the category of the nodes...
const array_type_def_sptr second_array() const
Getter for the second array of the diff.
size_t num_removed_var_syms_filtered_out() const
Getter for the number of removed variable symbols, not referenced by any debug info, that have been filtered out.
const function_type_diff * is_function_type_diff_with_local_changes(const diff *diff)
Test if a given diff node carries a function type change with local changes.
The abstraction of a qualified type.
This means that a diff node was marked as suppressed by a user-provided suppression specification...
void sort_string_data_member_diff_sptr_map(const string_var_diff_sptr_map &map, var_diff_sptrs_type &sorted)
Sort the values of a string_var_diff_sptr_map and store the result in a vector of var_diff_sptr...
size_t count_filtered_changed_dm(bool local_only=false)
Get the number of data member changes carried by the current diff node that were filtered out...
const typedef_decl_sptr first_typedef_decl() const
Getter for the firt typedef_decl involved in the diff.
type_or_decl_base_sptr first_subject() const
Getter of the first subject of the diff.
This means the diff node does not carry any (meaningful) change, or that it carries changes that have...
bool show_added_symbols_unreferenced_by_debug_info() const
Getter for the flag that indicates if symbols not referenced by any debug info and that got added are...
const diff * parent_node() const
Getter for the parent node of the current diff node.
const base_diff * is_base_diff(const diff *diff)
Test if a diff node is about differences between two base class specifiers.
Abstraction of a base specifier in a class declaration.
diff_sptr get_canonical_diff_for(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second) const
Getter for the canonical diff node for the diff represented by their two subjects.
const diff_stats & apply_filters_and_suppressions_before_reporting()
Apply the different filters that are registered to be applied to the diff tree; that includes the cat...
size_t net_num_vars_added() const
Getter for the net number of added variables.
const suppr::suppressions_type & suppressions() const
Getter for the vector of suppressions that specify which diff node reports should be dropped on the f...
size_t num_removed_unreachable_types() const
Getter of the number of removed types that are unreachable from the public interface of the ABI corpu...
unordered_map< string, const var_decl * > string_var_ptr_map
Convenience typedef for a map which key is a string and which value is a point to var_decl...
virtual const string & get_pretty_representation() const
Get the pretty representation of the current ptr_to_mbr_diff node.
bool is_filtered_out_wrt_non_inherited_categories() const
Test if this diff tree node is to be filtered out for reporting purposes, but by considering only the...
void forbid_visiting_a_node_twice_per_interface(bool)
This function sets a flag os that if forbid_visiting_a_node_twice() returns true, then each time the ...
unordered_map< string, class_decl::base_spec_sptr > string_base_sptr_map
Convenience typedef for a map of string and class_decl::basse_spec_sptr.
shared_ptr< diff_context > diff_context_sptr
Convenience typedef for a shared pointer of diff_context.
const corpus_diff_sptr & get_corpus_diff() const
Get the corpus diff for the current context.
Abstraction of a diff between two typedef_decl.
const scope_decl_sptr first_scope() const
Getter for the first scope of the diff.
virtual enum change_kind has_local_changes() const
diff_node_visitor()
Default constructor of the diff_node_visitor type.
bool deleted_unrefed_fn_sym_is_suppressed(const elf_symbol *) const
Test if the change reports for a given deleted function symbol (that is not referenced by any debug i...
const var_diff * is_var_diff(const diff *diff)
Test if a diff node is about differences between variables.
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Report the changes carried by the current class_or_union_diff node in a textual format.
diff_category get_default_harmful_categories_bitmap()
Getter of a bitmap made of the set of change categories that are considered harmful.
size_t num_leaf_var_changes() const
Getter for the number of leaf variable change diff nodes.
This means that a diff node in the sub-tree carries an addition of enumerator to an enum type...
bool is_mostly_distinct_diff(const diff *d)
Test if a diff node carries a distinct type change or a pointer/reference/typedef to distinct type ch...
virtual const string & get_pretty_representation() const
const diff * peel_typedef_diff(const diff *dif)
If a diff node is about changes between two typedef types, get the diff node about changes between th...
This means the diff node (or at least one of its descendant nodes) carries access related changes...
void sort_data_members(const string_decl_base_sptr_map &data_members, vector< decl_base_sptr > &sorted)
Sort a map of data members by the offset of their initial value.
shared_ptr< reference_diff > reference_diff_sptr
Convenience typedef for a shared pointer on a reference_diff type.
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
The variable was deleted from the second subject of the diff.
const type_decl_sptr first_type_decl() const
Getter for the first subject of the type_decl_diff.
diff * diff_has_been_visited(const diff *) const
Test if a diff node has been traversed.
virtual void report(ostream &, const string &indent="") const
Generates a report for the current instance of base_diff.
class_decl::base_spec_sptr second_base() const
Getter for the second base spec of the diff object.
A diff node in this category carries a change from void pointer to non-void pointer.
diff * get_current_topmost_iface_diff() const
Getter of the diff current topmost interface which is impacted by the current diff node being visited...
virtual enum change_kind has_local_changes() const
Test whether the current diff node carries any local change.
virtual enum change_kind has_local_changes() const
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
class_or_union_sptr first_class_or_union() const
A diff node in this category has a parent node that is in the HAS_ALLOWED_CHANGE_CATEGORY category...
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
void maybe_apply_filters(diff_sptr diff)
Apply the diff filters to a given diff sub-tree.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
The abstraction of a diff between two arrays.
const string_enumerator_map & deleted_enumerators() const
diff_maps()
Default constructor of the diff_maps type.
size_t num_removed_vars_filtered_out() const
Getter for the number removed variables that have been filtered out.
const string_diff_ptr_map & get_distinct_diff_map() const
Getter of the map that contains distinct diffs.
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
size_t num_added_var_syms_filtered_out() const
Getter for the number of added variable symbols, not referenced by any debug info, that have been filtered out.
virtual bool has_changes() const
Abstraction of the declaration of a method.
bool has_decl_only_def_change(const decl_base_sptr &first, const decl_base_sptr &second)
Test if two decl_base_sptr are different just by the fact that one is decl-only and the other one is ...
size_t net_num_added_func_syms() const
Getter of the net number of added function symbols that are not referenced by any debug info...
This says that the traversing code should not mark visited nodes as having been traversed. This is useful, for instance, for visitors which have debugging purposes.
void categorize_redundant_changed_sub_nodes()
Walk the changed functions and variables diff nodes to categorize redundant nodes.
size_t net_num_func_added() const
Getter for the net number of added functions.
shared_ptr< distinct_diff > distinct_diff_sptr
Convenience typedef for a shared pointer to distinct_types_diff.
ostream & operator<<(ostream &o, diff_category c)
Serialize an instance of diff_category to an output stream.
const fn_parm_diff * is_fn_parm_diff(const diff *diff)
Test if a diff node is about differences between two function parameters.
class_decl::base_spec_sptr first_base() const
Getter for the first base spec of the diff object.
virtual bool traverse(diff_node_visitor &v)
Traverse the diff sub-tree under the current instance corpus_diff.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
bool added_unreachable_type_is_suppressed(const type_base *t) const
Test if an added type that is unreachable from public interface has been suppressed by a suppression ...
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
const type_decl_diff * is_diff_of_basic_type(const diff *d)
Test if a diff node represents a diff between two basic types.
virtual enum change_kind has_local_changes() const
Check if the current diff node carries a local change.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Abstracts a class declaration.
Abstraction of a diff between two function_decl.
A diff node in this category is a function parameter type which top cv-qualifiers change...
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
virtual void report(ostream &out, const string &indent="") const
Report the diff in a serialized form.
void sort_string_diff_sptr_map(const string_diff_sptr_map &map, diff_sptrs_type &sorted)
Sort a map ofg string -> diff_sptr into a vector of diff_sptr. The diff_sptr are sorted lexicographic...
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
bool is_at_global_scope(const decl_base &decl)
Tests whether a given declaration is at global scope.
void propagate_categories(diff *diff_tree)
Visit all the nodes of a given sub-tree. For each node that has a particular category set...
This means that a diff node in the sub-tree carries an incompatible change to a vtable.
unordered_map< string, diff * > string_diff_ptr_map
Convenience typedef for a map which value is a diff*. The key of the map is the qualified name of the...
function_type_diff(const function_type_sptr first, const function_type_sptr second, diff_context_sptr ctxt)
Consutrctor of the function_type type.
bool currently_reporting() const
Tests if we are currently in the middle of emitting a report for this diff.
corpus_diff(corpus_sptr first, corpus_sptr second, diff_context_sptr ctxt=diff_context_sptr())
Constructor for corpus_diff.
size_t count_filtered_subtype_changed_dm(bool local_only=false)
Get the number of data member sub-type changes carried by the current diff node that were filtered ou...
const string_diff_ptr_map & get_enum_diff_map() const
Getter of the map that contains enum type diffs.
void switch_categories_on(diff_category c)
Setter for the bitmap that represents the set of categories that the user wants to see reported...
diff_category get_allowed_category() const
Getter for the bitmap that represents the set of categories that the user wants to see reported...
void apply_suppressions(diff *diff_tree)
Walk a given diff-sub tree and appply the suppressions carried by the context. If the suppression app...
size_t count_filtered_changed_mem_fns(const diff_context_sptr &)
Get the number of member functions changes carried by the current diff node that were filtered out...
const enum_type_decl_sptr first_enum() const
const string_diff_ptr_map & get_reference_diff_map() const
Getter of the map that contains reference type diffs.
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
shared_ptr< subrange_diff > subrange_diff_sptr
A convenience typedef for a shared pointer to subrange_diff type.
const class_diff * is_class_diff(const diff *diff)
Test if a diff node is a class_diff node.
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.
const edit_script & member_types_changes() const
shared_ptr< type_suppression > type_suppression_sptr
Convenience typedef for a shared pointer to type_suppression.
shared_ptr< scope_diff > scope_diff_sptr
Convenience typedef for a shared pointer on a scope_diff.
base_diff(class_decl::base_spec_sptr first, class_decl::base_spec_sptr second, class_diff_sptr underlying, diff_context_sptr ctxt=diff_context_sptr())
bool show_unreachable_types()
Getter for the flag that indicates if changes on types unreachable from global functions and variable...
Abstraction of a diff between two enums.
virtual void report(ostream &out, const string &indent="") const
Ouputs a report of the differences between of the two type_decl involved in the type_decl_diff.
The default, initial, reporter of the libabigail comparison engine.
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.
virtual enum change_kind has_local_changes() const
Abstracts a variable declaration.
void sort_string_elf_symbol_map(const string_elf_symbol_map &map, vector< elf_symbol_sptr > &sorted)
Sort a map of string -> pointer to elf_symbol.
The private data structure for distinct_diff.
void set_category(diff_category c)
Set the category of the current diff node. This category includes the categories inherited from the c...
virtual void report(ostream &, const string &indent="") const
Serialize a report of the changes encapsulated in the current instance of function_decl_diff over to ...
void sort_string_parm_map(const string_parm_map &map, vector< function_decl::parameter_sptr > &sorted)
Sort a map of string -> function parameters.
edit_script & variable_changes() const
A functor to compare instances of var_decl base on their qualified names.
void switch_categories_off(diff_category c)
Setter for the bitmap that represents the set of categories that the user wants to see reported...
bool is_diff_of_global_decls(const diff *)
Tests if a given diff node is to represent the changes between two gobal decls.
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Abstraction of a function parameter.
bool added_variable_is_suppressed(const var_decl *var) const
Test if the change reports for a given added variable have been suppressed.
The base class of diff between decls.
The base class of diff between types.
A reporter that only reports leaf changes.
Abstraction of a diff between two basic type declarations.
const function_decl_sptr second_function_decl() const
unordered_map< string, var_diff_sptr > string_var_diff_sptr_map
Convenience typedef for a map whose key is a string and whose value is a changed variable of type var...
unordered_map< string, base_diff_sptr > string_base_diff_sptr_map
Convenience typedef for a map of string and base_diff_sptr.
void initialize_canonical_diff(const diff_sptr diff)
Set the canonical diff node property of a given diff node appropriately.
void allocate_priv_data()
Allocate the memory for the priv_ pimpl data member of the class_or_union_diff class.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
bool soname_changed() const
Test if the soname of the underlying corpus has changed.
size_t net_num_removed_func_syms() const
Getter of the net number of removed function symbols that are not referenced by any debug info...
diff_sptr try_to_diff(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second, diff_context_sptr ctxt)
bool is_suppressed() const
Test if the current diff node has been suppressed by a user-provided suppression specification.
interned_string get_id() const
Return an ID that tries to uniquely identify the variable inside a program or a library.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
decl_base_sptr subtype_changed_dm(decl_base_sptr) const
Test if the current diff node carries a data member change for a data member which name is the same a...
bool has_net_changes() const
Test if the current instance of corpus_diff carries changes whose reports are not suppressed by any s...
const type_or_decl_base_sptr first() const
Getter for the first subject of the diff.
visiting_kind get_visiting_kind() const
Getter for the visiting policy of the traversing code while invoking this visitor.
unordered_map< string, elf_symbol_sptr > string_elf_symbol_map
Convenience typedef for a map whose key is a string and whose value is an elf_symbol_sptr.
This is the base class of class_diff and union_diff.
const string_decl_base_sptr_map & deleted_data_members() const
Getter for the data members that got deleted.
The internal type for the impl idiom implementation of subrange_diff.
bool has_changes() const
Return true iff the current corpus_diff node carries a change.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
size_t num_var_syms_removed() const
Getter for the number of variable symbols (not referenced by any debug info) that got removed...
The abstraction of the diff between two subrange types.
const string_diff_ptr_map & get_type_decl_diff_map() const
Getter of the map that contains basic type diffs.
unordered_map< unsigned, fn_parm_diff_sptr > unsigned_fn_parm_diff_sptr_map
Convenience typedef for a map which key is an integer and which value is a changed parameter...
A functor to compare instances of class_decl::base_spec.
void sort_string_base_diff_sptr_map(const string_base_diff_sptr_map &map, base_diff_sptrs_type &sorted)
Sort a map of string -> base_diff_sptr into a sorted vector of base_diff_sptr. The base_diff_sptr are...
An abstraction of a diff between between two abi corpus.
A functor to compare two instances of diff_sptr.
void sort_unsigned_data_member_diff_sptr_map(const unsigned_var_diff_sptr_map map, var_diff_sptrs_type &sorted)
Sort the values of a unsigned_var_diff_sptr_map map and store the result into a vector of var_diff_sp...
virtual bool traverse(diff_node_visitor &v)
The default traverse function.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of base_diff...
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of reference_d...
function_decl_diff(const function_decl_sptr first, const function_decl_sptr second, diff_context_sptr ctxt)
Constructor for function_decl_diff.
const var_decl_sptr get_next_data_member(const class_or_union *klass, const var_decl_sptr &data_member)
In the context of a given class or union, this function returns the data member that is located after...
void set_canonical_diff(diff *)
Setter for the canonical diff of the current instance of diff.
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
vector< changed_enumerator > changed_enumerators_type
Convenience typedef for a vector of changed enumerators.
void ensure_lookup_tables_populated()
If the lookup tables are not yet built, walk the differences and fill the lookup tables.
Abstracts a declaration for an enum type.
class_or_union_sptr second_class_or_union() const
bool is_traversing() const
Tell if a given node is being traversed or not.
size_t num_added_unreachable_types_filtered_out() const
Getter of the number of added types that are unreachable from public interfaces and that are filtered...
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
translation_unit_diff(translation_unit_sptr first, translation_unit_sptr second, diff_context_sptr ctxt=diff_context_sptr())
Constructor for translation_unit_diff.
const type_or_decl_base_sptr second() const
Getter for the second subject of the diff.
bool show_stats_only() const
Test if the comparison module should only show the diff stats.
diff_category
An enum for the different categories that a diff tree node falls into, regarding the kind of changes ...
ostream * default_output_stream()
Getter for the default output stream used by code of the comparison engine. By default the default ou...
Toplevel namespace for libabigail.
The variable was added to the second second subject of the diff.
bool do_log() const
Test if logging was requested.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
virtual bool has_changes() const
Test if the current diff node carries a change.
bool show_leaf_changes_only() const
Get the flag that indicates if the diff using this context should show only leaf changes or not...
size_t num_changed_vars_filtered_out() const
Getter for the number of variables that have a change in one of their sub-types, and that have been f...
unordered_set< type_or_decl_base_sptr, type_or_decl_hash, type_or_decl_equal > artifact_sptr_set_type
A convenience typedef for a hash set of type_or_decl_base_sptr.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
virtual void visit_end(corpus_diff *)
This is called by the traversing code on a corpus_diff node just after visiting it. That is after visiting it and its children nodes.
bool added_unrefed_var_sym_is_suppressed(const elf_symbol *) const
Test if the change reports for a given added variable symbol (that is not referenced by any debug inf...
const diff * peel_typedef_or_qualified_type_diff(const diff *dif)
If a diff node is about changes between two typedefs or qualified types, get the diff node about chan...
unordered_map< string, changed_enumerator > string_changed_enumerator_map
Convenience typedef for a map which value is a changed enumerator. The key is the name of the changed...
An abstraction of a diff between two instances of class_decl::base_spec.
#define SKIP_MEM_FN_IF_VIRTUALITY_DISALLOWED
Skip the processing of the current member function if its virtual-ness is disallowed by the user...
visiting_kind operator&(visiting_kind l, visiting_kind r)
The overloaded and operator for visiting_kind.
const string_base_sptr_map & inserted_bases() const
Getter for the inserted base classes of the diff.
corpus_sptr first_corpus() const
size_t count_filtered_deleted_mem_fns(const diff_context_sptr &)
Get the number of member functions deletions carried by the current diff node that were filtered out...
virtual const string & get_pretty_representation() const
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
virtual const string & get_pretty_representation() const
bool has_harmful_name_change(const decl_base_sptr &f, const decl_base_sptr &s)
Test if two decls represents a harmful name change.
virtual const string & get_pretty_representation() const
const string_diff_ptr_map & get_typedef_diff_map() const
Getter of the map that contains typedef type diffs.
bool reported_once() const
Tests if a report has already been emitted for the current diff.
virtual bool has_changes() const
Test if the current subrange_diff node carries any change.
void set_current_topmost_iface_diff(diff *)
Setter of the diff current topmost interface which is impacted by the current diff node being visited...
const diff * peel_pointer_or_qualified_type_diff(const diff *dif)
If a diff node is about changes between two pointer, reference or qualified types, get the diff node about changes between the underlying types.
bool is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr, const enum_type_decl &enom)
Test if a given enumerator is found present in an enum.
const string_function_ptr_map & added_functions()
Getter for the added functions of the diff.
type_base_sptr get_leaf_type(qualified_type_def_sptr t)
Return the first underlying type that is not a qualified type.
decl_diff_base(decl_base_sptr first_subject, decl_base_sptr second_subject, diff_context_sptr ctxt)
Constructor of decl_diff_base.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
const string_function_ptr_map & deleted_functions() const
Getter for the deleted functions of the diff.
friend corpus_diff_sptr compute_diff(const corpus_sptr f, const corpus_sptr s, diff_context_sptr ctxt)
Compute the diff between two instances of corpus.
void sort_string_base_sptr_map(const string_base_sptr_map &m, class_decl::base_specs &sorted)
Lexicographically sort base specifications found in instances of string_base_sptr_map.
virtual bool has_changes() const
Test if the current diff node carries changes.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
void set_corpus_diff(const corpus_diff_sptr &)
Set the corpus diff relevant to this context.
bool show_redundant_changes() const
A getter for the flag that says if we should report about functions or variables diff nodes that have...
const string_enumerator_map & inserted_enumerators() const
virtual void report(ostream &out, const string &indent="") const
Emit a report about the current diff instance.
shared_ptr< ptr_to_mbr_diff > ptr_to_mbr_diff_sptr
Typedef of a shared_ptr to ptr_to_mbr_diff.
bool perform_change_categorization() const
Test if it's requested to perform diff node categorization.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
The abstraction of a pointer-to-member type.
const diff_sptrs_type & changed_types() const
size_t num_leaf_changes() const
Getter of the number of leaf type change diff nodes.
The type of the private data of corpus_diff::diff_stats.
size_t net_num_vars_removed() const
Getter for the net number of removed variables.
size_t num_leaf_type_changes() const
Getter for the number of leaf type change diff nodes.
const edit_script & member_changes() const
Accessor of the edit script of the members of a scope.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
diff_category remove_from_local_category(diff_category c)
Remove the current diff tree node from the categories resulting from the local changes.
const string_elf_symbol_map & added_unrefed_function_symbols() const
Getter for function symbols not referenced by any debug info and that got added.
unordered_map< string, type_base_sptr > string_type_base_sptr_map
Convenience typedef for a map which key is a string and which value is a type_base_sptr.
var_decl_sptr second_var() const
Getter for the second var_decl of the diff.
This means that a diff node was warked as being for a private type. That is, the diff node is meant t...
Abstraction of a diff between two function parameters.
virtual enum change_kind has_local_changes() const
const function_decl::parameter_sptr first_parameter() const
Getter for the first subject of this diff node.
size_t num_added_unreachable_types() const
Getter of the number of added types that are unreachable from the public interface of the ABI corpus...
Abstraction for a function declaration.
virtual const string & get_pretty_representation() const
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of class_diff...
size_t num_added_func_filtered_out() const
Getter for the number of added function that have been filtered out.
void forget_visited_diffs()
Unmark all the diff nodes that were marked as being traversed.
const string_type_base_sptr_map & added_unreachable_types() const
Getter for a map of added types that are not reachable from global functions/variables.
virtual enum change_kind has_local_changes() const
size_t num_removed_func_syms_filtered_out() const
Getter for the number of removed function symbols, not referenced by debug info, that have been filte...
virtual const string & get_pretty_representation() const
Get a pretty representation of the current diff node.
This means that a diff node in the sub-tree carries a harmless declaration name change. This is set only for name changes for data members and typedefs.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of function_ty...
unordered_map< string, diff_sptr > string_diff_sptr_map
Convenience typedef for a map which value is a diff_sptr. The key of the map is the qualified name of...
const array_type_def::subrange_sptr first_subrange() const
Getter of the first subrange of the current instance subrange_diff.
This means that a diff node in the sub-tree carries a harmless data member change. An example of harmless data member change is an anonymous data member that replaces a given data member without locally changing the layout.
unordered_map< string, function_decl_diff_sptr > string_function_decl_diff_sptr_map
Convenience typedef for a map which key is a string and which value is a function_decl_diff_sptr.
bool is_less_than(const function_decl_diff &first, const function_decl_diff &second)
Compare two function_decl_diff for the purpose of sorting.
void apply_supprs_to_added_removed_fns_vars_unreachable_types()
Apply suppression specifications for this corpus diff to the set of added/removed functions/variables...
diff_sptr leaf_underlying_type_diff() const
Getter for the diff between the most underlying non-qualified types of two qualified types...
diff_sptr compute_diff(const decl_base_sptr first, const decl_base_sptr second, diff_context_sptr ctxt)
Compute the difference between two decls. The decls can represent either type declarations, or non-type declaration.
virtual enum change_kind has_local_changes() const
size_t num_func_removed() const
Getter for the number of functions removed.
diff_category get_category() const
Getter for the category of the current diff tree node.
void clear_redundancy_categorization()
Walk the changed functions and variables diff nodes and clear the redundancy categorization they migh...
void end_traversing()
Flag a given diff node as not being traversed anymore.
class_decl_sptr first_class_decl() const
The context of the diff. This type holds various bits of information that is going to be used through...
size_t net_num_removed_var_syms() const
Getter of the net number of removed variable symbols that are not referenced by any debug info...
const diff_sptr underlying_type_diff() const
Getter of the diff node of the underlying types of the current subrange_diff diff node...
The abstraction of a diff between two ptr_to_mbr_type.
A diff node in this category is redundant. That means it's present as a child of a other nodes in the...
The abstraction of a diff between two references.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
shared_ptr< function_decl_diff > function_decl_diff_sptr
Convenience typedef for a shared pointer to a function_decl type.
This means that a diff node in the sub-tree carries a type that was declaration-only and that is now ...
Functor to sort instances of var_diff_sptr.
size_t num_vars_changed() const
Getter for the number of variables that have a change in one of their sub-types.
virtual ~union_diff()
Destructor of the union_diff node.
void emit_diff_stats(const diff_stats &stats, ostream &out, const string &indent)
Emit the summary of the functions & variables that got removed/changed/added.
diff * get_canonical_diff() const
Getter for the canonical diff of the current instance of diff.
bool has_descendant_allowed_by_specific_negated_suppression() const
Test if the current diff node has a descendant node which is specifically allowed by a negated suppre...
unordered_map< const diff *, artifact_sptr_set_type, diff_hash, diff_equal > diff_artifact_set_map_type
A convenience typedef for an unordered_map which key is a diff* and which value is a artifact_sptr_se...
friend var_diff_sptr compute_diff(const var_decl_sptr first, const var_decl_sptr second, diff_context_sptr ctxt)
Compute the diff between two instances of var_decl.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
virtual const string & get_pretty_representation() const
Build and return a copy of a pretty representation of the current instance of function_type_diff.
size_t net_num_leaf_changes() const
Getter of the net number of leaf change diff nodes.
const string_diff_ptr_map & get_var_decl_diff_map() const
Getter of the map that contains var decl diffs.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
const string_function_decl_diff_sptr_map & changed_functions()
Getter for the functions which signature didn't change, but which do have some indirect changes in th...
shared_ptr< type_decl_diff > type_decl_diff_sptr
Convenience typedef for a shared pointer on a type_decl_diff type.
void keep_diff_alive(diff_sptr &)
Add a diff node to the set of diff nodes that are kept alive for the life time of the current instanc...
bool is_filtered_out() const
Test if this diff tree node is to be filtered out for reporting purposes.
void add_suppressions(const suppr::suppressions_type &supprs)
Add new suppression specifications that specify which diff node reports should be dropped on the floo...
virtual enum change_kind has_local_changes() const =0
Pure interface to know if the current instance of carries a local change. A local change is a change...
virtual bool has_changes() const
Return true iff the current diff node carries a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the corpus_diff type.
const vector< function_decl::parameter_sptr > & sorted_added_parms() const
Getter for the sorted vector of added parameters .
bool show_added_vars() const
ptr_to_mbr_type_sptr first_ptr_to_mbr_type() const
Getter of the first pointer-to-member subject of the current diff node.
The abstraction of a diff between two pointers.
Abstraction of an elf symbol.
virtual void report(ostream &, const string &indent="") const
Report the changes carried by the current union_diff node in a textual format.
const string_elf_symbol_map & deleted_unrefed_function_symbols() const
Getter for function symbols not referenced by any debug info and that got deleted.
virtual void report(ostream &out, const string &indent="") const
Report the changes of one scope against another.
const var_diff_sptrs_type & changed_variables_sorted()
Getter for the sorted vector of variables which signature didn't change but which do have some indire...
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...
virtual bool has_changes() const
Return true iff the current diff node carries a change.
size_t count_filtered_inserted_mem_fns(const diff_context_sptr &)
Get the number of member functions insertions carried by the current diff node that were filtered out...
size_t count_filtered_bases()
Count the number of bases classes whose changes got filtered out.
virtual const string & get_pretty_representation() const
The function was deleted from the second subject of the diff.
void forbid_visiting_a_node_twice(bool f)
This sets a flag that, if it's true, then during the traversing of a diff nodes tree each node is vis...
void apply_filter(filter_base &filter, corpus_diff_sptr d)
Walk the diff sub-trees of a a corpus_diff and apply a filter to the nodes visted. The filter categorizes each node, assigning it into one or several categories.
vector< method_decl_sptr > member_functions
Convenience typedef.
size_t net_num_added_var_syms() const
Getter of the net number of added variable symbols that are not referenced by any debug info...
const typedef_diff * is_typedef_diff(const diff *diff)
Test if a diff node is a typedef_diff node.
const function_decl_diff * is_function_decl_diff(const diff *diff)
Test if a diff node is about differences between functions.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
const diff * peel_fn_parm_diff(const diff *dif)
If a diff node is about changes between two function parameters get the diff node about changes betwe...
diff_category get_default_harmless_categories_bitmap()
Getter of a bitmap made of the set of change categories that are considered harmless.
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 ...
friend scope_diff_sptr compute_diff(const scope_decl_sptr first, const scope_decl_sptr second, scope_diff_sptr d, diff_context_sptr ctxt)
Compute the diff between two scopes.
void mark_leaf_diff_nodes()
Walks the diff nodes associated to the current corpus diff and mark those that carry local changes...
void set_local_category(diff_category c)
Set the local category of the current diff node.
virtual bool visit(diff *, bool)
Default visitor implementation.
shared_ptr< translation_unit_diff > translation_unit_diff_sptr
Convenience typedef for a shared pointer on a translation_unit_diff type.
size_t num_vars_removed() const
Getter for the number of variables removed.
A diff node in this category is for a variable which type holds a cv-qualifier change.
void add_suppression(const suppr::suppression_sptr suppr)
Add a new suppression specification that specifies which diff node reports should be dropped on the f...
void clear_lookup_tables()
Clear the lookup tables useful for reporting an enum_diff.
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
virtual bool traverse(diff_node_visitor &v)
The generic traversing code that walks a given diff sub-tree.
virtual const string & get_pretty_representation() const
pointer_diff(pointer_type_def_sptr first, pointer_type_def_sptr second, diff_sptr underlying_type_diff, diff_context_sptr ctxt=diff_context_sptr())
Constructor for a pointer_diff.
size_t count_filtered_changed_data_members(bool local_only=false) const
Count the number of /filtered/ data members that got replaced by another data member.
visiting_kind operator|(visiting_kind l, visiting_kind r)
The overloaded or operator for visiting_kind.
diff_sptr underlying_type_diff() const
virtual bool has_changes() const
Return true iff the current diff node carries a change.
shared_ptr< var_diff > var_diff_sptr
Convenience typedef for a shared pointer to a var_diff type.
void count_leaf_changes(size_t &num_changes, size_t &num_filtered)
Count the number of leaf changes as well as the number of the changes that have been filtered out...
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
const pointer_type_def_sptr second_pointer() const
Getter for the second subject of a pointer diff.
diff_category get_class_of_equiv_category() const
Getter of the category of the class of equivalence of the current diff tree node. ...
bool do_log() const
Test if logging was requested.
class_or_union_diff(class_or_union_sptr first_scope, class_or_union_sptr second_scope, diff_context_sptr ctxt=diff_context_sptr())
Constructor for the class_or_union_diff class.
const string_elf_symbol_map & added_unrefed_variable_symbols() const
Getter for variable symbols not referenced by any debug info and that got added.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
virtual enum change_kind has_local_changes() const
virtual void chain_into_hierarchy()
Populate the vector of children nodes of the diff base type sub-object of this instance of fn_parm_di...
virtual bool has_changes() const
Return true iff the current diff node carries a change.
void sort_string_var_ptr_map(const string_var_ptr_map &map, vector< const var_decl * > &sorted)
Sort a map of string -> pointer to var_decl.
bool is_opaque_type_suppr_spec(const type_suppression &s)
Test if a type suppression specification represents a private type suppression automatically generate...
size_t num_leaf_func_changes() const
Getter for the number of leaf function change diff nodes.
bool has_local_changes_to_be_reported() const
Test if this diff tree node should be reported when considering the categories that were *NOT* inheri...
virtual void visit_end(diff *)
This is called by the traversing code on a diff node just after visiting it. That is after visiting i...
virtual void report(ostream &, const string &indent="") const
Reports the difference between the two subjects of the diff in a serialized form. ...
void apply_filters(corpus_diff_sptr diff_tree)
Apply the diff tree filters that have been associated to the context of the a given corpus_diff tree...
const diff * peel_qualified_diff(const diff *dif)
If a diff node is about changes between two qualified types, get the diff node about changes between ...
size_t num_func_added() const
Getter for the number of functions added.
change_kind
The kind of change the current function suppression should apply to.
An abstraction of a diff between two translation units.
A diff node in this category has a function parameter type with a cv-qualifiers change.
vector< suppression_sptr > suppressions_type
Convenience typedef for a vector of suppression_sptr.
virtual void report(ostream &, const string &indent="") const
Build and emit a textual report about the current function_type_diff instance.
bool show_architecture_change() const
Getter for the property that says if the comparison module should show the architecture changes in it...
variable_suppression_sptr is_variable_suppression(const suppression_sptr s)
Test if an instance of suppression is an instance of variable_suppression.
visiting_kind
An enum for the different ways to visit a diff tree node.
interned_string get_function_id_or_pretty_representation(const function_decl *fn)
Get the ID of a function, or, if the ID can designate several different functions, get its pretty representation.
A diff node in this category has a descendant node that is in the HAS_ALLOWED_CHANGE_CATEGORY categor...
A functor to compare two enumerators based on their value. This implements the "less than" operator...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of array_diff...
const string_diff_sptr_map & changed_unreachable_types() const
Get the map of diff nodes representing changed unreachable types.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of var_diff...
const edit_script & member_class_tmpls_changes() const
A comparison functor to compare two instances of fn_parm_diff based on their indexes.
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Pure interface to report the diff in a serialized form that is legible for the user.
void begin_traversing()
Flag a given diff node as being traversed.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of function_de...
const decl_diff_base * is_decl_diff(const diff *diff)
Test if a diff node is about differences between declarations.
size_t num_changed_func_filtered_out() const
Getter for the number of functions that have a change in one of their sub-types, and that have been f...
type_base_sptr strip_typedef(const type_base_sptr type)
Recursively returns the the underlying type of a typedef. The return type should not be a typedef of ...
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of scope_diff...
const string_member_function_sptr_map & inserted_member_fns() const
diff_sptr underlying_type_diff() const
Getter for the diff between the pointed-to types of the pointers of this diff.
const string_parm_map & added_parms() const
Getter for the map of parameters that got added.
const vector< diff * > & children_nodes() const
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
const decl_base_sptr inserted_member_at(unsigned i)
Accessor that eases the manipulation of the edit script associated to this instance. It returns the scope member (of the second scope of this diff instance) that is reported as being inserted from a given index.
const array_diff * is_array_diff(const diff *diff)
Test if a diff node is a array_diff node.
bool has_basic_type_change_only(const diff *d)
Test if a diff node is a decl diff that only carries a basic type change on its type diff sub-node...
bool lookup_tables_empty() const
Tests if the lookup tables are empty.
diff_sptr type_diff() const
Getter for the diff representing the changes on the type of the function parameter involved in the cu...
size_t num_removed_unreachable_types_filtered_out() const
Getter of the number of removed types that are not reachable from public interfaces and that have bee...
A comparison functor to compare two instances of var_diff that represent changed data members based o...
change_kind
The kind of change the current variable suppression should apply to.
size_t net_num_func_changed() const
Getter for the number of functions that have a change in their sub-types, minus the number of these f...
const filtering::filters & diff_filters() const
Getter for the diff tree nodes filters to apply to diff sub-trees.
The abstraction of a pointer type.
bool lookup_tables_empty(void) const
Tests if the lookup tables are empty.
bool added_unrefed_fn_sym_is_suppressed(const elf_symbol *) const
Test if the change reports for a given added function symbol (that is not referenced by any debug inf...
virtual bool has_changes() const
Test whether the current diff node carries any change.
const string_diff_ptr_map & get_array_diff_map() const
Getter of the map that contains array type diffs.
This type contains maps. Each map associates a type name to a diff of that type. Not all kinds of dif...
virtual bool visit(distinct_diff *, bool)
Default visitor implementation.
unordered_map< unsigned, var_diff_sptr > unsigned_var_diff_sptr_map
Convenience typedef for a map whose key is an unsigned int and whose value is a changed variable of t...
size_t num_added_func_syms_filtered_out() const
Getter for the number of added function symbols, not referenced by any debug info, that have been filtered out.
const diff_sptr & element_type_diff() const
Getter for the diff between the two types of array elements.
const string & get_pretty_representation() const
virtual enum change_kind has_local_changes() const
Test if the current subrange_diff node carries any local change.
friend class_diff_sptr compute_diff(const class_decl_sptr first, const class_decl_sptr second, diff_context_sptr ctxt)
Compute the set of changes between two instances of class_decl.
const type_decl_sptr second_type_decl() const
Getter for the second subject of the type_decl_diff.
The function was added to the second subject of the diff.
bool show_symbols_unreferenced_by_debug_info() const
Getter for the flag that indicates if symbols not referenced by any debug info are to be compared and...
size_t num_var_syms_added() const
Getter for the number of variable symbols (not referenced by any debug info) that got added...
const array_type_def::subrange_sptr second_subrange() const
Getter of the second subrange of the current instance subrange_diff.
const vector< class_decl::base_spec_sptr > & moved_bases() const
Getter for the vector of bases that "moved". That is, the vector of base types which position changed...
const string_diff_ptr_map & get_subrange_diff_map() const
Getter of the map that contains subrange type diffs.
const string_diff_ptr_map & get_union_diff_map() const
Getter of the map that contains union type diffs.
const enum_diff * is_enum_diff(const diff *diff)
Test if a diff node is a enum_diff node.
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
The base class for the node visitors. These are the types used to visit each node traversed by the di...
bool dump_diff_tree() const
Test if the comparison engine should dump the diff tree for the changed functions and variables it ha...
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.
A filter that walks the diff nodes tree and tags relevant diff nodes into categories considered to re...
const function_type_sptr second_function_type() const
Getter for the second subject of the diff.
void append_child_node(diff_sptr)
Append a new child node to the vector of children nodes for the current instance of corpus_diff node...
A basic type declaration that introduces no scope.
void sort_changed_data_members(changed_var_sptrs_type &input)
Sort (in place) a vector of changed data members.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
shared_ptr< base_diff > base_diff_sptr
Convenience typedef for a shared pointer to a base_diff type.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of ...
void sort_changed_enumerators(const string_changed_enumerator_map &enumerators_map, changed_enumerators_type &sorted)
Sort a map of changed enumerators.
const subrange_diff * is_subrange_diff(const diff *diff)
Test if a diff node is a subrange_diff node.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
const decl_base_sptr deleted_member_at(unsigned index) const
Accessor that eases the manipulation of the edit script associated to this instance. It returns the scope member that is reported (in the edit script) as deleted at a given index.
const string_changed_enumerator_map & changed_enumerators() const
shared_ptr< array_diff > array_diff_sptr
Convenience typedef for a shared pointer on a array_diff type.
size_t num_func_syms_added() const
Getter for the number of function symbols (not referenced by any debug info) that got added...
ostream * error_output_stream() const
Getter for the errror output stream used by code of the comparison engine. By default the error outpu...
size_t num_vars_added() const
Getter for the number of variables added.
virtual ~ptr_to_mbr_diff()
Destructor of ptr_to_mbr_diff.
virtual enum change_kind has_local_changes() const
bool show_soname_change() const
Getter for the property that says if the comparison module should show the soname changes in its repo...
An equality functor to deeply compare pointers.
A comparison functor to compare two data members based on their offset.
bool deleted_unrefed_var_sym_is_suppressed(const elf_symbol *) const
Test if the change reports for a given deleted variable symbol (that is not referenced by any debug i...
static bool entities_are_of_distinct_kinds(type_or_decl_base_sptr first, type_or_decl_base_sptr second)
Test if the two arguments are of different kind, or that are both NULL.
shared_ptr< fn_parm_diff > fn_parm_diff_sptr
Convenience typedef for a shared pointer to a fn_parm_diff type.
unordered_map< string, method_decl_sptr > string_member_function_sptr_map
Convenience typedef for a hash map of strings and member functions.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
const class_or_union_diff * is_anonymous_class_or_union_diff(const diff *d)
Test if a diff node is a class_or_union_diff between two anonymous classes or unions.
const string_decl_base_sptr_map & data_members_replaced_by_adms() const
Get the map of data members that got replaced by anonymous data members.
bool is_diff_of_variadic_parameter(const diff *d)
Test if a diff node represents the difference between a variadic parameter and something else...
union_decl_sptr second_union_decl() const
const var_decl * lookup_data_member(const type_base *type, const char *dm_name)
Look for a data member of a given class, struct or union type and return it.
void count_leaf_type_changes(size_t &num_type_changes, size_t &num_type_changes_filtered)
Count the number of leaf *type* changes as well as the number of the leaf type changes that have been...
bool show_relative_offset_changes(void)
Get the flag saying if offset changes should be reported in a relative way. That is, if the report should say how of many bits a class/struct data member did move.
The type of private data of class_or_union_diff.
void set_underlying_class_diff(class_diff_sptr d)
Setter for the diff object for the diff of the underlyng base classes.
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer...
const translation_unit_sptr first_translation_unit() const
Getter for the first translation unit of this diff.
bool to_be_reported() const
Test if this diff tree node should be reported.
void clear_lookup_tables(void)
Clear the lookup tables useful for reporting.
virtual const string & get_pretty_representation() const
void or_visiting_kind(visiting_kind v)
Setter for the visiting policy of the traversing code while invoking this visitor. This one makes a logical or between the current policy and the bitmap given in argument and assigns the current policy to the result.
const function_type_sptr first_function_type() const
Getter for the first subject of the diff.
virtual enum change_kind has_local_changes() const
Test if the current diff node carries local changes.
This means that a given IR artifact has a local type change.
Abstracts a diff between two instances of var_decl.
const pointer_type_def_sptr first_pointer() const
Getter for the first subject of a pointer diff.
diff_sptr type_diff() const
Getter for the diff of the types of the instances of var_decl.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
corpus_sptr second_corpus() const
corpus_sptr get_second_corpus() const
Getter for the second corpus of the corpus diff of the current context.
const typedef_decl_sptr second_typedef_decl() const
Getter for the second typedef_decl involved in the diff.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
const vector< function_decl::parameter_sptr > & sorted_deleted_parms() const
Getter for the sorted vector of deleted parameters.
void maybe_dump_diff_tree()
If the user asked to dump the diff tree node (for changed variables and functions) on the error outpu...
const class_or_union_diff * is_class_or_union_diff(const diff *d)
Test if a diff node is a class_or_union_diff node.
const var_diff_sptrs_type & sorted_subtype_changed_data_members() const
Getter of the sorted vector of data members with a (sub-)type change.
corpus_sptr get_first_corpus() const
Getter for the first corpus of the corpus diff of the current context.
type_or_decl_base_sptr member_type_has_changed(decl_base_sptr) const
Test if the current diff node carries a member type change for a member type which name is the same a...
A comparison functor to compare pointer to instances of type_or_decl_base.
bool get_is_anonymous() const
Test if the current declaration is anonymous.
This means that a diff node in the sub-tree carries an addition or removal of a non-virtual member fu...
bool is_child_node_of_base_diff(const diff *diff)
Test if a diff node is a child node of a base diff node.
unordered_map< string, fn_parm_diff_sptr > string_fn_parm_diff_sptr_map
Convenience typedef for a map which value is a changed function parameter and which key is the name o...
reference_type_def_sptr second_reference() const
Getter for the second reference of the diff.
void sort_string_fn_parm_diff_sptr_map(const unsigned_fn_parm_diff_sptr_map &map, vector< fn_parm_diff_sptr > &sorted)
Sort a map of fn_parm_diff by the indexes of the function parameters.
The private data and functions of the abigail::ir::comparison types.
void sort_string_virtual_member_function_diff_sptr_map(const string_function_decl_diff_sptr_map &map, function_decl_diff_sptrs_type &sorted)
Sort an map of string -> virtual member function into a vector of virtual member functions. The virtual member functions are sorted by increasing order of their virtual index.
The abstraction of the version of an ELF symbol.
void sort_string_function_decl_diff_sptr_map(const string_function_decl_diff_sptr_map &map, function_decl_diff_sptrs_type &sorted)
Sort the values of a string_function_decl_diff_sptr_map map and store the result in a vector of funct...
const reference_diff * is_reference_diff(const diff *diff)
Test if a diff node is about differences between two references.
size_t net_num_removed_unreachable_types() const
Getter of the number of removed types that are not reachable from public interfaces and that have *NO...
This means that a diff node in the sub-tree carries an a symbol alias change that is harmless...
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
A diff node in this category carries a change that must be reported, even if the diff node is also in...
vector< diff_sptr > diff_sptrs_type
Convenience typedef for a vector of diff_sptr.
const qualified_type_def_sptr second_qualified_type() const
Getter for the second qualified type of the diff.
bool show_hex_values() const
Get the flag that indicates if the diff reports using this context should show sizes and offsets in a...
const scope_decl_sptr second_scope() const
Getter for the second scope of the diff.
const diff * peel_reference_diff(const diff *dif)
If a diff node is about changes between two reference types, get the diff node about changes between ...
A functor to compare two changed enumerators, based on their initial value.
const diff * get_typedef_diff_underlying_type_diff(const diff *diff)
Return the leaf underlying diff node of a typedef_diff node.
size_t num_func_changed() const
Getter for the number of functions that have a change in one of their sub-types.
union_diff(union_decl_sptr first_union, union_decl_sptr second_union, diff_context_sptr ctxt=diff_context_sptr())
Constructor for the union_diff type.
const type_diff_base * is_type_diff(const diff *diff)
Test if a diff node is about differences between types.
size_t num_leaf_func_changes_filtered_out() const
Getter for the number of leaf function change diff nodes that were filtered out.
shared_ptr< corpus_diff > corpus_diff_sptr
A convenience typedef for a shared pointer to corpus_diff.
size_t get_deleted_non_static_data_members_number() const
Get the number of non static data members that were deleted.
size_t net_num_leaf_type_changes() const
Getter for the net number of leaf type change diff nodes.
const diff_context_sptr context() const
Getter of the diff context of this diff.
const string_elf_symbol_map & deleted_unrefed_variable_symbols() const
Getter for variable symbols not referenced by any debug info and that got deleted.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
subrange_diff(const array_type_def::subrange_sptr &first, const array_type_def::subrange_sptr &second, const diff_sptr &underlying_type_diff, const diff_context_sptr ctxt=diff_context_sptr())
Constructor of the subrange_diff diff node type.
void do_dump_diff_tree(const diff_sptr) const
Emit a textual representation of a diff tree to the error output stream of the current context...
shared_ptr< variable_suppression > variable_suppression_sptr
A convenience typedef for a shared pointer to variable_suppression.
const suppr::suppressions_type & direct_suppressions() const
Getter of the direct suppression specification (those that are not negated) comprised in the general ...
virtual enum change_kind has_local_changes() const
const class_or_union_diff * is_diff_of_class_or_union_type(const diff *d)
Test if a diff node represents a diff between two class or union types.
This means that a given IR artifact has a local non-type change. That is a change that is carried by ...
const suppr::suppressions_type & negated_suppressions() const
Getter of the negated suppression specifications that are comprised in the general vector of suppress...
bool visiting_a_node_twice_is_forbidden_per_interface() const
Return a flag that, if true, then during the traversing of a diff nodes tree each node is visited at ...
bool show_changed_vars() const
reference_type_def_sptr first_reference() const
Getter for the first reference of the diff.
vector< base_diff_sptr > base_diff_sptrs_type
Convenience typedef for a vector of base_diff_sptr.
unordered_map< string, function_decl::parameter_sptr > string_parm_map
Convenience typedef for a map which value is a function parameter. The key is the name of the functio...
const diff_sptr compatible_child_diff() const
Getter for the child diff of this distinct_diff instance.
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
virtual void report(ostream &, const string &indent="") const
Report about the changes carried by this node.
"Less than" functor to compare instances of function_decl.
void add_to_local_and_inherited_categories(diff_category c)
Adds the current diff tree node to the categories resulting from the local and inherited changes of t...
void sort_string_type_base_sptr_map(string_type_base_sptr_map &map, vector< type_base_sptr > &sorted)
Sort a map of string to type_base_sptr entities.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
Functor that compares two function parameters for the purpose of sorting them.
const function_type_diff * is_function_type_diff(const diff *diff)
Test if a diff node is a function_type_diff node.
const function_decl_diff_sptrs_type & changed_member_fns() const
Getter for the virtual members functions that have had a change in a sub-type, without having a chang...
string get_pretty_representation(const type_or_decl_base *tod, bool internal)
Build and return a copy of the pretty representation of an ABI artifact that could be either a type o...
void compute_diff(RandomAccessOutputIterator a_base, RandomAccessOutputIterator a_begin, RandomAccessOutputIterator a_end, RandomAccessOutputIterator b_base, RandomAccessOutputIterator b_begin, RandomAccessOutputIterator b_end, vector< point > &lcs, edit_script &ses, int &ses_len)
Compute the longest common subsequence of two (sub-regions of) sequences as well as the shortest edit...
virtual enum change_kind has_local_changes() const
virtual bool has_changes() const =0
Pure interface to get the length of the changes encapsulated by this diff. A length of zero means tha...
This says that the traversing code should avoid visiting the children nodes of the current node being...
decl_base_sptr member_class_tmpl_has_changed(decl_base_sptr) const
Test if the current diff node carries a member class template change for a member class template whic...
shared_ptr< function_suppression > function_suppression_sptr
Convenience typedef for a shared pointer to function_suppression.
friend void apply_suppressions(const corpus_diff *diff_tree)
Walk a corpus_diff tree and appply the suppressions carried by the context. If the suppression applie...
virtual const string & get_pretty_representation() const
virtual enum change_kind has_local_changes() const
void sort_string_diff_ptr_map(const string_diff_ptr_map &map, diff_ptrs_type &sorted)
Sort a map ofg string -> diff* into a vector of diff_ptr. The diff_ptr are sorted lexicographically w...
A diff node in this category carries a change in the size of the array type of a global variable...
const translation_unit_sptr second_translation_unit() const
Getter for the second translation unit of this diff.
const vector< diff_sptr > & changed_unreachable_types_sorted() const
Getter of a sorted vector of changed types that are not reachable from global functions/variables.
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_...
size_t get_inserted_non_static_data_members_number() const
Get the number of non static data members that were inserted.
This means that a diff node in the sub-tree carries a harmless union or class change.
const string_base_sptr_map & deleted_bases() const
Getter for the deleted base classes of the diff.
type_or_decl_base_sptr second_subject() const
Getter of the second subject of the diff.
const var_diff_sptrs_type & sorted_changed_data_members() const
Getter of the sorted vector of data members that got replaced by another data member.
size_t num_added_vars_filtered_out() const
Getter for the number of added variables that have been filtered out.
bool deleted_unreachable_type_is_suppressed(const type_base *t) const
Test if a deleted type that is unreachable from public interface has been suppressed by a suppression...
unordered_map< string, enum_type_decl::enumerator > string_enumerator_map
Convenience typedef for a map which value is an enumerator. The key is the name of the enumerator...
const diff_sptr & underlying_type_diff() const
Getter for the diff between the two referred-to types.
bool is_allowed_by_specific_negated_suppression() const
Test if this diff node is allowed (prevented from being suppressed) by at least one negated suppressi...
const function_decl_diff_sptrs_type & changed_functions_sorted()
Getter for a sorted vector of functions which signature didn't change, but which do have some indirec...
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
bool has_basic_or_class_type_name_change(const diff *d)
Test if a diff node carries a basic or class type name change.
virtual void report(ostream &out, const string &indent="") const
Report the diff in a serialized form.
union_decl_sptr first_union_decl() const
void categorize_redundancy(diff *diff_tree)
Walk a given diff sub-tree to categorize each of the nodes with respect to the REDUNDANT_CATEGORY.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of typedef_dif...
void apply_filters_and_compute_diff_stats(corpus_diff::diff_stats &)
Compute the diff stats.
size_t num_changed_unreachable_types() const
Getter of the number of changed types that are unreachable from the public interface of the ABI corpu...
The abstraction of a typedef declaration.
std::vector< filter_base_sptr > filters
Convenience typedef for a vector of filter_base_sptr.
const diff_sptr underlying_type_diff() const
Getter for the diff between the two underlying types of the typedefs.
const vector< type_base_sptr > & added_unreachable_types_sorted() const
Getter of a sorted vector of added types that are not reachable from global functions/variables.
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
void set_visiting_kind(visiting_kind v)
Setter for the visiting policy of the traversing code while invoking this visitor.
artifact_sptr_set_type * lookup_impacted_interfaces(const diff *d) const
Lookup the interfaces that are impacted by a given leaf diff node.
vector< base_spec_sptr > base_specs
Convenience typedef.
void count_unreachable_types(size_t &num_added, size_t &num_removed, size_t &num_changed, size_t &num_filtered_added, size_t &num_filtered_removed, size_t &num_filtered_changed)
Count the number of types not reachable from the interface (i.e, not reachable from global functions ...
This is a document class that aims to capture statistics about the changes carried by a corpus_diff t...
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...
virtual bool has_changes() const
Return true iff the current diff node carries a change.
bool visiting_a_node_twice_is_forbidden() const
Return a flag that, if true, then during the traversing of a diff nodes tree each node is visited at ...
const union_diff * is_union_diff(const diff *diff)
Test if a diff node is a union_diff node.
virtual const string & get_pretty_representation() const
void print_diff_tree(diff *diff_tree, ostream &out)
Emit a textual representation of a diff sub-tree to an output stream.
diff_maps & get_leaf_diffs()
Get the set of maps that contain leaf nodes. A leaf node being a node with a local change...
The internal type for the impl idiom implementation of var_diff.
A diff node in this category is a function return type with a cv-qualifier change.
array_diff(const array_type_def_sptr first, const array_type_def_sptr second, diff_sptr element_type_diff, diff_context_sptr ctxt=diff_context_sptr())
Constructor for array_diff.
const string_diff_ptr_map & get_fn_parm_diff_map() const
Getter of the map that contains function parameter diffs.
reference_diff(const reference_type_def_sptr first, const reference_type_def_sptr second, diff_sptr underlying, diff_context_sptr ctxt=diff_context_sptr())
Constructor for reference_diff.
shared_ptr< diff > diff_sptr
Convenience typedef for a shared_ptr for the diff class.
shared_ptr< reporter_base > reporter_base_sptr
A convenience typedef for a shared pointer to a reporter_base.
enum_diff(const enum_type_decl_sptr, const enum_type_decl_sptr, const diff_sptr, diff_context_sptr ctxt=diff_context_sptr())
Constructor for enum_diff.
friend function_type_diff_sptr compute_diff(const function_type_sptr first, const function_type_sptr second, diff_context_sptr ctxt)
Compute the diff between two instances of function_type.
const vector< type_base_sptr > & deleted_unreachable_types_sorted() const
Getter of a sorted vector of deleted types that are not reachable from global functions/variables.
const distinct_diff * is_distinct_diff(const diff *diff)
Test if a diff node is about differences between two diff nodes of different kinds.
distinct_diff_sptr compute_diff_for_distinct_kinds(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second, diff_context_sptr ctxt)
Try to diff entities that are of distinct kinds.
const diff * peel_pointer_diff(const diff *dif)
If a diff node is about changes between two pointer types, get the diff node about changes between th...
reporter_base_sptr get_reporter() const
Getter of the reporter to be used in this context.
size_t net_num_leaf_func_changes() const
Getter for the net number of leaf function change diff nodes.
bool show_changed_fns() const
class_decl::base_spec_sptr base_has_changed(class_decl::base_spec_sptr) const
Test whether a given base class has changed. A base class has changed if it's in both in deleted *and...
var_diff(var_decl_sptr first, var_decl_sptr second, diff_sptr type_diff, diff_context_sptr ctxt=diff_context_sptr())
Constructor for var_diff.
void sort_artifacts_set(const artifact_sptr_set_type &set, vector< type_or_decl_base_sptr > &sorted)
Sort the set of ABI artifacts contained in a artifact_sptr_set_type.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
virtual void report(ostream &, const string &indent="") const
Emit a textual report about the current fn_parm_diff instance.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
bool is_diff_of_variadic_parameter_type(const diff *d)
Test if a diff node represents the difference between a variadic parameter type and something else...
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
visiting_kind operator~(visiting_kind l)
The overloaded 'bit inversion' operator for visiting_kind.
virtual const string & get_pretty_representation() const
bool architecture_changed() const
Test if the architecture of the underlying corpus has changed.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
bool is_decl_only_class_with_size_change(const class_or_union &first, const class_or_union &second)
Test if two classes that are decl-only (have the decl-only flag and carry no data members) but are di...
Abstraction of a diff between two function types.
virtual enum change_kind has_local_changes() const
class_diff(class_decl_sptr first_scope, class_decl_sptr second_scope, diff_context_sptr ctxt=diff_context_sptr())
Constructor of class_diff.
const class_diff_sptr get_underlying_class_diff() const
Getter for the diff object for the diff of the underlying base classes.
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
shared_ptr< filter_base > filter_base_sptr
Convenience typedef for a shared pointer to filter_base.
const array_type_def_sptr first_array() const
Getter for the first array of the diff.
virtual const string & get_pretty_representation() const
const base_diff_sptrs_type & changed_bases()
Getter for the changed base classes of the diff.
const diff_sptr return_type_diff() const
Getter for the diff of the return types of the two function types of the current diff.
void ensure_lookup_tables_populated(void) const
If the lookup tables are not yet built, walk the differences and fill them.
A comparison functor for instances of function_decl_diff that represent changes between two virtual m...
const string_type_base_sptr_map & deleted_unreachable_types() const
Getter for a map of deleted types that are not reachable from global functions/variables.
const diff_context_sptr context() const
Getter of the context of the current diff.
Abstraction of a function type.
virtual void finish_diff_type()
Finish the insertion of a diff tree node into the diff graph.
const enum_type_decl_sptr second_enum() const
size_t num_removed_func_filtered_out() const
Getter for the number of removed functions that have been filtered out.
const class_or_union_diff::priv_ptr & get_priv() const
Getter of the private data of the class_or_union_diff type.
void add_diff_filter(filtering::filter_base_sptr)
Setter for the diff filters to apply to a given diff sub-tree.
const 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...
const vector< diff_sptr > & changed_unreachable_types_sorted() const
Get the sorted vector of diff nodes representing changed unreachable types.
size_t num_func_syms_removed() const
Getter for the number of function symbols (not referenced by any debug info) that got removed...
const unsigned_var_diff_sptr_map & changed_data_members() const
Getter of the map of data members that got replaced by another data member. The key of the map is the...
diff_category add_to_local_category(diff_category c)
Adds the current diff tree node to the categories resulting from the local changes of the current dif...
This means that a diff node in the sub-tree carries an addition or removal of a static data member...