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<var_decl_sptr>& 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();
592 qualified_type_def_sptr qut = dynamic_pointer_cast<qualified_type_def>(ut);
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));}
723 if (dif->first_class_or_union()->get_is_anonymous())
759 if (dif->first_subrange()->get_is_anonymous())
796 if (d->has_local_changes())
970diff_context::diff_context()
986diff_context::~diff_context() =
default;
993{
return priv_->do_log_;}
1000{priv_->do_log_ = f;}
1007{priv_->corpus_diff_ = d;}
1014{
return priv_->corpus_diff_;}
1023 if (priv_->corpus_diff_)
1024 return priv_->corpus_diff_->first_corpus();
1025 return corpus_sptr();
1036 if (priv_->corpus_diff_)
1037 return priv_->corpus_diff_->second_corpus();
1038 return corpus_sptr();
1047 if (!priv_->reporter_)
1055 return priv_->reporter_;
1063{priv_->reporter_ = r;}
1077 types_or_decls_diff_map_type::const_iterator i =
1078 priv_->types_or_decls_diff_map.find(std::make_pair(first, second));
1079 if (i != priv_->types_or_decls_diff_map.end())
1093diff_context::has_diff_for_types(
const type_base_sptr first,
1094 const type_base_sptr second)
const
1095{
return has_diff_for(first, second);}
1103diff_context::has_diff_for(
const diff* d)
const
1104{
return has_diff_for(d->first_subject(), d->second_subject()).get();}
1112diff_context::has_diff_for(
const diff_sptr d)
const
1113{
return has_diff_for(d->first_subject(), d->second_subject());}
1122{
return priv_->allowed_category_;}
1131{priv_->allowed_category_ = c;}
1144{priv_->allowed_category_ = priv_->allowed_category_ | c;}
1155{priv_->allowed_category_ = priv_->allowed_category_ & ~c;}
1171{priv_->types_or_decls_diff_map[std::make_pair(first, second)] = d;}
1177diff_context::add_diff(
const diff* d)
1190diff_context::add_diff(
const diff_sptr d)
1193 add_diff(d->first_subject(), d->second_subject(), d);
1210{
return has_diff_for(first, second);}
1222{
return has_diff_for(d);}
1238 if (!has_diff_for(first, second))
1240 add_diff(first, second, d);
1241 priv_->canonical_diffs.push_back(d);
1257diff_context::set_or_get_canonical_diff_for(
const type_or_decl_base_sptr first,
1258 const type_or_decl_base_sptr second,
1266 canonical = canonical_diff;
1267 set_canonical_diff_for(first, second, canonical);
1310{priv_->live_diffs_.insert(d);}
1323 size_t ptr_value =
reinterpret_cast<size_t>(canonical);
1324 pointer_map::iterator it = priv_->visited_diff_nodes_.find(ptr_value);
1325 if (it != priv_->visited_diff_nodes_.end())
1326 return reinterpret_cast<diff*
>(it->second);
1359 size_t canonical_ptr_value =
reinterpret_cast<size_t>(canonical);
1360 size_t diff_ptr_value =
reinterpret_cast<size_t>(d);
1361 priv_->visited_diff_nodes_[canonical_ptr_value] = diff_ptr_value;
1367{priv_->visited_diff_nodes_.clear();}
1377{priv_->forbid_visiting_a_node_twice_ = f;}
1387{priv_->reset_visited_diffs_for_each_interface_ = f;}
1395{
return priv_->forbid_visiting_a_node_twice_;}
1409 return (priv_->forbid_visiting_a_node_twice_
1410 && priv_->reset_visited_diffs_for_each_interface_);
1418{
return priv_->filters_;}
1426{priv_->filters_.push_back(f);}
1444 for (filtering::filters::const_iterator i =
diff_filters().begin();
1451 std::cerr <<
"applying a filter to diff '"
1462 std::cerr <<
"filter applied!:" << t <<
"\n";
1464 std::cerr <<
"propagating categories for the same diff node ... \n";
1473 std::cerr <<
"category propagated!: " << t <<
"\n";
1494 for (filtering::filters::const_iterator i =
diff_filters().begin();
1509{
return priv_->suppressions_;}
1520 priv_->negated_suppressions_.clear();
1521 priv_->direct_suppressions_.clear();
1522 return priv_->suppressions_;
1541 if (priv_->negated_suppressions_.empty())
1544 priv_->negated_suppressions_.push_back(s);
1546 return priv_->negated_suppressions_;
1564 if (priv_->direct_suppressions_.empty())
1568 priv_->direct_suppressions_.push_back(s);
1570 return priv_->direct_suppressions_;
1581 priv_->suppressions_.push_back(suppr);
1584 priv_->negated_suppressions_.clear();
1585 priv_->direct_suppressions_.clear();
1596 priv_->suppressions_.insert(priv_->suppressions_.end(),
1597 supprs.begin(), supprs.end());
1606{
return priv_->perform_change_categorization_;}
1613{priv_->perform_change_categorization_ = f;}
1627 priv_->leaf_changes_only_ = f;
1637{
return priv_->leaf_changes_only_;}
1647{
return priv_->hex_values_;}
1657{priv_->hex_values_ = f;}
1666{
return priv_->show_offsets_sizes_in_bits_;}
1675{priv_->show_offsets_sizes_in_bits_ = f;}
1684{priv_->show_relative_offset_changes_ = f;}
1693{
return priv_->show_relative_offset_changes_;}
1701{priv_->show_stats_only_ = f;}
1709{
return priv_->show_stats_only_;}
1717{priv_->show_soname_change_ = f;}
1725{
return priv_->show_soname_change_;}
1733{priv_->show_architecture_change_ = f;}
1741{
return priv_->show_architecture_change_;}
1748{priv_->show_deleted_fns_ = f;}
1754{
return priv_->show_deleted_fns_;}
1761{priv_->show_changed_fns_ = f;}
1766{
return priv_->show_changed_fns_;}
1773{priv_->show_added_fns_ = f;}
1779{
return priv_->show_added_fns_;}
1786{priv_->show_deleted_vars_ = f;}
1792{
return priv_->show_deleted_vars_;}
1799{priv_->show_changed_vars_ = f;}
1804{
return priv_->show_changed_vars_;}
1811{priv_->show_added_vars_ = f;}
1817{
return priv_->show_added_vars_;}
1820diff_context::show_linkage_names()
const
1821{
return priv_->show_linkage_names_;}
1824diff_context::show_linkage_names(
bool f)
1825{priv_->show_linkage_names_= f;}
1832{priv_->show_locs_= f;}
1838{
return priv_->show_locs_;}
1847{
return priv_->show_redundant_changes_;}
1856{priv_->show_redundant_changes_ = f;}
1864{
return priv_->show_syms_unreferenced_by_di_;}
1872{priv_->show_syms_unreferenced_by_di_ = f;}
1881{
return priv_->show_added_syms_unreferenced_by_di_;}
1890{priv_->show_added_syms_unreferenced_by_di_ = f;}
1899{priv_->show_unreachable_types_ = f;}
1908{
return priv_->show_unreachable_types_;}
1919{
return priv_->show_impacted_interfaces_;}
1930{priv_->show_impacted_interfaces_ = f;}
1939{priv_->default_output_stream_ = o;}
1948{
return priv_->default_output_stream_;}
1956{priv_->error_output_stream_ = o;}
1964{
return priv_->error_output_stream_;}
1973{
return priv_->dump_diff_tree_;}
1982{priv_->dump_diff_tree_ = f;}
2021 : priv_(new priv(first_subject, second_subject,
2043 : priv_(new priv(first_subject, second_subject,
2082 if (priv_->canonical_diff_)
2083 priv_->canonical_diff_->priv_->traversing_ =
true;
2084 priv_->traversing_ =
true;
2101 if (priv_->canonical_diff_)
2102 return priv_->canonical_diff_->priv_->traversing_;
2103 return priv_->traversing_;
2117 if (priv_->canonical_diff_)
2118 priv_->canonical_diff_->priv_->traversing_ =
false;
2119 priv_->traversing_ =
false;
2135 if (diff::priv_->finished_)
2138 diff::priv_->finished_ =
true;
2146{
return dynamic_pointer_cast<type_or_decl_base>(priv_->first_subject_);}
2153{
return dynamic_pointer_cast<type_or_decl_base>(priv_->second_subject_);}
2160{
return priv_->children_;}
2167{
return priv_->parent_;}
2180{
return priv_->canonical_diff_;}
2188{priv_->canonical_diff_ = d;}
2201 context()->keep_diff_alive(d);
2208 priv_->children_.push_back(d.get());
2210 d->priv_->parent_ =
this;
2218{
return priv_->get_context();}
2235 if (priv_->canonical_diff_)
2236 return priv_->canonical_diff_->priv_->currently_reporting_;
2237 return priv_->currently_reporting_;
2248 if (priv_->canonical_diff_)
2249 priv_->canonical_diff_->priv_->currently_reporting_ = f;
2250 priv_->currently_reporting_ = f;
2261 return priv_->canonical_diff_->priv_->reported_once_;
2321 bool already_visited =
false;
2322 if (
context()->visiting_a_node_twice_is_forbidden()
2323 &&
context()->diff_has_been_visited(
this))
2324 already_visited =
true;
2326 bool mark_visited_nodes_as_traversed =
2329 if (!already_visited && !v.
visit(
this,
true))
2332 if (mark_visited_nodes_as_traversed)
2333 context()->mark_diff_as_visited(
this);
2339 && !already_visited)
2346 if (!(*i)->traverse(v))
2349 if (mark_visited_nodes_as_traversed)
2350 context()->mark_diff_as_visited(
this);
2358 if (!v.
visit(
this,
false))
2361 if (mark_visited_nodes_as_traversed)
2362 context()->mark_diff_as_visited(
this);
2367 if (!already_visited && mark_visited_nodes_as_traversed)
2368 context()->mark_diff_as_visited(
this);
2382 priv_->canonical_diff_->priv_->reported_once_ = f;
2383 priv_->reported_once_ = f;
2395{
return priv_->local_category_;}
2421{
return priv_->category_;}
2436 priv_->category_ = priv_->category_ | c;
2437 return priv_->category_;
2451 priv_->local_category_ = priv_->local_category_ | c;
2452 return priv_->local_category_;
2480 priv_->category_ = priv_->category_ & ~c;
2481 return priv_->category_;
2495 priv_->local_category_ = priv_->local_category_ & ~c;
2496 return priv_->local_category_;
2506{priv_->category_ = c;}
2513{priv_->local_category_ = c;}
2538 && !canonical->is_allowed_by_specific_negated_suppression()
2539 && !canonical->has_descendant_allowed_by_specific_negated_suppression()
2540 && !canonical->has_parent_allowed_by_specific_negated_suppression())
2581 return priv_->is_filtered_out(c);
2592 bool is_private =
false;
2621 bool do_suppress = !
context()->negated_suppressions().empty();
2625 for (
auto n :
context()->negated_suppressions())
2626 if (!n->suppresses_diff(
this))
2628 do_suppress =
false;
2635 for (
auto d :
context()->direct_suppressions())
2636 if (d->suppresses_diff(
this))
2640 is_private_type =
true;
2680 for (suppressions_type::const_iterator i = suppressions.begin();
2681 i != suppressions.end();
2685 && !(*i)->suppresses_diff(
this))
2725 if (priv_->pretty_representation_.empty())
2726 priv_->pretty_representation_ =
"empty_diff";
2727 return priv_->pretty_representation_;
2754type_diff_base::type_diff_base(type_base_sptr first_subject,
2755 type_base_sptr second_subject,
2757 :
diff(first_subject, second_subject, ctxt),
2761type_diff_base::~type_diff_base()
2777 decl_base_sptr second_subject,
2779 :
diff(first_subject, second_subject, ctxt),
2783decl_diff_base::~decl_diff_base()
2794 if (diff::priv_->pretty_representation_.empty())
2796 std::ostringstream o;
2797 o <<
"distinct_diff[";
2808 diff::priv_->pretty_representation_ = o.str();
2810 return diff::priv_->pretty_representation_;
2843 :
diff(first, second, ctxt),
2877 if (!priv_->compatible_child_diff)
2890 return priv_->compatible_child_diff;
2915 return typeid(f) !=
typeid(s);
2933 return NO_CHANGE_KIND;
2944 context()->get_reporter()->report(*
this, out, indent);
2967 ctxt->initialize_canonical_diff(result);
2992template<
typename DiffType>
2998 if (shared_ptr<DiffType> f =
2999 dynamic_pointer_cast<DiffType>(first))
3001 shared_ptr<DiffType> s =
3002 dynamic_pointer_cast<DiffType>(second);
3028 dynamic_pointer_cast<class_decl>(first))
3034 if (f->get_is_declaration_only())
3041 if (s->get_is_declaration_only())
3087compute_diff_for_types(
const type_or_decl_base_sptr& first,
3088 const type_or_decl_base_sptr& second,
3091 type_or_decl_base_sptr f = first;
3092 type_or_decl_base_sptr s = second;
3108 ||(d = try_to_diff_distinct_kinds(f, s, ctxt)));
3116operator|(diff_category c1, diff_category c2)
3117{
return static_cast<diff_category
>(
static_cast<unsigned>(c1)
3118 |
static_cast<unsigned>(c2));}
3121operator|=(diff_category& c1, diff_category c2)
3128operator&=(diff_category& c1, diff_category c2)
3135operator^(diff_category c1, diff_category c2)
3136{
return static_cast<diff_category
>(
static_cast<unsigned>(c1)
3137 ^
static_cast<unsigned>(c2));}
3140operator&(diff_category c1, diff_category c2)
3141{
return static_cast<diff_category
>(
static_cast<unsigned>(c1)
3142 &
static_cast<unsigned>(c2));}
3146{
return static_cast<diff_category
>(~static_cast<unsigned>(c));}
3185 | abigail::comparison::REFERENCE_LVALUENESS_CHANGE_CATEGORY
3201 bool emitted_a_category =
false;
3205 o <<
"NO_CHANGE_CATEGORY";
3206 emitted_a_category =
true;
3211 if (emitted_a_category)
3213 o <<
"ACCESS_CHANGE_CATEGORY";
3214 emitted_a_category |=
true;
3219 if (emitted_a_category)
3221 o <<
"COMPATIBLE_TYPE_CHANGE_CATEGORY";
3222 emitted_a_category |=
true;
3227 if (emitted_a_category)
3229 o <<
"HARMLESS_DECL_NAME_CHANGE_CATEGORY";
3230 emitted_a_category |=
true;
3235 if (emitted_a_category)
3237 o <<
"NON_VIRT_MEM_FUN_CHANGE_CATEGORY";
3238 emitted_a_category |=
true;
3243 if (emitted_a_category)
3245 o <<
"STATIC_DATA_MEMBER_CHANGE_CATEGORY";
3246 emitted_a_category |=
true;
3251 if (emitted_a_category)
3253 o <<
"HARMLESS_ENUM_CHANGE_CATEGORY";
3254 emitted_a_category |=
true;
3259 if (emitted_a_category)
3261 o <<
"HARMLESS_DATA_MEMBER_CHANGE_CATEGORY";
3262 emitted_a_category |=
true;
3267 if (emitted_a_category)
3269 o <<
"HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY";
3270 emitted_a_category |=
true;
3275 if (emitted_a_category)
3277 o <<
"HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY";
3278 emitted_a_category |=
true;
3283 if (emitted_a_category)
3285 o <<
"SUPPRESSED_CATEGORY";
3286 emitted_a_category |=
true;
3291 if (emitted_a_category)
3293 o <<
"PRIVATE_TYPE_CATEGORY";
3294 emitted_a_category |=
true;
3299 if (emitted_a_category)
3301 o <<
"SIZE_OR_OFFSET_CHANGE_CATEGORY";
3302 emitted_a_category |=
true;
3307 if (emitted_a_category)
3309 o <<
"VIRTUAL_MEMBER_CHANGE_CATEGORY";
3310 emitted_a_category |=
true;
3313 if (c & REFERENCE_LVALUENESS_CHANGE_CATEGORY)
3315 if (emitted_a_category)
3317 o <<
"REFERENCE_LVALUENESS_CHANGE_CATEGORY";
3318 emitted_a_category |=
true;
3323 if (emitted_a_category)
3325 o <<
"NON_COMPATIBLE_DISTINCT_CHANGE_CATEGORY";
3326 emitted_a_category |=
true;
3331 if (emitted_a_category)
3333 o <<
"NON_COMPATIBLE_NAME_CHANGE_CATEGORY";
3334 emitted_a_category |=
true;
3339 if (emitted_a_category)
3341 o <<
"REDUNDANT_CATEGORY";
3342 emitted_a_category |=
true;
3347 if (emitted_a_category)
3349 o <<
"TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY";
3350 emitted_a_category |=
true;
3355 if (emitted_a_category)
3357 o <<
"FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY";
3358 emitted_a_category |=
true;
3363 if (emitted_a_category)
3365 o <<
"FN_PARM_TYPE_CV_CHANGE_CATEGORY";
3366 emitted_a_category |=
true;
3371 if (emitted_a_category)
3373 o <<
"FN_RETURN_TYPE_CV_CHANGE_CATEGORY";
3374 emitted_a_category |=
true;
3379 if (emitted_a_category)
3381 o <<
"FN_PARM_ADD_REMOVE_CHANGE_CATEGORY";
3382 emitted_a_category |=
true;
3387 if (emitted_a_category)
3389 o <<
"VAR_TYPE_CV_CHANGE_CATEGORY";
3390 emitted_a_category |=
true;
3395 if (emitted_a_category)
3397 o <<
"VOID_PTR_TO_PTR_CHANGE_CATEGORY";
3398 emitted_a_category |=
true;
3403 if (emitted_a_category)
3405 o <<
"BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY";
3406 emitted_a_category |=
true;
3411 if (emitted_a_category)
3413 o <<
"HAS_ALLOWED_CHANGE_CATEGORY";
3414 emitted_a_category |=
true;
3419 if (emitted_a_category)
3421 o <<
"HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY";
3422 emitted_a_category |=
true;
3427 if (emitted_a_category)
3429 o <<
"HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY";
3430 emitted_a_category |=
true;
3453compute_diff_for_decls(
const decl_base_sptr first,
3454 const decl_base_sptr second,
3462 || (d = try_to_diff_distinct_kinds(first, second, ctxt)));
3485 const decl_base_sptr second,
3488 if (!first || !second)
3493 d = compute_diff_for_types(first, second, ctxt);
3495 d = compute_diff_for_decls(first, second, ctxt);
3515 const type_base_sptr second,
3521 diff_sptr d = compute_diff_for_types(f,s, ctxt);
3536 string prefix=
"diff of ";
3556 if (diff::priv_->pretty_representation_.empty())
3558 std::ostringstream o;
3564 diff::priv_->pretty_representation_ = o.str();
3566 return diff::priv_->pretty_representation_;
3609 if (
diff_sptr result = priv_->type_diff_.lock())
3616 context()->keep_diff_alive(result);
3617 priv_->type_diff_ = result;
3638 return ir::NO_CHANGE_KIND;
3650 context()->get_reporter()->report(*
this, out, indent);
3671 ctxt->initialize_canonical_diff(d);
3701 priv_(new
priv(underlying))
3709{
return dynamic_pointer_cast<pointer_type_def>(
first_subject());}
3716{
return dynamic_pointer_cast<pointer_type_def>(
second_subject());}
3723 if (diff::priv_->pretty_representation_.empty())
3725 std::ostringstream o;
3726 o <<
"pointer_diff["
3731 diff::priv_->pretty_representation_ = o.str();
3733 return diff::priv_->pretty_representation_;
3752 return ir::NO_CHANGE_KIND;
3761{
return priv_->underlying_type_diff_;}
3770{priv_->underlying_type_diff_ = d;}
3781 context()->get_reporter()->report(*
this, out, indent);
3801 diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
3802 second->get_pointed_to_type(),
3805 ctxt->initialize_canonical_diff(result);
3830 priv_(new
priv(underlying_type_diff))
3858{
return priv_->underlying_type_diff_;}
3867 if (diff::priv_->pretty_representation_.empty())
3869 std::ostringstream o;
3870 o <<
"subrange_diff["
3875 diff::priv_->pretty_representation_ = o.str();
3877 return diff::priv_->pretty_representation_;
3899 return ir::NO_CHANGE_KIND;
3909{
context()->get_reporter()->report(*
this, out, indent);}
3937 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
3938 second->get_underlying_type(),
3942 ctxt->initialize_canonical_diff(result);
3977 vector<subrange_diff_sptr>& subrange_diffs,
3980 priv_(new
priv(element_type_diff, subrange_diffs))
3988{
return dynamic_pointer_cast<array_type_def>(
first_subject());}
4002{
return priv_->element_type_diff_;}
4007const vector<subrange_diff_sptr>&
4009{
return priv_->subrange_diffs_;}
4030{priv_->element_type_diff_ = d;}
4037{priv_->subrange_diffs_ = d;}
4044 if (diff::priv_->pretty_representation_.empty())
4046 std::ostringstream o;
4052 diff::priv_->pretty_representation_ = o.str();
4054 return diff::priv_->pretty_representation_;
4071 if (f->get_name() != s->get_name())
4073 if (f->get_size_in_bits() != s->get_size_in_bits())
4075 if (f->get_alignment_in_bits() != s->get_alignment_in_bits())
4098 return ir::NO_CHANGE_KIND;
4109 context()->get_reporter()->report(*
this, out, indent);
4127 diff_sptr element_diff = compute_diff_for_types(first->get_element_type(),
4128 second->get_element_type(),
4130 vector<subrange_diff_sptr> subrange_diffs;
4131 if (first->get_subranges().size() == first->get_subranges().size())
4133 for (
unsigned i = 0; i < first->get_subranges().size(); ++i)
4137 second->get_subranges()[i],
4146 ctxt->initialize_canonical_diff(result);
4174 priv_(new
priv(underlying))
4182{
return dynamic_pointer_cast<reference_type_def>(
first_subject());}
4189{
return dynamic_pointer_cast<reference_type_def>(
second_subject());}
4197{
return priv_->underlying_type_diff_;}
4205 priv_->underlying_type_diff_ = d;
4206 return priv_->underlying_type_diff_;
4214 if (diff::priv_->pretty_representation_.empty())
4216 std::ostringstream o;
4217 o <<
"reference_diff["
4222 diff::priv_->pretty_representation_ = o.str();
4224 return diff::priv_->pretty_representation_;
4245 return ir::NO_CHANGE_KIND;
4256 context()->get_reporter()->report(*
this, out, indent);
4274 diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
4275 second->get_pointed_to_type(),
4278 ctxt->initialize_canonical_diff(result);
4305 priv_(new
priv(member_type_diff, containing_type_diff))
4315{
return dynamic_pointer_cast<ptr_to_mbr_type>(
first_subject());}
4333{
return priv_->member_type_diff_;}
4342{
return priv_->containing_type_diff_;}
4362 return ir::NO_CHANGE_KIND;
4372 if (diff::priv_->pretty_representation_.empty())
4374 std::ostringstream o;
4375 o <<
"ptr_to_mbr_diff["
4380 diff::priv_->pretty_representation_ = o.str();
4382 return diff::priv_->pretty_representation_;
4388 context()->get_reporter()->report(*
this, out, indent);
4425 is_type(second->get_member_type()),
4430 is_type(second->get_containing_type()),
4435 containing_type_diff,
4437 ctxt->initialize_canonical_diff(result);
4462 qualified_type_def_sptr second,
4466 priv_(new
priv(under))
4472const qualified_type_def_sptr
4474{
return dynamic_pointer_cast<qualified_type_def>(
first_subject());}
4479const qualified_type_def_sptr
4481{
return dynamic_pointer_cast<qualified_type_def>(
second_subject());}
4490{
return priv_->underlying_type_diff;}
4500 if (!priv_->leaf_underlying_type_diff)
4501 priv_->leaf_underlying_type_diff
4506 return priv_->leaf_underlying_type_diff;
4516{priv_->underlying_type_diff = d;}
4523 if (diff::priv_->pretty_representation_.empty())
4525 std::ostringstream o;
4526 o <<
"qualified_type_diff["
4531 diff::priv_->pretty_representation_ = o.str();
4533 return diff::priv_->pretty_representation_;
4552 return ir::NO_CHANGE_KIND;
4563 context()->get_reporter()->report(*
this, out, indent);
4576qualified_type_diff_sptr
4578 const qualified_type_def_sptr second,
4581 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
4582 second->get_underlying_type(),
4586 ctxt->initialize_canonical_diff(result);
4599enum_diff::clear_lookup_tables()
4601 priv_->deleted_enumerators_.clear();
4602 priv_->inserted_enumerators_.clear();
4603 priv_->changed_enumerators_.clear();
4610enum_diff::lookup_tables_empty()
const
4612 return (priv_->deleted_enumerators_.empty()
4613 && priv_->inserted_enumerators_.empty()
4614 && priv_->changed_enumerators_.empty());
4620enum_diff::ensure_lookup_tables_populated()
4622 if (!lookup_tables_empty())
4626 edit_script e = priv_->enumerators_changes_;
4628 for (vector<deletion>::const_iterator it = e.deletions().begin();
4629 it != e.deletions().end();
4632 unsigned i = it->index();
4633 const enum_type_decl::enumerator& n =
4635 const string& name = n.get_name();
4636 ABG_ASSERT(priv_->deleted_enumerators_.find(n.get_name())
4637 == priv_->deleted_enumerators_.end());
4638 priv_->deleted_enumerators_[name] = n;
4641 for (vector<insertion>::const_iterator it = e.insertions().begin();
4642 it != e.insertions().end();
4645 for (vector<unsigned>::const_iterator iit =
4646 it->inserted_indexes().begin();
4647 iit != it->inserted_indexes().end();
4651 const enum_type_decl::enumerator& n =
4653 const string& name = n.get_name();
4654 ABG_ASSERT(priv_->inserted_enumerators_.find(n.get_name())
4655 == priv_->inserted_enumerators_.end());
4656 string_enumerator_map::const_iterator j =
4657 priv_->deleted_enumerators_.find(name);
4658 if (j == priv_->deleted_enumerators_.end())
4659 priv_->inserted_enumerators_[name] = n;
4663 priv_->changed_enumerators_[j->first] =
4664 std::make_pair(j->second, n);
4665 priv_->deleted_enumerators_.erase(j);
4696 priv_(new
priv(underlying_type_diff))
4702{
return dynamic_pointer_cast<enum_type_decl>(
first_subject());}
4712{
return priv_->underlying_type_diff_;}
4717{
return priv_->deleted_enumerators_;}
4722{
return priv_->inserted_enumerators_;}
4727{
return priv_->changed_enumerators_;}
4734 if (diff::priv_->pretty_representation_.empty())
4736 std::ostringstream o;
4742 diff::priv_->pretty_representation_ = o.str();
4744 return diff::priv_->pretty_representation_;
4763 return ir::NO_CHANGE_KIND;
4774 context()->get_reporter()->report(*
this, out, indent);
4796 diff_sptr ud = compute_diff_for_types(first->get_underlying_type(),
4797 second->get_underlying_type(),
4799 enum_diff_sptr d(
new enum_diff(first, second, ud, ctxt));
4800 if (first != second)
4803 first->get_enumerators().end(),
4804 second->get_enumerators().begin(),
4805 second->get_enumerators().end(),
4806 d->priv_->enumerators_changes_);
4807 d->ensure_lookup_tables_populated();
4809 ctxt->initialize_canonical_diff(d);
4831 string qname = d->get_qualified_name();
4832 string_diff_sptr_map::const_iterator it =
4833 changed_member_types_.find(qname);
4835 return ((it == changed_member_types_.end())
4837 : it->second->second_subject());
4854 string qname = d->get_qualified_name();
4855 string_var_diff_sptr_map::const_iterator it =
4856 subtype_changed_dm_.find(qname);
4858 if (it == subtype_changed_dm_.end())
4859 return decl_base_sptr();
4860 return it->second->second_var();
4878 string qname = d->get_qualified_name();
4879 string_diff_sptr_map::const_iterator it =
4880 changed_member_class_tmpls_.find(qname);
4882 return ((it == changed_member_class_tmpls_.end())
4884 : dynamic_pointer_cast<decl_base>(it->second->second_subject()));
4895 for (string_decl_base_sptr_map::const_iterator i =
4896 deleted_data_members_.begin();
4897 i != deleted_data_members_.end();
4914 for (string_decl_base_sptr_map::const_iterator i =
4915 inserted_data_members_.begin();
4916 i != inserted_data_members_.end();
4936 size_t num_filtered= 0;
4937 for (var_diff_sptrs_type::const_iterator i =
4938 sorted_subtype_changed_dm_.begin();
4939 i != sorted_subtype_changed_dm_.end();
4944 if ((*i)->has_local_changes() && (*i)->is_filtered_out())
4949 if ((*i)->is_filtered_out())
4953 return num_filtered;
4967 size_t num_filtered= 0;
4969 for (unsigned_var_diff_sptr_map::const_iterator i = changed_dm_.begin();
4970 i != changed_dm_.end();
4985 return num_filtered;
4994#define SKIP_MEM_FN_IF_VIRTUALITY_DISALLOWED \
4996 if (get_member_function_is_virtual(f) \
4997 || get_member_function_is_virtual(s)) \
4999 if (!(allowed_category | VIRTUAL_MEMBER_CHANGE_CATEGORY)) \
5004 if (!(allowed_category | NON_VIRT_MEM_FUN_CHANGE_CATEGORY)) \
5019 diff_category allowed_category = ctxt->get_allowed_category();
5021 for (function_decl_diff_sptrs_type::const_iterator i =
5022 sorted_changed_member_functions_.begin();
5023 i != sorted_changed_member_functions_.end();
5026 method_decl_sptr f =
5027 dynamic_pointer_cast<method_decl>
5028 ((*i)->first_function_decl());
5031 method_decl_sptr s =
5032 dynamic_pointer_cast<method_decl>
5033 ((*i)->second_function_decl());
5039 ctxt->maybe_apply_filters(
diff);
5058 diff_category allowed_category = ctxt->get_allowed_category();
5060 for (string_member_function_sptr_map::const_iterator i =
5061 inserted_member_functions_.begin();
5062 i != inserted_member_functions_.end();
5065 method_decl_sptr f = i->second,
5071 ctxt->maybe_apply_filters(
diff);
5091 diff_category allowed_category = ctxt->get_allowed_category();
5093 for (string_member_function_sptr_map::const_iterator i =
5094 deleted_member_functions_.begin();
5095 i != deleted_member_functions_.end();
5098 method_decl_sptr f = i->second,
5104 ctxt->maybe_apply_filters(
diff);
5121 priv_->deleted_member_types_.clear();
5122 priv_->inserted_member_types_.clear();
5123 priv_->changed_member_types_.clear();
5124 priv_->deleted_data_members_.clear();
5125 priv_->inserted_data_members_.clear();
5126 priv_->subtype_changed_dm_.clear();
5127 priv_->deleted_member_functions_.clear();
5128 priv_->inserted_member_functions_.clear();
5129 priv_->changed_member_functions_.clear();
5130 priv_->deleted_member_class_tmpls_.clear();
5131 priv_->inserted_member_class_tmpls_.clear();
5132 priv_->changed_member_class_tmpls_.clear();
5141 return (priv_->deleted_member_types_.empty()
5142 && priv_->inserted_member_types_.empty()
5143 && priv_->changed_member_types_.empty()
5144 && priv_->deleted_data_members_.empty()
5145 && priv_->inserted_data_members_.empty()
5146 && priv_->subtype_changed_dm_.empty()
5147 && priv_->inserted_member_functions_.empty()
5148 && priv_->deleted_member_functions_.empty()
5149 && priv_->changed_member_functions_.empty()
5150 && priv_->deleted_member_class_tmpls_.empty()
5151 && priv_->inserted_member_class_tmpls_.empty()
5152 && priv_->changed_member_class_tmpls_.empty());
5163 for (vector<deletion>::const_iterator it = e.deletions().begin();
5164 it != e.deletions().end();
5167 unsigned i = it->index();
5171 if (record_type && record_type->get_is_declaration_only())
5173 string name = d->get_name();
5174 priv_->deleted_member_types_[name] = d;
5177 for (vector<insertion>::const_iterator it = e.insertions().begin();
5178 it != e.insertions().end();
5181 for (vector<unsigned>::const_iterator iit =
5182 it->inserted_indexes().begin();
5183 iit != it->inserted_indexes().end();
5190 if (record_type && record_type->get_is_declaration_only())
5192 string name = d->get_name();
5193 string_decl_base_sptr_map::const_iterator j =
5194 priv_->deleted_member_types_.find(name);
5195 if (j != priv_->deleted_member_types_.end())
5197 if (*j->second != *d)
5198 priv_->changed_member_types_[name] =
5201 priv_->deleted_member_types_.erase(j);
5204 priv_->inserted_member_types_[name] = d;
5212 for (vector<deletion>::const_iterator it = e.deletions().begin();
5213 it != e.deletions().end();
5216 unsigned i = it->index();
5219 string name = data_member->get_anon_dm_reliable_name();
5221 ABG_ASSERT(priv_->deleted_data_members_.find(name)
5222 == priv_->deleted_data_members_.end());
5223 priv_->deleted_data_members_[name] = data_member;
5226 for (vector<insertion>::const_iterator it = e.insertions().begin();
5227 it != e.insertions().end();
5230 for (vector<unsigned>::const_iterator iit =
5231 it->inserted_indexes().begin();
5232 iit != it->inserted_indexes().end();
5239 string name = added_dm->get_anon_dm_reliable_name();
5240 ABG_ASSERT(priv_->inserted_data_members_.find(name)
5241 == priv_->inserted_data_members_.end());
5243 bool ignore_added_anonymous_data_member =
false;
5281 bool added_anon_dm_changes_dm =
false;
5284 vector<var_decl_sptr> dms_replaced_by_anon_dm;
5293 for (string_decl_base_sptr_map::const_iterator it =
5294 priv_->deleted_data_members_.begin();
5295 it != priv_->deleted_data_members_.end();
5304 string deleted_dm_name = it->second->get_name();
5320 size_t replaced_dm_offset =
5322 replacing_dm_offset =
5325 if (replaced_dm_offset != replacing_dm_offset)
5333 added_anon_dm_changes_dm =
true;
5337 if (replaced_dm->get_type()->get_size_in_bits()
5338 == replaced_dm->get_type()->get_size_in_bits())
5339 dms_replaced_by_anon_dm.push_back(replaced_dm);
5342 added_anon_dm_changes_dm =
true;
5351 if (!added_anon_dm_changes_dm
5352 && !dms_replaced_by_anon_dm.empty())
5355 type_base_sptr added_dm_type = added_dm->get_type();
5371 ignore_added_anonymous_data_member =
true;
5372 for (vector<var_decl_sptr>::const_iterator i =
5373 dms_replaced_by_anon_dm.begin();
5374 i != dms_replaced_by_anon_dm.end();
5377 string n = (*i)->get_name();
5378 priv_->dms_replaced_by_adms_[n] =
5380 priv_->deleted_data_members_.erase(n);
5386 if (!ignore_added_anonymous_data_member)
5399 string_decl_base_sptr_map::const_iterator j =
5400 priv_->deleted_data_members_.find(name);
5401 if (j != priv_->deleted_data_members_.end())
5403 if (*j->second != *d)
5406 priv_->subtype_changed_dm_[name]=
5409 priv_->deleted_data_members_.erase(j);
5412 priv_->inserted_data_members_[name] = d;
5420 for (string_decl_base_sptr_map::const_iterator i =
5421 priv_->deleted_data_members_.begin();
5422 i != priv_->deleted_data_members_.end();
5426 priv_->deleted_dm_by_offset_[offset] = i->second;
5429 for (string_decl_base_sptr_map::const_iterator i =
5430 priv_->inserted_data_members_.begin();
5431 i != priv_->inserted_data_members_.end();
5435 priv_->inserted_dm_by_offset_[offset] = i->second;
5438 for (unsigned_decl_base_sptr_map::const_iterator i =
5439 priv_->inserted_dm_by_offset_.begin();
5440 i != priv_->inserted_dm_by_offset_.end();
5443 unsigned_decl_base_sptr_map::const_iterator j =
5444 priv_->deleted_dm_by_offset_.find(i->first);
5445 if (j != priv_->deleted_dm_by_offset_.end())
5449 priv_->changed_dm_[i->first] =
5454 for (unsigned_var_diff_sptr_map::const_iterator i =
5455 priv_->changed_dm_.begin();
5456 i != priv_->changed_dm_.end();
5459 priv_->deleted_dm_by_offset_.erase(i->first);
5460 priv_->inserted_dm_by_offset_.erase(i->first);
5461 priv_->deleted_data_members_.erase
5462 (i->second->first_var()->get_anon_dm_reliable_name());
5463 priv_->inserted_data_members_.erase
5464 (i->second->second_var()->get_anon_dm_reliable_name());
5472 non_anonymous_dms_in_second_class);
5473 vector<string> deleted_data_members_to_delete;
5475 for (
auto& entry : priv_->deleted_data_members_)
5492 bool anonymous_dm_members_present =
true;
5496 for (
auto& e : non_anonymous_data_members)
5498 if (non_anonymous_dms_in_second_class.find(e.first)
5499 == non_anonymous_dms_in_second_class.end())
5504 anonymous_dm_members_present =
false;
5506 if (anonymous_dm_members_present)
5511 deleted_data_members_to_delete.push_back(data_member->get_anon_dm_reliable_name());
5517 for (
string& name_of_dm_to_delete: deleted_data_members_to_delete)
5518 priv_->deleted_data_members_.erase(name_of_dm_to_delete);
5521 priv_->sorted_subtype_changed_dm_);
5523 priv_->sorted_changed_dm_);
5526 edit_script& e = priv_->member_class_tmpls_changes_;
5528 for (vector<deletion>::const_iterator it = e.deletions().begin();
5529 it != e.deletions().end();
5532 unsigned i = it->index();
5536 string name = d->get_name();
5537 ABG_ASSERT(priv_->deleted_member_class_tmpls_.find(name)
5538 == priv_->deleted_member_class_tmpls_.end());
5539 priv_->deleted_member_class_tmpls_[name] = d;
5542 for (vector<insertion>::const_iterator it = e.insertions().begin();
5543 it != e.insertions().end();
5546 for (vector<unsigned>::const_iterator iit =
5547 it->inserted_indexes().begin();
5548 iit != it->inserted_indexes().end();
5555 string name = d->get_name();
5556 ABG_ASSERT(priv_->inserted_member_class_tmpls_.find(name)
5557 == priv_->inserted_member_class_tmpls_.end());
5558 string_decl_base_sptr_map::const_iterator j =
5559 priv_->deleted_member_class_tmpls_.find(name);
5560 if (j != priv_->deleted_member_class_tmpls_.end())
5562 if (*j->second != *d)
5563 priv_->changed_member_types_[name]=
5565 priv_->deleted_member_class_tmpls_.erase(j);
5568 priv_->inserted_member_class_tmpls_[name] = d;
5573 priv_->sorted_changed_member_types_);
5582 priv_.reset(
new priv);
5593 class_or_union_sptr second_scope,
5611const class_or_union_diff::priv_ptr&
5624 return canonical->priv_;
5646{
return get_priv()->member_types_changes_;}
5652{
return get_priv()->member_types_changes_;}
5658{
return get_priv()->data_members_changes_;}
5664{
return get_priv()->data_members_changes_;}
5671{
return get_priv()->inserted_data_members_;}
5678{
return get_priv()->deleted_data_members_;}
5684{
return get_priv()->member_fns_changes_;}
5693{
return get_priv()->sorted_changed_member_functions_;}
5699{
return get_priv()->member_fns_changes_;}
5704{
return get_priv()->deleted_member_functions_;}
5709{
return get_priv()->inserted_member_functions_;}
5727{
return get_priv()->sorted_changed_dm_;}
5735{
return get_priv()->count_filtered_changed_dm(local);}
5742{
return get_priv()->sorted_subtype_changed_dm_;}
5749{
return get_priv()->count_filtered_subtype_changed_dm(local);}
5761{
return get_priv()->dms_replaced_by_adms_;}
5773 if (priv_->dms_replaced_by_adms_ordered_.empty())
5775 for (string_decl_base_sptr_map::const_iterator it =
5776 priv_->dms_replaced_by_adms_.begin();
5777 it != priv_->dms_replaced_by_adms_.end();
5784 priv_->dms_replaced_by_adms_ordered_.push_back(changed_dm);
5789 return priv_->dms_replaced_by_adms_ordered_;
5796{
return get_priv()->member_fn_tmpls_changes_;}
5802{
return get_priv()->member_fn_tmpls_changes_;}
5808{
return get_priv()->member_class_tmpls_changes_;}
5814{
return get_priv()->member_class_tmpls_changes_;}
5830 return ir::NO_CHANGE_KIND;
5843 context()->get_reporter()->report(*
this, out, indent);
5855 for (var_diff_sptrs_type::const_iterator i =
5856 get_priv()->sorted_subtype_changed_dm_.begin();
5857 i !=
get_priv()->sorted_subtype_changed_dm_.end();
5862 for (var_diff_sptrs_type::const_iterator i =
5863 get_priv()->sorted_changed_dm_.begin();
5864 i !=
get_priv()->sorted_changed_dm_.end();
5870 for (diff_sptrs_type::const_iterator i =
5871 get_priv()->sorted_changed_member_types_.begin();
5872 i !=
get_priv()->sorted_changed_member_types_.end();
5878 for (function_decl_diff_sptrs_type::const_iterator i =
5879 get_priv()->sorted_changed_member_functions_.begin();
5880 i !=
get_priv()->sorted_changed_member_functions_.end();
5895class_diff::clear_lookup_tables(
void)
5897 priv_->deleted_bases_.clear();
5898 priv_->inserted_bases_.clear();
5899 priv_->changed_bases_.clear();
5906class_diff::lookup_tables_empty(
void)
const
5908 return (priv_->deleted_bases_.empty()
5909 && priv_->inserted_bases_.empty()
5910 && priv_->changed_bases_.empty());
5920static string_member_function_sptr_map::const_iterator
5923 for (string_member_function_sptr_map::const_iterator i = map.begin();
5937class_diff::ensure_lookup_tables_populated(
void)
const
5941 if (!lookup_tables_empty())
5945 edit_script& e = get_priv()->base_changes_;
5947 for (vector<deletion>::const_iterator it = e.deletions().begin();
5948 it != e.deletions().end();
5951 unsigned i = it->index();
5954 string name = b->get_base_class()->get_qualified_name();
5955 ABG_ASSERT(get_priv()->deleted_bases_.find(name)
5956 == get_priv()->deleted_bases_.end());
5957 get_priv()->deleted_bases_[name] = b;
5960 for (vector<insertion>::const_iterator it = e.insertions().begin();
5961 it != e.insertions().end();
5964 for (vector<unsigned>::const_iterator iit =
5965 it->inserted_indexes().begin();
5966 iit != it->inserted_indexes().end();
5972 string name = b->get_base_class()->get_qualified_name();
5973 ABG_ASSERT(get_priv()->inserted_bases_.find(name)
5974 == get_priv()->inserted_bases_.end());
5975 string_base_sptr_map::const_iterator j =
5976 get_priv()->deleted_bases_.find(name);
5977 if (j != get_priv()->deleted_bases_.end())
5980 get_priv()->changed_bases_[name] =
5986 get_priv()->moved_bases_.push_back(b);
5987 get_priv()->deleted_bases_.erase(j);
5990 get_priv()->inserted_bases_[name] = b;
6000 class_or_union_diff::priv_->deleted_data_members_;
6002 vector<var_decl_sptr> deleted_data_members_present_in_bases;
6010 var_decl_sptr member = klass->find_data_member(deleted_member->get_name());
6012 deleted_data_members_present_in_bases.push_back(member);
6019 for (
var_decl_sptr m : deleted_data_members_present_in_bases)
6021 string name = m->get_name();
6025 if (*deleted_member != *m)
6029 class_or_union_diff::priv_->subtype_changed_dm_[name]= dif;
6036 get_priv()->sorted_deleted_bases_);
6038 get_priv()->sorted_inserted_bases_);
6040 get_priv()->sorted_changed_bases_);
6045 edit_script& e = p->member_fns_changes_;
6047 for (vector<deletion>::const_iterator it = e.deletions().begin();
6048 it != e.deletions().end();
6051 unsigned i = it->index();
6052 method_decl_sptr mem_fn =
6054 string name = mem_fn->get_linkage_name();
6056 name = mem_fn->get_pretty_representation();
6058 if (p->deleted_member_functions_.find(name)
6059 != p->deleted_member_functions_.end())
6061 p->deleted_member_functions_[name] = mem_fn;
6064 for (vector<insertion>::const_iterator it = e.insertions().begin();
6065 it != e.insertions().end();
6068 for (vector<unsigned>::const_iterator iit =
6069 it->inserted_indexes().begin();
6070 iit != it->inserted_indexes().end();
6075 method_decl_sptr mem_fn =
6077 string name = mem_fn->get_linkage_name();
6079 name = mem_fn->get_pretty_representation();
6081 if (p->inserted_member_functions_.find(name)
6082 != p->inserted_member_functions_.end())
6084 string_member_function_sptr_map::const_iterator j =
6085 p->deleted_member_functions_.find(name);
6087 if (j != p->deleted_member_functions_.end())
6089 if (*j->second != *mem_fn)
6090 p->changed_member_functions_[name] =
6091 compute_diff(static_pointer_cast<function_decl>(j->second),
6092 static_pointer_cast<function_decl>(mem_fn),
6094 p->deleted_member_functions_.erase(j);
6097 p->inserted_member_functions_[name] = mem_fn;
6144 vector<string> to_delete;
6145 corpus_sptr f =
context()->get_first_corpus(),
6146 s =
context()->get_second_corpus();
6148 for (string_member_function_sptr_map::const_iterator i =
6167 find_virtual_dtor_in_map(p->inserted_member_functions_);
6168 if (it != p->inserted_member_functions_.end())
6176 (!i->second->get_linkage_name().empty())
6177 ? i->second->get_linkage_name()
6178 : i->second->get_pretty_representation();
6179 to_delete.push_back(name);
6180 p->inserted_member_functions_.erase(it);
6187 if (!i->second->get_symbol()
6188 || s->lookup_function_symbol(*i->second->get_symbol()))
6189 to_delete.push_back(i->first);
6193 for (vector<string>::const_iterator i = to_delete.begin();
6194 i != to_delete.end();
6196 p->deleted_member_functions_.erase(*i);
6201 for (string_member_function_sptr_map::const_iterator i =
6210 if (!i->second->get_symbol()
6211 || f->lookup_function_symbol(*i->second->get_symbol()))
6212 to_delete.push_back(i->first);
6215 for (vector<string>::const_iterator i = to_delete.begin();
6216 i != to_delete.end();
6218 p->inserted_member_functions_.erase(*i);
6221 p->sorted_deleted_member_functions_);
6224 p->sorted_inserted_member_functions_);
6227 (p->changed_member_functions_,
6228 p->sorted_changed_member_functions_);
6235class_diff::allocate_priv_data()
6239 priv_.reset(
new priv);
6252 string qname = d->get_base_class()->get_qualified_name();
6253 string_base_diff_sptr_map::const_iterator it =
6254 changed_bases_.find(qname);
6256 return (it == changed_bases_.end())
6258 : it->second->second_base();
6269 size_t num_filtered = 0;
6270 for (base_diff_sptrs_type::const_iterator i = sorted_changed_bases_.begin();
6271 i != sorted_changed_bases_.end();
6278 return num_filtered;
6292 for (base_diff_sptrs_type::const_iterator i =
6293 get_priv()->sorted_changed_bases_.begin();
6294 i != get_priv()->sorted_changed_bases_.end();
6319class_diff::~class_diff()
6333const class_diff::priv_ptr&
6334class_diff::get_priv()
const
6346 return canonical->priv_;
6354 if (diff::priv_->pretty_representation_.empty())
6356 std::ostringstream o;
6362 diff::priv_->pretty_representation_ = o.str();
6364 return diff::priv_->pretty_representation_;
6383 return ir::NO_CHANGE_KIND;
6387shared_ptr<class_decl>
6394shared_ptr<class_decl>
6401{
return get_priv()->base_changes_;}
6409{
return get_priv()->deleted_bases_;}
6417{
return get_priv()->inserted_bases_;}
6424{
return get_priv()->sorted_changed_bases_;}
6432const vector<class_decl::base_spec_sptr>&
6434{
return get_priv()->moved_bases_;}
6439{
return get_priv()->base_changes_;}
6450 context()->get_reporter()->report(*
this, out, indent);
6475 ctxt->initialize_canonical_diff(changes);
6478 if (!ctxt->get_canonical_diff_for(first, second))
6482 diff_sptr canonical_diff = ctxt->get_canonical_diff_for(changes);
6484 ctxt->set_canonical_diff_for(first, second, canonical_diff);
6500 if (
is_class_diff(changes->get_canonical_diff()) == changes.get())
6503 changes->allocate_priv_data();
6515 f->get_base_specifiers().end(),
6516 s->get_base_specifiers().begin(),
6517 s->get_base_specifiers().end(),
6518 changes->base_changes());
6524 f->get_member_types().end(),
6525 s->get_member_types().begin(),
6526 s->get_member_types().end(),
6527 changes->member_types_changes());
6532 f->get_non_static_data_members().end(),
6533 s->get_non_static_data_members().begin(),
6534 s->get_non_static_data_members().end(),
6535 changes->data_members_changes());
6539 f->get_virtual_mem_fns().end(),
6540 s->get_virtual_mem_fns().begin(),
6541 s->get_virtual_mem_fns().end(),
6542 changes->member_fns_changes());
6545 compute_diff(f->get_member_function_templates().begin(),
6546 f->get_member_function_templates().end(),
6547 s->get_member_function_templates().begin(),
6548 s->get_member_function_templates().end(),
6549 changes->member_fn_tmpls_changes());
6554 f->get_member_class_templates().end(),
6555 s->get_member_class_templates().begin(),
6556 s->get_member_class_templates().end(),
6557 changes->member_class_tmpls_changes());
6560 changes->ensure_lookup_tables_populated();
6590 :
diff(first, second, ctxt),
6591 priv_(new
priv(underlying))
6599{
return dynamic_pointer_cast<class_decl::base_spec>(
first_subject());}
6606{
return dynamic_pointer_cast<class_decl::base_spec>(
second_subject());}
6615{
return priv_->underlying_class_diff_;}
6624{priv_->underlying_class_diff_ = d;}
6631 if (diff::priv_->pretty_representation_.empty())
6633 std::ostringstream o;
6639 diff::priv_->pretty_representation_ = o.str();
6641 return diff::priv_->pretty_representation_;
6660 return ir::NO_CHANGE_KIND;
6671 context()->get_reporter()->report(*
this, out, indent);
6693 second->get_base_class(),
6697 ctxt->initialize_canonical_diff(changes);
6712union_diff::clear_lookup_tables(
void)
6719union_diff::lookup_tables_empty(
void)
const
6725union_diff::ensure_lookup_tables_populated(
void)
const
6731union_diff::allocate_priv_data()
6744 union_decl_sptr second_union,
6767 if (diff::priv_->pretty_representation_.empty())
6769 std::ostringstream o;
6775 diff::priv_->pretty_representation_ = o.str();
6777 return diff::priv_->pretty_representation_;
6789 context()->get_reporter()->report(*
this, out, indent);
6804 const union_decl_sptr second,
6807 union_diff_sptr changes(
new union_diff(first, second, ctxt));
6809 ctxt->initialize_canonical_diff(changes);
6825 if (
is_union_diff(changes->get_canonical_diff()) == changes.get())
6828 changes->allocate_priv_data();
6839 compute_diff(first->get_non_static_data_members().begin(),
6840 first->get_non_static_data_members().end(),
6841 second->get_non_static_data_members().begin(),
6842 second->get_non_static_data_members().end(),
6843 changes->data_members_changes());
6848 first->get_mem_fns().end(),
6849 second->get_mem_fns().begin(),
6850 second->get_mem_fns().end(),
6851 changes->member_fns_changes());
6854 compute_diff(first->get_member_function_templates().begin(),
6855 first->get_member_function_templates().end(),
6856 second->get_member_function_templates().begin(),
6857 second->get_member_function_templates().end(),
6858 changes->member_fn_tmpls_changes());
6861 changes->ensure_lookup_tables_populated();
6875scope_diff::clear_lookup_tables()
6877 priv_->deleted_types_.clear();
6878 priv_->deleted_decls_.clear();
6879 priv_->inserted_types_.clear();
6880 priv_->inserted_decls_.clear();
6881 priv_->changed_types_.clear();
6882 priv_->changed_decls_.clear();
6883 priv_->removed_types_.clear();
6884 priv_->removed_decls_.clear();
6885 priv_->added_types_.clear();
6886 priv_->added_decls_.clear();
6896scope_diff::lookup_tables_empty()
const
6898 return (priv_->deleted_types_.empty()
6899 && priv_->deleted_decls_.empty()
6900 && priv_->inserted_types_.empty()
6901 && priv_->inserted_decls_.empty()
6902 && priv_->changed_types_.empty()
6903 && priv_->changed_decls_.empty()
6904 && priv_->removed_types_.empty()
6905 && priv_->removed_decls_.empty()
6906 && priv_->added_types_.empty()
6907 && priv_->added_decls_.empty());
6913scope_diff::ensure_lookup_tables_populated()
6915 if (!lookup_tables_empty())
6918 edit_script& e = priv_->member_changes_;
6921 for (
const auto& deletion : e.deletions())
6923 unsigned i = deletion.index();
6925 string qname = decl->get_qualified_name();
6929 if (klass_decl && klass_decl->get_is_declaration_only())
6940 == priv_->deleted_types_.end());
6941 priv_->deleted_types_[qname] = decl;
6946 == priv_->deleted_decls_.end());
6947 priv_->deleted_decls_[qname] = decl;
6953 for (vector<insertion>::const_iterator it = e.insertions().begin();
6954 it != e.insertions().end();
6957 for (vector<unsigned>::const_iterator i = it->inserted_indexes().begin();
6958 i != it->inserted_indexes().end();
6962 string qname = decl->get_qualified_name();
6966 dynamic_pointer_cast<class_decl>(decl);
6967 if (klass_decl && klass_decl->get_is_declaration_only())
6977 ABG_ASSERT(priv_->inserted_types_.find(qname)
6978 == priv_->inserted_types_.end());
6979 string_decl_base_sptr_map::const_iterator j =
6980 priv_->deleted_types_.find(qname);
6981 if (j != priv_->deleted_types_.end())
6983 if (*j->second != *decl)
6984 priv_->changed_types_[qname] =
6986 priv_->deleted_types_.erase(j);
6989 priv_->inserted_types_[qname] = decl;
6993 ABG_ASSERT(priv_->inserted_decls_.find(qname)
6994 == priv_->inserted_decls_.end());
6995 string_decl_base_sptr_map::const_iterator j =
6996 priv_->deleted_decls_.find(qname);
6997 if (j != priv_->deleted_decls_.end())
6999 if (*j->second != *decl)
7000 priv_->changed_decls_[qname] =
7002 priv_->deleted_decls_.erase(j);
7005 priv_->inserted_decls_[qname] = decl;
7011 priv_->sorted_changed_decls_);
7013 priv_->sorted_changed_types_);
7016 for (string_decl_base_sptr_map::const_iterator i =
7017 priv_->deleted_types_.begin();
7018 i != priv_->deleted_types_.end();
7021 string_decl_base_sptr_map::const_iterator r =
7022 priv_->inserted_types_.find(i->first);
7023 if (r == priv_->inserted_types_.end())
7024 priv_->removed_types_[i->first] = i->second;
7026 for (string_decl_base_sptr_map::const_iterator i =
7027 priv_->deleted_decls_.begin();
7028 i != priv_->deleted_decls_.end();
7031 string_decl_base_sptr_map::const_iterator r =
7032 priv_->inserted_decls_.find(i->first);
7033 if (r == priv_->inserted_decls_.end())
7034 priv_->removed_decls_[i->first] = i->second;
7038 for (string_decl_base_sptr_map::const_iterator i =
7039 priv_->inserted_types_.begin();
7040 i != priv_->inserted_types_.end();
7043 string_decl_base_sptr_map::const_iterator r =
7044 priv_->deleted_types_.find(i->first);
7045 if (r == priv_->deleted_types_.end())
7046 priv_->added_types_[i->first] = i->second;
7048 for (string_decl_base_sptr_map::const_iterator i =
7049 priv_->inserted_decls_.begin();
7050 i != priv_->inserted_decls_.end();
7053 string_decl_base_sptr_map::const_iterator r =
7054 priv_->deleted_decls_.find(i->first);
7055 if (r == priv_->deleted_decls_.end())
7056 priv_->added_decls_[i->first] = i->second;
7068 for (diff_sptrs_type::const_iterator i =
changed_types().begin();
7074 for (diff_sptrs_type::const_iterator i =
changed_decls().begin();
7094 :
diff(first_scope, second_scope, ctxt),
7132{
return priv_->member_changes_;}
7154{
return priv_->member_changes_;}
7169 return scope->get_member_decls()[i];
7200 return scope->get_member_decls()[i];
7221{
return priv_->sorted_changed_types_;}
7227{
return priv_->sorted_changed_decls_;}
7230scope_diff::removed_types()
const
7231{
return priv_->removed_types_;}
7234scope_diff::removed_decls()
const
7235{
return priv_->removed_decls_;}
7238scope_diff::added_types()
const
7239{
return priv_->added_types_;}
7242scope_diff::added_decls()
const
7243{
return priv_->added_decls_;}
7250 if (diff::priv_->pretty_representation_.empty())
7252 std::ostringstream o;
7258 diff::priv_->pretty_representation_ = o.str();
7260 return diff::priv_->pretty_representation_;
7282 return ir::NO_CHANGE_KIND;
7293 context()->get_reporter()->report(*
this, out, indent);
7319 ABG_ASSERT(d->first_scope() == first && d->second_scope() == second);
7322 first->get_member_decls().end(),
7323 second->get_member_decls().begin(),
7324 second->get_member_decls().end(),
7325 d->member_changes());
7327 d->ensure_lookup_tables_populated();
7353 ctxt->initialize_canonical_diff(d);
7377 ABG_ASSERT(first->get_index() == second->get_index());
7390{
return dynamic_pointer_cast<function_decl::parameter>(
first_subject());}
7398{
return dynamic_pointer_cast<function_decl::parameter>(
second_subject());}
7408{
return priv_->type_diff;}
7418 if (diff::priv_->pretty_representation_.empty())
7420 std::ostringstream o;
7421 o <<
"function_parameter_diff["
7426 diff::priv_->pretty_representation_ = o.str();
7428 return diff::priv_->pretty_representation_;
7449 return ir::NO_CHANGE_KIND;
7460 context()->get_reporter()->report(*
this, out, indent);
7494 if (!first || !second)
7498 ctxt->initialize_canonical_diff(result);
7507function_type_diff::ensure_lookup_tables_populated()
7509 priv_->return_type_diff_ =
7516 for (vector<deletion>::const_iterator i =
7517 priv_->parm_changes_.deletions().begin();
7518 i != priv_->parm_changes_.deletions().end();
7523 parm_name = parm->get_name_id();
7527 priv_->deleted_parms_[parm_name] = parm;
7528 priv_->deleted_parms_by_id_[parm->get_index()] = parm;
7531 for (vector<insertion>::const_iterator i =
7532 priv_->parm_changes_.insertions().begin();
7533 i != priv_->parm_changes_.insertions().end();
7536 for (vector<unsigned>::const_iterator j =
7537 i->inserted_indexes().begin();
7538 j != i->inserted_indexes().end();
7542 parm_name = parm->get_name_id();
7547 string_parm_map::const_iterator k =
7548 priv_->deleted_parms_.find(parm_name);
7549 if (k != priv_->deleted_parms_.end())
7551 if (*k->second != *parm)
7552 priv_->subtype_changed_parms_[parm_name] =
7554 priv_->deleted_parms_.erase(parm_name);
7557 priv_->added_parms_[parm_name] = parm;
7560 unsigned_parm_map::const_iterator k =
7561 priv_->deleted_parms_by_id_.find(parm->get_index());
7562 if (k != priv_->deleted_parms_by_id_.end())
7564 if (*k->second != *parm
7565 && (k->second->get_name_id() != parm_name))
7566 priv_->changed_parms_by_id_[parm->get_index()] =
7568 priv_->added_parms_.erase(parm_name);
7569 priv_->deleted_parms_.erase(k->second->get_name_id());
7570 priv_->deleted_parms_by_id_.erase(parm->get_index());
7573 priv_->added_parms_by_id_[parm->get_index()] = parm;
7579 priv_->sorted_subtype_changed_parms_);
7581 priv_->sorted_changed_parms_by_id_);
7583 priv_->sorted_deleted_parms_);
7586 priv_->sorted_added_parms_);
7596function_type_diff::deleted_parameter_at(
int i)
const
7602const vector<function_decl::parameter_sptr>&
7604{
return priv_->sorted_deleted_parms_;}
7609const vector<function_decl::parameter_sptr>&
7611{
return priv_->sorted_added_parms_;}
7620function_type_diff::inserted_parameter_at(
int i)
const
7648{
return dynamic_pointer_cast<function_type>(
first_subject());}
7664{
return priv_->return_type_diff_;}
7671{
return priv_->subtype_changed_parms_;}
7678{
return priv_->deleted_parms_;}
7685{
return priv_->added_parms_;}
7695 if (diff::priv_->pretty_representation_.empty())
7697 std::ostringstream o;
7698 o <<
"function_type_diff["
7703 diff::priv_->pretty_representation_ = o.str();
7705 return diff::priv_->pretty_representation_;
7729 return ir::NO_CHANGE_KIND;
7741 context()->get_reporter()->report(*
this, out, indent);
7755 for (vector<fn_parm_diff_sptr>::const_iterator i =
7756 priv_->sorted_subtype_changed_parms_.begin();
7757 i != priv_->sorted_subtype_changed_parms_.end();
7762 for (vector<fn_parm_diff_sptr>::const_iterator i =
7763 priv_->sorted_changed_parms_by_id_.begin();
7764 i != priv_->sorted_changed_parms_by_id_.end();
7787 if (!first || !second)
7796 first->get_parameters().end(),
7797 second->get_first_parm(),
7798 second->get_parameters().end(),
7799 result->priv_->parm_changes_);
7801 result->ensure_lookup_tables_populated();
7803 ctxt->initialize_canonical_diff(result);
7813function_decl_diff::ensure_lookup_tables_populated()
7850{
return dynamic_pointer_cast<function_decl>(
first_subject());}
7858function_decl_diff::type_diff()
const
7859{
return priv_->type_diff_;}
7866 if (diff::priv_->pretty_representation_.empty())
7868 std::ostringstream o;
7869 o <<
"function_diff["
7874 diff::priv_->pretty_representation_ = o.str();
7876 return diff::priv_->pretty_representation_;
7895 return ir::NO_CHANGE_KIND;
7907 context()->get_reporter()->report(*
this, out, indent);
7927 if (!first || !second)
7939 result->priv_->type_diff_ = type_diff;
7941 result->ensure_lookup_tables_populated();
7943 ctxt->initialize_canonical_diff(result);
7987 if (diff::priv_->pretty_representation_.empty())
7989 std::ostringstream o;
7990 o <<
"type_decl_diff["
7995 diff::priv_->pretty_representation_ = o.str();
7997 return diff::priv_->pretty_representation_;
8015 return ir::NO_CHANGE_KIND;
8026 context()->get_reporter()->report(*
this, out, indent);
8064 ctxt->initialize_canonical_diff(result);
8101 priv_(new
priv(underlying))
8109{
return dynamic_pointer_cast<typedef_decl>(
first_subject());}
8125{
return priv_->underlying_type_diff_;}
8134{priv_->underlying_type_diff_ = d;}
8141 if (diff::priv_->pretty_representation_.empty())
8143 std::ostringstream o;
8144 o <<
"typedef_diff["
8149 diff::priv_->pretty_representation_ = o.str();
8151 return diff::priv_->pretty_representation_;
8173 return ir::NO_CHANGE_KIND;
8185 context()->get_reporter()->report(*
this, out, indent);
8205 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
8206 second->get_underlying_type(),
8210 ctxt->initialize_canonical_diff(result);
8262 priv_(new
priv(first, second))
8271{
return priv_->first_;}
8278{
return priv_->second_;}
8292{
return ir::NO_CHANGE_KIND;}
8331 compute_diff(static_pointer_cast<scope_decl>(first->get_global_scope()),
8332 static_pointer_cast<scope_decl>(second->get_global_scope()),
8336 ctxt->initialize_canonical_diff(tu_diff);
8346struct diff_maps::priv
8369diff_maps::~diff_maps() =
default;
8376{
return priv_->type_decl_diff_map_;}
8383{
return priv_->type_decl_diff_map_;}
8390{
return priv_->enum_diff_map_;}
8397{
return priv_->enum_diff_map_;}
8404{
return priv_->class_diff_map_;}
8411{
return priv_->class_diff_map_;}
8418{
return priv_->union_diff_map_;}
8425{
return priv_->union_diff_map_;}
8432{
return priv_->typedef_diff_map_;}
8439{
return priv_->typedef_diff_map_;}
8446{
return priv_->subrange_diff_map_;}
8453{
return priv_->subrange_diff_map_;}
8460{
return priv_->array_diff_map_;}
8467{
return priv_->array_diff_map_;}
8474{
return priv_->reference_diff_map_;}
8481{{
return priv_->reference_diff_map_;}}
8488{
return priv_->fn_parm_diff_map_;}
8495{
return priv_->fn_parm_diff_map_;}
8502{
return priv_->function_type_diff_map_;}
8509{
return priv_->function_type_diff_map_;}
8516{
return priv_->function_decl_diff_map_;}
8523{
return priv_->function_decl_diff_map_;}
8530{
return priv_->var_decl_diff_map_;}
8537{
return priv_->var_decl_diff_map_;}
8544{
return priv_->distinct_diff_map_;}
8551{
return priv_->distinct_diff_map_;}
8609 diff_artifact_set_map_type::iterator i =
8610 priv_->impacted_artifacts_map_.find(dif);
8612 if (i == priv_->impacted_artifacts_map_.end())
8615 set.insert(impacted_iface);
8616 priv_->impacted_artifacts_map_[dif] = set;
8619 i->second.insert(impacted_iface);
8633 diff_artifact_set_map_type::iterator i =
8634 priv_->impacted_artifacts_map_.find(d);
8636 if (i == priv_->impacted_artifacts_map_.end())
8652 : priv_(new
priv(ctxt))
8660{
return priv_->num_func_removed;}
8667{priv_->num_func_removed = n;}
8677 if (priv_->ctxt() && !priv_->ctxt()->show_deleted_fns())
8678 return num_func_removed();
8679 return priv_->num_removed_func_filtered_out;
8688{priv_->num_removed_func_filtered_out = t;}
8699 ABG_ASSERT(num_func_removed() >= num_removed_func_filtered_out());
8700 return num_func_removed() - num_removed_func_filtered_out();
8708{
return priv_->num_func_added;}
8715{priv_->num_func_added = n;}
8723 if (priv_->ctxt() && !priv_->ctxt()->show_added_fns())
8724 return num_func_added();
8725 return priv_->num_added_func_filtered_out;
8734{priv_->num_added_func_filtered_out = n;}
8746 ABG_ASSERT(num_func_added() >= num_added_func_filtered_out());
8747 return num_func_added() - num_added_func_filtered_out();
8757{
return priv_->num_func_changed;}
8766{priv_->num_func_changed = n;}
8775{
return priv_->num_changed_func_filtered_out;}
8784{priv_->num_changed_func_filtered_out = n;}
8792{
return priv_->num_func_with_virt_offset_changes;}
8801{priv_->num_func_with_virt_offset_changes = n;}
8812{
return num_func_changed() - num_changed_func_filtered_out();}
8819{
return priv_->num_vars_removed;}
8826{priv_->num_vars_removed = n;}
8835 if (priv_->ctxt() && !priv_->ctxt()->show_deleted_vars())
8836 return num_vars_removed();
8837 return priv_->num_removed_vars_filtered_out;
8846{priv_->num_removed_vars_filtered_out = n;}
8858 ABG_ASSERT(num_vars_removed() >= num_removed_vars_filtered_out());
8859 return num_vars_removed() - num_removed_vars_filtered_out();
8867{
return priv_->num_vars_added;}
8874{priv_->num_vars_added = n;}
8883 if (priv_->ctxt() && !priv_->ctxt()->show_added_vars())
8884 return num_vars_added();
8885 return priv_->num_added_vars_filtered_out;
8894{priv_->num_added_vars_filtered_out = n;}
8906 ABG_ASSERT(num_vars_added() >= num_added_vars_filtered_out());
8907 return num_vars_added() - num_added_vars_filtered_out();
8917{
return priv_->num_vars_changed;}
8926{priv_->num_vars_changed = n;}
8935{
return priv_->num_changed_vars_filtered_out;}
8944{priv_->num_changed_vars_filtered_out = n;}
8955{
return num_vars_changed() - num_changed_vars_filtered_out();}
8964{
return priv_->num_func_syms_removed;}
8973{priv_->num_func_syms_removed = n;}
8984 && !priv_->ctxt()->show_symbols_unreferenced_by_debug_info())
8985 return num_func_syms_removed();
8986 return priv_->num_removed_func_syms_filtered_out;
8996{priv_->num_removed_func_syms_filtered_out = n;}
9011 ABG_ASSERT(num_func_syms_removed() >= num_removed_func_syms_filtered_out());
9012 return num_func_syms_removed() - num_removed_func_syms_filtered_out();
9022{
return priv_->num_func_syms_added;}
9031{priv_->num_func_syms_added = n;}
9042 && !(priv_->ctxt()->show_added_symbols_unreferenced_by_debug_info()
9043 && priv_->ctxt()->show_symbols_unreferenced_by_debug_info()))
9044 return num_func_syms_added();
9045 return priv_->num_added_func_syms_filtered_out;
9055{priv_->num_added_func_syms_filtered_out = n;}
9070 ABG_ASSERT(num_func_syms_added() >= num_added_func_syms_filtered_out());
9071 return num_func_syms_added()- num_added_func_syms_filtered_out();
9081{
return priv_->num_var_syms_removed;}
9090{priv_->num_var_syms_removed = n;}
9101 && !priv_->ctxt()->show_symbols_unreferenced_by_debug_info())
9102 return num_var_syms_removed();
9103 return priv_->num_removed_var_syms_filtered_out;
9113{priv_->num_removed_var_syms_filtered_out = n;}
9128 ABG_ASSERT(num_var_syms_removed() >= num_removed_var_syms_filtered_out());
9129 return num_var_syms_removed() - num_removed_var_syms_filtered_out();
9139{
return priv_->num_var_syms_added;}
9148{priv_->num_var_syms_added = n;}
9159 && !(priv_->ctxt()->show_added_symbols_unreferenced_by_debug_info()
9160 && priv_->ctxt()->show_symbols_unreferenced_by_debug_info()))
9161 return num_var_syms_added();
9162 return priv_->num_added_var_syms_filtered_out;
9172{priv_->num_added_var_syms_filtered_out = n;}
9187 ABG_ASSERT(num_var_syms_added() >= num_added_var_syms_filtered_out());
9188 return num_var_syms_added() - num_added_var_syms_filtered_out();
9196{
return priv_->num_leaf_changes;}
9203{priv_->num_leaf_changes = n;}
9211{
return priv_->num_leaf_changes_filtered_out;}
9220{priv_->num_leaf_changes_filtered_out = n;}
9233 ABG_ASSERT(num_leaf_changes() >= num_leaf_changes_filtered_out());
9234 return num_leaf_changes() - num_leaf_changes_filtered_out();
9242{
return priv_->num_leaf_type_changes;}
9249{priv_->num_leaf_type_changes = n;}
9256{
return priv_->num_leaf_type_changes_filtered_out;}
9262{priv_->num_leaf_type_changes_filtered_out = n;}
9272{
return num_leaf_type_changes() - num_leaf_type_changes_filtered_out();}
9279{
return priv_->num_leaf_func_changes;}
9286{priv_->num_leaf_func_changes = n;}
9295{
return priv_->num_leaf_func_changes_filtered_out;}
9304{priv_->num_leaf_func_changes_filtered_out = n;}
9315{
return num_leaf_func_changes() - num_leaf_func_changes_filtered_out();}
9322{
return priv_->num_leaf_var_changes;}
9329{priv_->num_leaf_var_changes = n;}
9341{
return priv_->num_added_unreachable_types;}
9354{priv_->num_added_unreachable_types = n;}
9365{
return priv_->num_added_unreachable_types_filtered_out;}
9376{priv_->num_added_unreachable_types_filtered_out = n;}
9390 num_added_unreachable_types_filtered_out());
9392 return (num_added_unreachable_types()
9394 num_added_unreachable_types_filtered_out());
9407{
return priv_->num_removed_unreachable_types;}
9419{priv_->num_removed_unreachable_types = n;}
9430{
return priv_->num_removed_unreachable_types_filtered_out;}
9441{priv_->num_removed_unreachable_types_filtered_out = n;}
9455 num_removed_unreachable_types_filtered_out());
9457 return (num_removed_unreachable_types()
9459 num_removed_unreachable_types_filtered_out());
9472{
return priv_->num_changed_unreachable_types;}
9484{priv_->num_changed_unreachable_types = n;}
9495{
return priv_->num_changed_unreachable_types_filtered_out;}
9506{priv_->num_changed_unreachable_types_filtered_out = n;}
9520 num_changed_unreachable_types_filtered_out());
9522 return (num_changed_unreachable_types()
9524 num_changed_unreachable_types_filtered_out());
9534{
return priv_->num_leaf_var_changes_filtered_out;}
9543{priv_->num_leaf_var_changes_filtered_out = n;}
9554{
return num_leaf_var_changes() - num_leaf_var_changes_filtered_out();}
9564{
return ctxt_.lock();}
9572 return (deleted_fns_.empty()
9573 && added_fns_.empty()
9574 && changed_fns_map_.empty()
9575 && deleted_vars_.empty()
9576 && added_vars_.empty()
9577 && changed_vars_map_.empty());
9584 deleted_fns_.clear();
9586 changed_fns_map_.clear();
9587 deleted_vars_.clear();
9588 added_vars_.clear();
9589 changed_vars_map_.clear();
9597 if (!lookup_tables_empty())
9605 for (vector<deletion>::const_iterator it = e.deletions().begin();
9606 it != e.deletions().end();
9609 unsigned i = it->index();
9610 ABG_ASSERT(i < first_->get_functions().size());
9612 const function_decl* deleted_fn = first_->get_functions()[i];
9619 deleted_fns_[n] = deleted_fn;
9622 for (vector<insertion>::const_iterator it = e.insertions().begin();
9623 it != e.insertions().end();
9626 for (vector<unsigned>::const_iterator iit =
9627 it->inserted_indexes().begin();
9628 iit != it->inserted_indexes().end();
9632 const function_decl* added_fn = second_->get_functions()[i];
9639 string_function_ptr_map::const_iterator j =
9640 deleted_fns_.find(n);
9641 if (j != deleted_fns_.end())
9648 if (*j->second != *added_fn)
9649 changed_fns_map_[j->first] = d;
9650 deleted_fns_.erase(j);
9653 added_fns_[n] = added_fn;
9662 vector<string> to_delete;
9663 for (string_function_ptr_map::const_iterator i = deleted_fns_.begin();
9664 i != deleted_fns_.end();
9666 if (second_->lookup_function_symbol(*i->second->get_symbol()))
9667 to_delete.push_back(i->first);
9669 for (vector<string>::const_iterator i = to_delete.begin();
9670 i != to_delete.end();
9672 deleted_fns_.erase(*i);
9677 for (string_function_ptr_map::const_iterator i = added_fns_.begin();
9678 i != added_fns_.end();
9681 if (first_->lookup_function_symbol(*i->second->get_symbol()))
9682 to_delete.push_back(i->first);
9683 else if (! i->second->get_symbol()->get_version().is_empty()
9684 && i->second->get_symbol()->get_version().is_default())
9692 if (first_->lookup_function_symbol(i->second->get_symbol()->get_name(),
9694 to_delete.push_back(i->first);
9698 for (vector<string>::const_iterator i = to_delete.begin();
9699 i != to_delete.end();
9701 added_fns_.erase(*i);
9707 for (vector<deletion>::const_iterator it = e.deletions().begin();
9708 it != e.deletions().end();
9711 unsigned i = it->index();
9712 ABG_ASSERT(i < first_->get_variables().size());
9714 const var_decl_sptr deleted_var = first_->get_variables()[i];
9715 string n = deleted_var->get_id();
9717 ABG_ASSERT(deleted_vars_.find(n) == deleted_vars_.end());
9718 deleted_vars_[n] = deleted_var;
9721 for (vector<insertion>::const_iterator it = e.insertions().begin();
9722 it != e.insertions().end();
9725 for (vector<unsigned>::const_iterator iit =
9726 it->inserted_indexes().begin();
9727 iit != it->inserted_indexes().end();
9731 const var_decl_sptr added_var = second_->get_variables()[i];
9732 string n = added_var->get_id();
9735 string_var_ptr_map::const_iterator k = added_vars_.find(n);
9736 if ( k != added_vars_.end())
9743 string_var_ptr_map::const_iterator j =
9744 deleted_vars_.find(n);
9745 if (j != deleted_vars_.end())
9747 if (*j->second != *added_var)
9753 deleted_vars_.erase(j);
9756 added_vars_[n] = added_var;
9760 sorted_changed_vars_);
9766 vector<string> to_delete;
9767 for (string_var_ptr_map::const_iterator i = deleted_vars_.begin();
9768 i != deleted_vars_.end();
9770 if (second_->lookup_variable_symbol(*i->second->get_symbol()))
9771 to_delete.push_back(i->first);
9773 for (vector<string>::const_iterator i = to_delete.begin();
9774 i != to_delete.end();
9776 deleted_vars_.erase(*i);
9781 for (string_var_ptr_map::const_iterator i = added_vars_.begin();
9782 i != added_vars_.end();
9784 if (first_->lookup_variable_symbol(*i->second->get_symbol()))
9785 to_delete.push_back(i->first);
9786 else if (! i->second->get_symbol()->get_version().is_empty()
9787 && i->second->get_symbol()->get_version().is_default())
9795 if (first_->lookup_variable_symbol(i->second->get_symbol()->get_name(),
9797 to_delete.push_back(i->first);
9800 for (vector<string>::const_iterator i = to_delete.begin();
9801 i != to_delete.end();
9803 added_vars_.erase(*i);
9811 for (vector<deletion>::const_iterator it = e.deletions().begin();
9812 it != e.deletions().end();
9815 unsigned i = it->index();
9816 ABG_ASSERT(i < first_->get_unreferenced_function_symbols().size());
9818 first_->get_unreferenced_function_symbols()[i];
9819 if (!second_->lookup_function_symbol(*deleted_sym))
9820 deleted_unrefed_fn_syms_[deleted_sym->get_id_string()] = deleted_sym;
9823 for (vector<insertion>::const_iterator it = e.insertions().begin();
9824 it != e.insertions().end();
9827 for (vector<unsigned>::const_iterator iit =
9828 it->inserted_indexes().begin();
9829 iit != it->inserted_indexes().end();
9833 ABG_ASSERT(i < second_->get_unreferenced_function_symbols().size());
9835 second_->get_unreferenced_function_symbols()[i];
9836 if ((deleted_unrefed_fn_syms_.find(added_sym->get_id_string())
9837 == deleted_unrefed_fn_syms_.end()))
9839 if (!first_->lookup_function_symbol(*added_sym))
9842 if (! added_sym->get_version().is_empty()
9843 && added_sym->get_version().is_default())
9851 if (first_->lookup_function_symbol(added_sym->get_name(),
9857 added_unrefed_fn_syms_[added_sym->get_id_string()] =
9862 deleted_unrefed_fn_syms_.erase(added_sym->get_id_string());
9872 for (vector<deletion>::const_iterator it = e.deletions().begin();
9873 it != e.deletions().end();
9876 unsigned i = it->index();
9877 ABG_ASSERT(i < first_->get_unreferenced_variable_symbols().size());
9879 first_->get_unreferenced_variable_symbols()[i];
9880 if (!second_->lookup_variable_symbol(*deleted_sym))
9881 deleted_unrefed_var_syms_[deleted_sym->get_id_string()] = deleted_sym;
9884 for (vector<insertion>::const_iterator it = e.insertions().begin();
9885 it != e.insertions().end();
9888 for (vector<unsigned>::const_iterator iit =
9889 it->inserted_indexes().begin();
9890 iit != it->inserted_indexes().end();
9894 ABG_ASSERT(i < second_->get_unreferenced_variable_symbols().size());
9896 second_->get_unreferenced_variable_symbols()[i];
9897 if (deleted_unrefed_var_syms_.find(added_sym->get_id_string())
9898 == deleted_unrefed_var_syms_.end())
9900 if (!first_->lookup_variable_symbol(*added_sym))
9903 if (! added_sym->get_version().is_empty()
9904 && added_sym->get_version().is_default())
9912 if (first_->lookup_variable_symbol(added_sym->get_name(),
9918 added_unrefed_var_syms_[added_sym->get_id_string()] =
9923 deleted_unrefed_var_syms_.erase(added_sym->get_id_string());
9934 for (vector<deletion>::const_iterator it = e.deletions().begin();
9935 it != e.deletions().end();
9938 unsigned i = it->index();
9940 (first_->get_types_not_reachable_from_public_interfaces()[i]);
9947 deleted_unreachable_types_[repr] = t;
9952 for (vector<insertion>::const_iterator it = e.insertions().begin();
9953 it != e.insertions().end();
9956 for (vector<unsigned>::const_iterator iit =
9957 it->inserted_indexes().begin();
9958 iit != it->inserted_indexes().end();
9963 (second_->get_types_not_reachable_from_public_interfaces()[i]);
9982 string_type_base_sptr_map::const_iterator j =
9983 deleted_unreachable_types_.find(repr);
9984 if (j != deleted_unreachable_types_.end())
9989 decl_base_sptr old_type =
is_decl(j->second);
9990 decl_base_sptr new_type =
is_decl(t);
9991 if (old_type != new_type)
9999 changed_unreachable_types_[repr]= d;
10005 deleted_unreachable_types_.erase(j);
10010 added_unreachable_types_[repr] = t;
10023 std::set<type_base_sptr> deleted_anon_types;
10024 std::set<type_base_sptr> added_anon_types;
10026 for (
auto entry : deleted_unreachable_types_)
10032 deleted_anon_types.insert(entry.second);
10036 for (
auto entry : added_unreachable_types_)
10041 added_anon_types.insert(entry.second);
10046 class_or_union_sptr deleted_class;
10051 for (
auto deleted: deleted_anon_types)
10060 for (
auto enr : deleted_enum->get_enumerators())
10062 bool this_enum_got_changed =
false;
10063 for (
auto t : added_anon_types)
10080 changed_unreachable_types_[repr]= d;
10081 this_enum_got_changed =
true;
10088 removed_anon_types_to_erase[r1] = deleted_enum;
10089 added_anon_types_to_erase[r2] = added_enum;
10093 if (this_enum_got_changed)
10097 else if (deleted_class)
10102 for (
auto dm : deleted_class->get_data_members())
10104 bool this_class_got_changed =
false;
10105 for (
auto klass : added_anon_types)
10107 if (class_or_union_sptr added_class =
10126 changed_unreachable_types_[repr]= d;
10127 this_class_got_changed =
true;
10134 removed_anon_types_to_erase[r1] = deleted_class;
10135 added_anon_types_to_erase[r2] = added_class;
10139 if (this_class_got_changed)
10148 for (
auto entry : added_anon_types_to_erase)
10149 added_unreachable_types_.erase(entry.first);
10151 for (
auto entry : removed_anon_types_to_erase)
10152 deleted_unreachable_types_.erase(entry.first);
10181 return fn_suppr->suppresses_function(fn, k, ctxt);
10208 return var_suppr->suppresses_variable(var, k, ctxt);
10220 for (suppressions_type::const_iterator i = suppressions.begin();
10221 i != suppressions.end();
10228 for (string_function_ptr_map::const_iterator e = added_fns_.begin();
10229 e != added_fns_.end();
10231 if (function_is_suppressed(e->second, fn_suppr,
10234 suppressed_added_fns_[e->first] = e->second;
10237 for (string_function_ptr_map::const_iterator e = deleted_fns_.begin();
10238 e != deleted_fns_.end();
10240 if (function_is_suppressed(e->second, fn_suppr,
10243 suppressed_deleted_fns_[e->first] = e->second;
10246 for (string_elf_symbol_map::const_iterator e =
10247 added_unrefed_fn_syms_.begin();
10248 e != added_unrefed_fn_syms_.end();
10250 if (fn_suppr->suppresses_function_symbol(e->second,
10253 suppressed_added_unrefed_fn_syms_[e->first] = e->second;
10256 for (string_elf_symbol_map::const_iterator e =
10257 deleted_unrefed_fn_syms_.begin();
10258 e != deleted_unrefed_fn_syms_.end();
10260 if (fn_suppr->suppresses_function_symbol(e->second,
10263 suppressed_deleted_unrefed_fn_syms_[e->first] = e->second;
10271 for (string_function_ptr_map::const_iterator e = added_fns_.begin();
10272 e != added_fns_.end();
10281 if (type_suppr->suppresses_type(c, ctxt))
10282 suppressed_added_fns_[e->first] = e->second;
10285 for (string_function_ptr_map::const_iterator e = deleted_fns_.begin();
10286 e != deleted_fns_.end();
10295 if (type_suppr->suppresses_type(c, ctxt))
10296 suppressed_deleted_fns_[e->first] = e->second;
10301 for (string_type_base_sptr_map::const_iterator e =
10302 deleted_unreachable_types_.begin();
10303 e != deleted_unreachable_types_.end();
10305 if (type_suppr->suppresses_type(e->second, ctxt))
10306 suppressed_deleted_unreachable_types_[e->first] = e->second;
10310 for (string_type_base_sptr_map::const_iterator e =
10311 added_unreachable_types_.begin();
10312 e != added_unreachable_types_.end();
10314 if (type_suppr->suppresses_type(e->second, ctxt))
10315 suppressed_added_unreachable_types_[e->first] = e->second;
10322 for (string_var_ptr_map::const_iterator e = added_vars_.begin();
10323 e != added_vars_.end();
10325 if (variable_is_suppressed(e->second, var_suppr,
10328 suppressed_added_vars_[e->first] = e->second;
10331 for (string_var_ptr_map::const_iterator e = deleted_vars_.begin();
10332 e != deleted_vars_.end();
10334 if (variable_is_suppressed(e->second, var_suppr,
10337 suppressed_deleted_vars_[e->first] = e->second;
10340 for (string_elf_symbol_map::const_iterator e =
10341 added_unrefed_var_syms_.begin();
10342 e != added_unrefed_var_syms_.end();
10344 if (var_suppr->suppresses_variable_symbol(e->second,
10347 suppressed_added_unrefed_var_syms_[e->first] = e->second;
10350 for (string_elf_symbol_map::const_iterator e =
10351 deleted_unrefed_var_syms_.begin();
10352 e != deleted_unrefed_var_syms_.end();
10354 if (var_suppr->suppresses_variable_symbol(e->second,
10357 suppressed_deleted_unrefed_var_syms_[e->first] = e->second;
10375 string_function_ptr_map::const_iterator i =
10376 suppressed_deleted_fns_.find(fn->
get_id());
10378 return (i != suppressed_deleted_fns_.end());
10395 string_type_base_sptr_map::const_iterator i =
10396 suppressed_added_unreachable_types_.find(repr);
10397 if (i == suppressed_added_unreachable_types_.end())
10417 string_type_base_sptr_map::const_iterator i =
10418 suppressed_deleted_unreachable_types_.find(repr);
10419 if (i == suppressed_deleted_unreachable_types_.end())
10438 string_function_ptr_map::const_iterator i =
10439 suppressed_added_fns_.find(fn->
get_id());
10441 return (i != suppressed_added_fns_.end());
10457 string_var_ptr_map::const_iterator i =
10458 suppressed_deleted_vars_.find(var->get_id());
10460 return (i != suppressed_deleted_vars_.end());
10476 string_var_ptr_map::const_iterator i =
10477 suppressed_added_vars_.find(var->get_id());
10479 return (i != suppressed_added_vars_.end());
10495 string_elf_symbol_map::const_iterator i =
10496 suppressed_deleted_unrefed_fn_syms_.find(s->
get_id_string());
10498 return (i != suppressed_deleted_unrefed_fn_syms_.end());
10514 string_elf_symbol_map::const_iterator i =
10515 suppressed_added_unrefed_fn_syms_.find(s->
get_id_string());
10517 return (i != suppressed_added_unrefed_fn_syms_.end());
10533 string_elf_symbol_map::const_iterator i =
10534 suppressed_deleted_unrefed_var_syms_.find(s->
get_id_string());
10536 return (i != suppressed_deleted_unrefed_var_syms_.end());
10552 string_elf_symbol_map::const_iterator i =
10553 suppressed_added_unrefed_var_syms_.find(s->
get_id_string());
10555 return (i != suppressed_added_unrefed_var_syms_.end());
10558#ifdef do_count_diff_map_changes
10559#undef do_count_diff_map_changes
10561#define do_count_diff_map_changes(diff_map, n_changes, n_filtered) \
10563 string_diff_ptr_map::const_iterator i; \
10564 for (i = diff_map.begin(); \
10565 i != diff_map.end(); \
10568 if (const var_diff* d = is_var_diff(i->second)) \
10569 if (is_data_member(d->first_var())) \
10572 if (i->second->has_local_changes()) \
10574 if (!i->second->get_canonical_diff()->to_be_reported()) \
10590 count_leaf_type_changes(num_changes, num_filtered);
10593 do_count_diff_map_changes(leaf_diffs_.get_function_decl_diff_map(),
10594 num_changes, num_filtered);
10595 do_count_diff_map_changes(leaf_diffs_.get_var_decl_diff_map(),
10596 num_changes, num_filtered);
10609 size_t &num_filtered)
10611 do_count_diff_map_changes(leaf_diffs_.get_type_decl_diff_map(),
10612 num_changes, num_filtered);
10613 do_count_diff_map_changes(leaf_diffs_.get_enum_diff_map(),
10614 num_changes, num_filtered);
10615 do_count_diff_map_changes(leaf_diffs_.get_class_diff_map(),
10616 num_changes, num_filtered);
10617 do_count_diff_map_changes(leaf_diffs_.get_union_diff_map(),
10618 num_changes, num_filtered);
10619 do_count_diff_map_changes(leaf_diffs_.get_typedef_diff_map(),
10620 num_changes, num_filtered);
10621 do_count_diff_map_changes(leaf_diffs_.get_subrange_diff_map(),
10622 num_changes, num_filtered);
10623 do_count_diff_map_changes(leaf_diffs_.get_array_diff_map(),
10624 num_changes, num_filtered);
10625 do_count_diff_map_changes(leaf_diffs_.get_distinct_diff_map(),
10626 num_changes, num_filtered);
10627 do_count_diff_map_changes(leaf_diffs_.get_fn_parm_diff_map(),
10628 num_changes, num_filtered);
10656 size_t &num_deleted,
10657 size_t &num_changed,
10658 size_t &num_filtered_added,
10659 size_t &num_filtered_deleted,
10660 size_t &num_filtered_changed)
10662 num_added = added_unreachable_types_.size();
10663 num_deleted = deleted_unreachable_types_.size();
10664 num_changed = changed_unreachable_types_.size();
10665 num_filtered_added = suppressed_added_unreachable_types_.size();
10666 num_filtered_deleted = suppressed_deleted_unreachable_types_.size();
10668 for (vector<diff_sptr>::const_iterator i =
10672 if (!(*i)->to_be_reported())
10673 ++num_filtered_changed;
10682{
return changed_unreachable_types_;}
10693const vector<diff_sptr>&
10696if (changed_unreachable_types_sorted_.empty())
10697 if (!changed_unreachable_types_.empty())
10699 changed_unreachable_types_sorted_);
10701 return changed_unreachable_types_sorted_;
10736 if (ctxt->perform_change_categorization())
10738 if (get_context()->
do_log())
10740 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10741 <<
"applying filters to "
10742 << changed_fns_.size()
10743 <<
" changed fns ...\n";
10749 for (function_decl_diff_sptrs_type::const_iterator i =
10750 changed_fns_.begin();
10751 i != changed_fns_.end();
10755 ctxt->maybe_apply_filters(
diff);
10758 if (get_context()->
do_log())
10761 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10762 <<
"filters to changed fn applied!:" << t <<
"\n";
10764 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10765 <<
"applying filters to "
10766 << sorted_changed_vars_.size()
10767 <<
" changed vars ...\n";
10773 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
10774 i != sorted_changed_vars_.end();
10778 ctxt->maybe_apply_filters(
diff);
10781 if (get_context()->
do_log())
10784 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10785 <<
"filters to changed vars applied!:" << t <<
"\n";
10787 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10788 <<
"applying filters to unreachable types ...\n";
10795 ctxt->maybe_apply_filters(
diff);
10798 ctxt->maybe_apply_filters(entry.second);
10800 if (get_context()->
do_log())
10803 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10804 <<
"filters to unreachable types applied!:" << t <<
"\n";
10806 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10807 <<
"categorizing redundant changed sub nodes ...\n";
10811 categorize_redundant_changed_sub_nodes();
10813 if (get_context()->
do_log())
10816 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10817 <<
"redundant changed sub nodes categorized!:" << t <<
"\n";
10819 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10820 <<
"count changed fns ...\n";
10828 for (function_decl_diff_sptrs_type::const_iterator i =
10829 changed_fns_.begin();
10830 i != changed_fns_.end();
10833 if ((*i)->is_filtered_out())
10838 if ((*i)->has_local_changes())
10849 if ((*i)->has_local_changes())
10854 if (get_context()->
do_log())
10857 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10858 <<
"changed fn counted!:" << t <<
"\n";
10860 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10861 <<
"count changed vars ...\n";
10867 for (var_diff_sptrs_type ::const_iterator i = sorted_changed_vars_.begin();
10868 i != sorted_changed_vars_.end();
10871 if ((*i)->is_filtered_out())
10876 if ((*i)->has_local_changes())
10880 if ((*i)->has_local_changes())
10885 if (get_context()->
do_log())
10888 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10889 <<
"changed vars counted!:" << t <<
"\n";
10891 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10892 <<
"count leaf changed types ...\n";
10907 size_t num_type_changes = 0, num_type_filtered = 0;
10908 count_leaf_type_changes(num_type_changes, num_type_filtered);
10914 if (get_context()->
do_log())
10917 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10918 <<
"changed leaf types counted!:" << t <<
"\n";
10920 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10921 <<
"count leaf changed artefacts ...\n";
10927 size_t num_changes = 0, num_filtered = 0;
10928 count_leaf_changes(num_changes, num_filtered);
10934 if (get_context()->
do_log())
10937 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10938 <<
"changed leaf artefacts counted!:" << t <<
"\n";
10940 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10941 <<
"count unreachable types ...\n";
10947 size_t num_added_unreachable_types = 0,
10948 num_changed_unreachable_types = 0,
10949 num_deleted_unreachable_types = 0,
10950 num_added_unreachable_types_filtered = 0,
10951 num_changed_unreachable_types_filtered = 0,
10952 num_deleted_unreachable_types_filtered = 0;
10954 count_unreachable_types(num_added_unreachable_types,
10955 num_deleted_unreachable_types,
10956 num_changed_unreachable_types,
10957 num_added_unreachable_types_filtered,
10958 num_deleted_unreachable_types_filtered,
10959 num_changed_unreachable_types_filtered);
10961 if (get_context()->
do_log())
10964 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10965 <<
"unreachable types counted!:" << t <<
"\n";
10972 (num_added_unreachable_types_filtered);
10974 (num_deleted_unreachable_types_filtered);
10976 (num_changed_unreachable_types_filtered);
10992 const string& indent)
10995 size_t net_num_leaf_changes =
11008 if (!sonames_equal_)
11009 out << indent <<
"ELF SONAME changed\n";
11011 if (!architectures_equal_)
11012 out << indent <<
"ELF architecture changed\n";
11016 if (ctxt->show_leaf_changes_only())
11018 out <<
"Leaf changes summary: ";
11019 out << net_num_leaf_changes <<
" artifact";
11020 if (net_num_leaf_changes > 1)
11025 out <<
" (" << num_filtered <<
" filtered out)";
11028 out << indent <<
"Changed leaf types summary: "
11032 <<
" filtered out)";
11033 out <<
" leaf type";
11036 out <<
" changed\n";
11039 out << indent <<
"Removed/Changed/Added functions summary: ";
11044 <<
" filtered out)";
11051 <<
" filtered out)";
11058 out <<
"functions";
11064 out << indent <<
"Removed/Changed/Added variables summary: ";
11068 <<
" filtered out)";
11075 <<
" filtered out)";
11082 out <<
"variables";
11085 <<
" filtered out)";
11094 out << indent <<
"Functions changes summary: ";
11099 <<
" filtered out)";
11110 if (total_nb_function_changes <= 1)
11111 out <<
" function";
11113 out <<
" functions";
11120 out << indent <<
"Variables changes summary: ";
11124 <<
" filtered out)";
11135 <<
" filtered out)";
11136 if (total_nb_variable_changes <= 1)
11137 out <<
" variable";
11139 out <<
" variables";
11145 if (ctxt->show_unreachable_types())
11147 size_t total_nb_unreachable_type_changes =
11153 out << indent <<
"Unreachable types summary: "
11158 <<
" filtered out)";
11165 <<
" filtered out)";
11172 <<
" filtered out)";
11173 if (total_nb_unreachable_type_changes <= 1)
11180 if (ctxt->show_symbols_unreferenced_by_debug_info()
11188 if (!ctxt->show_added_symbols_unreferenced_by_debug_info()
11198 <<
"Function symbols changes summary: "
11202 <<
" filtered out)";
11207 <<
" filtered out)";
11208 out <<
" function symbol";
11211 out <<
" not referenced by debug info\n";
11216 if (!ctxt->show_added_symbols_unreferenced_by_debug_info()
11226 <<
"Variable symbols changes summary: "
11230 <<
" filtered out)";
11235 <<
" filtered out)";
11236 out <<
" variable symbol";
11239 out <<
" not referenced by debug info\n";
11253 ctxt->forget_visited_diffs();
11254 for (function_decl_diff_sptrs_type::const_iterator i =
11255 changed_fns_.begin();
11256 i!= changed_fns_.end();
11263 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
11264 i!= sorted_changed_vars_.end();
11271 for (diff_sptrs_type::const_iterator i =
11287 for (function_decl_diff_sptrs_type::const_iterator i = changed_fns_.begin();
11288 i!= changed_fns_.end();
11295 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
11296 i!= sorted_changed_vars_.end();
11314 if (!ctxt->dump_diff_tree()
11315 || ctxt->error_output_stream() == 0)
11318 if (!changed_fns_.empty())
11320 *ctxt->error_output_stream() <<
"changed functions diff tree: \n\n";
11321 for (function_decl_diff_sptrs_type::const_iterator i =
11322 changed_fns_.begin();
11323 i != changed_fns_.end();
11331 if (!sorted_changed_vars_.empty())
11333 *ctxt->error_output_stream() <<
"\nchanged variables diff tree: \n\n";
11334 for (var_diff_sptrs_type::const_iterator i =
11335 sorted_changed_vars_.begin();
11336 i != sorted_changed_vars_.end();
11346 *ctxt->error_output_stream() <<
"\nchanged unreachable "
11347 "types diff tree: \n\n";
11348 for (vector<diff_sptr>::const_iterator i =
11366 for (function_decl_diff_sptrs_type::const_iterator i =
11385 corpus_sptr second,
11387 : priv_(new
priv(first, second, ctxt))
11390corpus_diff::~corpus_diff() =
default;
11396 if (priv_->finished_)
11399 priv_->finished_ =
true;
11419{
return priv_->first_;}
11424{
return priv_->second_;}
11427const vector<diff*>&
11429{
return priv_->children_;}
11447 bool inserted =
false;
11448 for (vector<diff*>::iterator i = priv_->children_.begin();
11449 i != priv_->children_.end();
11454 context()->keep_diff_alive(d);
11455 priv_->children_.insert(i, d.get());
11464 context()->keep_diff_alive(d);
11468 priv_->children_.push_back(d.get());
11476{
return priv_->fns_edit_script_;}
11482{
return priv_->vars_edit_script_;}
11489{
return !priv_->sonames_equal_;}
11496{
return !priv_->architectures_equal_;}
11503{
return priv_->deleted_fns_;}
11510{
return priv_->added_fns_;}
11522{
return priv_->changed_fns_map_;}
11531{
return priv_->changed_fns_;}
11539{
return priv_->deleted_vars_;}
11546{
return priv_->added_vars_;}
11554{
return priv_->changed_vars_map_;}
11562{
return priv_->sorted_changed_vars_;}
11571{
return priv_->deleted_unrefed_fn_syms_;}
11580{
return priv_->added_unrefed_fn_syms_;}
11589{
return priv_->deleted_unrefed_var_syms_;}
11598{
return priv_->added_unrefed_var_syms_;}
11607{
return priv_->deleted_unreachable_types_;}
11615const vector<type_base_sptr>&
11618 if (priv_->deleted_unreachable_types_sorted_.empty())
11619 if (!priv_->deleted_unreachable_types_.empty())
11621 priv_->deleted_unreachable_types_sorted_);
11623 return priv_->deleted_unreachable_types_sorted_;
11633{
return priv_->added_unreachable_types_;}
11641const vector<type_base_sptr>&
11644 if (priv_->added_unreachable_types_sorted_.empty())
11645 if (!priv_->added_unreachable_types_.empty())
11647 priv_->added_unreachable_types_sorted_);
11649 return priv_->added_unreachable_types_sorted_;
11659{
return priv_->changed_unreachable_types_;}
11667const vector<diff_sptr>&
11669{
return priv_->changed_unreachable_types_sorted();}
11676{
return priv_->get_context();}
11683 if (priv_->pretty_representation_.empty())
11685 std::ostringstream o;
11686 o <<
"corpus_diff["
11691 priv_->pretty_representation_ = o.str();
11693 return priv_->pretty_representation_;
11704 || !(priv_->deleted_fns_.empty()
11705 && priv_->added_fns_.empty()
11706 && priv_->changed_fns_map_.empty()
11707 && priv_->deleted_vars_.empty()
11708 && priv_->added_vars_.empty()
11709 && priv_->changed_vars_map_.empty()
11710 && priv_->added_unrefed_fn_syms_.empty()
11711 && priv_->deleted_unrefed_fn_syms_.empty()
11712 && priv_->added_unrefed_var_syms_.empty()
11713 && priv_->deleted_unrefed_var_syms_.empty()
11714 && priv_->deleted_unreachable_types_.empty()
11715 && priv_->added_unreachable_types_.empty()
11716 && priv_->changed_unreachable_types_.empty()));
11771 for (
auto &entry : priv_->changed_unreachable_types())
11815{
return context()->get_reporter()->diff_has_net_changes(
this);}
11840 if (priv_->diff_stats_)
11841 return *priv_->diff_stats_;
11846 std::cerr <<
"Applying suppressions ...\n";
11855 std::cerr <<
"suppressions applied!:" << t <<
"\n";
11862 std::cerr <<
"Marking leaf nodes ...\n";
11871 std::cerr <<
"leaf nodes marked!:" << t <<
"\n";
11872 std::cerr <<
"Applying filters and computing diff stats ...\n";
11876 priv_->apply_filters_and_compute_diff_stats(*priv_->diff_stats_);
11881 std::cerr <<
"Filters applied and diff stats computed!: " << t <<
"\n";
11884 return *priv_->diff_stats_;
11906 visit_begin(
diff *d)
11953 const corpus_diff *corpus_diff_node = ctxt->get_corpus_diff().get();
11963 get_leaf_diffs().insert_diff_node(d, iface);
11981 if (!
context()->show_leaf_changes_only())
11984 leaf_diff_node_marker_visitor v;
11985 context()->forget_visited_diffs();
11986 bool s =
context()->visiting_a_node_twice_is_forbidden();
11987 context()->forbid_visiting_a_node_twice(
true);
11988 if (
context()->show_impacted_interfaces())
11989 context()->forbid_visiting_a_node_twice_per_interface(
true);
11991 context()->forbid_visiting_a_node_twice(s);
11992 context()->forbid_visiting_a_node_twice_per_interface(
false);
12002{
return priv_->leaf_diffs_;}
12011{
return priv_->leaf_diffs_;}
12022 context()->get_reporter()->report(*
this, out, indent);
12037 if (!v.
visit(
this,
true))
12043 for (function_decl_diff_sptrs_type::const_iterator i =
12051 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
12052 ctxt->forget_visited_diffs();
12065 for (var_diff_sptrs_type::const_iterator i =
12073 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
12074 ctxt->forget_visited_diffs();
12091 for (vector<diff_sptr>::const_iterator i =
12099 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
12100 ctxt->forget_visited_diffs();
12128 const corpus_sptr s,
12131 typedef corpus::functions::const_iterator fns_it_type;
12132 typedef corpus::variables::const_iterator vars_it_type;
12133 typedef elf_symbols::const_iterator symbols_it_type;
12135 typedef vector<type_base_wptr>::const_iterator type_base_wptr_it_type;
12144 ctxt->set_corpus_diff(r);
12146 if(ctxt->show_soname_change())
12147 r->priv_->sonames_equal_ = f->get_soname() == s->get_soname();
12149 r->priv_->sonames_equal_ =
true;
12151 r->priv_->architectures_equal_ =
12152 f->get_architecture_name() == s->get_architecture_name();
12156 f->get_functions().end(),
12157 s->get_functions().begin(),
12158 s->get_functions().end(),
12159 r->priv_->fns_edit_script_);
12163 (f->get_variables().begin(), f->get_variables().end(),
12164 s->get_variables().begin(), s->get_variables().end(),
12165 r->priv_->vars_edit_script_);
12170 (f->get_unreferenced_function_symbols().begin(),
12171 f->get_unreferenced_function_symbols().end(),
12172 s->get_unreferenced_function_symbols().begin(),
12173 s->get_unreferenced_function_symbols().end(),
12174 r->priv_->unrefed_fn_syms_edit_script_);
12179 (f->get_unreferenced_variable_symbols().begin(),
12180 f->get_unreferenced_variable_symbols().end(),
12181 s->get_unreferenced_variable_symbols().begin(),
12182 s->get_unreferenced_variable_symbols().end(),
12183 r->priv_->unrefed_var_syms_edit_script_);
12185 if (ctxt->show_unreachable_types())
12189 (f->get_types_not_reachable_from_public_interfaces().begin(),
12190 f->get_types_not_reachable_from_public_interfaces().end(),
12191 s->get_types_not_reachable_from_public_interfaces().begin(),
12192 s->get_types_not_reachable_from_public_interfaces().end(),
12193 r->priv_->unreachable_types_edit_script_);
12195 r->priv_->ensure_lookup_tables_populated();
12216 const corpus_group_sptr& s,
12220 corpus_sptr c1 = f;
12221 corpus_sptr c2 = s;
12232struct diff_node_visitor::priv
12234 diff* topmost_interface_diff;
12238 : topmost_interface_diff(),
12242 priv(visiting_kind k)
12243 : topmost_interface_diff(),
12253diff_node_visitor::~diff_node_visitor() =
default;
12259 : priv_(new priv(k))
12269{
return priv_->kind;}
12289{priv_->kind = priv_->kind | v;}
12297{priv_->topmost_interface_diff = d;}
12305{
return priv_->topmost_interface_diff;}
12532 bool already_visited = d->
context()->diff_has_been_visited(d);
12540 bool update_canonical = !already_visited && canonical;
12542 for (vector<diff*>::const_iterator i = d->
children_nodes().begin();
12554 ? (*i)->get_canonical_diff()
12572 c &= ~HARMLESS_DECL_NAME_CHANGE_CATEGORY;
12575 if (!already_visited && canonical)
12576 if (update_canonical)
12577 canonical->add_to_category(c);
12605 c &= (~NON_COMPATIBLE_NAME_CHANGE_CATEGORY
12606 & ~NON_COMPATIBLE_DISTINCT_CHANGE_CATEGORY);
12613 c &= ~NON_COMPATIBLE_NAME_CHANGE_CATEGORY;
12628 category_propagation_visitor v;
12629 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12630 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
12631 diff_tree->
context()->forget_visited_diffs();
12633 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12655 category_propagation_visitor v;
12656 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12657 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
12659 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12684 visit_begin(
diff* d)
12686 bool is_private_type =
false;
12697 if (canonical_diff != d)
12753 bool has_non_suppressed_child =
false;
12754 bool has_non_empty_child =
false;
12755 bool has_suppressed_child =
false;
12756 bool has_non_private_child =
false;
12757 bool has_private_child =
false;
12758 bool has_descendant_with_allowed_change =
false;
12791 && (!d->has_local_changes()
12816 for (vector<diff*>::const_iterator i = d->children_nodes().begin();
12817 i != d->children_nodes().end();
12821 if (child->has_changes())
12823 has_non_empty_child =
true;
12825 has_suppressed_child =
true;
12826 else if (child->get_class_of_equiv_category()
12832 has_non_suppressed_child =
true;
12834 if (child->get_class_of_equiv_category()
12836 has_private_child =
true;
12837 else if (child->get_class_of_equiv_category()
12843 has_non_private_child =
true;
12847 if (has_non_empty_child
12848 && has_suppressed_child
12849 && !has_non_suppressed_child)
12855 if (canonical_diff != d)
12871 if (has_non_empty_child
12872 && has_private_child
12873 && !has_non_private_child)
12879 if (canonical_diff != d)
12889 && has_private_child
12890 && has_non_empty_child)
12896 if (canonical_diff != d)
12913 if (fn_type_diff->is_suppressed())
12919 if (canonical_diff != d)
12928 for (
auto child_node : d->children_nodes())
12931 diff_category c = canonical_diff->get_category();
12934 has_descendant_with_allowed_change =
true;
12936 if (has_descendant_with_allowed_change)
12939 d->add_to_category(c);
12940 d->get_canonical_diff()->add_to_category(c);
12954 if (diff_tree && !diff_tree->
context()->suppressions().empty())
12958 suppression_categorization_visitor v;
12959 diff_tree->
context()->forget_visited_diffs();
12960 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12961 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
12963 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12986 if (diff_tree && !diff_tree->
context()->suppressions().empty())
12991 suppression_categorization_visitor v;
12992 diff_tree->
context()->forget_visited_diffs();
12993 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12994 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
12995 const_cast<corpus_diff*
>(diff_tree)->traverse(v);
12996 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13002 apply_supprs_to_added_removed_fns_vars_unreachable_types();
13032 do_indent(
unsigned level)
13034 for (
unsigned i = 0; i < level; ++i)
13038 diff_node_printer(ostream& out)
13057 visit_begin(corpus_diff*)
13063 visit_end(corpus_diff*)
13069 visit(diff* d,
bool pre)
13078 out_ << d->get_pretty_representation();
13082 do_indent(level_ + 1);
13083 out_ <<
"category: "<< d->get_category() <<
"\n";
13084 do_indent(level_ + 1);
13085 out_ <<
"@: " << std::hex << d << std::dec <<
"\n";
13086 do_indent(level_ + 1);
13087 out_ <<
"@-canonical: " << std::hex
13088 << d->get_canonical_diff()
13089 << std::dec <<
"\n";
13097 visit(corpus_diff* d,
bool pre)
13106 for (
unsigned i = 0; i < level_; ++i)
13108 out_ << d->get_pretty_representation();
13127 diff_node_printer p(out);
13128 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13129 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13131 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13145 diff_node_printer p(out);
13146 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13147 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13149 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13188 bool skip_children_nodes_;
13190 redundancy_marking_visitor()
13191 : skip_children_nodes_()
13195 visit_begin(diff* d)
13197 if (d->to_be_reported())
13203 if ((d->context()->diff_has_been_visited(d)
13204 || d->get_canonical_diff()->is_traversing())
13205 && d->has_changes())
13220 bool redundant_with_sibling_node =
false;
13225 if (p &&
dynamic_cast<const fn_parm_diff*
>(p))
13229 for (vector<diff*>::const_iterator s =
13230 p->children_nodes().begin();
13231 s != p->children_nodes().end();
13239 if (fn_parm_diff* f =
dynamic_cast<fn_parm_diff*
>(*s))
13240 sib = f->type_diff().get();
13243 if (sib->get_canonical_diff() == d->get_canonical_diff()
13248 redundant_with_sibling_node =
true;
13252 if (!redundant_with_sibling_node
13273 && (!d->get_canonical_diff()->is_filtered_out()
13274 || (d->get_canonical_diff()->get_category()
13281 && d->context()->diff_has_been_visited(d) != d
13303 skip_children_nodes_ =
true;
13311 skip_children_nodes_ =
true;
13316 visit_begin(corpus_diff*)
13323 if (skip_children_nodes_)
13330 skip_children_nodes_ =
false;
13338 && (!d->has_local_changes_to_be_reported()
13366 && (!(d->has_local_changes()
13377 && (!(d->has_local_changes()
13384 && (!(d->has_local_changes()
13388 bool has_non_redundant_child =
false;
13389 bool has_non_empty_child =
false;
13391 for (vector<diff*>::const_iterator i =
13392 d->children_nodes().begin();
13393 i != d->children_nodes().end();
13396 if ((*i)->has_changes())
13407 has_non_empty_child =
true;
13414 if ((*i)->to_be_reported()
13416 has_non_redundant_child =
true;
13418 if (has_non_redundant_child)
13425 if (has_non_empty_child
13426 && !has_non_redundant_child)
13433 visit_end(corpus_diff*)
13442 visit(corpus_diff*,
bool)
13450struct redundancy_clearing_visitor :
public diff_node_visitor
13453 visit(corpus_diff*,
bool)
13457 visit(diff* d,
bool)
13460 diff_category c = d->get_category();
13461 c &= ~REDUNDANT_CATEGORY;
13462 d->set_category(c);
13474 if (diff_tree->
context()->show_redundant_changes())
13476 redundancy_marking_visitor v;
13477 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13478 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13480 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13498 redundancy_marking_visitor v;
13499 diff_tree->
context()->forget_visited_diffs();
13500 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13501 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13503 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13523 redundancy_clearing_visitor v;
13524 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13525 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13527 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13528 diff_tree->
context()->forget_visited_diffs();
13546 redundancy_clearing_visitor v;
13547 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
13548 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
13550 diff_tree->
context()->forbid_visiting_a_node_twice(s);
13551 diff_tree->
context()->forget_visited_diffs();
13572 diff_tree->context()->maybe_apply_filters(diff_tree);
13590 if (t && t->get_environment().is_variadic_parameter_type(t))
13594 if (t && t->get_environment().is_variadic_parameter_type(t))
13659 if (allow_indirect_type)
13860has_local_type_change_only(
const diff *d)
13888 return (has_local_type_change_only(v)
13891 return (has_local_type_change_only(p)
13895 return (has_local_type_change_only(f)
The private data and functions of the abigail::ir::comparison types.
#define SKIP_MEM_FN_IF_VIRTUALITY_DISALLOWED
Skip the processing of the current member function if its virtual-ness is disallowed by the user.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
The abstraction of a diff between two arrays.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of array_diff.
const diff_sptr & element_type_diff() const
Getter for the diff between the two types of array elements.
array_diff(const array_type_def_sptr first, const array_type_def_sptr second, diff_sptr element_type_diff, vector< subrange_diff_sptr > &subrange_diffs, diff_context_sptr ctxt=diff_context_sptr())
Constructor for array_diff.
bool any_subrange_diff_to_be_reported() const
Test if any subrange diff is to be reported.
const array_type_def_sptr second_array() const
Getter for the second array of the diff.
const array_type_def_sptr first_array() const
Getter for the first array of the diff.
virtual enum change_kind has_local_changes() const
const vector< subrange_diff_sptr > & subrange_diffs() const
Getter for the diffs between the array subranges.
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
An abstraction of a diff between two instances of class_decl::base_spec.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of base_diff.
void set_underlying_class_diff(class_diff_sptr d)
Setter for the diff object for the diff of the underlyng base classes.
class_decl::base_spec_sptr second_base() const
Getter for the second base spec of the diff object.
base_diff(class_decl::base_spec_sptr first, class_decl::base_spec_sptr second, class_diff_sptr underlying, diff_context_sptr ctxt=diff_context_sptr())
const class_diff_sptr get_underlying_class_diff() const
Getter for the diff object for the diff of the underlying base classes.
class_decl::base_spec_sptr first_base() const
Getter for the first base spec of the diff object.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Generates a report for the current instance of base_diff.
This type abstracts changes for a class_decl.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of class_diff.
class_decl_sptr first_class_decl() const
const base_diff_sptrs_type & changed_bases()
Getter for the changed base classes of the diff.
const vector< class_decl::base_spec_sptr > & moved_bases() const
Getter for the vector of bases that "moved". That is, the vector of base types which position changed...
const string_base_sptr_map & inserted_bases() const
Getter for the inserted base classes of the diff.
const string_base_sptr_map & deleted_bases() const
Getter for the deleted base classes of the diff.
virtual enum change_kind has_local_changes() const
const edit_script & base_changes() const
virtual const string & get_pretty_representation() const
class_diff(class_decl_sptr first_scope, class_decl_sptr second_scope, diff_context_sptr ctxt=diff_context_sptr())
Constructor of class_diff.
friend class_diff_sptr compute_diff(const class_decl_sptr first, const class_decl_sptr second, diff_context_sptr ctxt)
Compute the set of changes between two instances of class_decl.
class_decl_sptr second_class_decl() const
Getter of the second class involved in the diff.
virtual void report(ostream &, const string &indent="") const
Produce a basic report about the changes between two class_decl.
This is the base class of class_diff and union_diff.
virtual bool has_changes() const
Test if the current diff node carries a change.
const edit_script & member_fn_tmpls_changes() const
size_t count_filtered_subtype_changed_data_members(bool local_only=false) const
Count the number of /filtered/ data members with a sub-type change.
const class_or_union_diff::priv_ptr & get_priv() const
Getter of the private data of the class_or_union_diff type.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of class_or_un...
const edit_script & member_class_tmpls_changes() const
void allocate_priv_data()
Allocate the memory for the priv_ pimpl data member of the class_or_union_diff class.
class_or_union_diff(class_or_union_sptr first_scope, class_or_union_sptr second_scope, diff_context_sptr ctxt=diff_context_sptr())
Constructor for the class_or_union_diff class.
const unsigned_var_diff_sptr_map & changed_data_members() const
Getter of the map of data members that got replaced by another data member. The key of the map is the...
const edit_script & member_types_changes() const
const string_member_function_sptr_map & deleted_member_fns() const
class_or_union_sptr first_class_or_union() const
const var_diff_sptrs_type & sorted_subtype_changed_data_members() const
Getter of the sorted vector of data members with a (sub-)type change.
bool lookup_tables_empty(void) const
Tests if the lookup tables are empty.
const string_decl_base_sptr_map & data_members_replaced_by_adms() const
Get the map of data members that got replaced by anonymous data members.
void clear_lookup_tables(void)
Clear the lookup tables useful for reporting.
const string_decl_base_sptr_map & deleted_data_members() const
Getter for the data members that got deleted.
virtual ~class_or_union_diff()
Destructor of class_or_union_diff.
const string_decl_base_sptr_map & inserted_data_members() const
Getter for the data members that got inserted.
void ensure_lookup_tables_populated(void) const
If the lookup tables are not yet built, walk the differences and fill them.
const string_member_function_sptr_map & inserted_member_fns() const
const function_decl_diff_sptrs_type & changed_member_fns() const
Getter for the virtual members functions that have had a change in a sub-type, without having a chang...
const edit_script & data_members_changes() const
const changed_var_sptrs_type & ordered_data_members_replaced_by_adms() const
Get an ordered vector of of data members that got replaced by anonymous data members.
virtual enum change_kind has_local_changes() const
size_t count_filtered_changed_data_members(bool local_only=false) const
Count the number of /filtered/ data members that got replaced by another data member.
const edit_script & member_fns_changes() const
class_or_union_sptr second_class_or_union() const
const var_diff_sptrs_type & sorted_changed_data_members() const
Getter of the sorted vector of data members that got replaced by another data member.
virtual void report(ostream &, const string &indent="") const
Report the changes carried by the current class_or_union_diff node in a textual format.
This is a document class that aims to capture statistics about the changes carried by a corpus_diff t...
size_t num_changed_unreachable_types_filtered_out() const
Getter of the number of changed types that are unreachable from public interfaces and that have been ...
size_t num_func_removed() const
Getter for the number of functions removed.
size_t num_removed_unreachable_types_filtered_out() const
Getter of the number of removed types that are not reachable from public interfaces and that have bee...
size_t num_vars_changed() const
Getter for the number of variables that have a change in one of their sub-types.
size_t net_num_leaf_var_changes() const
Getter for the net number of leaf variable change diff nodes.
size_t num_vars_added() const
Getter for the number of variables added.
size_t num_removed_unreachable_types() const
Getter of the number of removed types that are unreachable from the public interface of the ABI corpu...
size_t num_changed_vars_filtered_out() const
Getter for the number of variables that have a change in one of their sub-types, and that have been f...
size_t num_changed_func_filtered_out() const
Getter for the number of functions that have a change in one of their sub-types, and that have been f...
size_t num_removed_vars_filtered_out() const
Getter for the number removed variables that have been filtered out.
size_t net_num_func_changed() const
Getter for the number of functions that have a change in their sub-types, minus the number of these f...
size_t net_num_vars_removed() const
Getter for the net number of removed variables.
size_t net_num_added_unreachable_types() const
Getter of the number of added types that are unreachable from public interfaces and that are *NOT* fi...
size_t num_removed_var_syms_filtered_out() const
Getter for the number of removed variable symbols, not referenced by any debug info,...
size_t net_num_added_func_syms() const
Getter of the net number of added function symbols that are not referenced by any debug info.
size_t num_added_var_syms_filtered_out() const
Getter for the number of added variable symbols, not referenced by any debug info,...
size_t num_added_unreachable_types() const
Getter of the number of added types that are unreachable from the public interface of the ABI corpus.
size_t net_num_removed_func_syms() const
Getter of the net number of removed function symbols that are not referenced by any debug info.
size_t num_var_syms_added() const
Getter for the number of variable symbols (not referenced by any debug info) that got added.
size_t num_leaf_var_changes() const
Getter for the number of leaf variable change diff nodes.
size_t net_num_removed_var_syms() const
Getter of the net number of removed variable symbols that are not referenced by any debug info.
size_t net_num_func_removed() const
Getter for the net number of function removed.
size_t net_num_func_added() const
Getter for the net number of added functions.
size_t net_num_removed_unreachable_types() const
Getter of the number of removed types that are not reachable from public interfaces and that have *NO...
size_t net_num_leaf_changes() const
Getter of the net number of leaf change diff nodes.
size_t num_removed_func_syms_filtered_out() const
Getter for the number of removed function symbols, not referenced by debug info, that have been filte...
size_t num_added_unreachable_types_filtered_out() const
Getter of the number of added types that are unreachable from public interfaces and that are filtered...
size_t num_added_func_filtered_out() const
Getter for the number of added function that have been filtered out.
size_t num_func_syms_added() const
Getter for the number of function symbols (not referenced by any debug info) that got added.
size_t net_num_leaf_type_changes() const
Getter for the net number of leaf type change diff nodes.
size_t num_func_added() const
Getter for the number of functions added.
size_t net_num_added_var_syms() const
Getter of the net number of added variable symbols that are not referenced by any debug info.
size_t num_leaf_type_changes() const
Getter for the number of leaf type change diff nodes.
size_t num_leaf_var_changes_filtered_out() const
Getter for the number of leaf variable changes diff nodes that have been filtered out.
size_t num_added_vars_filtered_out() const
Getter for the number of added variables that have been filtered out.
size_t num_func_with_virtual_offset_changes() const
Getter for the number of functions that carry virtual member offset changes.
size_t num_func_changed() const
Getter for the number of functions that have a change in one of their sub-types.
size_t num_removed_func_filtered_out() const
Getter for the number of removed functions that have been filtered out.
size_t net_num_vars_added() const
Getter for the net number of added variables.
size_t num_leaf_changes() const
Getter of the number of leaf type change diff nodes.
size_t num_leaf_func_changes_filtered_out() const
Getter for the number of leaf function change diff nodes that were filtered out.
size_t num_added_func_syms_filtered_out() const
Getter for the number of added function symbols, not referenced by any debug info,...
size_t num_leaf_type_changes_filtered_out() const
Getter for the number of filtered out leaf type change diff nodes.
size_t num_changed_unreachable_types() const
Getter of the number of changed types that are unreachable from the public interface of the ABI corpu...
size_t net_num_leaf_func_changes() const
Getter for the net number of leaf function change diff nodes.
size_t num_leaf_func_changes() const
Getter for the number of leaf function change diff nodes.
size_t net_num_changed_unreachable_types() const
Getter of the number of changed types that are unreachable from public interfaces and that have *NOT*...
size_t num_func_syms_removed() const
Getter for the number of function symbols (not referenced by any debug info) that got removed.
size_t num_leaf_changes_filtered_out() const
Getter of the number of leaf type change diff nodes that have been filtered out.
size_t num_vars_removed() const
Getter for the number of variables removed.
size_t num_var_syms_removed() const
Getter for the number of variable symbols (not referenced by any debug info) that got removed.
size_t net_num_vars_changed() const
Getter for the number of variables that have a change in their sub-types, minus the number of these v...
An abstraction of a diff between between two abi corpus.
bool has_incompatible_changes() const
Test if the current instance of corpus_diff carries changes that we are sure are incompatible....
bool has_changes() const
Return true iff the current corpus_diff node carries a change.
void finish_diff_type()
Finish building the current instance of corpus_diff.
virtual void chain_into_hierarchy()
Populate the vector of children node of the corpus_diff type.
const string_var_ptr_map & deleted_variables() const
Getter for the variables that got deleted from the first subject of the diff.
const vector< diff_sptr > & changed_unreachable_types_sorted() const
Getter of a sorted vector of changed types that are not reachable from global functions/variables.
bool soname_changed() const
Test if the soname of the underlying corpus has changed.
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.
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.
edit_script & function_changes() const
edit_script & variable_changes() const
const vector< diff * > & children_nodes() const
const string_diff_sptr_map & changed_unreachable_types() const
Getter for a map of changed types that are not reachable from global functions/variables.
const var_diff_sptrs_type & changed_variables_sorted()
Getter for the sorted vector of variables which signature didn't change but which do have some indire...
const string_elf_symbol_map & deleted_unrefed_function_symbols() const
Getter for function symbols not referenced by any debug info and that got deleted.
const string_elf_symbol_map & deleted_unrefed_variable_symbols() const
Getter for variable symbols not referenced by any debug info and that got deleted.
corpus_diff(corpus_sptr first, corpus_sptr second, diff_context_sptr ctxt=diff_context_sptr())
Constructor for corpus_diff.
corpus_sptr second_corpus() const
bool do_log() const
Test if logging was requested.
const string_elf_symbol_map & added_unrefed_function_symbols() const
Getter for function symbols not referenced by any debug info and that got added.
bool has_net_subtype_changes() const
Test if the current instance of corpus_diff carries subtype changes whose reports are not suppressed ...
const string_var_ptr_map & added_variables() const
Getter for the added variables of the diff.
diff_maps & get_leaf_diffs()
Get the set of maps that contain leaf nodes. A leaf node being a node with a local change.
const diff_context_sptr context() const
Getter of the diff context of this diff.
bool has_net_changes() const
Test if the current instance of corpus_diff carries changes whose reports are not suppressed by any s...
virtual bool traverse(diff_node_visitor &v)
Traverse the diff sub-tree under the current instance corpus_diff.
const diff_stats & apply_filters_and_suppressions_before_reporting()
Apply the different filters that are registered to be applied to the diff tree; that includes the cat...
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...
const string_function_ptr_map & added_functions()
Getter for the added functions of the diff.
void mark_leaf_diff_nodes()
Walks the diff nodes associated to the current corpus diff and mark those that carry local changes....
const string_type_base_sptr_map & deleted_unreachable_types() const
Getter for a map of deleted types that are not reachable from global functions/variables.
corpus_sptr first_corpus() const
const vector< type_base_sptr > & added_unreachable_types_sorted() const
Getter of a sorted vector of added types that are not reachable from global functions/variables.
virtual void report(ostream &out, const string &indent="") const
Report the diff in a serialized form.
const string_elf_symbol_map & added_unrefed_variable_symbols() const
Getter for variable symbols not referenced by any debug info and that got added.
const 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...
const string & get_pretty_representation() const
const string_function_ptr_map & deleted_functions() const
Getter for the deleted functions 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.
friend void apply_suppressions(const corpus_diff *diff_tree)
Walk a corpus_diff tree and appply the suppressions carried by the context. If the suppression applie...
const string_type_base_sptr_map & added_unreachable_types() const
Getter for a map of added types that are not reachable from global functions/variables.
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...
bool architecture_changed() const
Test if the architecture of the underlying corpus has changed.
The base class of diff between decls.
decl_diff_base(decl_base_sptr first_subject, decl_base_sptr second_subject, diff_context_sptr ctxt)
Constructor of decl_diff_base.
The default, initial, reporter of the libabigail comparison engine.
The context of the diff. This type holds various bits of information that is going to be used through...
bool show_deleted_vars() const
void add_suppressions(const suppr::suppressions_type &supprs)
Add new suppression specifications that specify which diff node reports should be dropped on the floo...
diff_category get_allowed_category() const
Getter for the bitmap that represents the set of categories that the user wants to see reported.
void forget_visited_diffs()
Unmark all the diff nodes that were marked as being traversed.
corpus_sptr get_first_corpus() const
Getter for the first corpus of the corpus diff of the current context.
bool show_architecture_change() const
Getter for the property that says if the comparison module should show the architecture changes in it...
bool show_offsets_sizes_in_bits() const
Get the flag that indicates if diff reports using this context should show sizes and offsets in bits,...
void forbid_visiting_a_node_twice(bool f)
This sets a flag that, if it's true, then during the traversing of a diff nodes tree each node is vis...
bool show_changed_fns() const
void initialize_canonical_diff(const diff_sptr diff)
Set the canonical diff node property of a given diff node appropriately.
bool show_redundant_changes() const
A getter for the flag that says if we should report about functions or variables diff nodes that have...
void forbid_visiting_a_node_twice_per_interface(bool)
This function sets a flag os that if forbid_visiting_a_node_twice() returns true, then each time the ...
void keep_diff_alive(diff_sptr &)
Add a diff node to the set of diff nodes that are kept alive for the life time of the current instanc...
diff * diff_has_been_visited(const diff *) const
Test if a diff node has been traversed.
bool visiting_a_node_twice_is_forbidden_per_interface() const
Return a flag that, if true, then during the traversing of a diff nodes tree each node is visited at ...
void set_corpus_diff(const corpus_diff_sptr &)
Set the corpus diff relevant to this context.
bool show_leaf_changes_only() const
Get the flag that indicates if the diff using this context should show only leaf changes or not.
bool perform_change_categorization() const
Test if it's requested to perform diff node categorization.
bool show_impacted_interfaces() const
Getter of the flag that indicates if the leaf reporter should display a summary of the interfaces imp...
bool show_soname_change() const
Getter for the property that says if the comparison module should show the soname changes in its repo...
reporter_base_sptr get_reporter() const
Getter of the reporter to be used in this context.
void add_diff_filter(filtering::filter_base_sptr)
Setter for the diff filters to apply to a given diff sub-tree.
bool do_log() const
Test if logging was requested.
const suppr::suppressions_type & direct_suppressions() const
Getter of the direct suppression specification (those that are not negated) comprised in the general ...
void maybe_apply_filters(diff_sptr diff)
Apply the diff filters to a given diff sub-tree.
bool show_added_fns() const
const suppr::suppressions_type & suppressions() const
Getter for the vector of suppressions that specify which diff node reports should be dropped on the f...
bool show_relative_offset_changes(void)
Get the flag saying if offset changes should be reported in a relative way. That is,...
bool visiting_a_node_twice_is_forbidden() const
Return a flag that, if true, then during the traversing of a diff nodes tree each node is visited at ...
void do_dump_diff_tree(const diff_sptr) const
Emit a textual representation of a diff tree to the error output stream of the current context,...
const suppr::suppressions_type & negated_suppressions() const
Getter of the negated suppression specifications that are comprised in the general vector of suppress...
void add_suppression(const suppr::suppression_sptr suppr)
Add a new suppression specification that specifies which diff node reports should be dropped on the f...
bool show_hex_values() const
Get the flag that indicates if the diff reports using this context should show sizes and offsets in a...
bool show_deleted_fns() const
void switch_categories_off(diff_category c)
Setter for the bitmap that represents the set of categories that the user wants to see reported.
bool show_stats_only() const
Test if the comparison module should only show the diff stats.
bool show_added_vars() const
const filtering::filters & diff_filters() const
Getter for the diff tree nodes filters to apply to diff sub-trees.
bool show_unreachable_types()
Getter for the flag that indicates if changes on types unreachable from global functions and variable...
const corpus_diff_sptr & get_corpus_diff() const
Get the corpus diff for the current context.
void mark_diff_as_visited(const diff *)
Mark a diff node as traversed by a traversing algorithm.
diff_sptr get_canonical_diff_for(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second) const
Getter for the canonical diff node for the diff represented by their two subjects.
bool show_changed_vars() const
void switch_categories_on(diff_category c)
Setter for the bitmap that represents the set of categories that the user wants to see reported.
ostream * default_output_stream()
Getter for the default output stream used by code of the comparison engine. By default the default ou...
bool dump_diff_tree() const
Test if the comparison engine should dump the diff tree for the changed functions and variables it ha...
bool show_symbols_unreferenced_by_debug_info() const
Getter for the flag that indicates if symbols not referenced by any debug info are to be compared and...
bool show_added_symbols_unreferenced_by_debug_info() const
Getter for the flag that indicates if symbols not referenced by any debug info and that got added are...
corpus_sptr get_second_corpus() const
Getter for the second corpus of the corpus diff of the current context.
void set_allowed_category(diff_category c)
Setter for the bitmap that represents the set of categories that the user wants to see reported.
void set_reporter(reporter_base_sptr &)
Setter of the reporter to be used in this context.
ostream * error_output_stream() const
Getter for the errror output stream used by code of the comparison engine. By default the error outpu...
This type contains maps. Each map associates a type name to a diff of that type. Not all kinds of dif...
const string_diff_ptr_map & get_function_decl_diff_map() const
Getter of the map that contains function decl diffs.
const string_diff_ptr_map & get_var_decl_diff_map() const
Getter of the map that contains var decl diffs.
const string_diff_ptr_map & get_enum_diff_map() const
Getter of the map that contains enum type diffs.
bool insert_diff_node(const diff *d, const type_or_decl_base_sptr &impacted_iface)
Insert a new diff node into the current instance of diff_maps.
diff_maps()
Default constructor of the diff_maps type.
const string_diff_ptr_map & get_union_diff_map() const
Getter of the map that contains union type diffs.
artifact_sptr_set_type * lookup_impacted_interfaces(const diff *d) const
Lookup the interfaces that are impacted by a given leaf diff node.
const string_diff_ptr_map & get_function_type_diff_map() const
Getter of the map that contains function type diffs.
const string_diff_ptr_map & get_typedef_diff_map() const
Getter of the map that contains typedef type diffs.
const string_diff_ptr_map & get_distinct_diff_map() const
Getter of the map that contains distinct diffs.
const string_diff_ptr_map & get_subrange_diff_map() const
Getter of the map that contains subrange type diffs.
const string_diff_ptr_map & get_reference_diff_map() const
Getter of the map that contains reference type diffs.
const string_diff_ptr_map & get_array_diff_map() const
Getter of the map that contains array type diffs.
const string_diff_ptr_map & get_type_decl_diff_map() const
Getter of the map that contains basic type diffs.
const string_diff_ptr_map & get_fn_parm_diff_map() const
Getter of the map that contains function parameter diffs.
const string_diff_ptr_map & get_class_diff_map() const
Getter of the map that contains class type diffs.
The base class for the node visitors. These are the types used to visit each node traversed by the di...
void or_visiting_kind(visiting_kind v)
Setter for the visiting policy of the traversing code while invoking this visitor....
virtual bool visit(diff *, bool)
Default visitor implementation.
void set_current_topmost_iface_diff(diff *)
Setter of the diff current topmost interface which is impacted by the current diff node being visited...
virtual void visit_begin(diff *)
This is called by the traversing code on a diff node just before visiting it. That is,...
visiting_kind get_visiting_kind() const
Getter for the visiting policy of the traversing code while invoking this visitor.
virtual void visit_end(diff *)
This is called by the traversing code on a diff node just after visiting it. That is after visiting i...
diff_node_visitor()
Default constructor of the diff_node_visitor type.
void set_visiting_kind(visiting_kind v)
Setter for the visiting policy of the traversing code while invoking this visitor.
diff * get_current_topmost_iface_diff() const
Getter of the diff current topmost interface which is impacted by the current diff node being visited...
virtual bool traverse(diff_node_visitor &v)
The default traverse function.
The abstraction of a change between two ABI artifacts, a.k.a an artifact change.
void begin_traversing()
Flag a given diff node as being traversed.
void set_category(diff_category c)
Set the category of the current diff node. This category includes the categories inherited from the c...
virtual void finish_diff_type()
Finish the insertion of a diff tree node into the diff graph.
virtual void chain_into_hierarchy()
This constructs the relation between this diff node and its detail diff nodes, in the generic view of...
diff_category remove_from_category(diff_category c)
Remove the current diff tree node from an a existing sef of categories. The categories include those ...
type_or_decl_base_sptr second_subject() const
Getter of the second subject of the diff.
bool is_traversing() const
Tell if a given node is being traversed or not.
type_or_decl_base_sptr first_subject() const
Getter of the first subject of the diff.
bool is_suppressed() const
Test if the current diff node has been suppressed by a user-provided suppression specification.
bool is_filtered_out_without_looking_at_allowed_changes() const
Test if this diff tree node is to be filtered out for reporting purposes, but without considering the...
diff * get_canonical_diff() const
Getter for the canonical diff of the current instance of diff.
bool has_parent_allowed_by_specific_negated_suppression() const
Test if the current diff node has a parent node which is specifically allowed by a negated suppressio...
bool has_local_changes_to_be_reported() const
Test if this diff tree node should be reported when considering the categories that were *NOT* inheri...
const vector< diff * > & children_nodes() const
Getter for the children nodes of the current diff node.
diff_category get_category() const
Getter for the category of the current diff tree node.
bool is_allowed_by_specific_negated_suppression() const
Test if this diff node is allowed (prevented from being suppressed) by at least one negated suppressi...
diff_category remove_from_local_category(diff_category c)
Remove the current diff tree node from the categories resulting from the local changes.
void add_to_local_and_inherited_categories(diff_category c)
Adds the current diff tree node to the categories resulting from the local and inherited changes of t...
bool do_log() const
Test if logging was requested.
diff_category get_local_category() const
Getter for the local category of the current diff tree node.
diff_category add_to_category(diff_category c)
Adds the current diff tree node to an additional set of categories. Note that the categories include ...
const diff_context_sptr context() const
Getter of the context of the current diff.
virtual enum change_kind has_local_changes() const =0
Pure interface to know if the current instance of @diff carries a local change. A local change is a c...
virtual bool traverse(diff_node_visitor &v)
The generic traversing code that walks a given diff sub-tree.
bool currently_reporting() const
Tests if we are currently in the middle of emitting a report for this diff.
virtual bool has_changes() const =0
Pure interface to get the length of the changes encapsulated by this diff. A length of zero means tha...
bool has_descendant_allowed_by_specific_negated_suppression() const
Test if the current diff node has a descendant node which is specifically allowed by a negated suppre...
bool to_be_reported() const
Test if this diff tree node should be reported.
const diff * parent_node() const
Getter for the parent node of the current diff node.
diff_category get_class_of_equiv_category() const
Getter of the category of the class of equivalence of the current diff tree node.
void set_canonical_diff(diff *)
Setter for the canonical diff of the current instance of diff.
bool is_filtered_out_wrt_non_inherited_categories() const
Test if this diff tree node is to be filtered out for reporting purposes, but by considering only the...
diff_category add_to_local_category(diff_category c)
Adds the current diff tree node to the categories resulting from the local changes of the current dif...
void set_local_category(diff_category c)
Set the local category of the current diff node.
virtual const string & get_pretty_representation() const
Get a pretty representation of the current diff node.
void append_child_node(diff_sptr)
Add a new child node to the vector of children nodes for the current diff node.
bool is_filtered_out() const
Test if this diff tree node is to be filtered out for reporting purposes.
void end_traversing()
Flag a given diff node as not being traversed anymore.
bool reported_once() const
Tests if a report has already been emitted for the current diff.
An abstraction of a diff between entities that are of a different kind (disctinct).
virtual bool has_changes() const
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of @distinct_d...
const diff_sptr compatible_child_diff() const
Getter for the child diff of this distinct_diff instance.
distinct_diff(type_or_decl_base_sptr first, type_or_decl_base_sptr second, diff_context_sptr ctxt=diff_context_sptr())
Constructor for distinct_diff.
static bool entities_are_of_distinct_kinds(type_or_decl_base_sptr first, type_or_decl_base_sptr second)
Test if the two arguments are of different kind, or that are both NULL.
virtual void report(ostream &out, const string &indent="") const
Emit a report about the current diff instance.
const type_or_decl_base_sptr first() const
Getter for the first subject of the diff.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
const type_or_decl_base_sptr second() const
Getter for the second subject of the diff.
Abstraction of a diff between two enums.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of enum_diff.
enum_diff(const enum_type_decl_sptr, const enum_type_decl_sptr, const diff_sptr, diff_context_sptr ctxt=diff_context_sptr())
Constructor for enum_diff.
diff_sptr underlying_type_diff() const
const string_changed_enumerator_map & changed_enumerators() const
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
const enum_type_decl_sptr first_enum() const
const string_enumerator_map & deleted_enumerators() const
const enum_type_decl_sptr second_enum() const
const string_enumerator_map & inserted_enumerators() const
virtual void report(ostream &, const string &indent="") const
Report the differences between the two enums.
A filter that walks the diff nodes tree and tags relevant diff nodes into categories considered to re...
Abstraction of a diff between two function parameters.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
virtual void chain_into_hierarchy()
Populate the vector of children nodes of the diff base type sub-object of this instance of fn_parm_di...
const function_decl::parameter_sptr first_parameter() const
Getter for the first subject of this diff node.
virtual enum change_kind has_local_changes() const
Check if the current diff node carries a local change.
virtual const string & get_pretty_representation() const
Build and return a textual representation of the current instance of fn_parm_diff.
const function_decl::parameter_sptr second_parameter() const
Getter for the second subject of this diff node.
diff_sptr type_diff() const
Getter for the diff representing the changes on the type of the function parameter involved in the cu...
virtual void report(ostream &, const string &indent="") const
Emit a textual report about the current fn_parm_diff instance.
Abstraction of a diff between two function_decl.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of function_de...
const function_decl_sptr second_function_decl() const
function_decl_diff(const function_decl_sptr first, const function_decl_sptr second, diff_context_sptr ctxt)
Constructor for function_decl_diff.
virtual enum change_kind has_local_changes() const
const function_decl_sptr first_function_decl() const
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Serialize a report of the changes encapsulated in the current instance of function_decl_diff over to ...
Abstraction of a diff between two function types.
virtual bool has_changes() const
Test if the current diff node carries changes.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of function_ty...
const string_fn_parm_diff_sptr_map & subtype_changed_parms() const
Getter for the map of function parameter changes of the current diff.
const diff_sptr return_type_diff() const
Getter for the diff of the return types of the two function types of the current diff.
const string_parm_map & removed_parms() const
Getter for the map of parameters that got removed.
const string_parm_map & added_parms() const
Getter for the map of parameters that got added.
friend function_type_diff_sptr compute_diff(const function_type_sptr first, const function_type_sptr second, diff_context_sptr ctxt)
Compute the diff between two instances of function_type.
const vector< function_decl::parameter_sptr > & sorted_added_parms() const
Getter for the sorted vector of added parameters .
const function_type_sptr first_function_type() const
Getter for the first subject of the diff.
const function_type_sptr second_function_type() const
Getter for the second subject of the diff.
function_type_diff(const function_type_sptr first, const function_type_sptr second, diff_context_sptr ctxt)
Consutrctor of the function_type type.
virtual enum change_kind has_local_changes() const
Test if the current diff node carries local changes.
virtual const string & get_pretty_representation() const
Build and return a copy of a pretty representation of the current instance of function_type_diff.
const vector< function_decl::parameter_sptr > & sorted_deleted_parms() const
Getter for the sorted vector of deleted parameters.
virtual void report(ostream &, const string &indent="") const
Build and emit a textual report about the current function_type_diff instance.
A reporter that only reports leaf changes.
The abstraction of a diff between two pointers.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
const pointer_type_def_sptr first_pointer() const
Getter for the first subject of a pointer diff.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of pointer_dif...
const pointer_type_def_sptr second_pointer() const
Getter for the second subject of a pointer diff.
diff_sptr underlying_type_diff() const
Getter for the diff between the pointed-to types of the pointers of this diff.
pointer_diff(pointer_type_def_sptr first, pointer_type_def_sptr second, diff_sptr underlying_type_diff, diff_context_sptr ctxt=diff_context_sptr())
Constructor for a pointer_diff.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
The abstraction of a diff between two ptr_to_mbr_type.
virtual bool has_changes() const
Test whether the current diff node carries any change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of ptr_to_mbr_...
virtual ~ptr_to_mbr_diff()
Destructor of ptr_to_mbr_diff.
ptr_to_mbr_type_sptr first_ptr_to_mbr_type() const
Getter of the first pointer-to-member subject of the current diff node.
const diff_sptr containing_type_diff() const
Getter of the diff node carrying changes to the containing type of first subject of the current diff ...
const diff_sptr member_type_diff() const
Getter of the diff node carrying changes to the member type of first subject of the current diff node...
ptr_to_mbr_type_sptr second_ptr_to_mbr_type() const
Getter of the second pointer-to-member subject of the current diff node.
virtual enum change_kind has_local_changes() const
Test whether the current diff node carries any local change.
virtual const string & get_pretty_representation() const
Get the pretty representation of the current ptr_to_mbr_diff node.
virtual void report(ostream &, const string &indent="") const
Pure interface to report the diff in a serialized form that is legible for the user.
Abstraction of a diff between two qualified types.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of qualified_t...
diff_sptr leaf_underlying_type_diff() const
Getter for the diff between the most underlying non-qualified types of two qualified types.
diff_sptr underlying_type_diff() const
Getter for the diff between the underlying types of the two qualified types.
qualified_type_diff(qualified_type_def_sptr first, qualified_type_def_sptr second, diff_sptr underling, diff_context_sptr ctxt=diff_context_sptr())
Constructor for qualified_type_diff.
const qualified_type_def_sptr second_qualified_type() const
Getter for the second qualified type of the diff.
virtual enum change_kind has_local_changes() const
const qualified_type_def_sptr first_qualified_type() const
Getter for the first qualified type of the diff.
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
The abstraction of a diff between two references.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of reference_d...
reference_type_def_sptr first_reference() const
Getter for the first reference of the diff.
reference_type_def_sptr second_reference() const
Getter for the second reference of the diff.
reference_diff(const reference_type_def_sptr first, const reference_type_def_sptr second, diff_sptr underlying, diff_context_sptr ctxt=diff_context_sptr())
Constructor for reference_diff.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
const diff_sptr & underlying_type_diff() const
Getter for the diff between the two referred-to types.
virtual void report(ostream &, const string &indent="") const
Report the diff in a serialized form.
An abstractions of the changes between two scopes.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of scope_diff.
const diff_sptrs_type & changed_types() const
const scope_decl_sptr second_scope() const
Getter for the second scope of the diff.
const scope_decl_sptr first_scope() const
Getter for the first scope of the diff.
const decl_base_sptr deleted_member_at(unsigned index) const
Accessor that eases the manipulation of the edit script associated to this instance....
const diff_sptrs_type & changed_decls() const
scope_diff(scope_decl_sptr first_scope, scope_decl_sptr second_scope, diff_context_sptr ctxt=diff_context_sptr())
Constructor for scope_diff.
friend scope_diff_sptr compute_diff(const scope_decl_sptr first, const scope_decl_sptr second, scope_diff_sptr d, diff_context_sptr ctxt)
Compute the diff between two scopes.
const decl_base_sptr inserted_member_at(unsigned i)
Accessor that eases the manipulation of the edit script associated to this instance....
virtual void report(ostream &out, const string &indent="") const
Report the changes of one scope against another.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
const edit_script & member_changes() const
Accessor of the edit script of the members of a scope.
The abstraction of the diff between two subrange types.
virtual bool has_changes() const
Test if the current subrange_diff node carries any change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of subrange_di...
const array_type_def::subrange_sptr second_subrange() const
Getter of the second subrange of the current instance subrange_diff.
subrange_diff(const array_type_def::subrange_sptr &first, const array_type_def::subrange_sptr &second, const diff_sptr &underlying_type_diff, const diff_context_sptr ctxt=diff_context_sptr())
Constructor of the subrange_diff diff node type.
const array_type_def::subrange_sptr first_subrange() const
Getter of the first subrange of the current instance subrange_diff.
const diff_sptr underlying_type_diff() const
Getter of the diff node of the underlying types of the current subrange_diff diff node.
virtual enum change_kind has_local_changes() const
Test if the current subrange_diff node carries any local change.
virtual const string & get_pretty_representation() const
Getter the pretty representation of the subrange_diff diff node.
virtual void report(ostream &, const string &indent="") const
Report about the changes carried by this node.
An abstraction of a diff between two translation units.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
const translation_unit_sptr second_translation_unit() const
Getter for the second translation unit of this diff.
translation_unit_diff(translation_unit_sptr first, translation_unit_sptr second, diff_context_sptr ctxt=diff_context_sptr())
Constructor for translation_unit_diff.
virtual void report(ostream &out, const string &indent="") const
Report the diff in a serialized form.
virtual enum change_kind has_local_changes() const
const translation_unit_sptr first_translation_unit() const
Getter for the first translation unit of this diff.
Abstraction of a diff between two basic type declarations.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
const type_decl_sptr first_type_decl() const
Getter for the first subject of the type_decl_diff.
const type_decl_sptr second_type_decl() const
Getter for the second subject of the type_decl_diff.
virtual void report(ostream &out, const string &indent="") const
Ouputs a report of the differences between of the two type_decl involved in the type_decl_diff.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
The base class of diff between types.
Abstraction of a diff between two typedef_decl.
virtual bool has_changes() const
Return true iff the current diff node carries a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of typedef_dif...
const typedef_decl_sptr second_typedef_decl() const
Getter for the second typedef_decl involved in the diff.
const typedef_decl_sptr first_typedef_decl() const
Getter for the firt typedef_decl involved in the diff.
const diff_sptr underlying_type_diff() const
Getter for the diff between the two underlying types of the typedefs.
virtual enum change_kind has_local_changes() const
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Reports the difference between the two subjects of the diff in a serialized form.
union_diff(union_decl_sptr first_union, union_decl_sptr second_union, diff_context_sptr ctxt=diff_context_sptr())
Constructor for the union_diff type.
union_decl_sptr first_union_decl() const
union_decl_sptr second_union_decl() const
virtual ~union_diff()
Destructor of the union_diff node.
virtual const string & get_pretty_representation() const
virtual void report(ostream &, const string &indent="") const
Report the changes carried by the current union_diff node in a textual format.
Abstracts a diff between two instances of var_decl.
virtual bool has_changes() const
Return true iff the diff node has a change.
virtual void chain_into_hierarchy()
Populate the vector of children node of the diff base type sub-object of this instance of var_diff.
var_diff(var_decl_sptr first, var_decl_sptr second, diff_sptr type_diff, diff_context_sptr ctxt=diff_context_sptr())
Constructor for var_diff.
var_decl_sptr first_var() const
Getter for the first var_decl of the diff.
virtual void report(ostream &out, const string &indent="") const
Report the diff in a serialized form.
virtual enum change_kind has_local_changes() const
friend var_diff_sptr compute_diff(const var_decl_sptr first, const var_decl_sptr second, diff_context_sptr ctxt)
Compute the diff between two instances of var_decl.
virtual const string & get_pretty_representation() const
diff_sptr type_diff() const
Getter for the diff of the types of the instances of var_decl.
var_decl_sptr second_var() const
Getter for the second var_decl of the diff.
The abstraction of an edit script for transforming a sequence A into a sequence B.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
vector< base_spec_sptr > base_specs
Convenience typedef.
vector< method_decl_sptr > member_functions
Convenience typedef.
bool get_is_anonymous() const
Test if the current declaration is anonymous.
The abstraction of the version of an ELF symbol.
Abstraction of an elf symbol.
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Abstraction for a function declaration.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
interned_string get_id() const
Return an ID that tries to uniquely identify the function inside a program or a library.
An abstraction helper for type declarations.
The base class of both types and declarations.
change_kind
The kind of change the current function suppression should apply to.
@ ADDED_FUNCTION_CHANGE_KIND
The function was added to the second subject of the diff.
@ DELETED_FUNCTION_CHANGE_KIND
The function was deleted from the second subject of the diff.
change_kind
The kind of change the current variable suppression should apply to.
@ ADDED_VARIABLE_CHANGE_KIND
The variable was added to the second second subject of the diff.
@ DELETED_VARIABLE_CHANGE_KIND
The variable was deleted from the second subject of the diff.
bool has_void_ptr_to_ptr_change(const diff *dif)
Test if a diff node carries a void* to pointer type change.
std::vector< filter_base_sptr > filters
Convenience typedef for a vector of filter_base_sptr.
bool has_harmless_enum_to_int_change(const diff *diff)
Test if a diff node carries a harmless change of an enum into an integer (or vice-versa).
bool is_decl_only_class_with_size_change(const class_or_union &first, const class_or_union &second)
Test if two classes that are decl-only (have the decl-only flag and carry no data members) but are di...
shared_ptr< filter_base > filter_base_sptr
Convenience typedef for a shared pointer to filter_base.
bool has_harmful_name_change(const decl_base_sptr &f, const decl_base_sptr &s)
Test if two decls represents a harmful name change.
bool has_benign_array_of_unknown_size_change(const diff *dif)
Test if a diff node carries a benign change to the size of a variable of type array.
bool has_decl_only_def_change(const decl_base_sptr &first, const decl_base_sptr &second)
Test if two decl_base_sptr are different just by the fact that one is decl-only and the other one is ...
bool has_basic_or_class_type_name_change(const diff *d)
Test if a diff node carries a basic or class type name change.
void apply_filter(filter_base &filter, corpus_diff_sptr d)
Walk the diff sub-trees of a a corpus_diff and apply a filter to the nodes visted....
bool is_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...
shared_ptr< diff > diff_sptr
Convenience typedef for a shared_ptr for the diff class.
visiting_kind operator~(visiting_kind l)
The overloaded 'bit inversion' operator for visiting_kind.
const decl_diff_base * is_decl_diff(const diff *diff)
Test if a diff node is about differences between declarations.
const diff * peel_qualified_diff(const diff *dif)
If a diff node is about changes between two qualified types, get the diff node about changes between ...
const diff * peel_pointer_or_qualified_type_diff(const diff *dif)
If a diff node is about changes between two pointer, reference or qualified types,...
void categorize_redundancy(diff *diff_tree)
Walk a given diff sub-tree to categorize each of the nodes with respect to the REDUNDANT_CATEGORY.
vector< diff * > diff_ptrs_type
Convenience typedef for a vector of diff*.
void sort_string_diff_ptr_map(const string_diff_ptr_map &map, diff_ptrs_type &sorted)
Sort a map ofg string -> diff* into a vector of diff_ptr. The diff_ptr are sorted lexicographically w...
diff_category
An enum for the different categories that a diff tree node falls into, regarding the kind of changes ...
@ ACCESS_CHANGE_CATEGORY
This means the diff node (or at least one of its descendant nodes) carries access related changes,...
@ HARMLESS_DATA_MEMBER_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless data member change....
@ SUPPRESSED_CATEGORY
This means that a diff node was marked as suppressed by a user-provided suppression specification.
@ VIRTUAL_MEMBER_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an incompatible change to a vtable.
@ REDUNDANT_CATEGORY
A diff node in this category is redundant. That means it's present as a child of a other nodes in the...
@ SIZE_OR_OFFSET_CHANGE_CATEGORY
This means the diff node (or at least one of its descendant nodes) carries a change that modifies the...
@ NON_VIRT_MEM_FUN_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an addition or removal of a non-virtual member fu...
@ HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY
A diff node in this category has a descendant node that is in the HAS_ALLOWED_CHANGE_CATEGORY categor...
@ HARMLESS_ENUM_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an addition of enumerator to an enum type.
@ FN_PARM_ADD_REMOVE_CHANGE_CATEGORY
A diff node in this category is a function (or function type) with at least one parameter added or re...
@ VOID_PTR_TO_PTR_CHANGE_CATEGORY
A diff node in this category carries a change from void pointer to non-void pointer.
@ NON_COMPATIBLE_DISTINCT_CHANGE_CATEGORY
A change between two non-compatible types of different kinds.
@ PRIVATE_TYPE_CATEGORY
This means that a diff node was warked as being for a private type. That is, the diff node is meant t...
@ NON_COMPATIBLE_NAME_CHANGE_CATEGORY
A non-compatible name change between two types.
@ COMPATIBLE_TYPE_CHANGE_CATEGORY
This means the diff node (or at least one of its descendant nodes) carries a change involving two com...
@ TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a type that was declaration-only and that is now ...
@ STATIC_DATA_MEMBER_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an addition or removal of a static data member.
@ HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless union or class change.
@ HARMLESS_DECL_NAME_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless declaration name change....
@ NO_CHANGE_CATEGORY
This means the diff node does not carry any (meaningful) change, or that it carries changes that have...
@ HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY
A diff node in this category has a parent node that is in the HAS_ALLOWED_CHANGE_CATEGORY category....
@ BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY
A diff node in this category carries a change in the size of the array type of a global variable,...
@ VAR_TYPE_CV_CHANGE_CATEGORY
A diff node in this category is for a variable which type holds a cv-qualifier change.
@ HAS_ALLOWED_CHANGE_CATEGORY
A diff node in this category carries a change that must be reported, even if the diff node is also in...
@ FN_PARM_TYPE_CV_CHANGE_CATEGORY
A diff node in this category has a function parameter type with a cv-qualifiers change.
@ FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY
A diff node in this category is a function parameter type which top cv-qualifiers change.
@ FN_RETURN_TYPE_CV_CHANGE_CATEGORY
A diff node in this category is a function return type with a cv-qualifier change.
@ HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an a symbol alias change that is harmless.
shared_ptr< reporter_base > reporter_base_sptr
A convenience typedef for a shared pointer to a reporter_base.
void sort_string_var_diff_sptr_map(const string_var_diff_sptr_map &map, var_diff_sptrs_type &sorted)
Sort of an instance of string_var_diff_sptr_map map.
unordered_map< string, var_diff_sptr > string_var_diff_sptr_map
Convenience typedef for a map whose key is a string and whose value is a changed variable of type var...
const class_or_union_diff * is_diff_of_class_or_union_type(const diff *d)
Test if a diff node represents a diff between two class or union types.
const subrange_diff * is_anonymous_subrange_diff(const diff *d)
Test if a diff node is a subrange_diff between two anonymous subranges.
const pointer_diff * is_pointer_diff(const diff *diff)
Test if a diff node is about differences between two pointers.
vector< var_diff_sptr > var_diff_sptrs_type
Convenience typedef for a vector of var_diff_sptr.
unordered_map< string, class_decl::base_spec_sptr > string_base_sptr_map
Convenience typedef for a map of string and class_decl::basse_spec_sptr.
void sort_string_function_ptr_map(const string_function_ptr_map &map, vector< const function_decl * > &sorted)
Sort an instance of string_function_ptr_map map and stuff a resulting sorted vector of pointers to fu...
diff_sptr try_to_diff(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second, diff_context_sptr ctxt)
</distinct_diff>
bool has_basic_type_change_only(const diff *d)
Test if a diff node is a decl diff that only carries a basic type change on its type diff sub-node.
void propagate_categories(diff *diff_tree)
Visit all the nodes of a given sub-tree. For each node that has a particular category set,...
const subrange_diff * is_subrange_diff(const diff *diff)
Test if a diff node is a subrange_diff node.
unordered_map< unsigned, fn_parm_diff_sptr > unsigned_fn_parm_diff_sptr_map
Convenience typedef for a map which key is an integer and which value is a changed parameter.
void sort_string_base_sptr_map(const string_base_sptr_map &m, class_decl::base_specs &sorted)
Lexicographically sort base specifications found in instances of string_base_sptr_map.
diff_category get_default_harmless_categories_bitmap()
Getter of a bitmap made of the set of change categories that are considered harmless.
vector< diff_sptr > diff_sptrs_type
Convenience typedef for a vector of diff_sptr.
distinct_diff_sptr compute_diff_for_distinct_kinds(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second, diff_context_sptr ctxt)
Try to diff entities that are of distinct kinds.
void sort_changed_data_members(changed_var_sptrs_type &input)
Sort (in place) a vector of changed data members.
unordered_map< string, type_base_sptr > string_type_base_sptr_map
Convenience typedef for a map which key is a string and which value is a type_base_sptr.
diff_sptr try_to_diff< class_decl >(const type_or_decl_base_sptr first, const type_or_decl_base_sptr second, diff_context_sptr ctxt)
This is a specialization of try_to_diff() template to diff instances of class_decl.
shared_ptr< type_decl_diff > type_decl_diff_sptr
Convenience typedef for a shared pointer on a type_decl_diff type.
bool is_diff_of_variadic_parameter(const diff *d)
Test if a diff node represents the difference between a variadic parameter and something else.
shared_ptr< diff_context > diff_context_sptr
Convenience typedef for a shared pointer of diff_context.
bool is_diff_of_global_decls(const diff *)
Tests if a given diff node is to represent the changes between two gobal decls.
shared_ptr< subrange_diff > subrange_diff_sptr
A convenience typedef for a shared pointer to subrange_diff type.
bool is_diff_of_variadic_parameter_type(const diff *d)
Test if a diff node represents the difference between a variadic parameter type and something else.
diff_category get_default_harmful_categories_bitmap()
Getter of a bitmap made of the set of change categories that are considered harmful.
unordered_map< string, function_decl::parameter_sptr > string_parm_map
Convenience typedef for a map which value is a function parameter. The key is the name of the functio...
unordered_map< string, enum_type_decl::enumerator > string_enumerator_map
Convenience typedef for a map which value is an enumerator. The key is the name of the enumerator.
shared_ptr< var_diff > var_diff_sptr
Convenience typedef for a shared pointer to a var_diff type.
unordered_map< string, method_decl_sptr > string_member_function_sptr_map
Convenience typedef for a hash map of strings and member functions.
const diff * peel_typedef_diff(const diff *dif)
If a diff node is about changes between two typedef types, get the diff node about changes between th...
shared_ptr< reference_diff > reference_diff_sptr
Convenience typedef for a shared pointer on a reference_diff type.
vector< base_diff_sptr > base_diff_sptrs_type
Convenience typedef for a vector of base_diff_sptr.
shared_ptr< function_decl_diff > function_decl_diff_sptr
Convenience typedef for a shared pointer to a function_decl type.
shared_ptr< ptr_to_mbr_diff > ptr_to_mbr_diff_sptr
Typedef of a shared_ptr to ptr_to_mbr_diff.
void sort_string_elf_symbol_map(const string_elf_symbol_map &map, vector< elf_symbol_sptr > &sorted)
Sort a map of string -> pointer to elf_symbol.
const function_decl_diff * is_function_decl_diff(const diff *diff)
Test if a diff node is about differences between functions.
void sort_string_function_decl_diff_sptr_map(const string_function_decl_diff_sptr_map &map, function_decl_diff_sptrs_type &sorted)
Sort the values of a string_function_decl_diff_sptr_map map and store the result in a vector of funct...
shared_ptr< fn_parm_diff > fn_parm_diff_sptr
Convenience typedef for a shared pointer to a fn_parm_diff type.
unordered_map< string, function_decl_diff_sptr > string_function_decl_diff_sptr_map
Convenience typedef for a map which key is a string and which value is a function_decl_diff_sptr.
void clear_redundancy_categorization(diff *diff_tree)
Walk a given diff sub-tree to clear the REDUNDANT_CATEGORY out of the category of the nodes.
void sort_unsigned_data_member_diff_sptr_map(const unsigned_var_diff_sptr_map map, var_diff_sptrs_type &sorted)
Sort the values of a unsigned_var_diff_sptr_map map and store the result into a vector of var_diff_sp...
void sort_string_fn_parm_diff_sptr_map(const unsigned_fn_parm_diff_sptr_map &map, vector< fn_parm_diff_sptr > &sorted)
Sort a map of fn_parm_diff by the indexes of the function parameters.
bool is_child_node_of_base_diff(const diff *diff)
Test if a diff node is a child node of a base diff node.
visiting_kind
An enum for the different ways to visit a diff tree node.
@ SKIP_CHILDREN_VISITING_KIND
This says that the traversing code should avoid visiting the children nodes of the current node being...
@ DO_NOT_MARK_VISITED_NODES_AS_VISITED
This says that the traversing code should not mark visited nodes as having been traversed....
visiting_kind operator&(visiting_kind l, visiting_kind r)
The overloaded and operator for visiting_kind.
const diff * peel_fn_parm_diff(const diff *dif)
If a diff node is about changes between two function parameters get the diff node about changes betwe...
const function_type_diff * is_function_type_diff(const diff *diff)
Test if a diff node is a function_type_diff node.
const distinct_diff * is_distinct_diff(const diff *diff)
Test if a diff node is about differences between two diff nodes of different kinds.
unordered_map< string, changed_enumerator > string_changed_enumerator_map
Convenience typedef for a map which value is a changed enumerator. The key is the name of the changed...
visiting_kind operator|(visiting_kind l, visiting_kind r)
The overloaded or operator for visiting_kind.
const array_diff * is_array_diff(const diff *diff)
Test if a diff node is a array_diff node.
const diff * peel_reference_diff(const diff *dif)
If a diff node is about changes between two reference types, get the diff node about changes between ...
unordered_map< string, fn_parm_diff_sptr > string_fn_parm_diff_sptr_map
Convenience typedef for a map which value is a changed function parameter and which key is the name o...
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
unordered_map< string, var_decl_sptr > string_var_ptr_map
Convenience typedef for a map which key is a string and which value is a point to var_decl.
void sort_artifacts_set(const artifact_sptr_set_type &set, vector< type_or_decl_base_sptr > &sorted)
Sort the set of ABI artifacts contained in a artifact_sptr_set_type.
const class_or_union_diff * is_anonymous_class_or_union_diff(const diff *d)
Test if a diff node is a class_or_union_diff between two anonymous classes or unions.
shared_ptr< base_diff > base_diff_sptr
Convenience typedef for a shared pointer to a base_diff type.
shared_ptr< scope_diff > scope_diff_sptr
Convenience typedef for a shared pointer on a scope_diff.
shared_ptr< class_diff > class_diff_sptr
Convenience typedef for a shared pointer on a class_diff type.
const base_diff * is_base_diff(const diff *diff)
Test if a diff node is about differences between two base class specifiers.
const fn_parm_diff * is_fn_parm_diff(const diff *diff)
Test if a diff node is about differences between two function parameters.
void sort_string_member_function_sptr_map(const string_member_function_sptr_map &map, class_or_union::member_functions &sorted)
Sort a map that's an instance of string_member_function_sptr_map and fill a vector of member function...
const union_diff * is_union_diff(const diff *diff)
Test if a diff node is a union_diff node.
vector< changed_var_sptr > changed_var_sptrs_type
Convenience typedef for a vector of @changed_var_sptr.gg381.
shared_ptr< pointer_diff > pointer_diff_sptr
Convenience typedef for a shared pointer on a pointer_diff type.
const diff * peel_pointer_diff(const diff *dif)
If a diff node is about changes between two pointer types, get the diff node about changes between th...
void sort_string_var_ptr_map(const string_var_ptr_map &map, vector< var_decl_sptr > &sorted)
Sort a map of string -> pointer to var_decl.
void apply_suppressions(diff *diff_tree)
Walk a given diff-sub tree and appply the suppressions carried by the context. If the suppression app...
void sort_string_parm_map(const string_parm_map &map, vector< function_decl::parameter_sptr > &sorted)
Sort a map of string -> function parameters.
void sort_string_type_base_sptr_map(string_type_base_sptr_map &map, vector< type_base_sptr > &sorted)
Sort a map of string to type_base_sptr entities.
const enum_diff * is_enum_diff(const diff *diff)
Test if a diff node is a enum_diff node.
unordered_map< string, base_diff_sptr > string_base_diff_sptr_map
Convenience typedef for a map of string and base_diff_sptr.
void sort_data_members(const string_decl_base_sptr_map &data_members, vector< decl_base_sptr > &sorted)
Sort a map of data members by the offset of their initial value.
const class_or_union_diff * is_class_or_union_diff(const diff *d)
Test if a diff node is a class_or_union_diff node.
const corpus_diff * is_corpus_diff(const diff *diff)
Test if a diff node is a corpus_diff node.
const diff * get_typedef_diff_underlying_type_diff(const diff *diff)
Return the leaf underlying diff node of a typedef_diff node.
const typedef_diff * is_typedef_diff(const diff *diff)
Test if a diff node is a typedef_diff node.
unordered_map< unsigned, var_diff_sptr > unsigned_var_diff_sptr_map
Convenience typedef for a map whose key is an unsigned int and whose value is a changed variable of t...
type_base_sptr get_leaf_type(qualified_type_def_sptr t)
Return the first underlying type that is not a qualified type.
const diff * peel_typedef_qualified_type_or_parameter_diff(const diff *dif)
If a diff node is about changes between two typedefs or qualified types, get the diff node about chan...
bool is_less_than(const function_decl_diff &first, const function_decl_diff &second)
Compare two function_decl_diff for the purpose of sorting.
shared_ptr< array_diff > array_diff_sptr
Convenience typedef for a shared pointer on a array_diff type.
bool is_reference_or_ptr_diff_to_non_basic_nor_distinct_types(const diff *diff)
Test if a diff node is a reference or pointer diff node to a change that is neither basic type change...
const class_diff * is_class_diff(const diff *diff)
Test if a diff node is a class_diff node.
const type_decl_diff * is_diff_of_basic_type(const diff *d)
Test if a diff node represents a diff between two basic types.
unordered_map< string, diff_sptr > string_diff_sptr_map
Convenience typedef for a map which value is a diff_sptr. The key of the map is the qualified name of...
unordered_map< const diff *, artifact_sptr_set_type, diff_hash, diff_equal > diff_artifact_set_map_type
A convenience typedef for an unordered_map which key is a diff* and which value is a artifact_sptr_se...
const qualified_type_diff * is_qualified_type_diff(const diff *diff)
Test if a diff node is about differences between two qualified types.
diff_sptr compute_diff(const decl_base_sptr first, const decl_base_sptr second, diff_context_sptr ctxt)
Compute the difference between two decls. The decls can represent either type declarations,...
unordered_map< string, diff * > string_diff_ptr_map
Convenience typedef for a map which value is a diff*. The key of the map is the qualified name of the...
void sort_string_base_diff_sptr_map(const string_base_diff_sptr_map &map, base_diff_sptrs_type &sorted)
Sort a map of string -> base_diff_sptr into a sorted vector of base_diff_sptr. The base_diff_sptr are...
void sort_changed_enumerators(const string_changed_enumerator_map &enumerators_map, changed_enumerators_type &sorted)
Sort a map of changed enumerators.
void print_diff_tree(diff *diff_tree, ostream &out)
Emit a textual representation of a diff sub-tree to an output stream.
vector< changed_enumerator > changed_enumerators_type
Convenience typedef for a vector of changed enumerators.
vector< function_decl_diff_sptr > function_decl_diff_sptrs_type
Convenience typedef for a vector of function_decl_diff_sptr.
bool is_child_node_of_function_parm_diff(const diff *diff)
Test if a diff node is a child node of a function parameter diff node.
void sort_string_virtual_member_function_diff_sptr_map(const string_function_decl_diff_sptr_map &map, function_decl_diff_sptrs_type &sorted)
Sort an map of string -> virtual member function into a vector of virtual member functions....
shared_ptr< function_type_diff > function_type_diff_sptr
A convenience typedef for a shared pointer to function_type_type_diff.
const function_type_diff * is_function_type_diff_with_local_changes(const diff *diff)
Test if a given diff node carries a function type change with local changes.
const var_diff * is_var_diff(const diff *diff)
Test if a diff node is about differences between variables.
const type_diff_base * is_type_diff(const diff *diff)
Test if a diff node is about differences between types.
unordered_map< string, elf_symbol_sptr > string_elf_symbol_map
Convenience typedef for a map whose key is a string and whose value is an elf_symbol_sptr.
void sort_string_diff_sptr_map(const string_diff_sptr_map &map, diff_sptrs_type &sorted)
Sort a map ofg string -> diff_sptr into a vector of diff_sptr. The diff_sptr are sorted lexicographic...
const reference_diff * is_reference_diff(const diff *diff)
Test if a diff node is about differences between two references.
void sort_string_data_member_diff_sptr_map(const string_var_diff_sptr_map &map, var_diff_sptrs_type &sorted)
Sort the values of a string_var_diff_sptr_map and store the result in a vector of var_diff_sptr.
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....
shared_ptr< distinct_diff > distinct_diff_sptr
Convenience typedef for a shared pointer to distinct_types_diff.
shared_ptr< corpus_diff > corpus_diff_sptr
A convenience typedef for a shared pointer to corpus_diff.
std::pair< var_decl_sptr, var_decl_sptr > changed_var_sptr
Convenience typedef for a pair of var_decl_sptr representing a var_decl change. The first member of t...
shared_ptr< typedef_diff > typedef_diff_sptr
Convenience typedef for a shared pointer on a typedef_diff type.
const diff * peel_typedef_or_qualified_type_diff(const diff *dif)
If a diff node is about changes between two typedefs or qualified types, get the diff node about chan...
void sort_enumerators(const string_enumerator_map &enumerators_map, enum_type_decl::enumerators &sorted)
Sort a map of enumerators by their value.
unordered_map< string, const function_decl * > string_function_ptr_map
Convenience typedef for a map which key is a string and which value is a pointer to decl_base.
ostream & operator<<(ostream &o, diff_category c)
Serialize an instance of diff_category to an output stream.
shared_ptr< translation_unit_diff > translation_unit_diff_sptr
Convenience typedef for a shared pointer on a translation_unit_diff type.
void compute_diff(RandomAccessOutputIterator a_base, RandomAccessOutputIterator a_begin, RandomAccessOutputIterator a_end, RandomAccessOutputIterator b_base, RandomAccessOutputIterator b_begin, RandomAccessOutputIterator b_end, vector< point > &lcs, edit_script &ses, int &ses_len)
Compute the longest common subsequence of two (sub-regions of) sequences as well as the shortest edit...
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
unordered_set< type_or_decl_base_sptr, type_or_decl_hash, type_or_decl_equal > artifact_sptr_set_type
A convenience typedef for a hash set of type_or_decl_base_sptr.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
@ LOCAL_TYPE_CHANGE_KIND
This means that a given IR artifact has a local type change.
@ ALL_LOCAL_CHANGES_MASK
Testing (anding) against this mask means that a given IR artifact has local differences,...
@ LOCAL_NON_TYPE_CHANGE_KIND
This means that a given IR artifact has a local non-type change. That is a change that is carried by ...
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
bool collect_non_anonymous_data_members(const class_or_union *cou, string_decl_base_sptr_map &dms)
Collect all the non-anonymous data members of a class or union type.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
string get_pretty_representation(const type_or_decl_base *tod, bool internal)
Build and return a copy of the pretty representation of an ABI artifact that could be either a type o...
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
const var_decl_sptr get_next_data_member(const class_or_union *klass, const var_decl_sptr &data_member)
In the context of a given class or union, this function returns the data member that is located after...
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
var_decl_sptr find_data_member_from_anonymous_data_member(const var_decl_sptr &anon_dm, const string &name)
Find a data member inside an anonymous data member.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
unordered_map< string, decl_base_sptr > string_decl_base_sptr_map
Convenience typedef for a map which key is a string and which value is a decl_base_sptr.
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
bool is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr, const enum_type_decl &enom)
Test if a given enumerator is found present in an enum.
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
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 ...
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
class_or_union * anonymous_data_member_to_class_or_union(const var_decl *d)
Get the class_or_union type of a given anonymous data member.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
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.
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,...
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
bool class_or_union_types_of_same_kind(const class_or_union *first, const class_or_union *second)
Test if two class or union types are of the same kind.
bool is_at_global_scope(const decl_base &decl)
Tests whether a given declaration is at global scope.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
shared_ptr< variable_suppression > variable_suppression_sptr
A convenience typedef for a shared pointer to variable_suppression.
vector< suppression_sptr > suppressions_type
Convenience typedef for a vector of suppression_sptr.
shared_ptr< function_suppression > function_suppression_sptr
Convenience typedef for a shared pointer to function_suppression.
variable_suppression_sptr is_variable_suppression(const suppression_sptr s)
Test if an instance of suppression is an instance of variable_suppression.
bool is_opaque_type_suppr_spec(const type_suppression &s)
Test if a type suppression specification represents a private type suppression automatically generate...
shared_ptr< type_suppression > type_suppression_sptr
Convenience typedef for a shared pointer to type_suppression.
function_suppression_sptr is_function_suppression(const suppression_sptr suppr)
Test if an instance of suppression is an instance of function_suppression.
type_suppression_sptr is_type_suppression(suppression_sptr suppr)
Test if an instance of suppression is an instance of type_suppression.
shared_ptr< suppression_base > suppression_sptr
Convenience typedef for a shared pointer to a suppression.
bool is_negated_suppression(const suppression_base &s)
Test if a suppression specification is a negated suppression.
Toplevel namespace for libabigail.
A comparison function for instances of base_diff.
A functor to compare instances of class_decl::base_spec.
A functor to compare two changed enumerators, based on their initial value.
size_t count_filtered_bases()
Count the number of bases classes whose changes got filtered out.
class_decl::base_spec_sptr base_has_changed(class_decl::base_spec_sptr) const
Test whether a given base class has changed. A base class has changed if it's in both in deleted *and...
The type of private data of class_or_union_diff.
size_t count_filtered_changed_dm(bool local_only=false)
Get the number of data member changes carried by the current diff node that were filtered out.
size_t count_filtered_subtype_changed_dm(bool local_only=false)
Get the number of data member sub-type changes carried by the current diff node that were filtered ou...
size_t get_deleted_non_static_data_members_number() const
Get the number of non static data members that were deleted.
size_t count_filtered_changed_mem_fns(const diff_context_sptr &)
Get the number of member functions changes carried by the current diff node that were filtered out.
decl_base_sptr subtype_changed_dm(decl_base_sptr) const
Test if the current diff node carries a data member change for a data member which name is the same a...
type_or_decl_base_sptr member_type_has_changed(decl_base_sptr) const
Test if the current diff node carries a member type change for a member type which name is the same a...
decl_base_sptr member_class_tmpl_has_changed(decl_base_sptr) const
Test if the current diff node carries a member class template change for a member class template whic...
size_t count_filtered_inserted_mem_fns(const diff_context_sptr &)
Get the number of member functions insertions carried by the current diff node that were filtered out...
size_t count_filtered_deleted_mem_fns(const diff_context_sptr &)
Get the number of member functions deletions carried by the current diff node that were filtered out.
size_t get_inserted_non_static_data_members_number() const
Get the number of non static data members that were inserted.
The type of the private data of corpus_diff::diff_stats.
bool 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 ...
void ensure_lookup_tables_populated()
If the lookup tables are not yet built, walk the differences and fill the lookup tables.
const vector< diff_sptr > & changed_unreachable_types_sorted() const
Get the sorted vector of diff nodes representing changed unreachable types.
diff_context_sptr get_context()
Getter of the context associated with this corpus.
void categorize_redundant_changed_sub_nodes()
Walk the changed functions and variables diff nodes to categorize redundant nodes.
const string_diff_sptr_map & changed_unreachable_types() const
Get the map of diff nodes representing changed unreachable types.
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...
bool lookup_tables_empty() const
Tests if the lookup tables are empty.
bool deleted_unrefed_fn_sym_is_suppressed(const elf_symbol *) const
Test if the change reports for a given deleted function symbol (that is not referenced by any debug i...
void apply_filters_and_compute_diff_stats(corpus_diff::diff_stats &)
Compute the diff stats.
bool deleted_unreachable_type_is_suppressed(const type_base *t) const
Test if a deleted type that is unreachable from public interface has been suppressed by a suppression...
bool deleted_unrefed_var_sym_is_suppressed(const elf_symbol *) const
Test if the change reports for a given deleted variable symbol (that is not referenced by any debug i...
void maybe_dump_diff_tree()
If the user asked to dump the diff tree node (for changed variables and functions) on the error outpu...
void count_unreachable_types(size_t &num_added, size_t &num_removed, size_t &num_changed, size_t &num_filtered_added, size_t &num_filtered_removed, size_t &num_filtered_changed)
Count the number of types not reachable from the interface (i.e, not reachable from global functions ...
bool deleted_variable_is_suppressed(const var_decl_sptr &var) const
Test if the change reports for a give given deleted variable has been deleted.
void clear_redundancy_categorization()
Walk the changed functions and variables diff nodes and clear the redundancy categorization they migh...
void count_leaf_changes(size_t &num_changes, size_t &num_filtered)
Count the number of leaf changes as well as the number of the changes that have been filtered out.
void count_leaf_type_changes(size_t &num_type_changes, size_t &num_type_changes_filtered)
Count the number of leaf *type* changes as well as the number of the leaf type changes that have been...
bool added_variable_is_suppressed(const var_decl_sptr &var) const
Test if the change reports for a given added variable have been suppressed.
bool added_unrefed_fn_sym_is_suppressed(const elf_symbol *) const
Test if the change reports for a given added function symbol (that is not referenced by any debug inf...
bool deleted_function_is_suppressed(const function_decl *fn) const
Test if the change reports for a given deleted function have been deleted.
void apply_supprs_to_added_removed_fns_vars_unreachable_types()
Apply suppression specifications for this corpus diff to the set of added/removed functions/variables...
void emit_diff_stats(const diff_stats &stats, ostream &out, const string &indent)
Emit the summary of the functions & variables that got removed/changed/added.
bool added_function_is_suppressed(const function_decl *fn) const
Test if the change reports for a give given added function has been deleted.
void clear_lookup_tables()
Clear the lookup tables useful for reporting an enum_diff.
A comparison functor to compare two data members based on their offset.
A comparison functor to compare two instances of var_diff that represent changed data members based o...
A comparison functor for instances of diff.
A functor to compare two instances of diff_sptr.
The private data structure for distinct_diff.
A functor to compare instances of elf_symbol base on their names.
A functor to compare two enumerators based on their value. This implements the "less than" operator.
A comparison functor to compare two instances of fn_parm_diff based on their indexes.
"Less than" functor to compare instances of function_decl.
A "Less Than" functor to compare instance of function_decl_diff.
Functor that compares two function parameters for the purpose of sorting them.
The internal type for the impl idiom implementation of pointer_diff.
The private data of the ptr_to_mbr_diff type.
The internal type for the impl idiom implementation of subrange_diff.
A functor to compare instances of var_decl base on their qualified names.
The internal type for the impl idiom implementation of var_diff.
Functor to sort instances of var_diff_sptr.
A comparison functor for instances of function_decl_diff that represent changes between two virtual m...
An equality functor to deeply compare pointers.
A comparison functor to compare pointer to instances of type_or_decl_base.
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.